TQ中断向量表的嵌套
首先,在2410init.s 文件的最前面,存放着一些异常跳转的指令,必须保证他们在如下地址。如果是从Nor Flash或Nand Flash启动,那么2410init开始在0x00000000地址,他们可以保证满
足,如果是从SDRAM调试,那么就必须经过MMU地址映射
b ResetHandler ;地址0x00000000
b HandlerUndef ;地址0x00000004
b HandlerSWI ;地址0x00000008
b HandlerPabort ;地址0x0000000c
b HandlerDabort ;地址0x00000010
b . ;reserved ;地址0x00000014
b HandlerIRQ ;地址0x00000018
b HandlerFIQ ;地址0x0000001c
再看后面代码
HandlerFIQ HANDLER HandleFIQ
HandlerIRQ HANDLER HandleIRQ
HandlerUndef HANDLER HandleUndef
HandlerSWI HANDLER HandleSWI
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort
这是调用HANDLER宏,上面的调用都会被宏展开,注意HANDLER前后的文字是不一样的,一个是HandlerXXX一各是HandleXXX。HandlerXXX再最前面的跳转里已经出现了,那HandleXXX是什么呢,稍后说明,先看看宏定义
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} ;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, ;load the contents(service routine start address) of
HandleXXX
str r0, ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
MEND
宏的作用就是保存返回地址,以便退出异常模式时能继续执行程序,跳转到异常向量所指向的地
址执行异常处理程序,然后返回,那么HandleXXX肯定是异常向量的地址了,在2410init.s文件的最后可以找到
^ _ISR_STARTADDRESS
HandleReset # 4
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
HandleFIQ # 4
上面符号^ 是MAP的简写形式,再option.s里有定义 _ISR_STARTADDRESS EQU 0x33ffff00,这是一个内存地址。
在程序真正开始有,有一段代码,就是设置这个内存空间,让其指向IsrIRQ
ldr r0,=HandleIRQ ;This routine is needed
ldr r1,=IsrIRQ ;hjhhhhh
str r1,
IsrIRQ 如下
sub sp,sp,#4 ;reserved for PC
stmfd sp!,{r8-r9}
ldr r9,=INTOFFSET
ldr r9,
ldr r8,=HandleEINT0
add r8,r8,r9,lsl #2
ldr r8,
str r8,
ldmfd sp!,{r8-r9,pc}
其中HandleEINT0是第一个中断的向量地址,其他的从这个偏移得来,如下
HandleEINT0 # 4
HandleEINT1 # 4
HandleEINT2 # 4
HandleEINT3 # 4
HandleEINT4_7 # 4
HandleEINT8_23 # 4
HandleRSV6 # 4
HandleBATFLT # 4
HandleTICK # 4
HandleWDT # 4
HandleTIMER0 # 4
HandleTIMER1 # 4
HandleTIMER2 # 4
HandleTIMER3 # 4
HandleTIMER4 # 4
HandleUART2 # 4
HandleLCD # 4
HandleDMA0 # 4
HandleDMA1 # 4
HandleDMA2 # 4
HandleDMA3 # 4
HandleMMC # 4
HandleSPI0 # 4
HandleUART1 # 4
HandleRSV24 # 4
HandleUSBD # 4
HandleUSBH # 4
HandleIIC # 4
HandleUART0 # 4
HandleSPI1 # 4
HandleRTC # 4
HandleADC # 4
分析中断处理的整个过程:首先执行了这段代码
ldr r0,=HandleIRQ ;This routine is needed
ldr r1,=IsrIRQ ;hjhhhhh
str r1,
中断来了后,产生中断异常,跳转到0x00000018
0x00000018 放着一条指令
b HandlerIRQ ;地址0x00000018
跳转到了HanderIRQ
中断宏展开后,如下:
HandlerIRQ
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} ;PUSH the work register to stack(lr does't push because it
return to original address)
ldr r0,=$HandleIRQ; load the address of HandleXXX to r0
;这个地址是 _ISR_STARTADDRESS+0x1c
ldr r0, ;load the contents(service routine start address) of
HandleXXX
str r0, ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
系统这时候已经取得了HandleIRQ空间的值,准备跳过去。再最前面,已经设置了HandleIRQ指向了IsrIRQ
所以,程序跳到IsrIRQ。
再IsrIRQ中取得向量地址,并跳过去执行中断程序!
我是沈阳的 欢迎和我探讨 或者需要家教的联系我qq:1092819587我可以交有linux和无linux的arm,cpld,mc51,dsp这些的整个板子的软硬件开发,以及高速pcb的制作,原理图设计。有过几次带本科生和研究生家教的经验。祝您好运! 谢谢分享
页:
[1]