异常与中断
6.1 概述
嵌入式系统中,微处理器控制I/O端口或部件的数据传送方式有2种:程序查询方式和中断方式。程序查询方式是由微处理器周期性地执行一段查询程序来读取I/O端口或部件中状态寄存器的内容,并判断其状态,从而使微处理器与I/O端口或部件在进行数据、命令传送时保持同步。程序查询方式下效率非常低,因为微处理器要花费大量时间测试I/O端口或部件的状态。并且I/O端口或部件的数据也不能得到实时地处理。
中断方式是I/O端口或部件在完成了一个I/O操作后,产生一个信号给微处理器,这个信号叫做“中断请求”,微处理器响应这个请求信号,停止其当前的程序操作,而转向对该I/O端口或部件进行新的读/写操作,特点是实时性能好。
早期的嵌入式系统只有中断的概念,而ARM微处理器内核增加了处理器的异常模式。异常包含了中断。
6.2 S5PV210的异常与中断
异常是处理外部异步事件的一种方法,当某个异常发生时,处理器将暂停正常运行的程序;在处理这个异常之前,处理器保留当前处理器状态以便在异常处理程序结束之后恢复原来程序运行。若有两个或更多异常同时发生,处理器将根据优先级来处理这些异常。
异常向量表与8种工作模式
并非一一对应。8种工作模式中的Supervisor和Abort各占用了两个表项,而User、System和Monitor没有任何关联表项,这是因为:
·User模式是程序正常运行模式,不需要进行特殊的异常处理,不是异常模式,所以它没
有占任何表项;
·System是特权模式,但不是异常模式,所以也不需要占用任何表项,System与User完全
共用寄存器,同时有能力进行模式切换(修改PSR寄存器的模式位),所以它是其它特权
模式与User模式的交互桥梁;
·对于Secure Monitor模式来说,是安全模式,需要协处理器来启动该模块,方能工作。
在上表所示的处理器异常中,和中断有关的包括软中断异常、外部中断异常与快速中断异常。
6.3 SWI软中断异常
软中断是软件实现的中断,也就是程序运行时其他程序对它的中断。软中断与硬中断的区别有:
·软中断发生时间由程序控制,而硬中断发生时间随机;
·软中断是由程序调用发生的,而硬中断是由外设引发的。
SWI指令
SWI指令用于产生软中断,从用户模式变换到管理模式,CPSR保存到管理模式的SPSR中。
指令格式如下:
SWI{cond} immed_24 ;immed_24为软中断号(服务类型)
使用SWI指令时,通常使用两种方法进行传递参数:
·指令中24位立即数指定用户请求的服务类型,参数通过通用寄存器传递。
mov r0,#34 ;设置子功能号为34
SWI 12 ;调用12号软中断
·指令中的24位立即数被忽略,用户请求的服务类型有寄存器R0值决定,参数通过其他
的通用寄存器传递。
mov r0,#12 ;调用12号软中断
mov r1,#34 ;设置子功能号为34
SWI 0
SWI异常中断处理程序中,取出SWI立即数的步骤为:
·首先确定引起软中断的SWI指令是ARM指令还是Thumb指令,这可通过对SPSR访问得
到;
·然后取得该SWI指令的地址,这可通过访问LR寄存器得到;
·接着读出指令,分解出立即数。
T_bit EQU 0X20
SWI_Handler
STMFD SP!,{R0-R3,R12,LR} ;现场保护
MOV R1, SP ;得到参数指针
MRS R0,SPSR ;读取SPSR
STMFD SP!,{R0} ;保存SPSR
TST R0,#T_bit
LDRNEH R0,[LR,#-2] ;若是Thumb指令,读取指令码(16位)
BICNE R0,#0XFF00 :取得Thumb指令的8位立即数
LDREQ R0,[LR,#-4] ;若是ARM指令,读取指令码(32位)
BICEQ R0,#0XFF000000 ;取得ARM指令的24位立即数
; R0保存SWI号,而R1保存堆栈内寄存器指针
BL C_SWI_Handler ; 调用中断处理函数
MSR spsr_cf, r0 ;恢复spsr
LDMFD SP!,{R0-R3,R12,PC}^ ;SWI异常中断返回
虽然第一级SWI处理函数(完成中断向量号的提取)必须用汇编语言完成,但具体的中断处理函数可以使用C语言来完成。例如上面所调用的C_SWI_Handler句柄。
void C_SWI_Handler( int swi_num, int *regs )
{
switch(swi_num )
{
case 0:
regs[0] = regs[0] * regs[1];
break;
case 1:
regs[0] = regs[0] + regs[1];
break;
case 2:
regs[0] = (regs[0] * regs[1]) + (regs[2] * regs[3]);
break;
}
}
可以在汇编程序或者C程序中触发SWI中断,调用前设定所有必须的值并发出相关的SWI。例如:
MOV R0, #34
SWI 0x0
6.4 IRQ中断与FIQ中断
ARM微处理器有IRQ中断和FIQ中断两种硬件中断,其响应的优先级不同。但处理步骤类似,包括:
·初始化微处理器中断有关的寄存器,开放中断。
·I/O端口或部件完成数据操作后产生中断请求信号。
·当中断请求信号有效时,微处理器可能处在不可中断状态。等微处理器允许中断时保存当
前状态,停止它现行的操作并开始进行中断源的识别。
·在识别出优先级最高的中断源后,微处理器转到对应的中断服务例程入口,并应答中断,
I/O端口或部件收到应答信号后,撤消其中断请求。
·微处理器读入或写出数据,当中断服务例程结束后,返回到原来的被中断程序处继续执行。
中断源识别
嵌入式系统中,需要采用中断控制方式的I/O端口或部件有许多,而通常微处理器能够提供的中断请求信号线是有限的,如ARM Cortex核提供给外部的中断请求信号线仅有IRQ和FIQ两根。因此,当有中断产生时,微处理器就必须通过一定的方式识别出是哪个中断源发来的请求信号,以便转向其对应的中断服务程序例程,这就是中断源的识别。
中断优先级仲裁
若嵌入式系统中由多个中断源,则这些中断源必须要进行中断优先级的排列。所谓优先级,指的以下两层含义:
·若有2个及2个以上的中断源同时提出中断请求,微处理器先响应哪个中断源,后响应哪
个中断源。
·若1个中断源提出中断请求,并得到响应后,又有1个中断源提出中断请求,后来的中断
源能否中断前一个中断源的中断服务程序。
中断控制器
S5PV210的中断控制器由四个向量中断控制器(VIC)组成,可以支持多达93个中断源以菊花链方式连接一起。
·支持93个向量IRQ中断;
·固定的硬件中断优先级;
·可编程中断优先级;
·支持硬件中断优先级屏蔽;
·可编程中断优先级屏蔽;
·产生IRQ与FIQ;
·产生软件中断;
·测试寄存器;
·原中断状态;
·中断请求状态;
·支持对限制访问特权模式。
6.5 中断相关寄存器
中断状态寄存器VICnIRQSTATUS
快中断状态寄存器VICnFIQSTATUS
中断源未决寄存器VICnRAWINTR
中断选择寄存器VICnINTSELECT
中断使能寄存器VICnINTENABLE
向量地址寄存器VICnADDRESS
向量地址寄存器组VICnVECTADDR[0~31]
向量优先级寄存器VICnVECTPRIORITY