ARM中断宏定义
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;decrement sp(to store jump address) 存贮PC跳转地址
stmfd sp!,{r0} ;PUSH the work register to stack(lr does not 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
MACRO相当于c中的#define
而$HandlerLabel 和 $HandleLabel是两个参数,大家注意,第一个参数和第二个参数是不一样的,中间少了个r
而第一个参数在本宏中是一个标号,而第二个函数是一个入口地址
以下有定义:
HandlerFIQ HANDLER HandleFIQ
HandlerIRQ HANDLER HandleIRQ
HandlerUndef HANDLER HandleUndef
HandlerSWI HANDLER HandleSWI
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort
拿HandlerSWI HANDLER HandleSWI说明:把它用宏给替换下来以后是:
$HandlerSWI
1:sub sp,sp,#4 ;decrement sp(to store jump address) 存贮PC跳转地址
2:stmfd sp!,{r0} ;PUSH the work register to stack(lr does not push because it return to original address)
3:ldr r0,=$HandleSWI ;load the address of HandleXXX to r0
4:ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
5:str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
6:ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
这段宏定义的作用是什么呢?是安装SWI中断,如何安装的呢?
sub sp,sp,#4 是把SP的地址减4字节,而这个地方需要存放跳转地址也就是第5行的HandleSWI指向的内容(ISR)
接下来是压栈所需要的寄存器r0,因为接下来需要使用r0所以先压栈r0,这也是为什么刚刚先把SP加四字节的原因,第6句话就是跳转到刚刚第5句所压栈的地址处,也就是HandleSWI指向的内容(ISR)处
这里有一句话不是很明白,就是r0,这样压栈又出栈,跟没有压和出有什么区别,也就是说,上下文的内容一样了,破坏了中断前的r0,返回后的r0不再是原先的r0了,不理解?
VectorsAddr
LDR PC, Reset_Addr
LDR PC, Undefined_Addr
LDR PC, SWI_Addr
LDR PC, Prefetch_Addr
LDR PC, Abort_Addr
NOP ; Reserved vector
LDR PC, IRQ_Addr
LDR PC, FIQ_Addr
EXPORT VectorsAddr
Reset_Addr DCD ResetHandler ;第一次地址转换
Undefined_Addr DCD HandlerUndef
SWI_Addr DCD HandlerSWI
Prefetch_Addr DCD HandlerPabort
Abort_Addr DCD HandlerDabort
IRQ_Addr DCD HandlerIRQ
FIQ_Addr DCD HandlerFIQ
按照我的想法执行中断时是这样的:
首先PC->0x30000000比如说这个地址是IRQ_Addr ,因为DCD是接下来的连续的4字节,PC需要执行
PC->0x30000004这个地址就是执行的HandlerIRQ,而这个地址根据上面安装好的中断,它应该是一个指针,也就是说PC执行的这一句话是一个跳转指令,因为HandlerIRQ是一个指针,那么应该跳到HandlerIRQ所指地方处运行,HandlerIRQ所指的就是真正的中断程序IRQ_ISR,大家看这里使用了两次地址转换,第一次是顺序执行,第二次才是真正的跳转,那么我们在安装中断时就是在第二次的地方改变HandlerIRQ所指向的函数就可以控制中断函数的不同。
MACRO ;宏定义开始
MOV_PC_LR ;宏的名字
[THUMBCODE ;表示在Thumb工作状态
bxlr ;分支到 Thumb 代码 lr
|
movpc,lr ;把lr 保存到PC指针
]
MEND ;宏定义结束
;arm处理器有两种工作状态
1.arm:32位 这种工作状态下执行字对准的arm指令
2.Thumb:16位 这种工作状态执行半字对准的Thumb指令
;因为处理器分为16位 32位两种工作状态 程序的编译器也是分16位和32两种编译方式 所以下面的程序用于根据处理器工作状态确定编译器编译方式
;co
;co
;这段是为了统一目前的处理器工作状态和软件编译方式(16位编译环境使用tasm.exe编译)
另外
[ =if
| =else
] =end if
ARM中断宏定 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)