从裸机到 RTOS:中断服务程序里调用 FreeRTOS API 的边界与 FromISR 陷阱

· 5 浏览

回答(4)

调试时可以在 ISR 入口加 configASSERT(portNVIC_INT_CTRL_REG & 0x1FF) 之类的检查,或者用 FreeRTOS 的 trace 宏记录中断内 API 调用,快速定位优先级违规。
固件调试员 · 2026-09-24
FromISR 版本不会阻塞,如果队列满会直接返回 errQUEUE_FULL,所以 ISR 中要处理发送失败,不能像任务里那样无限等待。
RTOS小兵 · 2026-09-24
补充一个常见坑:Cortex-M 的优先级数值越小优先级越高,而 FreeRTOS 的 configMAX_SYSCALL_INTERRUPT_PRIORITY 是数值阈值,务必在启动文件中确认 NVIC 分组,否则高优先级中断会直接绕过内核。
嵌入式老鸟 · 2026-09-24
在 FreeRTOS 中,中断服务程序(ISR)里只能调用带 FromISR 后缀的 API,且必须注意以下边界:1) 优先级限制:ISR 的优先级数值必须 >= configMAX_SYSCALL_INTERRUPT_PRIORITY(数值越大优先级越低),否则调用任何 FreeRTOS API 都会破坏内核临界区。2) 必须使用 xxxFromISR 版本,如 xQueueSendFromISR、xSemaphoreGiveFromISR,并传入 pxHigherPriorityTaskWoken 变量。3) 退出 ISR 前,若 pxHigherPriorityTaskWoken 为 pdTRUE,需手动触发一次任务切换(如 portYIELD_FROM_ISR)。4) 不可在 ISR 中调用非 FromISR 版本,如 vTaskDelay、xQueueSend,否则可能死锁或断言失败。5) 注意临界区:ISR 中不要调用 taskENTER_CRITICAL,应使用 taskENTER_CRITICAL_FROM_ISR。实操建议:用 configASSERT 检查优先级,并确保中断优先级分组正确(如 Cortex-M 的 NVIC 优先级分组设为全部抢占位)。
mcuku 阿沐 · 2026-09-24

🧰 配套工具

⏱️ 定时器计算器