ARM启动代码详解 - LPC2104启动代码之Vectors.s注释

来源:互联网 发布:网络搭建项目计划书 编辑:程序博客网 时间:2024/06/01 23:52
; ARM启动代码分析
;     -LPC2104启动代码之Vectors.s注释(用于uC/OS-II 2.52移植)

;LPC2104启动代码之Vectors.s注释(用于uC/OS-II 2.52移植)
;
;******************************************************************************
;Vectors.s
;******************************************************************************
;定义堆栈的大小,根据需要改变
FIQ_STACK_LENGTH     EQU         0
IRQ_STACK_LENGTH     EQU         64
ABT_STACK_LENGTH     EQU         0
UND_STACK_LENGTH     EQU         0
;VICVectAddr寄存器地址
VICVectAddr         EQU         0xFFFFF030
;用于置位程序状态寄存器的I位(IRQ中断屏蔽位)
NoInt       EQU 0x80

;引入的外部标号在这声明
        IMPORT  FIQ_Exception                ;快速中断异常处理程序
        IMPORT  SoftwareInterrupt            ;软中断入口
        IMPORT  Reset                        ;复位向量入口
        IMPORT  OSIntCtxSw                   ;中断中任务切换函数
        IMPORT  OSIntExit                    ;中断退出函数
        IMPORT  OSTCBCur                     ;指向当前任务TCB的指针
        IMPORT  OSTCBHighRdy                 ;指向将要运行的任务TCB的指针(最高优先级任务)
 
        IMPORT  OSIntNesting                 ;中断嵌套计数器


;给外部使用的标号在这声明,InitStack是必须的
        EXPORT  InitStack                     
        EXPORT  Vectors

    CODE32

    AREA    StartUp,CODE,READONLY

    ENTRY
;中断向量表
Vectors
        LDR     PC, ResetAddr
        LDR     PC, UndefinedAddr
        LDR     PC, SWI_Addr
        LDR     PC, PrefetchAddr
        LDR     PC, DataAbortAddr
        DCD     0xb9205f80
        LDR     PC, [PC, #-0xff0]           ;VICVectAddr寄存器的地址0xFFFFF030:PC当前位置是0x18,读出的值为0x18+8 = 0x20,0x20-0xff0 = 0xFFFFF030
        LDR     PC, FIQ_Addr

ResetAddr            DCD     Reset
UndefinedAddr     DCD     Undefined
SWI_Addr            DCD     SoftwareInterrupt
PrefetchAddr        DCD     PrefetchAbort
DataAbortAddr     DCD     DataAbort
nouse                   DCD     0
IRQ_Addr            DCD     IRQ_Handler
FIQ_Addr            DCD     FIQ_Handler

;中断服务程序与C语言的接口的宏定义
    MACRO
$IRQ_Label HANDLER $IRQ_Exception

        EXPORT  $IRQ_Label                  ;输出的标号
        IMPORT  $IRQ_Exception              ;引用的外部标号

$IRQ_Label
        SUB     LR, LR, #4                  ;计算返回地址
        STMFD   SP!, {R0-R3, R12, LR}       ;保存任务环境
        MRS     R3, SPSR                    ;保存状态
        STMFD   SP!, {R3}

        LDR     R2,  =OSIntNesting          ;OSIntNesting++
        LDRB    R1, [R2]
        ADD     R1, R1, #1
        STRB    R1, [R2]
      
        BL      $IRQ_Exception              ;调用C语言的中断处理程序
 ;MSR写状态寄存器指令使得CPSR[7:0]=0b10010010
 ;作用为关IRQ中断
        MSR     CPSR_c, #0x92  
        BL      OSIntExit                   ;调用OSIntExit
 
 ;比较OSTCBHighRdy和OSTCBCur
 ;作用为判断在退出中断处理之后是否进行任务切换
        LDR     R0, =OSTCBHighRdy
        LDR     R0, [R0]
        LDR     R1, =OSTCBCur
        LDR     R1, [R1]
        CMP     R0, R1   
      
        LDMFD   SP!, {R3}  
        MSR     SPSR_cxsf, R3               ;SPSR[31:0]=R3

        LDMEQFD SP!, {R0-R3, R12, PC}^      ;不进行任务切换则恢复任务环境
        LDR     PC, =OSIntCtxSw             ;进行任务切换则调用OSIntCtxSw
    MEND

;未定义指令
Undefined
        b       Undefined

;取指令中止
PrefetchAbort
        b       PrefetchAbort

;取数据中止
DataAbort
        b       DataAbort

;中断(HANDLER宏调用)
IRQ_Handler HANDLER IRQ_Exception

;快速中断
FIQ_Handler
        STMFD   SP!, {R0-R3, LR}
        BL      FIQ_Exception
        LDMFD   SP!, {R0-R3, LR}
        SUBS    PC,  LR,  #4

;定时器0中断(HANDLER宏调用)
Timer0_Handler  HANDLER Timer0

;/***********************************************************************************
;**函数名称: InitStack
;** 功能描述: 初始化堆栈
;** 输 入:   无
;** 输 出 :  无
;** 全局变量: 无
;** 调用模块: 无
;***********************************************************************************
InitStack  
        MOV     R0, LR                    ;使用R0来保存返回地址
;设置中断模式堆栈
        MSR     CPSR_c, #0xd2
        LDR     SP, StackIrq
;设置快速中断模式堆栈
        MSR     CPSR_c, #0xd1
        LDR     SP, StackFiq
;设置中止模式堆栈
        MSR     CPSR_c, #0xd7
        LDR     SP, StackAbt
;设置未定义模式堆栈
        MSR     CPSR_c, #0xdb
        LDR     SP, StackUnd
;设置系统模式堆栈
        MSR     CPSR_c, #0xdf
        LDR     SP, StackIrq
        MOV     PC, R0                    ;使用R0来返回

StackIrq            DCD     (IrqStackSpace + IRQ_STACK_LENGTH * 4 - 4)
StackFiq            DCD     (FiqStackSpace + FIQ_STACK_LENGTH * 4 - 4)
StackAbt           DCD     (AbtStackSpace + ABT_STACK_LENGTH * 4 - 4)
StackUnd          DCD     (UndtStackSpace + UND_STACK_LENGTH * 4 - 4)

;/* 分配堆栈空间 */
        AREA    MyStacks, DATA, NOINIT
IrqStackSpace      SPACE   IRQ_STACK_LENGTH * 4   ;中断模式堆栈空间
FiqStackSpace      SPACE   FIQ_STACK_LENGTH * 4   ;快速中断模式堆栈空间
AbtStackSpace      SPACE   ABT_STACK_LENGTH * 4   ;中止义模式堆栈空间
UndtStackSpace     SPACE   UND_STACK_LENGTH * 4   ;未定义模式堆栈

        END
原创粉丝点击