ARM的异常处理

ARM的异常处理

    当异常中断发生时,系统执行完当前指令后,将跳转到相应的异常中断处理程序处执行。当异常中断处理程序执行完成后,程序返回到发生中断指令的下条指令处执行。在进入异常中断处理程序时,要保存被中断程序的执行现场,从异常中断处理程序退出时,要恢复被中断程序的执行现场。

     

    1、引起异常的原因
        (1)、指令执行引起的异常
        软件中断、未定义指令(包括所要求的协处理器不存在对于协处理器指令)、预取址中止(存储器故障)、数据中止。
        (2)、外部产生的中断
        复位、FIQ、IRQ。

     

    2、ARM中异常中断的种类
         (1)、复位(RESET)
        a、当处理器复位引脚有效时,系统产生复位异常中断,程序跳转到复位异常中断处理程序处执行,包括系统加电和系统复位。
        b、通过设置PC跳转到复位中断向量处执行称为软复位。
        (2)、未定义的指令
        当ARM处理器或者是系统中的协处理器认为当前指令未定义时,产生未定义的指令异常中断,可以通过改异常中断机制仿真浮点向量运算。
         (3)、软件中断
        这是一个由用户定义的中断指令(SWI)。 该异常由执行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中 。(注意:如果通过程序修改CPSR进入异常模式,硬件将不会将CPSR保存到SPSR中)
        (3)、设置CPSR相应的位进入相应的中断模式。
        (4)、通过设置CPSR的第7位来禁止IRQ。如果异常为快速中断和复位。则还要设置CPSR的第6位来禁止快速中断。
        (5)、给PC强制赋向量地址值。
        ARM处理器内核会自动执行以上几步,程序计数器PC总是跳转到相应的固定地址。
        如果异常发生时,处理器处于Thumb状态,则当异常向量地址加载入PC时,处理器自动切换到ARM状态,则异常处理返回时,自动切换到Thumb状态, 即中断处理只在ARM状态下处理。
     
    4、异常中断处理返回
        异常处理完毕之后,ARM微处理器会执行以下几步操作从异常返回:
        (1)、将所有修改过的用户寄存器从处理程序的保护栈中恢复。
        (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

    _fiq:                     .wordfiq

    碰到异常时,PC会被强制设置为对应的异常向量,从而跳转到相应的处理程序,然后再返回到主程序继续执行。 这些引导程序的中断向量,是仅供引导程序自己使用的,一旦引导程序引导Linux内核完毕后,会使用自己的中断向量。

    ARM发生中断(irq)的时候,总是会跑到0x18上执行啊。那Linux内核又怎么能使用自己的中断向量呢?原因在于Linux内核采用页式存储管理。开通MMU的页面映射以后,CPU所发出的地址就是虚拟地址而不是物理地址。就Linux内核而言,虚拟地址0x18经过映射以后的物理地址就是0xc000 0018。所以Linux把中断向量放到0xc000 0018就可以了。

    异常优先级
    ARM的异常优先级如下表所示:
    异常                           优先级               I位                F位
    复位                               1                     1                   1
    数据中止                       2                     1                   -
    快速中断请求               3                     1                   1
    中断请求                       4                     1                   -
    预取指中止                   5                     1                   -
    软件中断                       6                     1                   -
    未定义指令                   6                     1                   -
    从上表还可以看出, cpsr的I位和F位可以屏蔽或使能某些异常
    复位程序具有最高的优先级,是系统启动(或复位)时调用的程序。1)它应该对异常处理程序的系统进行初始化(包括配置存储器和cache)。2)保证在IRQ和FIQ中断允许之前初始化外部的中断源,避免在还没有设置好相应的处理程序前产生中断。3)设置好各种处理器模式的堆栈指针。
    数据中止异常指示访问了无效的存储器地址,或者当前代码没有正确的数据访问权限。 它不屏蔽FIQ,所以在处理过程中可以处理IRQFIQ中断的优先级比IRQ中断的优先级要高,且 内核进入FIQ处理程序时,把FIQ和IRQ都禁止了,因此,任何外部中断源都不能被处理,如果要实现嵌套或者优先级时就要对上下文进行适当处理然后用软件使能中断。同样,要实现IRQ的嵌套,也要相应的上下文操作和软件开中断, 但IRQ不能屏蔽FIQ请求当IRQ中断请求出现时,只有当FIQ异常和数据中止异常都没有发生时,IRQ处理程序才被调用,并屏蔽IRQ中断,直到中断源被清除。
    预取指中断会屏蔽IRQ异常,但不影响FIQ。     
    当上述的所有异常都没有发生,此时系统可以处理SWI异常,cpsr会被置成管理模式。如果要实现SWI的嵌套,也要保存r14(lr)和spsr。SWI和未定义指令异常共享同一优先级,所以两者不能同时出现。
    我的同类文章
    • 3
      点赞
    • 11
      收藏
      觉得还不错? 一键收藏
    • 0
      评论
    提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值