arm - ARM Cortex-M、MSP 或 PSP 中复位后使用哪个堆栈?

标签 arm cortex-m stack-pointer

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

据我所知,Cortex-M 处理器中有两个堆栈:

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

我试图弄清楚 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并且总是在Handler模​​式下使用,而PSP在Thread模式下使用,那么如果复位时处理器处于Thread模式,那么如何在复位时使用MSP?

最佳答案

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

您没有说明您正在使用什么处理器,所以我们假设是 Cortex-M3。查看 this page 底部的 CONTROL 寄存器的说明:SPSEL 位控制使用哪个堆栈,线程和处理程序模式默认为 MSP,并且仅在线程模式下可写。

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

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

更多背景信息...

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

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

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

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

关于arm - ARM Cortex-M、MSP 或 PSP 中复位后使用哪个堆栈?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52013343/

相关文章:

arm - 从 linux 交叉编译到 ARM-ELF (armv5tejl )

windows - 使用CMake在Visual Studio中构建ARM64 ASM

arm - 在 Qemu 中模拟基于 NAND 的存储设备?

c - 在不使用标准函数的情况下在 C 中生成正弦信号

gdb - 为什么 cortex-m3 会在 gdb 中重置为地址 0?

assembly - 关于STM32 ARM Cortex M LDRB指令

assembly - 使用 NEON 优化 Cortex-A8 颜色转换

assembly - x64 程序集中的堆栈对齐

c++ - 嵌入式 asm 代码中的运行时检查失败 #0

c++ - 在 C++ 中使用多重继承时 ESP 无效 (VS2005)