天嵌 ARM开发社区

 找回密码
 注册
查看: 3738|回复: 1

TQ中断向量表的嵌套

[复制链接]
沈阳TQ-arm 发表于 2010-1-23 17:52:47 | 显示全部楼层 |阅读模式
首先,在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,[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,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,[r0]
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}
其中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,[r0]
中断来了后,产生中断异常,跳转到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,[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,pc}     ;POP the work register and pc(jump to ISR)
系统这时候已经取得了HandleIRQ空间的值,准备跳过去。再最前面,已经设置了HandleIRQ指向了IsrIRQ
所以,程序跳到IsrIRQ。
再IsrIRQ中取得向量地址,并跳过去执行中断程序!
我是沈阳的 欢迎和我探讨 或者需要家教的联系我qq:1092819587我可以交有linux和无linux的arm,cpld,mc51,dsp这些的整个板子的软硬件开发,以及高速pcb的制作,原理图设计。有过几次带本科生和研究生家教的经验。祝您好运!
TQ_guoxixiao 发表于 2012-5-12 15:08:48 | 显示全部楼层
谢谢分享                    
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

i.MX8系列ARM cortex A53 M4 工控板上一条 /1 下一条

Archiver|手机版|小黑屋|天嵌 嵌入式开发社区 ( 粤ICP备11094220号 )

GMT+8, 2024-5-19 10:48 , Processed in 1.031250 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表