D4. ARM异常处理
如果出现图片无法查看可能是网络问题,我用的GitHub+图床保存的图片,可以参考我另外一篇文章GitHub的使用方法含网络问题解决
GitHub使用教程含网络问题_github加速器_肉丸子QAQ的博客-CSDN博客
1. ARM异常处理
1.1异常
-
概念(有点类似应用层的信号)
处理器在正常执行程序的过程中可能会遇到一些不正常的事件发生。这时处理器就要将当前的程序暂停下来转而去处理这个异常的事件(就是执行另外一个程序(自己写的异常处理程序))。异常事件处理完成之后再返回到被异常打断的点继续执行程序
1.2异常处理机制
不同的处理器对异常的处理的流程大体相似,但是不同的处理器在具体实现的机制上有所不同;比如处理器遇到哪些事件认为是异常事件遇到异常事件之后处理器有哪些动作、处理器如何跳转到异常处理程序如何处理异常、处理完异常之后又如何返回到被打断的程序继续执行等我们将这些细节的实现称为处理器的异常处理机制
1.3ARM异常源
-
概念
导致异常产生的事件称为异常源
-
ARM异常源(7个):要非常注意下列和工作模式类似,但是模式是模式,异常源是异常源,不要混在一起
-
FIQ
快速中断请求引脚有效 -
IRQ
外部中断请求引脚有效 -
Reset
复位电平有效 -
Software Interrupt
执行swi指令(软中断) -
Data Abort
数据终止 -
Prefetch Abort
指令预取终止 -
Undefined Instruction
遇到不能处理的指令
-
1.4异常模式
- 异常模式:在ARM的基本工作模式中有5个属于异常模式,即ARM遇到异常后会切
换成对应的异常模式
1.5异常优先级
多个异常同时产生时的服务顺序
高
- Reset
- Data Abort
- FIQ
- IRQ
- Prefetch Abort
- Software Interrupt
- Undefined instruction
低
1.6FIQ和IRQ
FIQ的响应速度比IRQ快的原因:
- FIQ在异常向量表位于最末
可直接把异常处理写在异常向量表之后,省去跳转
- FIQ模式有5个私有寄存器(R8-R12)
执行中断处理程序前无需压栈保存寄存器,可直接处理中断
- 比如:在usr模式下r8-r12寄存器已经存了内容,但是如果其他模式要使用这几个寄存器的话,就要先将这几个寄存器的内容保存起来(压栈),IRQ有特有的寄存器所以没有这个步骤
-
FIQ的优先级高于IRQ
-
两个中断同时发生时先响应FIQ
-
FIQ可以打断IRQ,但IRQ不能打断FIQ
-
2. ARM异常处理过程
2.1 ARM异常响应
-
ARM产生异常后的动作(自动完成)
-
拷贝
CPSR
(状态寄存器)中的内容到对应异常模式下的SPSR_<mode>
将当前状态备份一下,处理完异常后能恢复
对应异常模式:每个异常都有个对应的
SPSR
-
修改
CPSR
的值-
修改中断禁止位禁止相应的中断(高位中断能打断低位中断,平级不打断)
-
修改模式位进入相应的异常模式 产生异常
-
修改状态位进入(强行)ARM状态
-
-
保存返回地址到对应异常模式下的
LR_<mode>
(打断的点的下一条地址) -
设置
PC
为相应的异常向量(异常向量表对应的地址)(不是直接跳转到异常处理程序,而是一个固定的地方(异常向量表))
-
2.2 异常向量表
32个字节,分成8分
-
异常向量表的本质是内存中的一段代码
-
表中为每个异常源分配了四个字节的存储空间(所以不能直接把异常处理程序写在这个地址上)
-
遇到异常后处理器自动将PC修改为对应的地址
-
因为异常向量表空间有限一般我们不会再这里
-
写异常处理程序,而是在对应的位置写一条跳转指令使其跳转到指定的异常处理程序的入口
注:ARM的异常向量表的基地址默认在0x00地址 但可以通过配置协处理器来修改其地址
3.3.异常返回
ARM异常返回的动作(自己编写)
- 将
SPSR_<mode>
的值复制给CPSR
,使处理器恢复之前的状态
产生异常
恢复到之前的模式,前面将
CPSR
的内容拷贝到相应的SPSR_<mode>
的目的就是保存异常前的模式,这里是恢复之前的模式
- 将
LR_<mode>
的值复制给PC
,使程序跳转回被打断的地址继续执行
恢复到之前的运行代码
4.4 IRQ异常举例
所有的异常都是按照上述过程执行,这里使用IRQ举例
- 遇到IRQ后将
cpsr
保存到spsr_<irq>
- 切换模式,
cpsr
寄存器禁止irq(禁止再处理irq),切换为arm状态- 断点的下一条地址保存到LR
- PC修改为对应的异常向量表地址,然后根据向量表跳转到异常处理程序
- 异常返回:
spsr
返回到cpsr
恢复模式,lr
返回给pc
恢复程序
3. ARM微架构
3.1流水线
3.2指令流水线
同理将取指,译码,执行当成三个工人
3.3指令流水线
-
ARM指令流水线
-
ARM7采用3级流水线
-
ARM9采用5级流水线
-
Cortex-A9采用8级流水线
注1:虽然流水线级数越来越多,但都是在三级流水线(取指,译码,执行)的基础上进行了细分
-
-
PC的作用(取指)
不管几级流水线,PC指向的永远是当前正在取指的指令,而当前正在执行的指令的地址为
PC减8
-
指令流水线机制的引入确实能够大大的提升指令执行的速度但在实际执行程序的过程中很多情况下流水线时是无法形成的
比如芯片刚上电的前两个周期、执行跳转指令后的两个周期等,所以指令流水线的引入以及优化只能使平均指令周期不断的接近1而不可能真正的达到1,且流水线级数越多芯片设计的复杂程度就越高,芯片的功耗就越高
当执行完加法时,我想跳转到或运算,但是取指和译码两个步骤已经进行到了减法和乘法,跳转后就得从头开始组装流水线
3.4多核处理器
-
多核处理器
即一个SOC中集成了多个CPU核
-
作用
不同的线程可以运行在不同的核心中
做到真正的并发
-
资源
多核处理器共用外设与接口资源
4.作业
1.以IRQ为例,简述ARM处理器在正常执行程序过程中如果遇到IRQ异常会自动完成哪些动作以及处理完异常后如何返回到正常程序
- 遇到IRQ后将
cpsr
保存到spsr_<irq>
- 切换模式,
cpsr
寄存器禁止irq(禁止再处理irq),切换为arm状态- 断点的下一条地址保存到LR
- PC修改为对应的异常向量表地址,然后根据向量表跳转到异常处理程序
- 异常返回:
spsr
返回到cpsr
恢复模式,lr
返回给pc
恢复程序