大家应该都玩过中断,也清楚中断的特性。但是今天要讲的是为什么中断会执行到IRQHANDLE函数中。很多时候我们并没有好好考虑到这个问题,因为这些大部分都含在了库函数中,我们只要应用就可以了。这里我通过朱老师ARM裸机了解后,做了总结。
一、一个背景是大家要知道的,就是异常向量表,这是什么呢,这其实是soc内部已经编制好的一张表(S5PV210为例)。看下图:这个表中能看到IRQ所在的地址,当然vector table的基地址我们也能从右边的图上看出来是0xD003 7480(满减栈)。所以IRQ其实是异常向量表中的一部分而已。
二、背景知道后,我们来看下IRQ
IRQ其实是异常向量表中的一种模式而已,硬件在触发中断的时候,cpu的工作模式就切换到了IRQ模式,那么在期间需要执行的是什么呢(异常向量表编程)?
答:S5PV210的异常向量表可以改变(在CP15协处理器中),当我们将异常处理程序的首地址和异常向量表绑定起来标记文本后,异常处理初步阶段就完成了。到目前可以保证相应异常发生后,硬件自动跳转到对应异常向量表入口去执行时,可以执行到我们事先绑定的函数。
#define IRQ_STACK 0xd0037f80
IRQ_handle:
// 设置IRQ模式下的栈
ldr sp, =IRQ_STACK
// 保存LR
// 因为ARM有流水线,所以PC的值会比真正执行的代码+8,
sub lr, lr, #4
// 保存r0-r12和lr到irq模式下的栈上面
stmfd sp!, {r0-r12, lr} //满减栈 保存lr,r0-r12到栈中 ,lr中保存的是中断返回地址
// 在此调用真正的isr来处理中断
bl irq_handler
// 处理完成开始恢复现场,其实就是做中断返回,关键是将r0-r12,pc,cpsr一起回复
ldmfd sp!, {r0-r12, pc}^ //恢复之前保存的状态
代码的详细解释:
(1)中断处理要注意保护现场(中断从SVC模式来,则保存SVC模式下的必要寄存器的值)和恢复现场(中断处理完成后,准备返回SVC模式前,要将保存的SVC模式下的必要寄存器的值恢复回去,不然到了SVC模式后寄存器的值乱了,SVC模式下原来正在进行的常规任务就被你搞坏了)
(2)保存现场包括:第一:设置IRQ栈;第二,保存LR;第三,保存R0~R12
(3)为什么要保存LR寄存器?要考虑中断返回的问题。中断ISR执行完后如何返回SVC模式下去接着执行原来的代码。中断返回其实取决于我们进入中断时如何保存现场。中断返回时关键的2个寄存器就是PC和CPSR。所以我们在进入IRQ模式时,应该将SVC模式下的下一句指令的地址(中断返回地址)和CPSR保存起来,将来恢复时才可以将中断返回地址给PC,将保存的CPSR给CPSR。
(4)中断返回地址就保存在LR中,而CPSR(自动)保存在(IRQ模式下的)SPSR
在下面汇编函数中,用来做中断模式下的现场保护和恢复,并且调用真正的中断处理程序
以上的(4)个步骤是朱老师的笔记中COPY的。
这段代码最重要的其实是把正真的IRQ处理函数链接起来了。
三、链接好了真正的函数后,那么问题来了,中断有很多个,其他中断是怎么一一对应的呢?
1)第一个问题,怎么找到具体是哪个中断:
答:S5PV210中因为支持的中断源很多,所以直接设计了4个中断寄存器,每个32位,每位对应一个中断源。(理论上210最多支持128个中断,实际支持不足128个,有些位是空的);210没有子中断寄存器,每个中断源都是并列的。当中断发生时,在irq_handler中依次去查询4个中断源寄存器,看哪一个的哪一位被置1,则这个位对应的寄存器就发生了中断,即找到了中断编号。
(2)第二个问题,怎么找到对应的isr的问题:
答:210中支持的中断源多了很多,如果还使用2440的那一套来寻找isr地址就太慢了,太影响实时性了。于是210开拓了一种全新的寻找isr的机制。210提供了很多寄存器来解决每个中断源对应isr的寻找问题,具体寻找过程和建立过程见下面,实现的效果是当发生相应中断时,硬件会自动的将相应isr推入一定的寄存器中,我们软件只要去这个寄存器中执行函数就行了。
怎么寻找到个ISR呢?
(1)VICnVECTADDR(n是0~3一共4个32位寄存器) 0到31这32个寄存器分别用来存放真正的各个中断对应的isr的函数地址。相当于每一个中断源都有一个VECTADDR寄存器,程序员在设置中断的时候,把这个中断的isr地址直接放入这个中断对应的VECTADDR寄存器即可。
(2)VICnADDR这个寄存器是只需要读的,它里面的内容是由硬件自动设置的。当发生了相应中断时,硬件会自动识别中断编号,并且会自动找到这个中断的VECTADDR寄存器,然后将其读出复制到VICnADDR中,供我们使用。这样的设计避免了软件查找中断源和isr,节省了时间,提高了210的中断响应速度。