
PRIMASK 和 BASEPRI 都是 Cortex-M 内核的中断屏蔽寄存器区别在于屏蔽的“粒度”不同PRIMASK全局开关一关全关除了 NMI 和 HardFault。BASEPRI优先级阈值开关只关掉优先级低于某个阈值的中断高优先级中断不受影响。1. PRIMASK位宽1 位。作用写 1 后屏蔽所有可配置优先级的中断和异常只有NMI和HardFault不受影响。写 0不屏蔽任何中断。CMSIS 函数c__disable_irq(); // 设置 PRIMASK 1 __enable_irq(); // 设置 PRIMASK 0典型用途全局关中断、低功耗进入 WFI 前防止临界区被打断。对 WFI 的影响即使PRIMASK 1WFI 仍然可以被中断唤醒。但唤醒后不会执行中断服务函数直到PRIMASK被清零。所以 FreeRTOS 的 tickless idle 常用__disable_irq()包住__WFI()这样任何中断都能唤醒 CPU但不会立刻执行 ISR。2. BASEPRI位宽8 位实际有效位取决于芯片实现的优先级位数。作用写 0不屏蔽任何中断。写非 0 值 N屏蔽所有优先级数值 ≥ N的中断即逻辑优先级 ≤ N 的中断。优先级数值 N 的高优先级中断不受影响。CMSIS 函数c__set_BASEPRI(N); __get_BASEPRI();典型用途FreeRTOS 临界区选择性屏蔽低优先级中断允许高优先级中断继续响应。对 WFI 的影响被 BASEPRI 屏蔽的中断不能唤醒 WFI。所以如果在BASEPRI ! 0时执行WFI只有优先级高于 BASEPRI 阈值的中断才能唤醒 CPU。这也是为什么低功耗睡眠前通常不用 BASEPRI 屏蔽中断而用 PRIMASK。3. 对比总结特性PRIMASKBASEPRI位宽1 位8 位屏蔽范围所有可配置优先级中断优先级数值 ≥ 阈值的中断影响 NMI/HardFault否否写 0允许所有中断不屏蔽任何中断典型用途全局关中断、WFI 前FreeRTOS 临界区、选择性屏蔽WFI 唤醒仍可唤醒但不执行 ISR被屏蔽的中断不能唤醒CMSIS__disable_irq()/__enable_irq()__set_BASEPRI()/__get_BASEPRI()4. 在 FreeRTOS 中的使用临界区ctaskENTER_CRITICAL(); // 此处 BASEPRI configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY taskEXIT_CRITICAL(); // BASEPRI 0这样只有优先级高于configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY的中断能打断临界区且这些中断不能调用 FreeRTOS 的 FromISR API。Tickless idle使用__disable_irq()PRIMASK而不是 BASEPRI确保任何中断都能把 CPU 从WFI唤醒唤醒后再__enable_irq()让 ISR 执行。5. 常见误区PRIMASK 1 不是让 WFI 不唤醒而是唤醒后不执行 ISR。BASEPRI 屏蔽的中断不能唤醒 WFI。BASEPRI 0 时任何已使能的中断都能唤醒 WFI与优先级无关。高优先级中断优先级数值 configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY不能调用 FreeRTOS 的FromISRAPI因为 FreeRTOS 无法用 BASEPRI 屏蔽它们。一句话PRIMASK 是全局中断开关BASEPRI 是优先级阈值开关WFI 怕 BASEPRI不怕 PRIMASK