CPU的运行状态有三种:
1、usr 正常工作模式
2、sys 系统模式
3、异常模式
CPU在运行过程中,会被各种“异常”打断。“异常”包括:
1、und 指令未定义
2、SVC 管理模式
3、Abt 中止模式
4、IRQ 中断模式
5、FIQ 快中断模式
CPSR:当前程序状态寄存器(Current Program Status Register)
SPSR:CPSR的备份寄存器
每种异常下都会有特有的一些寄存器(带有三角符号的)
中断处理流程:保存、处理、恢复
arm对异常(中断)处理过程:
① 初始化:
a. 设置中断源,让它可以产生中断
b. 设置中断控制器(可以屏蔽某个中断,优先级)
c. 设置CPU总开关(使能中断)
② 执行其他程序:正常程序
③ 产生中断:比如 按下按键--->中断控制器--->CPU
④ CPU每执行完一条指令都会检查有无中断/异常产生
⑤ CPU发现有中断/异常产生,开始处理
对于不同的异常,跳去不同的地址执行程序。
在地址上,只是一条跳转指令,跳去执行某个函数,这个就是异常向量
软件的任务就是:
a. 保存现场(各种寄存器)CPSR SPSR
b. 处理异常(中断)
分辨中断源,再调用不同的处理函数
c. 恢复现场
下面讲的是如何将 硬件的中断线与软件中断号进行对应:(参考蜗窝科技 谢谢!http://www.wowotech.net/irq_subsystem/irq-domain.html)
具体如何在中断处理过程中,将HW interrupt ID转成IRQ number
在系统的启动过程中,经过了各个interrupt controller以及各个外设驱动的努力,整个interrupt系统的database(将HW interrupt ID转成IRQ number的数据库,这里的数据库不是指SQL lite或者oracle这样通用数据库软件)已经建立。一旦发生硬件中断,经过CPU architecture相关的中断代码之后,会调用irq handler,该函数的一般过程如下:
(1)首先找到root interrupt controller对应的irq domain。
(2)根据HW 寄存器信息和irq domain信息获取HW interrupt ID
(3)调用irq_find_mapping找到HW interrupt ID对应的irq number
(4)调用handle_IRQ(对于ARM平台)来处理该irq number
handle_edge_irq与handle_level_irq中断触发方式的区别:
handle_level_irq在high level handler中首先mask并ack该IRQ。这一点和边缘触发的high level handler有显著的不同,在handle_edge_irq中,我们仅仅是ack了中断,并没有mask,因为边缘触发的中断稍纵即逝,一旦mask了该中断,容易造成中断丢失。而对于电平中断,我们不得不mask住该中断,如果不mask住,只要CPU ack中断,中断控制器将持续的assert CPU中断(因为有效电平状态一直保持)。如果我们mask住该中断,中断控制器将不再转发该interrupt source来的中断,因此,所有的CPU都不会感知到该中断,直到软件unmask。这里的ack是针对interrupt controller的ack,本身ack就是为了clear interrupt controller对该IRQ的状态寄存器,不过由于外部的电平仍然是有效信号,其实未必能清除interrupt controller的中断状态,不过这是和中断控制器硬件实现相关的。