这里主要介绍异常的进入行为(不包括复位异常)。(这里主要参考 armv7m)。
在发生抢占的时候(异常发生且开始执行),硬件将上下文状态保存到一个 SP 寄存器指向的栈中,使用的堆栈取决于异常发送时处理器的模式。
在 armv7m 中使用 全降序栈,也就是压栈的时候 SP 地址递减,出现的时候 SP 指针递增
压栈的时候,硬件将保存 8 个 32bit 数据,包括 xPSR、ReturnAddress、LR、R12、R3、R2、R1、R0。如果存在浮点扩展,那么还会将 FP 状态压入栈或者仅为状态保留空间(状态指 S0~S15 和 FPSCR)
异常进入行为如下:/*如果在压栈期间出现故障,PushStack 能放弃内存访问,然后会根据派生异常决定下一步行为*/
ExceptionEntry(integer ExceptionType):
PushStack(ExceptionType);
ExceptionTaken(ExceptionType);
(1)检查是否有 FP 扩展且是否 active FP扩展,如果有,压栈需要 104 字节且栈强制 8 字节对齐;如果没有,压栈 32字节,对齐根据 CCR.STKALIGN
(2)检查当时使用 SP 是 PSP 还是 MSP,当前使用那个就会在哪一个里面进行压栈,压栈值如下:
如果没有 FP 状态需要压栈,那么就仅压栈 R0~R3、R12、LR、 ReturnAddress(也就是在异常返回时候要返回的地址) 和 ( XPSR<31:10>: frameptralign:XPSR<8:0>)
如果有 FP 状态需要压栈,则 还需要 预留 S0~S15、FPSCR 的空间,根据 FPCCR.LSPEN 看是否要压栈还是仅仅是预留,等于 0 说明 FP 状态也要一起压栈,等于 1表示仅仅预留改空间,但不将数据写入
(3)对于 LR 寄存器,这里存的是 是否启用了 FP 扩展和 使用的是 MSP 亦或 PSP 信息,用于后续的返回,也就是 EXC_RETURN 值
注意:关于 ReturnAddress。如果是同步异常,那么会返回到未进入异常时候执行的地址,但如果是异步异常,那么就会返回到下一个地址
如下,是无 FP 扩展的压栈过程,这里上下文状态称为基本帧(这里以 8 字节对齐为例)
(图片来着 ARM:《DDI0403E_d_armv7m_arm.pdf》)
以下是有 FP 扩展的压栈过程,这里上下文状态称为扩展帧(这里以 8 字节对齐为例)
(图片来着 ARM:《DDI0403E_d_armv7m_arm.pdf》)
如上,是异常进入压栈的过程。
首先是栈指针是 4/8 字节对齐(如果没对齐会在压栈这里对齐),在将 PSR 压栈的时候,使用 PSR[9] 指示是否有重新对齐栈(正常情况下这个位是保留的,1表示栈有重新对齐过,后续会与 EXC_RETURN[4] 联合确定 SP 是否经过调整)。如果有 FP 扩展且使用了改扩展,强制使用 8 字节对齐。
对于有 FP 扩展的,压栈上实现了三种模式:(CONTROL.FPCA、FPCCR.ASPEN 和 FPCCR.LSPEN 决定了哪种模式,该寄存器只有特权模式才能访问):
(1)栈不保存 FP 状态,只压入基本栈(CONTROL.FPCA=0)
(2)栈按照扩展帧保留空间,但只写基本帧信息(FPCCR.LSPEN =1 且CONTROL.FPCA=1或FPCCR.ASPEN=1),如果后续软件处理尝试会用到 FP 指令,那么就会将 FP 状态保存到保留的空间,然后将 FPCCR.LSPACT 设置为 0
(3)栈写入扩展帧数据(FPCCR.LSPEN =0 且CONTROL.FPCA=1或FPCCR.ASPEN=1)
注意:在没有 FP 扩展使能的情况下,如果使用的是 8 字节对齐,在进入到退出的过程中将 CCR.STKALIGN 设置为 0,且 SP 进入时候不是 8 字节对齐,那么可能会导致系统损坏。
(1)设置 PC 值,指向 异常处理函数入口,这里仅仅只是设置 PC 值而已,还没执行
(2)将模式改为 Handler
(3)将异常向量号写入 IPSR
(4)禁用 FP 扩展,使用 MSP
(5)将该向量号设置为激活状态
从上面可以看出,在进入 故障 ISR 之后,其实如 LR、PSR 这些寄存器可参考意义相对较小,但我们仍旧可以在这里获取当前异常类型(IPSR)和栈顶(SP,在无 SP 溢出和其他会对栈数据进行破坏情况下)
通过 SP 指针,我们可以找到压栈的数据,这里有 ReturnAddress 数据可以让我们清楚的知道运行到那个地址出现了该错误。
通过获取当前的异常类型,可以知道是那种异常进入了处理。如果是故障,还可以 SCS 里面的 CFSR、HFSR、MMFAR、BFAR、AFSR、
ARM:《DDI0403E_d_armv7m_arm.pdf》
欢迎登录大大通,了解更多精彩内容!