特殊寄存器

← 返回 Cortex-M4内核原理 | ← 主页

← 任务的调度|← 临界段保护

Cortex-M 内核寄存器,控制执行状态与中断屏蔽,没有内存地址,只能用 MRS/MSR 指令读写。


是什么

特殊寄存器(Special Register)和 R0~R15 一样属于内核寄存器,但不映射到内存地址(不能用指针、不能 = 0x40000000 这种写法访问),只能靠两条专用指令:

指令方向
MRS Rd, <特殊寄存器>读:特殊寄存器 → 通用寄存器MRS R0, PRIMASK
MSR <特殊寄存器>, Rn写:通用寄存器 → 特殊寄存器MSR PRIMASK, R0

CMSIS 已封装成 __get_PRIMASK() / __set_PRIMASK(x) 这类内联函数,工程里直接用即可。

注意区分「内存映射的外设寄存器」,见文末拓展。


典型特殊寄存器

寄存器位宽作用
XPSR32状态寄存器:APSR + EPSR + IPSR 三段拼成
PRIMASK1全局中断总开关(除 NMI/HardFault)
FAULTMASK1连 HardFault 一起屏蔽(除 NMI)
BASEPRI≤9按优先级门限屏蔽低优先级中断
CONTROL2特权级 + 栈指针选择

XPSR(展开)

一条 MRS R0, XPSR 读出的 32 位被三段瓜分:

位宽位域作用
APSR5 位[31:27]N/Z/C/V/Q 条件标志
EPSR9 位[26:24] + [15:10]T(Thumb) + ICI/IT 执行状态
IPSR9 位[8:0]当前异常号
保留其余

APSR(应用状态,5 位)

含义
NNegative运算结果最高位为 1(负数)
ZZero结果为 0
CCarry进位/借位(加法、移位)
VoVerflow有符号溢出
Qsaturation饱和标志(DSP 指令粘滞位)

条件分支、比较跳转(if/cmp+bxx)判断的就是 N/Z/C/V。

EPSR(执行状态,9 位)

  • T(Thumb,bit24):恒为 1,表示处于 Thumb 状态(Cortex-M 只支持 Thumb)。
  • ICI/IT:中断继续(Interrupt-Continuable Instruction)+ If-Then 条件执行的状态位。

IPSR(中断状态,9 位)

存当前正在执行的异常号

含义
0线程模式(正常跑 main/任务)
1Reset
2NMI
3HardFault
15SysTick
≥16外部 IRQ

HardFault 调试时读 IPSR 能确认「挂在哪个异常」,见 HardFault调试


PRIMASK / FAULTMASK / BASEPRI(中断屏蔽三件套)

寄存器屏蔽范围开关对应指令
PRIMASK所有可屏蔽中断(NMI、HardFault 除外)1=关,0=开CPSID I / CPSIE I
FAULTMASK所有中断 + HardFault(NMI 除外)1=关,0=开CPSID F / CPSIE F
BASEPRI优先级值 ≥ N 的中断写 0=不屏蔽
  • 优先级数值越大优先级越低;BASEPRI 写 N = 屏蔽所有「优先级值 ≥ N」的低优先级中断。
  • FAULTMASK 用在「正在处理 HardFault、怕被再次嵌套打断」的场景。
  • 临界区常见套路(备份-关闭-恢复):
uint32_t primask = __get_PRIMASK();   // 1. 备份
__disable_irq();                      // 2. 关中断(PRIMASK=1)
/* 临界区代码 */
__set_PRIMASK(primask);               // 3. 恢复原状态

CONTROL

只有 2 位,且只能在特权模式下写

含义
0nPRIV线程模式特权级:0=特权,1=非特权
1SPSEL栈指针:0=用 MSP,1=用 PSP
  • 操作模式和状态 的特权/线程模式、MSP/PSP 一一对应。
  • RTOS 切任务时靠 SPSEL 在 MSP(内核/中断栈)和 PSP(任务栈)之间切换。
  • 有 FPU 的 M4F 还有 bit2 FPCA(浮点上下文激活),无 FPU 则只有 2 位。

拓展:8051 的 SFR 不是「特殊寄存器」

8051 的 SFR(Special Function Register,特殊功能寄存器) 和本文的「特殊寄存器」是两回事:

Cortex-M 特殊寄存器8051 SFR(特殊功能寄存器)
本质内核寄存器内存映射寄存器
地址无地址,MRS/MSR 访问有地址:内部 RAM 高 128 字节 0x80~0xFF
用途控制内核执行/中断屏蔽操作外设(P0/P1 端口、TMOD 定时器等)

真正对应 8051 SFR 的,是 Cortex-M 的外设寄存器:挂在总线地址上,用 *(volatile uint32_t *)0x40000000 这种写法读写。这类寄存器会被外设硬件随时改变,所以必须加 volatile 防止被编译器优化掉,详见 volatile 关键字。Cortex-M 外设寄存器另起笔记再展开。