60 秒回答模板

FreeRTOS 临界区的目的,是保护会被任务切换或中断并发访问的共享资源。很多 Cortex-M 移植里,taskENTER_CRITICAL 会提高 BASEPRI 或屏蔽一定范围的中断,并支持嵌套;这样 tick 和可调用内核 API 的较低优先级中断不能打断当前代码。但高于 configMAX_SYSCALL_INTERRUPT_PRIORITY 的高优先级 ISR 仍可能运行,这类 ISR 不应访问同一临界资源,或要用更底层的全局关中断、原子操作、硬件互斥或重新设计保护。临界区必须极短,不能调用阻塞 API;ISR 中要用 FromISR 或 portSET_INTERRUPT_MASK_FROM_ISR。vTaskSuspendAll 只是挂起调度,不等于屏蔽中断。

考点 保护对象
难度 真实面经题
回答目标 证明自己能正确使用临界区保护共享状态,并控制实时性副作用。

深入解析

01

临界区保护共享状态

当多个任务或 ISR 会访问同一变量、链表或硬件寄存器序列时,需要保证更新过程不可被打断。临界区就是把这一小段代码做成原子区间。

02

实现常依赖中断屏蔽

单核 MCU 上任务切换通常由 tick 或异常触发,屏蔽相关中断即可避免调度和 ISR 并发。Cortex-M FreeRTOS 常用 BASEPRI 屏蔽一部分中断,而不是一定屏蔽所有异常。

03

高优先级 ISR 是边界

优先级高于 configMAX_SYSCALL_INTERRUPT_PRIORITY 的 ISR 仍可运行,而且不应调用 FreeRTOS API。如果这类 ISR 也会访问同一资源,taskENTER_CRITICAL 保护不了它,必须用更底层的原子保护或调整资源归属。

04

临界区必须短小

关中断时间直接增加外设响应延迟。临界区内不应做 printf、malloc、大循环或等待资源,更不能调用可能阻塞的 API。

05

任务和 ISR 场景不同

任务上下文使用 taskENTER_CRITICAL;ISR 要使用专门的中断安全屏蔽和 FromISR API。混用可能破坏中断嵌套和内核调度状态。

06

挂起调度不是关中断

vTaskSuspendAll 可以防止任务切换,但中断仍可能执行。如果共享数据会被 ISR 修改,仅挂起调度不够。

易错点

  • 把临界区当成普通锁,里面调用阻塞 API。
  • 关中断时间过长,导致串口、定时器或控制环路延迟。
  • 任务上下文和 ISR 上下文使用同一套 API。
  • 认为挂起调度等同于关中断,保护范围判断错误。

面试官追问

临界区里能不能等待信号量?

不能。等待可能阻塞当前任务,而临界区屏蔽调度或中断,会导致系统无法正常切换甚至死锁。

挂起调度能保护 ISR 共享变量吗?

不能完全保护。挂起调度只阻止任务切换,不阻止中断执行;ISR 共享变量仍需中断屏蔽或原子机制。

怎么验证这个 RTOS 方案没有引入新的实时性问题?

要看最坏响应时间、任务优先级、栈水位、队列积压、临界区时长和中断延迟,用压力用例和日志证明正常路径、阻塞路径、异常恢复路径都在预算内。