异常是由 Cortex-M 硬件以线程模式还是处理程序模式堆叠的?

Are exceptions stacked by the Cortex-M hardware in thread-mode or handler mode?

在带有 MPU 的 Cortex-M 处理器上(让我们使用 Cortex-M4 来具体说明,但我打赌答案是相同的,例如 M3),硬件异常入口堆栈是什么特权模式 运行在 w.r.t MPU 中?

假设我运行在非特权线程模式下使用进程堆栈 (PSP),MPU 设置为仅接受特定区域内的写入(例如,用户模式进程是 运行宁)。当发生异常时,在处理程序执行之前(在处理程序模式下),硬件将寄存器 r0-r3、lr、pc 等堆栈到 PSP 上。这是否也发生在非特权线程模式下?

具体来说,假设进程将其 SP 设置为内存中不允许写入的任意点,异常堆栈是否会导致内存错误?

在处理完这个问题一年后回到这个问题,答案是堆叠发生在以前的任何特权下 运行。

因此,如果在非特权模式下发生中断,硬件将使用现有的 MPU 设置在 PSP 上堆叠寄存器,就好像非特权代码正在执行堆叠一样。如果堆栈违反 MPU 规则,则会发生 MemManage 故障,并且 MemManage 故障状态寄存器的 MSTKERR 字段将被设置(Cortex-M4 用户指南第 4-25 页)

关于MPU规则违规&MSTKERR / MUNSKERR,当非特权软件出现异常,并且启用MPU时:

  • 在异常条目上,如果为非特权软件分配的堆栈内存的基地址与其堆栈大小不对齐,则 Cortex-M4 会生成 MemManage 错误并设置 MSTKERR 字段。

  • 异常return,类似地,如果分配的堆栈内存的基地址未与其堆栈大小对齐,则 Cortex-M4 会生成 MemManage 错误并设置 MUNSKERR 字段。

例如 MPU_RASR.SIZE = 0x7 表示堆栈的 MPU 区域大小为 2^(7+1) = 256 bytes ,那么 MPU_RBAR.ADDR 必须类似于 0x000001000x00000200 ...等等,否则 Cortex-M4 会在异常 entry/return.

时立即生成相应的 MemManage 错误

有关详细信息,请阅读 DUI0553 - Cortex™ -M4 设备通用用户指南 中的第 4.5.4 节 MPU 区域基址寄存器 .