从裸机到 FreeRTOS:中断服务程序里调用 xQueueSendFromISR 的边界条件与实测陷阱

· 8 浏览

回答(4)

注意portYIELD_FROM_ISR在Cortex-M3/M4上会触发PendSV,若在中断嵌套中调用,要确保只在最外层ISR退出时执行,否则可能丢失一次调度。
码农阿峰 · 2026-09-16
如果队列满且不能丢数据,可在ISR里只置标志,由任务轮询发送;或者用xQueueOverwriteFromISR做覆盖式发送,适合状态类数据。
RTOS小兵 · 2026-09-16
补充一个实测坑:STM32 HAL库的HAL_NVIC_SetPriority默认分组可能让中断优先级数值小于configMAX_SYSCALL_INTERRUPT_PRIORITY,直接HardFault,务必先调NVIC_PriorityGroupConfig。
嵌入式老张 · 2026-09-16
在FreeRTOS中,ISR里必须用xQueueSendFromISR而非xQueueSend。核心边界条件:1) 中断优先级必须≥configMAX_SYSCALL_INTERRUPT_PRIORITY(数值上更高,即优先级更低),否则临界区屏蔽失效,导致内核数据结构损坏;2) 必须传入pxHigherPriorityTaskWoken变量,并在ISR退出前根据其值调用portYIELD_FROM_ISR,否则唤醒的任务要等下一个tick;3) 队列满时xQueueSendFromISR返回errQUEUE_FULL,ISR中不能阻塞等待,需自行设计丢弃或重试策略。实测陷阱:在Cortex-M上,若中断优先级配置为0(最高),调用FromISR API会触发configASSERT失败或直接HardFault;另外,xQueueSendFromISR本身不是线程安全的,多个ISR同时操作同一队列仍需临界区保护。建议用configASSERT验证优先级,并优先使用xQueueSendFromISR的返回值做流控。
mcuku 阿沐 · 2026-09-16

🧰 配套工具

⏱️ 定时器计算器