4

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

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

  • MSP(主堆栈指针)
  • PSP(进程堆栈指针)

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

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

主堆栈在复位时使用,并且始终在处理程序模式下使用(进入异常处理程序时)。进程堆栈指针仅在线程模式下作为当前堆栈指针可用。

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

线程模式

用于执行应用软件。处理器退出复位后进入线程模式。

处理程序模式

用于处理异常。处理器在完成所有异常处理后返回线程模式。

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

4

1 回答 1

5

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

你没有说你正在使用什么处理器,所以让我们假设一个 Cortex-M3。查看本页CONTROL底部的寄存器描述:该位控制使用哪个堆栈,Thread 和 Handler 模式默认为 MSP,并且仅在 Thread 模式下可写。SPSEL

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

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

多一点上下文...

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

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

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

正在运行的线程模式代码则成为空闲任务。

于 2018-08-25T08:08:11.070 回答