ARM中断流程基于CM33
异常处理的基本术语
中断抢占 Preemption
如果异常的优先级高于当前执行优先级,则可以先发制人当前执行。
当一个异常优先于另一个异常时,这些异常被称为嵌套异常。
中断返回 Return
当异常处理程序完成时,就会发生这种情况。
处理器弹出堆栈,并将处理器状态恢复到中断发生前的状态。
末尾连续中断 Tail-chaining
这种机制加快了异常服务。在异常处理程序完成后或返回操作期间,如果有符合异常输入要求的挂起异常,则跳过堆栈弹出,控制直接传输到新的异常处理程序。
迟到中断 Late arriving interrupts
这种机制可以有效的提高高优先级抢占中断速度。如果在为上一个异常保存状态期间发生更高优先级异常,处理器将切换以处理高优先级异常,并启动该高优先级异常的向量获取。状态保存可能会受到当前中断和迟到的更高优先级中断的影响,具体取决于原始异常和延迟到达异常的堆栈要求。从延迟到达异常的异常处理程序返回时,系统会通过末尾连续中断的方式处理悬起的低优先级中断。
中断进入
当处理器正在处理中断或者处于线程模式的时候,如果此时有更高优先级的异常事件发生,处理器就会开始进入异常处理流程,在这种情况下,新的中断会抢占正在处理的低优先级的中断。
高优先级中断打断低优先级中断的情况称为中断嵌套。
如果处理器在处理中断的过程中,发生了优先级较低的中断,那么这个低优先级的中断会悬起(pending),处理器必须在处理完当前中断之后才会通过末尾连续的中断方式处理低优先级中断。
当处理器接受异常时,除非异常是尾链或延迟到达的异常,否则处理器会将信息推送到当前堆栈中。此操作称为压栈,压入堆栈数据结构称为堆栈Frame。
如果浮点上下文处于活动状态,Cortex-M33处理器可以在中断处理过程中自动将浮点处理的数据压入堆栈。下图显示了当堆栈上中断或异常时Cortex-M33处理器堆栈数据结构:
- 具有浮点状态。
- 没有浮点状态。
在未分配浮点状态的堆栈空间时,堆栈结构与没有FPU的Armv8-M实现相同。
上图中无论是否处于浮点状态,处理器状态结构体(state context)都会保存在堆栈中。
如果实现了安全扩展,当非安全异常抢占安全状态运行的软件时,处理器会将额外的其他上下文信息将保存到堆栈中,并清除压入过堆栈的寄存器,以确保非安全软件没有不会读取到安全数据,如下图所示。
如果浮点上下文处于活动状态,Cortex-M33处理器会自动将浮点状态堆叠到堆栈帧中。有两种帧格式包含浮点上下文。如果从安全状态中提取异常并设置了FPCR.TS
,则系统还需要保存额外的浮点上下文。在所有其他情况下,系统堆栈仅保存标准浮点上下文,如下图所示。
处理器将会根据不同的触发条件决定是否需要保存额外的浮点信息上下文数据。
在中断发生的时候,系统总是直接使用当前的堆栈指针来进行压栈操作。例如,如果异常从安全状态带到非安全处理程序,则使用安全堆栈指针来保存状态。
压栈后,堆栈指针会立即指向堆栈帧中的最低地址。
堆栈数据包含中断返回地址。这是中断程序中下一个指令的地址。处理器在中断返回时候通过这个值恢复PC,以便中断的程序恢复。
在处理器进行压栈操作的同时,处理器执行中断向量获取,从中断向量表中读取中断处理程序开始地址。压栈完成后,处理器开始执行中断处理程序。同时,处理器将EXC_RETURN
值写入LR
。此值用于在异常处理程序完成后触发异常返回。
如果中断进入期间没有发生更高的优先级中断,处理器将开始执行异常处理程序,并自动将相应挂起中断的状态更改为活动状态。
如果在中断处理期间发生另一个更高的优先级异常,处理器将开始执行此异常的异常处理程序,并且不会更改早期异常的挂起状态。这种状态就是中断延迟。
异常返回
当处理器处于处理程序模式,并且执行以下指令之一试图将PC设置为EXC_RETURN值时,就会发生异常返回:
- 加载PC的
POP
或LDM
指令。 - 加载PC的
LDR
指令 - 使用任何寄存器的
BX
指令。
使用安全扩展实现中的异常返回
处理器在中断进入时将EXC_RETURN值保存到LR。异常处理机制依赖于此值来检测处理器何时完成异常处理程序。当处理器将与此模式匹配的值加载到PC时,它会检测到该操作不是正常的分支操作,而是异常是完整的。因此,它开始异常返回序列。EXC_RETURN
值的位[6:0]表示所需的返回堆栈、处理器模式、安全状态和堆栈框架,如下表所示。
表2-22异常返回行为
Bit | Name | Function |
---|---|---|
[31:24] | PREFIX | 表示这是一个EXC_RETURN 值。此字段读为0b11111111。 |
[23:7] | — | 保留,RES1。 |
[6] | S | 指示寄存器是否已推送到安全堆栈或非安全堆栈。0表示使用非安全堆栈。1表示使用安全堆栈。 |
[5] | DCRS | 指示默认堆栈规则是否适用,或者被调用方寄存器是否已经在堆栈上。0表示跳过被调用方保存的寄存器的堆栈。1表示遵循堆栈的默认规则。 |
[4] | FType | 在具有主点和浮点扩展的PE中:0表示PE在堆栈上为FP上下文分配了空间。1表示PE没有为FP上下文在堆栈上分配空间。在没有浮点扩展的PE中,此位是保留的,RES1。 |
[3] | Mode | 指示堆叠的模式。0表示Handler模式。1表示线程(Thread)模式。 |
[2] | SPSEL | 指示哪个堆栈包含异常堆栈帧。0表示主堆栈指针。1表示进程堆栈指针。 |
[1] | — | 保留,RES0。 |
[0] | ES | 指示被异常的安全状态。0不安全。1安全。 |
没有安全扩展系统中的异常返回
处理器在中断进入时将EXC_RETURN
值保存到LR。处理器的异常处理机制依赖于此值来检测处理器何时完成异常处理程序。当处理器将与此模式匹配的值加载到PC时,它会检测到该操作不是正常的分支操作,而是异常是完整的。因此,它开始异常返回序列。EXC_RETURN
值的位[6:0]表示所需的返回堆栈、处理器模式和堆栈帧,如下表所示。
表2-23异常返回行为
比特 | 姓名 | 功能 |
---|---|---|
[31:24] | PREFIX | 表示这是一个EXC_RETURN值。此字段读为0b11111111。 |
[23:7] | — | 保留,RES1。 |
[6] | — | 保留,RES0。 |
[5] | — | 保留,RES1。 |
[4] | FType | 在具有主点和浮点扩展的PE中:0表示PE在堆栈上为FP上下文分配了空间。1表示PE没有为FP上下文在堆栈上分配空间。在没有浮点扩展的PE中,此位是保留的,RES1。 |
[3] | Mode | 指示堆叠的模式。0表示Handler模式。1表示线程(Thread)模式。 |
[2] | SPSEL | 指示哪个堆栈包含异常堆栈帧。0表示主堆栈指针。1表示线程堆栈指针。 |
[1:0] | — | 保留,RES0。 |
系统的工作模式
线程模式(Thread mode)
处理器复位或异常退出时为此模式。此模式下的代码可以是特权代码也可以是用户代码,通过CONTROL[0]控制。
处理模式(Handler mode)
出现异常(包括中断)时进入此模式,此模式下所有代码为特权访问。
特权访问
对处理器资源拥有完全访问限权;处理器复位后进入此访问模式;清零 CONTROL[0]进入用户模式。
用户访问
禁止访问多数系统寄存器。只能通过进入异常(中断)来返回特权模式。进入异常前是用户级访问,则退出异常时自动回到用户及,除非在异常中修改CONTROL[0]位。
最后更新于 2022-10-25 00:58:39 并被添加「MCU ARM CORE」标签,已有 3284 位童鞋阅读过。
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。