在 ARM Cortex-M、MSP 或 PSP 中使用哪个堆栈退出复位?

Which Stack Is Used Coming Out of Reset In ARM Cortex-M, MSP or PSP?

我一直在阅读 ARM 信息中心的各个部分,试图找到我的答案,但是我发现文档让我感到困惑,所以我希望这里有人可以提供帮助。

我了解到 Cortex-M 处理器中有两个堆栈:

我正在尝试弄清楚 ARM 内核如何使用每一个。

ARM 信息中心的文档在讨论 Cortex-M3 时说明如下:

The main stack is used at reset, and is always used in Handler mode (when entering an exception handler). The process stack pointer is only available as the current stack pointer when in Thread mode.

好的,这告诉我 MSP 在重置时使用。但是,文档还说明了以下内容:

线程模式

Used to execute application software. The processor enters Thread mode when it comes out of reset.

处理程序模式

Used to handle exceptions. The processor returns to Thread mode when it has finished all exception processing.

好吧,这就是让我困惑的地方。如果MSP在reset时使用,一直在Handler模​​式下使用,而PSP在Thread模式下使用,那么如果处理器在reset时处于Thread模式,如何在reset时使用MSP?

简单回答:您的最后一段不正确。 线程模式默认使用MSP。

你没有说明你使用的是什么处理器,所以让我们假设一个 Cortex-M3。查看this page底部的CONTROL寄存器的描述:SPSEL位控制使用哪个堆栈,Thread和Handler模​​式默认为MSP,只能写在线程模式下。

此外,虽然这不是您问题的一部分,但默认情况下线程模式也具有特权。在同一寄存器中设置 nPRIV 位会使线程模式无特权。

总结:处理程序模式始终是特权模式,并且始终使用 MSP。默认情况下,线程模式也是如此,但是 CONTROL 寄存器允许更改它。

更多上下文...

例如,如果您正在编写一个小型操作系统,通常希望线程模式代码是非特权的。如果线程模式代码使用 PSP,它也会使任务切换更容易,因为那么你的任务切换代码,在处理程序模式下不可避免地是 运行(通常在 Cortex-M 上的 PendSV 处理程序中),可以利用它自己的堆栈而不影响它试图切换的任务的堆栈。

为此,操作系统的初始化代码通常必须(按此顺序):

  • 为空闲任务的堆栈保留一些space,并使用MSR指令使PSP指向该区域的顶部(这需要权限但也必须在线程模式下完成因为 SPSEL 忽略处理程序模式下的写入)
  • 使用另一个MSR指令设置CONTROL寄存器中的SPSEL位,将运行代码切换为使用PSP和新准备的堆栈space
  • 发出ISB指令以确保所有后续指令都按要求使用PSP
  • 再次使用MSR设置CONTROL寄存器中的nPRIV位,立即从线程模式中移除特权

运行 线程模式代码成为空闲任务。