1. 结构框图
这里我以外部中断为例画出了中断响应的过程。
- 当外部中断得到响应,会由硬件自动转到异常向量表,执行对应的异常处理程序。在这里指的就是IRQ的处理程序。
- 在异常处理程序IRQ_handle中将会执行现场的保护与恢复,以及最重要的中断处理函数(注意,这里就来到了中断处理部分,而不是异常处理了,相当于是一个两级的机制)。
- 在中断处理程序irq_handler中(代码如下),将会通过判断中断标志位来找到外部中断到底来自于VIC0/VIC1/VIC2/VIC3。(S5PV210支持多达93个中断,所以有四个中断控制器来控制。)找到之后,调用对应外部中断的处理函数(即VICnADDR指向的函数)。
void irq_handler(void)
{
unsigned long vicaddr[4] = {VIC0ADDR,VIC1ADDR,VIC2ADDR,VIC3ADDR};
int i=0;
void (*isr)(void) = NULL;
for(i=0; i<4; i++)
{
// 发生一个中断时,4个VIC中有3个是全0,1个的其中一位不是0
if(intc_getvicirqstatus(i) != 0)
{
isr = (void (*)(void)) vicaddr[i];
break;
}
}
(*isr)(); // 通过函数指针来调用函数
}
2. 详细讲述如何找到外部中断对应的处理函数
在上面我们提到,S5PV210支持多达93个中断,而在S3C2440中也支持几十个中断,但是两者的处理方式是截然不同的。
- 在S3C2440中,同样也有类似于上图中“外部中断向量表1”这样的表格,但是当一个外部中断发生后,需要通过轮询的方式查找中断标志位得到正确的外部中断编号,然后调用对应的中断处理子函数。这样处理器的响应时间变长,无法适应高实时性要求。
- S5PV210则用硬件更好地解决了问题,以上面的外部中断向量表1为例,如果是其中的中断源发生了中断,那么相应的中断处理函数将会自动复制到VIC0ADDR寄存器当中,不需要人工轮询,只需要将中断处理函数写到“外部中断向量表1”的对应位置处即可,,当然了因为S5PV210有四个VIC,所以还是要轮询四次。
3. 其他
其他诸如中断使能、中断模式(IRQ/FIQ)的选择、中断引脚的相关配置(GPIO设成外部中断、触发方式、中断使能)、清挂起等不在此赘述。