ARM 架构中的 PRIMASK、FAULTMAST、BASEPRI 寄存器
这三个是 ARM Cortex-M 系列处理器 中的关键系统异常屏蔽寄存器,用于控制中断和异常的行为。下面分别解释:
1. PRIMASK(优先级屏蔽寄存器)
- 作用:临时屏蔽所有可配置优先级的中断(即除NMI、HardFault外的异常)。
- 位宽:1位(只有最低位有效)。
- 值 :
0:允许所有中断(默认)。1:屏蔽所有可屏蔽中断(进入临界区)。
- 使用场景 :
- 保护临界代码,防止被中断打断。
- 通常用
__disable_irq()和__enable_irq()CMSIS函数操作。
- 注意:不影响NMI、HardFault等不可屏蔽异常。
2. FAULTMASK(故障屏蔽寄存器)
- 作用 :屏蔽除NMI外的所有异常(包括可配置优先级的中断和HardFault)。
- 位宽:1位(只有最低位有效)。
- 值 :
0:允许所有异常(默认)。1:屏蔽所有异常(仅NMI能响应)。
- 使用场景 :
- 用于故障处理程序(如HardFault)中,防止其他异常干扰。
- 可以屏蔽HardFault自身,使当前故障升级为NMI。
- 注意:通常只有操作系统或错误恢复代码使用。
3. BASEPRI(基础优先级寄存器)
- 作用 :屏蔽优先级低于或等于某个阈值的中断。
- 位宽:取决于具体Cortex-M内核(如M3/M4为8位,支持256级优先级)。
- 值 :
0:关闭屏蔽功能(默认)。非0:屏蔽所有优先级值大于等于该数值的中断(数值越大,逻辑优先级越低)。
- 使用场景 :
- 选择性屏蔽低优先级中断,允许高优先级中断响应。
- 更精细的临界区保护。
- 示例 :
- 设置
BASEPRI = 0x20,则屏蔽优先级 ≥ 0x20(数字越大优先级越低)的中断。 - 允许优先级更高的中断(数值 < 0x20)继续响应。
- 设置
三者的比较
| 寄存器 | 屏蔽对象 | 是否屏蔽NMI/HardFault | 粒度 |
|---|---|---|---|
| PRIMASK | 所有可屏蔽中断 | 否 | 全有或全无 |
| FAULTMASK | 所有中断 + HardFault | 仅NMI可响应 | 全有或全无 |
| BASEPRI | 优先级低于等于某阈值的中断 | 否 | 优先级阈值 |
操作方式(以Cortex-M为例)
汇编指令:
assembly
CPSID I ; 置位PRIMASK(关中断)
CPSIE I ; 清零PRIMASK(开中断)
CPSID F ; 置位FAULTMASK
CPSIE F ; 清零FAULTMASK
MSR BASEPRI, r0 ; 设置BASEPRI
MRS r0, BASEPRI ; 读取BASEPRI
CMSIS函数(C语言):
c
void __disable_irq(void); // 置位 PRIMASK
void __enable_irq(void); // 清零 PRIMASK
void __set_FAULTMASK(uint32_t value);
uint32_t __get_FAULTMASK(void);
void __set_BASEPRI(uint32_t value);
uint32_t __get_BASEPRI(void);
典型使用场景
- 实时任务保护 :使用
PRIMASK或BASEPRI保护短暂临界区。 - 错误处理 :在 HardFault 处理中操作
FAULTMASK避免嵌套异常。 - 任务调度 :RTOS 在切换上下文时用
BASEPRI屏蔽低优先级中断。
总结:这三个寄存器是 Cortex-M 异常/中断管理的关键,PRIMASK 用于全局中断开关,FAULTMASK 用于故障处理时的强屏蔽,BASEPRI 提供基于优先级的精细中断控制。