打印
[ZLG-ARM]

ARM 的异常处理

[复制链接]
1042|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
synics|  楼主 | 2009-8-16 15:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
当异常中断发生时,系统执行完当前指令后,将跳转到相应的异常中断处理程序处执行。当异常中断处理程序执行完成后,程序返回到发生中断指令的下条指令处执行。在进入异常中断处理程序时,要保存被中断程序的执行现场,从异常中断处理程序退出时,要恢复被中断程序的执
行现场。
1、引起异常的原因
       对于ARM核,可以且只能识别7种处理器异常,每种异常都对应一种ARM处理器模式,当发生异常时,ARM处理器就切换到相应的异常模式,并调用异常处理程序进行处理。
   
(1)、指令执行引起的异常
    软件中断、未定义指令(包括所要求的协处理器不存在是的协处理器指令)、预取址中止(存储器故障)、数据中止。
   
(2)、外部产生的中断
    复位、FIQ、IRQ。
2、ARM中异常中断的种类
  
  (1)、复位(RESET)
    a、当处理器复位引脚有效时,系统产生复位异常中断,程序跳转到复位异常中断处理程序处执行,包括系统加电和系统复位。
    b、通过设置PC跳转到复位中断向量处执行称为软复位。
    (2)、未定义的指令
    当ARM处理器或者是系统中的协处理器认为当前指令未定义时,产生未定义的指令异常中断,可以通过改异常中断机制仿真浮点向量运算。
   (3)、软件中断
    这是一个由用户定义的中断指令(SWI)。可用于用户模式下的程序调用特权操作指令。在实时操作系统中可以通过该机制实现系统功能调用。
    (4)、指令与取终止(Prefech Abort)
    如果处理器预取的指令的地址不存在,或者该地址不允许当前指令访问,当被预取的指令执行时,处理器产生指令预取终止异常中断。
   
(5)、数据访问终止(DATAABORT)
    如果数据访问指令的目标地址不存在,或者该地址不允许当前指令访问,处理器产生数据访问终止异常中断。
   
(6)、外部中断请求(IRQ)
    当处理器的外部中断请求引脚有效,而且CPSR的寄存器的I控制位被清除时,处理器产生外部中断请求异常中断。系统中个外设通过该异常中断请求处理服务。
    (7)、快速中断请求(FIQ)
    当处理器的外部快速中断请求引脚有效,而且CPSR的F控制位被清除时,处理器产生外部中断请求异常中断。
   
3、异常的响应过程
    除了复位异常外,当异常发生时,ARM处理器尽可能完成当前指令(除了复位异常)后,再去处理异常。并执行如下动作:
    (1)、将引起异常指令的下一条指令的地址保存到新模式的R14中,若异常是从ARM状态进入,LR寄存器中保存的是下一条指令的地址(当前PC+4或PC+8,与异常的类型有关);若异常是从Thumb状态进入,则在LR寄存器中保存当前PC的偏移量,这样,异常处理程序就不需要确定异常是从何种状态进入的。例如:在软件中断异常SWI,指令MOV PC,R14_svc总是返回到下一条指令,不管SWI是在ARM状态执行,还是在Thumb状
态执行。
    (2)、将CPSR的内容保存到要执行异常中断模式的SPSR中。
    (3)、设置CPSR相应的位进入相应的中断模式。
    (4)、通过设置CPSR的第7位来禁止IRQ。如果异常为快速中断和复位。则还要设置CPSR的第6位来禁止快速中断。
    (5)、给PC强制赋向量地址值。
    上面的异常处理操作都是由ARM核硬件逻辑自动完成的,程序计数器PC总是跳转到相应的固定地址。
    如果异常发生时,处理器处于Thumb状态,则当异常向量地址加载入PC时,处理器自动切换到ARM状态,则异常处理返回时,自动切换到Thumb状态。

4、异常中断处理返回
    异常处理完毕之后,ARM微处理器会执行以下几步操作从异常返回:
    (1)、将所有修改过的用户寄存器从处理程序的保护栈中恢复。
    (2)、将SPSR复制回CPSR中,将连接寄存器LR的值减去相应的偏移量后送到PC中。
    (3)、若在进入异常处理时设置了中断禁止位,要在此清除。
    复位异常处理程序不需要返回。

5、软件则需要完成的工作
        软件则需要完成以下工作:

       (1)为ARM核建立异常向量表。ARM体系结构中定义了各种异常的入口地址,例如复位异常的入口地址为0x0,发生复位时,ARM核自动跳转到0x0处开始执行。因此,需要在各入口地址处放一条跳转指令,跳转到相应的异常处理服务程序。因此,异常向量表就是从0x0地址开始的8个字(除了7条跳转到上述异常处理程序的跳转指令外,还有一个保留字)。

       (2)为各种处理器模式设置堆栈:由于异常处理程序中需要用到通用寄存器,因此,进入异常时,应该保存要使用的寄存器,保存方法是将其压入本异常模式下的堆栈,异常处理完毕后返回时,从堆栈中恢复通用寄存器的值。

       (3)编写异常处理服务程序。异常服务程序应首先保护中断现场(将相关寄存器压入堆栈),并判断中断源以执行相应的服务子程序,完成后恢复中断现场并返回。典型的异常处理例程框架如下(以IRQ和FIQ为例):

SUBS      LR, LR, #4                   ;事先修正返回地址

STMFD  SP!, { reglist, LR }        ;保护现场

; ...                                            ;异常处理程序主体

LDMFD  SP!, { reglist, PC }^      ;恢复现场,(^表示将SPSR恢复到CPSR),并将LR出栈送PC返回

注意,各种处理器异常对返回地址的修正是不一样的。可以参考相关资料[1][2][3]。

       STMFD  SP!, { reglist, LR }        ;保护现场

       ; ...                                            ;异常处理程序主体

       LDMFD  SP!, { reglist, LR }        ;恢复现场

       SUBS      PC, LR, #4                   ;修正返回地址并返回

       因此,ARM处理器核心所能处理的就是异常向量表中的7种异常。而在一个具体的ARM芯片中,通常会有多个外部FIQ/IRQ中断源,还会提供一个中断控制器对这些中断源进行集中管理,因此,上面的IRQ/FIQ异常处理例程可以作为一个顶层服务程序,在程序主体中对中断源进行判决,跳转到相应的服务子程序。

     


相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

38

主题

161

帖子

0

粉丝