2. Cortex-M内核编程模型:寄存器组与操作模式
寄存器,说白了就是CPU内部的高速暂存器。你写的C代码,最终都要靠它们来干活。Cortex-M内核的寄存器设计得相当规整,我个人觉得比老式ARM7好理解多了。
咱们先看一张总览图,把整个编程模型的骨架搭起来。
2.1 通用寄存器组:R0-R15
这16个寄存器是干活的主力。我习惯把它们分成三组来看:
2.1.1 R0-R7:低组寄存器
所有Thumb指令都能直接访问它们。说白了,这是最常用的8个寄存器,编译器会把局部变量、临时结果往这里塞。你在调试器里看汇编代码,频繁出现的R0、R1就是它们。
2.1.2 R8-R12:高组寄存器
部分Thumb指令不能直接操作它们,需要先MOV到低组。嗯,这里要注意,写内联汇编时容易踩坑——我见过有人直接在R8上做加法,结果编译器报错。
2.1.3 R13 (SP):堆栈指针
这个寄存器有点特殊。物理上存在两个SP:
| 指针 | 全称 | 默认使用场景 |
|---|---|---|
| MSP | 主堆栈指针 | 复位后默认使用,Handler Mode强制使用 |
| PSP | 进程堆栈指针 | Thread Mode下可选,常用于RTOS任务栈 |
2.1.4 R14 (LR):链接寄存器
函数调用时,硬件自动把返回地址存到LR里。但要注意,异常发生时LR会被赋予一个特殊值——EXC_RETURN,用来指示返回后的模式、栈选择等信息。
2.1.5 R15 (PC):程序计数器
指向当前正在执行的指令地址。Cortex-M的PC有个特点:读PC时返回的值是当前指令地址+4(流水线效应),写PC则触发跳转。调试时看PC值,能快速定位程序卡在哪。
2.2 特殊寄存器
这些寄存器不直接参与数据运算,但控制着内核的行为。我刚开始学的时候觉得它们很抽象,后来调试中断相关问题时,才发现它们有多重要。
2.2.1 PRIMASK
只有第0位有效。置1时,屏蔽所有可屏蔽中断(NMI和硬fault除外)。
// 关闭所有中断(除了NMI和硬fault)
__disable_irq(); // 等价于设置PRIMASK=1
// 临界区代码...
__enable_irq(); // 清除PRIMASK
2.2.2 FAULTMASK
比PRIMASK更狠。置1时,连硬fault都被屏蔽了(除了NMI)。
2.2.3 BASEPRI
这个寄存器很实用。它设置一个优先级阈值,只有优先级高于这个值的中断才能响应。
// 屏蔽优先级低于等于2的中断
__set_BASEPRI(2 << 4); // Cortex-M用高4位表示优先级
为什么说它实用?你想想看,有时候你只想关掉低优先级中断,但不想动高优先级的实时响应。PRIMASK一刀切太粗暴,BASEPRI就优雅多了。
2.2.4 CONTROL
这个寄存器控制两个关键选择:
- 第0位:Thread Mode下选择栈指针(0=MSP,1=PSP)
- 第1位:选择特权级别(0=特权级,1=用户级)
2.2.5 xPSR:程序状态寄存器
它其实是三个寄存器的组合体:
| 组成部分 | 位域 | 作用 |
|---|---|---|
| APSR | [31:27] | 算术标志:N(负)、Z(零)、C(进位)、V(溢出)、Q(饱和) |
| IPSR | [8:0] | 当前异常编号(0=无异常,非0=正在处理的异常号) |
| EPSR | [26:25],[15:10] | 执行状态:T位(Thumb状态)、ICI/IT位(中断连续/IF-THEN) |
2.3 操作模式:Thread Mode 与 Handler Mode
Cortex-M只有两种模式,简单明了:
- Thread Mode(线程模式):跑普通代码的地方。复位后默认进入此模式。
- Handler Mode(处理模式):处理异常或中断时自动进入。退出异常时自动返回Thread Mode。
这两种模式的区别,我总结成一张表:
| 特性 | Thread Mode | Handler Mode |
|---|---|---|
| 触发方式 | 复位或从异常返回 | 发生异常/中断 |
| 栈指针选择 | MSP 或 PSP(由CONTROL决定) | 强制使用MSP |
| 特权级别 | 特权级或用户级 | 始终特权级 |
| 典型场景 | main()循环、任务代码 | 中断服务函数、fault处理 |
为什么会设计两种模式?你想想看,中断处理需要高可靠性,如果中断里还能被其他代码干扰栈指针,那系统就乱套了。Handler Mode强制使用MSP,就是为了保证异常处理时栈的确定性。
嗯,到这里编程模型的核心内容就讲完了。记住一句话:寄存器是CPU的双手,模式是CPU的规则。搞懂了这些,后面看中断响应、任务切换这些机制,就会觉得顺理成章。