KEIL写IRQ握手函数的问题[注意]
?当ARM响应IRQ中断的时候,会自动将LR中存放返回地址,并将CPSR复制到相应中断模式下的SPSR中,这些应该都是ARM处理器自动完成的对吗?而且ARM退出中断的时候,复制相应SPSR到CPSR中,也应该是硬件完成的吧?
但是用KEIL下—irq关键字声明的中断函数,我在看汇编的时候,发现中断处理函数只将R0-R6 还有LR进行了压栈,并没有将刚进入中断后的SPSR进行压栈,这样,中断处理函数就有可能在运行过程中更改了SPSR的某些值,而更改后的SPSR在退出中断的时候,重新复制到CPSR,这样很可能会造成当前被打断的程序打断时的CPSR与中断结束后从SPSR复制回CPSR的两个值不同而无法在中断后正常工作啊。
比如我声明的中断握手函数是:__irq void IRQ_Handler (void)
生成的汇编代码是
STMDB R13!,{R0-R6,R12,R14}
并没有相应的保存刚进入中断的SPSR
! 当异常产生时, ARM core:
拷贝 CPSR 到 SPSR_ <mode>
设置适当的 CPSR 位:
改变处理器状态进入 ARM 状态
改变处理器模式进入相应的异常模式
设置中断禁止位禁止相应中断 (如果需要)
保存返回地址到 LR_ <mode>
设置 PC 为相应的异常向量
ARM退出中断的时候是由指令完成的
从SWI 和 Undef异常返回
MOVS pc,lr
从FIQ, IRQ 和 预取异常(Prefect Abort)返回
SUBS pc,lr,#4
从数据异常( Data Abort)返回
SUBS pc,lr,#8 n如果 LR之前被压栈的话使用LDM “ ^”
LDMFD sp!,{pc}^
发表时间:2008年5月13日9:11:25