ARM架构之异常处理

简介

本文内容主要从四个方面介绍ARM中断。

1、中断和异常相关的内容。

2、ARM中断响应和退出过程。

3、异常中断程序的安装

4、FIQ和IRQ异常中断处理程序

5、SWI软件中断异常处理程序

异常和中断

异常和中断是这样一个过程:当CPU内部或者外部出现某种事件(中断源)需要处理时,暂停正在执行的程序(断点),转去执行请求中断的那个事件的处理程序(中断服务程序),执行完成后,在返回被暂停执行的程序(中断返回),从断点处继续执行。其执行流程如下图所示。

在这里插入图片描述

异常和中断的处理过程基本一致,但二者并不是完全等同,习惯上将CPU内部产生中断叫异常,外部控制器产生中断叫中断。本文无特别说明,统一将中断和异常称为异常。

ARM有7种类型的异常,按优先级从高到低的排列如下:复位异常(Reset)、数据异常(Data Abort)、快速中断异常(FIQ)、外部中断异常(IRQ)、预取异常(Prefetch Abort)、软件中断(SWI)和未定义指令异常(Undefined instruction)。

异常种类和异常向量表

ARM体系结构中,存在7种异常。当异常发生时,处理器会把PC设置为一个特定的存储器地址。这一地址放在被称为向量表(vector table)的特定地址范围内。向量表的入口是一些跳转指令,跳转到专门处理某个异常或中断的子程序。存储器映射地址0x00000000是为向量表(一组32位字)保留的。在有些处理器中,向量表可以选择定位在存储空间的高地址(从偏移量 0xffff0000开始)。前面文档中已经说过,ARM有7种工作模式,处理用户模式外其他6种工作模式属于特权模式,特权模式中除了系统模式之外其他的都是异常模式,5种异常模式对应着系统的7种异常。对应的异常关系如下表所示。
在这里插入图片描述

向量表的入口是一些跳转指令,跳转到专门处理某个异常或中断的子程序,常见的跳转指令有:

(1) B <Addr>

这条分支指令实现了相对于PC的分支跳转,跳转的范围为PC向前或者向后的32M的空间。

(2) LDR PC, [PC , #offset]

这条指令是把异常处理程序的入口地址装载到PC,该地址是一个32位的绝对地址,可以访问到存储器的4G的空间范围。

(3) MOV PC, #Immediate

这条MOV指令把一个立即数复制到PC,该指令和第二指令一样可以跨越全部的地址空间,但是该指令受到地址对齐的限制,即立即数必须是一个8位立即数循环右移偶数次得到的结果。例如“MOV PC, #0x30000000”是合法的,因为0x30000000可以通过0x03循环右移4位得到。

每个异常发生时,总是从异常向量表开始起跳的,如下图所示,向量表里的每一条指令直接跳向对应的异常处理函数,其中,FIQ_Handleer()可以直接从地址0x1C处开始,从而节省了一条跳转指令,提高了FIQ的处理速度。

在这里插入图片描述

异常优先级

异常可以同时发生,当多个异常同时发生时,系统根据固定的优先级决定异常的处理次序,异常优先级由高到低排列次序如下表所示:
在这里插入图片描述
例如,复位异常的优先级最高,处理器上电时发生复位异常。所以当产生复位时,它将优先于其他异常得到处理。同样,当一个数据访问中止异常发生时,它将优先于除复位异常外的其他所有异常。优先级最低的2种异常是软件中断和未定义指令异常。因为正在执行的指令不可能既是一条SWI指令,又是一条未定义指令,所以软件中断异常SWI和未定义指令异享有相同的优先级。

ARM异常中断的处理过程

异常中断的响应过程

当一个异常出现以后,ARM微处理器会执行以下几步操作(由硬件自动执行):

1、保存处理器当前状态、中断屏蔽位以及各条件标志位。

这是通过将当前程序状态寄存器CPSR的内容赋值到要执行异常中断对应模式下的SPSR寄存器中实现的。

2、设置当前程序状态寄存器CPSR中对应的位。

  • 改变处理器状态进入ARM状态。
  • 改变处理器模式进入相应的异常模式。
  • 设置中断禁止位禁止相应的中断。

3、保存返回地址

将下一条指令的地址存入相应的连接寄存器LR,以便程序在异常返回时能从正确的位置重新开始执行。若异常是从ARM状态进入,则LR寄存器中保存的是下一条指令的地址(发生中断时的指令PC+4或者+8,与异常类型有关);从Thumb状态进入的内容将在Thumb小节中介绍。

4、执行中断处理程序。

强制PC从相关的异常向量地址取下一条指令执行,从而跳转到相应的异常处理程序。

当异常发生时,操作伪指令如下:

R14_<exception_mode> = return link 
SPSR_<exception_mode> = CPSR 
CPSR[4∶0] = exception mode number
CPSR[5] = 0                    /*进入 ARM 状态*/
If <exception_mode> = = reset or FIQ then
     CPSR[6] = 1               /*屏蔽快速中断 FIQ*/ 
CPSR[7] = 1                    /*屏蔽外部中断 IRQ*/ 
PC = exception vector address

处理器的状态判断

当异常发生时,处理器自动切换到ARM状态,但是在异常处理函数中要判断异常发生前处理器是ARM状态还是Thumb状态。这可以通过检测SPSR的T位来判断。

通常情况下,只有在SWI处理函数中才需要知道异常发生前处理器的状态。主要原因是响应SWI异常时,需要读取swi指令获取swi指令的请求立即数, 由于ARM状态和Thumb状态下swi指令的长度一样,所以Thumb状态下,调用SWI软中断异常必须注意以下两点。

① 发生异常的指令地址为(lr-2)而不是(lr-4)。

② Thumb状态下的指令是16位的,在判断中断向量号时使用半字加载指令LDRH。

下面的例子显示了一个标准的SWI处理函数,在函数中通过SPSR的T位判断异常发生前的处理器状态。

    T_bit EQU 0x20                ; bit 5. SPSR 中的 ARM/Thumb 状态位, 
    : 
    : 
SWIHandler  
    STMFD sp!, {r0-r3,r12,lr}     ; 寄存器压栈,保护程序现场
    MRS r0, spsr            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值