异常源及处理过程

  • 模式回顾:
ARM7-117种基本工作模式:(不同的模式下干不同的事,效率高)
User :  非特权模式,大部分任务执行在这种模式
FIQ :   当一个高优先级(fast) 中断产生时将会进入这种模式
IRQ :   当一个低优先级(normal) 中断产生时将会进入这种模式
Supervisor :  当复位或软中断指令执行时将会进入这种模式
Abort :   当存取异常时将会进入这种模式
Undef :   当执行未定义指令时会进入这种模式
System :  使用和User模式相同寄存器集的特权模式
Cortex-A特有模式:
Monitor : 是为了安全而扩展出的用于执行安全监控代码的模式;也是一种特权模式

异常

        异常是理解CPU运转最重要的一个知识点,几乎每种处理器都支持特定异常处理,中断是异常中的一种。 有时候我们衡量一个操作系统的实时性就是看os最短响应中断时间以及单位时间内响应中断次数。

注:处理器遇到异常后会暂停当前的程序转而去处理异常(执行异常处理程序), 处理完成后返回到被异常打断的代码处继续执行

异常源

导致异常产生的事件有7个:FIQ、IRQ(接触最多)、Reset(复位)、软中断、DataAbort、PrefetchAbort、Undef。

1reset复位异常 (svc
CPU刚上电时或按下reset重启键之后进入该异常,该异常在管理模式下处理。
    
2irq/fiq一般/快速中断请求  (irqfiq
        CPU和外部设备是分别独立的硬件执行单元,CPU对全部设备进行管理和资源调度处理,CPU要想
知道外部设备的运行状态,要么CPU定时的去查看外部设备特定寄存器,要么让外部设备在出现需要CPU干
涉处理时“打断”CPU,让它来处理外部设备的请求,毫无疑问第二种方式更合理,可以让CPU“专心”去工作
,这里的“打断”操作就叫做中断请求,根据请求的紧急情况,中断请求分一般中断和快速中断,快速中断
具有最高中断优先级和最小的中断延迟,通常用于处理高速数据传输及通道的中数据恢复处理,如DMA等,
绝大部分外设使用一般中断请求。
        
3》预取指令中止异常     PrefetchAbortabort
      该异常发生在CPU流水线取指阶段,如果目标指令地址是非法地址进入该异常,该异常在中止异常
模式下处理。
      
4》未定义指令异常(Undef
该异常发生在流水线技术里的译码阶段,如果当前指令不能被识别为有效指令,产生未定义指令异常,
该异常在未定义异常模式下处理。

5》软件中断指令(swi)异常 (svc
         该异常是应用程序自己调用时产生的,用于用户程序申请访问硬件资源时,例如:printf()打
印函数,要将用户数据打印到显示器上,用户程序要想实现打印必须申请使用显示器,而用户程序又没有
外设硬件的使用权,只能通过使用软件中断指令切换到内核态,通过操作系统内核代码来访问外设硬件,
内核态是工作在特权模式下,操作系统在特权模式下完成将用户数据打印到显示器上。这样做的目的无非
是为了保护操作系统的安全和硬件资源的合理使用,该异常在管理模式下处理。
         
6》数据中止访问异常 DataAbortAbort
该异常发生在要访问数据地址不存在或者为非法地址时,该异常在中止异常模式下处理。

异常处理*****

步骤(自动完成):

1.拷贝CPSR到SPSR_<mode>

将正在运行的模式的cpsr保存到对应异常模式下的spsr中。

2.修改CPSR:(修改cpsr让它切换到对应异常模式下)

a.进入ARM状态 (强制)

b.进入相应的异常模式 (切换模式)

c.禁止相应中断 (再来异常,不会打断当前的异常处理)

3.保存返回地址到LR_<mode>

跳转到异常处理(修改的是pc)之前,将pc下一条指令地址保存lr中,再修改pc跳转对应异常处理位置。

4.设置PC为相应的异常向量地址(跳转到异常向量表中对应的位置)

修改pc切换到异常处理位置

步骤详解:

1》保存执行状态

当前程序的执行状态是保存在CPSR里面的,异常发生时,要保存当前的CPSR里的执行状态到异常模式里的SPSR里,将来异常返回时,恢复回CPSR,恢复执行状态。

2》模式切换

硬件自动根据当前的异常类型,将异常码写入CPSR里的M[4:0]模式位,这样CPU就进入了对应异常模式下。不管是在ARM状态下还是在THUMB状态下发生异常,都会强制切换到ARM状态下进行异常的处理,这是由硬件自动完成的,将CPSR[5] 设置为 0。同时,CPU会关闭中断IRQ(设置CPSR 寄存器I位),防止中断进入,如果当前是快速中断FIQ异常,关闭快速中断(设置CPSR寄存器F位)。

3》保存返回地址

当前程序被异常打断,切换到异常处理程序里,异常处理完之后,返回当前被打断模式继续执行,因此必须要保存当前执行指令的下一条指令的地址到LR_excep(异常模式下LR,并不存在LR_excep寄存器,为方便读者理解加上_excep,以下道理相同),由于异常模式不同以及ARM内核采用流水线技术,异常处理程序里要根据异常模式计算返回地址。

4》跳入异常向量表

该操作是CPU硬件自动完成的,当异常发生时,CPU强制将PC的值修改为一个固定内存地址,这个固定地址叫做异常向量。

异常向量表

整个异常处理过程是自动完成的,ARM内部会有对应硬件自动完成,即在设计ARM时就被固定了,所以每个异常处理会有固定的地址。异常向量表地址不能更改,后期一些新的处理器可以通过协处理器更改。

linu若想修改异常向量表的起始地址,需要借助协处理器完成,一般会将异常向量表的地址设置在0xFFFF0000地址处(若产生IRQ,异常向量地址在0xFFFF0018)

总结:

异常向量表是处于内存中的一段空间

在异常向量表中为每个异常源分配了四个字节的存储空间

当产生了异常后PC的值会自动变成该异常源在异常向量表中的地址

我们在异常向量表对应的位置写一条跳转指令使其跳转到异常处理程序入口

对于Cortex-A系列的处理器的异常向量表的基地址可以通过协处理器CP15来设置

详解:(帮助理解)

1》跳入异常向量表操作是异常发生时,硬件自动完成的,剩下的异常处理任务完全交给了程序员。由上表可知,异常向量是一个固定的内存地址,我们可以通过向该地址处写一条跳转指令,让它跳向我们自己定义的异常处理程序的入口,就可以完成异常处理了。

2》正是由于异常向量表的存在,才让硬件异常处理和程序员自定义处理程序有机联系起来。异常向量表里0x00000000地址处是reset复位异常,之所以它为0地址,是因为CPU在上电时自动从0地址处加载指令,由此可见将复位异常安装在此地址处也是前后接合起来设计的,其后面分别是其余7种异常向量,每种异常向量都占有四个字节,正好是一条指令的大小,最后一个异常是快速中断异常,将其安装在此也有它的意义,在0x0000001C地址处可以直接存放快速中断的处理程序,不用设置跳转指令,这样可以节省一个时钟周期,加快快速中断处理时间。

3》存储器映射地址0x00000000是为向量表保留的。在有些处理器中,向量表可以选择定位在高地址0xFFFF0000处【可以通过协处理器指令配置】,当今操作系统为了控制内存访问权限,通常会开启虚拟内存,开启了虚拟内存之后,内存的开始空间通常为内核进程空间,和页表空间,异常向量表不能再安装在0地址处了。

安装设置异常向量表及保存现场指令

2》 安装异常向量表

我们可以通过简单的使用下面的指令来安装异常向量表:

b reset ; 跳入reset处理程序

b undef_handler ;跳入未定义处理程序

b swi_handler ;跳入软中断处理程序

b pref_handler ;跳入预取指令处理程序

b data_handler ;跳入数据访问中止处理程序

b res ; 跳入未使用程序

b irq_handler ;跳入中断处理程序

b fiq_handler ;跳入快速中断处理程序

通常安装完异常向量表,跳到我们自己定义的处理程序入口,这时我们还没有保存被打断程序的现场,因此在异常处理程序的入口里先要保存打断程序现场。

2》 保存执行现场

异常处理程序最开始,要保存被打断程序的执行现场,程序的执行现场无非就是保存当前操作寄存器里的数据,可以通过下面的栈操作指令实现保存现场:

stmfd sp!, {r0-r1,lr}

需要注意的是,在跳转到异常处理程序入口时,已经切换到对应异常模式下了,因此这里的SP是异常模式下的SP了,所以被打断程序现场(寄存器数据)是保存在异常模式下的栈里,上述指令将R0~R1全部都保存到了异常模式栈,最后将修改完的被打断程序返回地址入栈保存,之所以保存该返回地址就是将来可以通过类似:MOV PC, LR的指令,返回用户程序继续执行。

异常发生后,要针对异常类型进行处理,因此,每种异常都有自己的异常处理程序,中断异常处理过程通过系统中断处理来进行分析。

异常处理的返回(用户自己完成)

异常处理代码自己写。

1)从SPSR_<mode>恢复CPSR,使处理器恢复到异常前的状态

2)从LR_<mode>恢复PC,使程序返回到被异常打断的位置继续执行

注:CPSR中保存的永远是当前程序运行状态,SPSR只是异常时对CPSR进行备份

异常处理完成之后,返回被打断程序继续执行,具体操作如下:
1-》恢复被打断程序运行时寄存器数据(从栈中恢复)
2-》恢复程序运行时状态CPSR(恢复spsr_<mode>到cpsr)
3-》通过进入异常时保存的返回地址,返回到被打断程序继续执行(恢复lr<mode>到pc)

异常源与异常模式对应关系

异常源: FIQ IRQ Reset/软中断 DataAbort/PrefetchAbort Undef

异常模式:FIQ IRQ SVC Abort Undef

异常响应优先级

Reset、Data Abort、FIQ、IRQ、Prefetch Abort、SWI、Undefined instruction

高 - 低

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值