程序运行在Supervisor Mode下,当程序做完初始化、中断向量表初始化以后。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
这是一段宏指令,用于下面的程序调用。
MACRO
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0-r1} ;PUSH the work register to stack(lr does't push because it return to original address)
ldr r0,=$HandleLabel;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0-r1,pc} ;POP the work register and pc(jump to ISR)
MEND
LTORG
HandlerIRQ HANDLER AddrIRQ 调用上面的宏,令HandlerIRQ 的内容存放AddrIRQ(0x33ffff18)的地址
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
b ResetHandler 程序的第一条指令,地址为0
省略
b HandlerIRQ 程序的irq指令,地址为0x18,为了让程序跳入AddrIRQ(0x33ffff18)的地址里面存放的中断向量影射函数地址IsrIRQ(0x30000190),
程序应该跳转到IsrIRQ 处执行。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
获得中断类型,依据中断类型查找向量表(见最后),pc跳转到向量表对应的中断服务首地址
IsrIRQ
sub sp,sp,#4 ;reserved for PC
stmfd sp!,{r8-r9}
ldr r9,=INTOFFSET
ldr r9,[r9]依据中断类型
ldr r8,=HandleEINT0
add r8,r8,r9,lsl #2
ldr r8,[r8]查找向量表
str r8,[sp,#8]
ldmfd sp!,{r8-r9,pc}pc跳转到向量表对应的中断服务首地址
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
ResetHandler(程序真正开始执行的地方)
。。。。。。。初始化一些东西
bl InitStacks //各个模式下的堆栈初始化,最后初始化管理模式下的堆栈,[color=#FF0000]并且令管理模式下允许接收irq中断
; Setup IRQ handler设置中断向量表查询入口地址
ldr r0,=HandleIRQ HandleIRQ =0x33ffff18
ldr r1,=IsrIRQ IsrIRQ=0x30000190
str r1,[r0] 意图想在中断来临的时候,程序自动从0x33ffff18 读出0x30000190,并跳转到0x30000190处执行查询中断向量表[/color]
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
AREA RamData, DATA, READWRITE 中断向量表
^ _ISR_STARTADDRESS(ISR_STARTADDRESS==0x33ffff00)
HandleReset # 4
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
AddrIRQ # 4
HandleFIQ # 4
;Don't use the label 'IntVectorTable',
;The value of IntVectorTable is different with the address you think it may be.