本博客用于鄙人的每周总结,如有错误不妥之处,还望各位前辈指导。谢谢!
一、中断处理机制
当中断发生的时候,CPU就中断当前的程序,转到中断服务子程序中去执行,CPU从当前程序跳转到中断服务子程序中去执行的这个过程中,需要做很多事情:
1、根据中断类型的不同,跳转到异常向量表的不同位置去查找中断服务程序的地址。
2、进行中断现场的保护。
3、调用中断服务子程序。
4、现场恢复。
下面对这个步骤做进一步的解释。
二、中断向量表
首先,我们需要明白cpu实现中断的方式,或者说它是怎么实现CPU中断这个框架的,CPU发生中断的时候,需要寻找到中断服务子程序的首地址,那么如何寻找到首地址呢。CPU在设计的时候,就固定了一块内存用作中断向量表的地址,以及在各个中断在表中的相对位置是固定,但是这其中基地址可以设置,偏移地址必须保持一致,不然CPU无法正确的进行中断的处理。不同类型的中断发生的时候,CPU就到不同的偏移地址去取得中断服务子程序的地址。
异常向量表
所以,我们要CPU能够进入我们编写的中断子程序中去执行代码,就需要把中断服务子程序的代码的首地址,放到中断向量表中的相应位置中,但是在调用中断服务子程序之前,还需要进行现场保护。
二、现场保护和现场恢复
当中断相应中断的时候,我们需要进行现场保护,现场保护需要做哪些事情了:
1、设置栈地址
2、将R0-R12存储到栈中。
3、中断返回地址的保存
4、CPSR的保存。
5、调用中断服务子程序:使用C语言编写的。
6、现场恢复:需要把保存到栈中的相关数据还原。
程序代码:
RIQ_Handle:
//设置栈地址,为保存数据做准备
ldr sp,=STACK_IRQ
//保存lr,由于arm流水线的原则
sub lr,lr,#4 //lr中存储的是程序发生中断之前的PC的值
//保存r0-r12到栈中
stmfd sp!,{r0-r12,lr} //将lr保存到栈中
//调用中断处理函数
bl exception_irq_hander //调用中断处理子程序
//现场恢复
ldmfd sp!,{r0-r12,pc}^ //^代表的意思是将spsr寄存器中的数值,恢复到对应的CPSR中
备注:ARM流水线的原则:由于流水线的缘故,CPU的PC指针位置是当前程序执行位置+8的位置。所以我们返回的时候,是要返回到发生中断位置的下一句代码处,所以是+4的位置,所以这里需要减4。CPU在每条代码执行结束的时候,会检查系统是否有中断发生。