;=========================================
; NAME: 2440INIT.S
; DESC: C start up codes
; Configure memory, ISR ,stacks
; Initialize C-variables
; HISTORY:
; 2002.02.25:kwtark: ver 0.0
; 2002.03.20:purnnamu: Add some functions for testing STOP,Sleep mode
; 2003.03.14:DonGo: Modified for 2440.
;=========================================
001 GET option.inc
002 GET memcfg.inc
003 GET 2440addr.inc
004
005 BIT_SELFREFRESH EQU (1<<22)
006
007 ;Pre-defined constants
008 USERMODE EQU 0x10
009 FIQMODE EQU 0x11
010 IRQMODE EQU 0x12
011 SVCMODE EQU 0x13
012 ABORTMODE EQU 0x17
013 UNDEFMODE EQU 0x1b
014 MODEMASK EQU 0x1f
015 NOINT EQU 0xc0
016
1-16行 EQU伪操作为数字常量,基于寄存器的值和程序中的标号定义一个字符名称。类似于C语言中的#define.在这里,分别定义BIT_SELFREFRESH的值为1<<22及几种处理器模式的值
017 ;The location of stacks
018 UserStack EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 ~
019 SVCStack EQU (_STACK_BASEADDRESS-0x2800) ;0x33ff5800 ~
020 UndefStack EQU (_STACK_BASEADDRESS-0x2400) ;0x33ff5c00 ~
021 AbortStack EQU (_STACK_BASEADDRESS-0x2000) ;0x33ff6000 ~
022 IRQStack EQU (_STACK_BASEADDRESS-0x1000) ;0x33ff7000 ~
023 FIQStack EQU (_STACK_BASEADDRESS-0x0) ;0x33ff8000 ~
024
18-23行几种处理器模式堆栈的基地址。
025 ;Check if tasm.exe(armasm -16 ...@ADS 1.0) is used.
026 GBLL THUMBCODE
027 [ {CONFIG} = 16
028 THUMBCODE SETL {TRUE}
029 CODE32
030 |
031 THUMBCODE SETL {FALSE}
032 ]
033
034 MACRO
035 MOV_PC_LR
036 [ THUMBCODE
037 bx lr
038 |
039 mov pc,lr
040 ]
041 MEND
042
043 MACRO
044 MOVEQ_PC_LR
045 [ THUMBCODE
046 bxeq lr
047 |
048 moveq pc,lr
049 ]
050 MEND
051
052 MACRO
053 $HandlerLabel HANDLER $HandleLabel
054
055 $HandlerLabel
056 sub sp,sp,#4 ;decrement sp(to store jump address)
057 stmfd sp!,{r0} ;PUSH the work register to stack(lr does not push because it return to original address)
058 ldr r0,=$HandleLabel;load the address of HandleXXX to r0
059 ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
060 str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
061 ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
062 MEND
063
第 52-62行MACRO伪操作标识宏定义的开始,MEND标识宏定义的结束。其中$HandlerLabel在展开时被替换成相应的符号,在这里分别被替换为HandlerFIQ、HandlerIRQ、HandlerUndef、HandlerSWI、HandlerDabort、HandlerPabort。$HandleLabel为宏指令的参数,它被替换成HandleFIQ、HandleIRQ、HandleUndef、HandlerSWI、HandleDabort、 HandlePabort。这个宏的作用是,在出现异常中断时找到相应的中断处理函数,也就是传说中的一级向量表。下面用图来表示执行的过程
图1为栈的初始状态,图2为sub sp sp,#4.图3为 stmfd sp!,[R0]
58-59行分别把中断函数的地址赋给R0,然后再R0中的内容赋给R0,相当于把中断处理函数赋给了R0.。
60行把中断处理函数中的值写到SP+4的地址中,也就是图4的表示。
61行出栈,把栈中保存的R0的值写会R0,把PC指针,指向中断处理函数,跳到中断处理函数处。