分类: 嵌入式
2011-12-11 16:21:26
ARM处理器异常处理
1 异常分类
(1) 复位异常。当CPU刚上电时或按下reset重启键之后进入该异常,该异常在管理模式下处理。
(2) 一般/快速中断请求。 CPU和外围设备是分别独立的硬件执行单元,CPU对全部设备进行管理和资源调度处理,CPU要想知道外围设备的运行状态,要么CPU定时的去查看外围设备特定寄存器,要么让外围设备在出现需要CPU干涉处理时“打断”CPU,让它来处理外围设备的请求,第二种即为中断请求,分一般中断和快速中断。
(3) 预取指令中止异常。该异常发生在CPU流水线取指令阶段,如果目标指令地址是非法地址则进入该异常,该异常在中止异常模式下处理。
(4) 未定义指令异常。该异常发生在流水线处理技术中的译码阶段。如果当前指令不能被识别为有效指令,则产生未定义指令异常,该异常在未定义异常模式下处理。
(5) 软件中断指令(swi)异常。该异常是应用程序自己调用时产生的,用于用户程序申请访问硬件资源时,而用户程序又没有外设硬件的使用权,只能通过使用软件中断指令切换到内核态,通过操作系统内核代码来访问外设硬件,内核态是工作在特权模式下。这样做的目的是保护操作系统的安全和硬件资源的合理使用,该异常在管理模式下处理。
(6) 数据中止访问异常。该异常发生在要访问数据地址不存在或者为非法地址时,该异常在中止异常模式下处理。
在异常发生后,ARM内核会自动做以下工作:
1) 保存执行状态:将CPSR复制到发生的异常模式下的SPSR中。
2) 模式切换:将CPSR模式位强制设置为与异常类型相对应的值,同时处理器进入到ARM执行模式,禁止所有IRQ中断,当进入FIQ快速中断模式时禁止FIQ中断。
3) 保存返回地址:将下一条指令的地址(被打断程序)保存在LR(异常模式下LR_excep)中。
4) 跳入异常向量表:强制设置PC的值为相应异常向量地址,跳转到异常处理程序中。
异常返回地址:
CPU使用流水线技术,造成当前执行指令的地址应该是PC-8(32位机一条指令4字节),那么执行指令的下一条指令应该是PC-4。在异常发生时,CPU自动会将PC-4的值保存在LR里,但是该值是否正确还要看异常类型才能决定。
1) 一般/快速中断请求:通常处理器执行完当前指令后,查询FIQ/IRQ中断引脚,并查看是否允许中断,如果某个中断有效,并且系统允许该中断产生,处理器将产生FIQ/IRQ异常中断,当FIQ/IRQ异常中断产生时,程序计数器PC的值已经更新,它指向当前指令后面第3条指令(对ARM指令,它指向当前指令地址加12字节的位置;对Thumb指令,它指向当前指令地址加6字节的位置),当FIQ/IRQ异常中断产生时,处理器将值(PC-4)保存到FIQ/IRQ异常模式一的寄存器lr_irq中,它指向当前指令之后的第2第指令,因此正确的返回的地址可以通过下面指令算出:
SUBS PC,LR_irq, #4
SUBS PC,LR_fiq, #4
2)预取指令中止异常。在指令预取时,如果目标地址是非法的,该指令被标记成有问题的指令,这时,流水上线的该指令之前的指令继续执行,当执行到该被标记成有问题的指令时,处理器产生指令预取中止异常中断。发生指令预取异常中断时,程序要返回到该有问题的指令处,重新读取并执行该指令。因此指令预取中止异常中断应该返回到该指令预取中止异常中断的指令处,而不是当前指令的下一条指令。
指令预取中止异常中断由当前执行的指令在ALU里执行时产生,当指令预取中止异常中断发生时,程序计数器PC的值还未更新,它指向 前指令后面第二条指令(ARM为当前指令地址加8字节的位置,Thumb为当前指令地址加4指令的位置)。此时处理器将值(PC-4)保存到lr_abt中,它指向当前指令的下一条指令,所以返回操作可以通过下面的指令实现。
SUBS PC, LR_abt, #4
3) 未定义指令异常:未定义指令异常中断由当前执行的指令在ALU里执行时产生,当未定义异常中断发生时,程序计数器PC的值还未更新,它指向 前指令后面第二条指令(ARM为当前指令地址加8字节的位置,Thumb为当前指令地址加4指令的位置)。此时处理器将值(PC-4)保存到lr_und中,它指向当前指令的下一条指令,所以返回操作可以通过下面的指令实现。
MOV PC, LR_und
4) 软中断指令(SWI)异常。SWI异常中断和未定义异常中断一样,也是由当前执行的指令在ALU里执行时产生,当SWI指令执行时,PC的值还未更新,定指向当前指令后面的第二条指令(ARM为当前指令地址加8字节的位置,Thumb为当前指令地址加4指令的位置),当软中断发生,处理器将值(PC-4)保存到lr_SVC中,此时(PC-4)指向当前指令的下一条指令,所以从SWI异常中断处理返回的实现与未定义指令异常中断处理返回一样。
MOV PC, LR_svc
5) 数据中止异常:发生在数据访问异常中断时,程序要返回到该有问题的指令处,重新访问该数据,因此数据访问异常中断应该返回到产生该数据访问中断异常的指令处,而不是当前指令的下一条指令。
数据访问异常中断由当前执行的指令在ALU里执行时产生,当数据访问异常中断发生时,程序计数器PC的值已更新,它指向前指令后面第3条指令(ARM为当前指令地址加12字节的位置,Thumb为当前指令地址加6指令的位置)。此时处理器将值(PC-4)保存到lr_und中,它指向当前指令后面第2条指令,所以返回操作可以通过下面的指令实现。
SUBS PC,LR_abt, #8
异常向量表:
异常向量表是一段特定内在地址空间,每种ARM异常对应一个字长空间(4byte),正好是一条32位指令长度,当异常发生时,CPU强制将PC的值设置为当前异常对应的固定内在地址。异常向量是一个固定的内存地址,我们可以通过向该地址处写一条跳转指令,让它跳向我们自己定义的异常处理程序入口,就可以完成异常处理。
异常处理程序的入口里先要保存打断程序现场。在跳转到异常处理程序入口时,已经切换到对应异常模式下了,因此这时的SP已经是异常模式下的SP_excep,所以被打断程序现场是保存在异常模式下的栈里。
异常处理返回:
1) 恢复被打断程序运行时的寄存器数据。
2) 恢复程序运行时状态CPSR
3) 通过进入异常时保存的返回地址,返回到被打断程序继续执行。