当异常中断发生时,系统执行完当前指令后,将跳转到相应的异常中断处理程序处执行。当异常中断处理程序执行完成后,程序返回到发生中断指令的下条指令处执行。在进入异常中断处理程序时,要保存被中断程序的执行现场,从异常中断处理程序退出时,要恢复被中断程序的执行现场。
1、引起异常的原因
(1)、指令执行引起的异常
软件中断、未定义指令(包括所要求的协处理器不存在对于协处理器指令)、预取址中止(存储器故障)、数据中止。
(2)、外部产生的中断
复位、FIQ、IRQ。
a、当处理器复位引脚有效时,系统产生复位异常中断,程序跳转到复位异常中断处理程序处执行,包括系统加电和系统复位。
b、通过设置PC跳转到复位中断向量处执行称为软复位。
当ARM处理器或者是系统中的协处理器认为当前指令未定义时,产生未定义的指令异常中断,可以通过改异常中断机制仿真浮点向量运算。
这是一个由用户定义的中断指令(SWI)。 该异常由执行SWI指令产生,可用于用户模式下的程序调用特权操作指令。在实时操作系统中可以通过该机制实现系统功能调用。
如果处理器预取的指令的地址不存在,或者该地址不允许当前指令访问,当被预取的指令执行时,处理器产生指令预取终止异常中断。
如果数据访问指令的目标地址不存在,或者该地址不允许当前指令访问,处理器产生数据访问终止异常中断。
当处理器的外部中断请求引脚有效,而且CPSR的寄存器的I控制位被清除时,处理器产生外部中断请求异常中断。系统中个外设通过该异常中断请求处理服务。
当处理器的外部快速中断请求引脚有效,而且CPSR的F控制位被清除时,处理器产生外部中断请求异常中断。
除了复位异常外,当异常发生时,ARM处理器尽可能完成当前指令(除了复位异常)后,再去处理异常。并执行如下动作:
(2)、将CPSR的内容保存到要执行异常中断模式的SPSR中 。(注意:如果通过程序修改CPSR进入异常模式,硬件将不会将CPSR保存到SPSR中)
(3)、设置CPSR相应的位进入相应的中断模式。
(4)、通过设置CPSR的第7位来禁止IRQ。如果异常为快速中断和复位。则还要设置CPSR的第6位来禁止快速中断。
(5)、给PC强制赋向量地址值。
异常处理完毕之后,ARM微处理器会执行以下几步操作从异常返回:
(2)、将SPSR复制回CPSR中,将连接寄存器LR的值减去相应的偏移量后送到PC中。
(3)、若在进入异常处理时设置了中断禁止位,要在此清除。
当系统运行时,异常可能会随时发生,为保证在ARM处理器发生异常时不至于处于未知状态,在应用程序的设计中,首先要进行异常处理,采用的方式是在异常向量表中的特定位置放置一条跳转指令,跳转到异常处理程序,当ARM处理器发生异常时,程序计数器PC会被强制设置为对应的异常向量,从而跳转到异常处理程序,当异常处理完成以后,返回到主程序继续执行.
向量表是异常发生时,ARM内核跳转地址组成的表,通常用跳转指令跳转到对应的处理程序。
地 址 | 异 常 | 进入模式 |
0x0000,0000 | 复位 | 管理模式 |
0x0000,0004 | 未定义指令 | 未定义模式 |
0x0000,0008 | 软件中断 | 管理模式 |
0x0000,000C | 中止(预取指令) | 中止模式 |
0x0000,0010 | 中止(数据) | 中止模式 |
0x0000,0014 | 保留 | 保留 |
0x0000,0018 | IRQ | IRQ |
0x0000,001C | FIQ | FIQ |
当异常发生时,内核会跳转到向量表的相应位置,并执行当中的指令,通常,在向量表中会存放一些B,LDR PC等跳转指令,用来跳转到对应的处理程序,下面给出一个一地址0x00000000开始的向量表例子:
b reset ; 复位 0x00000000
ldr pc, _undefined_instruction ;未定义的指令异常 0x00000004
ldr pc, _software_interrupt ;软件中断异常 0x000000008
ldr pc, _prefetch_abort ;预取指令 0x0000000c
ldr pc, _data_abort ;数据 0x00000010
ldr pc, _not_used ;未使用 0x00000014
ldr pc, _irq ;慢速中断异常 0x00000018
ldr pc, _fiq ;快速中断异常 0x0000001c
/* 中断向量表入口地址 */
_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .wordnot_used
_irq: .wordirq