ARM异常处理(IRQ中断处理)总结1
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ARM异常处理(IRQ中断处理)总结1相关的知识,希望对你有一定的参考价值。
ARM A8的异常处理表如下
可以看到vector table的基地址是不固定的但是所有异常的偏移地址是固定的。这张表也为了体现这个偏移量,还有要从硬件角度理解的是在CPU设计的时候这些异常就已经定义好了在发生相应的异常时候CPU就自动的转到在异常向量表里的地址处去执行这个过程是不需要软件干预的因此就简单了我们只要把出现相应的异常时候处理过程的函数名(函数名就是这个函数体的指针)放在相应的地址里边就可以执行了举例说明。以三星S5PV210为例,我们根据官方的Application Node可以查到在iROM中定义的Exeception vector table的基地址是0xD003_7400(其实这个地址在移植操作系统后会更改)那么我们就根据上图中的偏移地址可以把定义好的异常处理函数直接放在相对应的地址上代码可以写成
#define Exception_base 0xd0037400
#defien Exception_rest (Exception_base + 0x00)
#define rException_rest ((volatile unsigned int)Exception_rest)
假如用C语言定义了一个void ex_rest(void)函数那么就可以rException_rest=ex_rest;
这样的话就可以在产生REST异常的时候直接跳转到ex_rest这个函数执行了。
但是中断就要不一样一些因为中断是需要返回的因此需要考虑的问题是如何保存CPU的上下文,这个一般都在汇编中实现(其实也是格式化了的已经)一般的写法都是
ldr sp, =IRQ_STACK
sub lr, lr, #4
stmfd sp!, {r0-r12, lr}
bl irq_handler
ldmfd sp!, {r0-r12, pc}^
这个段代码要理解需要了解三个知识点:
第一:ldr sp, =IRQ_STACK这是在给C语言提供栈的保障可以让C语言运行。
第二:sub lr, lr, #4和 stmfd sp!, {r0-r12, lr}
先要了解下面这张图
我们现在要从SVC转换模式到IRQ因此需要保存的寄存器是R0~R12因为是共用的这两个模式之间,还有一个就是SVC下的PC(在模式跳转的时候硬件会把SVC下的PC直接保存到IRQ下的lr里边)因为不保存这个就没办法返回了但是要减4个字节这是因为ARM的流水线的缘故(大概了解流水线反正你记住ARM的流水线都是提前4个字节就可以了)这条语句就把所有的需要保存的数据都保存到了IRQ下的栈里边了,其实同时CPU也帮你把CPSR保存到了SPSR里边去了这个过程是自动的。
第三: ldmfd sp!, {r0-r12, pc}^
这个过程和上面的压栈过程正好是相反的这个好理解主要是后边的‘^’符号的作用这个符号就是把SPSR里的内容直接回复给CPSR这样就完全回到了SVC模式中断完美返回了。
以上是关于ARM异常处理(IRQ中断处理)总结1的主要内容,如果未能解决你的问题,请参考以下文章