关于朱有鹏老师中断课程的学习总结
S5PV210的中断系统
首先放一张自己总结的210的中断工作流程图
中断就是当CPU在处理主程序时,突发了一个新任务,然后CPU先暂停主程序,去处理新任务相关部分的代码,处理结束后再回到主程序继续执行的过程。
那我们主要学习的点在哪里?就是学习在SoC中,SoC是如何处理中断的这一系列的操作。
首先是210的工作模式:这里我理解有限,目前只知道在写裸机代码时,正常情况下,SoC是运行在SVC模式下的。当中断到来时,SoC是会自动切换到IRQ模式下运行。
下图是各个模式下对应的寄存器,黑色部分是所有模式公用的寄存器,彩色的则是各个模式专用的寄存器。在什么模式下,就会使用该模式下对应的寄存器来进行数据的运算和处理。
那上图解释了在不同模式下该用哪些寄存器来运算这个问题。还有个问题是怎么找到要处理的那段代码在哪里?
那就要依靠异常向量表以及210的中断寄存器之间的配合了。
什么是异常向量表?
上图就是210的异常向量表。异常向量表其实就是一段有特定意义的特定地址空间。假如Reset异常到来,cpu会马上跳到Reset异常向量对应的地址上来运行。如果是中断到来,则cpu会马上进入IRQ模式,并跳到IRQ异常向量对应的地址上来运行。
210中异常向量表的地址位置是可以修改的。初始化时,210的异常向量表被设置在IRAM中,基地址是0XD0037400。如下图:
这里我定义三个函数:中断预处理函数;中断处理函数;中断最终处理函数
有了异常向量表之后,只要有中断到来,CPU自动会指向IRQ向量的地址去继续执行程序。这时只要在IRQ向量的地址中放入一个函数的入口地址,就可以跳转到相关函数中继续执行了。如果说SoC只有一个中断源,那直接把中断最终处理函数的入口地址放在IRQ向量的地址中,就已经解决了怎么找到要处理的那段代码的问题。
但是问题是210有很多个中断源,而且CPU在不同模式下,有公用的寄存器。所以我们还要保证在模式切换时,公用寄存器中原先模式下的数据不丢失。以及判断出到底是哪一个中断源产生了中断信号,从而选择相应的中断最终处理函数。
为了保证模式切换时,公用寄存器中原先模式下的数据不丢失(原先模式下的寄存器数据一旦丢失,执行完中断再回去工作的时候,就会运行不了)。我们在IRQ向量的地址中放入的是中断预处理函数的入口地址。中断预处理函数的功能:1.设置IRQ模式下的栈空间。2.保存现场,也就是保存下公用寄存器中原先模式下的数据。3.跳转到中断处理函数中。4.恢复现场,也就是将原先模式下公用寄存器中的数据恢复。
在保存完数据后,接下来就要判断到底是那个中断源产生了中断了。这就要依赖与210的中断寄存器了。
210中总共有106个中断源,分为四组(具体几个没数过。但是确实是分成了4组)。每一组的寄存器处了编号功能都是相同的。只是由于中断源太多分为4组管理。
这些寄存器中有几个重要的寄存器:
VICnIRQSTATUS
VICnINTSELECT
VICnINTENABLE
VICnINTENCLEAR
VICnVECTADDR0-31
VICnADDRESS
VICnIRQSTATUS这个寄存器是用来查看每个组中中断源的状态的。
VICnINTSELECT这个寄存器是用来为中断源原则工作方式的:IRQ还是FIQ。
VICnINTENABLE这个寄存器是用来使能相关中断源的。
VICnINTENCLEAR这个寄存器是用来失能相关中断源的。
VICnVECTADDR0-31这个寄存器是用来存放相应中断源的中断最终处理函数的入口地址的。
VICnADDRESS这个寄存器是存放被触发的中断源的中断最终处理函数的入口地址的。
判断中断源的关键寄存器是最后这两类寄存器。VICnVECTADDR0-31这类寄存器,每一组中都有32个。每一个对应一个中断源的中断最终处理函数。我们要自己通过软件实现将每个中断源的中断最终处理函数的入口 地址放到VICnVECTADDR0-31寄存器中。需要在中断被开启之前放入。而VICnADDRESS寄存器的数据是会通过硬件自动放进去的。当某个中断源被触发后,对应的VICnVECTADDR寄存器中的中断最终处理函数的入口地址就被自动放进VICnADDRESS寄存器中。
由于中断源太多,所以在中断处理函数中,主要是在判断到底是哪一个中断源被触发了。并且将相应的中断最终处理函数给找出来跳转执行。
所以总结一下,这三个函数的作用。
1.中断预处理函数:进入IRQ模式之前的相关预处理,栈设置,保存现场,恢复现场,跳转到中断处理函数。
2.中断处理函数:识别出到底是哪个中断源被触发了。并且从VICnADDRESS寄存器中,取出中断最终处理函数的入口地址,并跳转到中断最终处理函数运行。
3.中断最终处理函数:存放着真正的需要被执行的中断处理代码。
最后的工作流程就如第一张图片所述。
最后记录一下为什么FIQ会比IRQ执行的快。
两点原因:
1.FIQ模式有专用的r8-r12寄存器,因此在FIQ模式下,代码处理过程中可以直接使用r8-r12,不需要事先保存之前模式下这些寄存器的数据。从而省下了保存数据的时间。
2.在210的异常向量表中,FIQ是最后一个异常向量入口。因此FIQ不需要像IRQ一样进行跳转。相关的处理代码可以直接从FIQ向量的入口地址接着写下去。减少了程序跳转的时间。