临界区保护
__STATIC_FORCEINLINE cortex_int_state_t cortex_int_get_and_disable(void)
是用于安全禁用中断并保存中断状态的内联函数,常见于嵌入式系统(如STM32)的临界区保护。以下是详细解析:
⚙️ 一、函数功能与原理
-
核心作用
- 保存当前中断状态:通过
__get_PRIMASK()
读取PRIMASK
寄存器的值(0表示中断使能,1表示中断禁用)。 - 禁用所有可屏蔽中断:调用
__disable_irq()
设置PRIMASK=1
,屏蔽除NMI和HardFault外的所有中断。 - 返回原始中断状态:将保存的状态返回,供后续恢复中断使用(如
cortex_int_restore(state)
)。
- 保存当前中断状态:通过
-
执行流程
cortex_int_state_t state; // 定义状态变量 state = __get_PRIMASK(); // 保存当前PRIMASK值 __disable_irq(); // 设置PRIMASK=1(关中断) return state; // 返回原始中断状态
🔧 二、关键组件解析
1. __STATIC_FORCEINLINE
宏
-
__STATIC
:等效于static
,限制函数作用域为当前文件,避免符号冲突。 -
__FORCEINLINE
:强制编译器内联展开函数(即使优化关闭),消除调用开销。 - 适用场景:高频调用的底层操作(如中断控制),确保零额外开销。
2. PRIMASK
寄存器
值 | 含义 | 影响范围 |
---|---|---|
0 | 中断使能 | 所有可屏蔽中断(IRQ)可响应 |
1 | 中断禁用 | 仅NMI和HardFault可响应 |
- 操作指令:
__disable_irq()
→CPSID I
(汇编指令)。__get_PRIMASK()
→ 读取PRIMASK
当前值。
⚠️ 三、使用场景与注意事项
-
典型应用
- 临界区保护:在操作共享资源(如全局变量、外设寄存器)前禁用中断,操作完成后恢复原始状态。
// 进入临界区 cortex_int_state_t state = cortex_int_get_and_disable(); // 操作共享资源... // 退出临界区 cortex_int_restore(state); // 根据state恢复PRIMASK
-
注意事项
- 特权模式要求:必须在特权模式下执行(用户模式无效)。
- 临界区长度:中断禁用时间应极短(通常 <10μs),避免影响实时性。
- 不可嵌套:若已禁用中断,再次调用本函数会导致状态保存错误(需配套恢复函数)。
⚖️ 四、与其他中断控制方式的对比
方法 | 优势 | 局限性 |
---|---|---|
本函数 | 安全保存/恢复状态,避免误开启中断 | 需配套恢复函数 |
__disable_irq() | 简单直接 | 可能误开启原本关闭的中断 |
BASEPRI 寄存器 | 可屏蔽指定优先级以下的中断 | 配置复杂,需优先级管理 |
💎 总结
- 该函数是嵌入式临界区保护的黄金标准:通过保存和恢复
PRIMASK
状态,确保中断控制的安全性。 - 强制内联设计:消除函数调用开销,适用于实时性要求高的场景。
- 使用铁律:临界区代码必须简短,且与状态恢复函数严格配对。