☰
FREE RTOS MCXW23
2026/10/14 10:51:29 网站建设 项目流程

static void NHS2x34_InterruptHandler(void)

{

BaseType_t xHigherPriorityTaskWoken = pdFALSE;

xSemaphoreGiveFromISR(s_intSem, &xHigherPriorityTaskWoken);

portYIELD_FROM_ISR(xHigherPriorityTaskWoken);

NHS2x34_PAL_DisableInterrupts();

}

第 1 步:初值pdFALSE

表示"目前还没发现需要切换的任务"。

第 2 步:xSemaphoreGiveFromISR会修改它

内核在 give 信号量时会检查:被唤醒的IrqTask(阻塞在这个信号量上)的优先级,是否严格高于中断打断的那个任务?

  • 是→ 内核把这个变量置为pdTRUE,表示"中断返回后应该立刻切到IrqTask"。
  • 否→ 保持pdFALSE,中断返回原任务。

为什么要传入指针?因为 give 信号量的 API 不能有返回值(ISR 版本不能返回pdPASS/pdFAIL那套),所以用out 参数把"是否需要切换"这个结果带出来。

第 3 步:portYIELD_FROM_ISR(xHigherPriorityTaskWoken)

  • 参数为pdTRUE→ 中断退出时强制触发一次 PendSV,立刻切到IrqTask。
  • 参数为pdFALSE→ 什么都不做,正常返回被中断的任务。

为什么需要它

考虑一个场景:

  • 中断发生时,CPU 正在跑一个低优先级任务(比如 Idle 或某个后台任务)。
  • IrqTask的优先级是configMAX_PRIORITIES - 1(最高,见 第23行)。
  • 如果不 yield:中断返回后还会继续跑那个低优先级任务,直到下一次 tick 才可能切换 →增加延迟。
  • 如果 yield:中断一退出立刻切到IrqTask去处理中断 →低延迟。

反过来,如果中断发生时 CPU 正在跑一个比IrqTask还高优先级的任务,那xHigherPriorityTaskWoken会是pdFALSE,不会打断那个高优先级任务——这正是我们想要的语义。

多个...FromISR的累积

如果在同一个 ISR 里调用了多次...FromISR(比如 give 了多个信号量/队列),要复用同一个xHigherPriorityTaskWoken变量,每次都传它的地址。任何一次 give 触发了更高优先级任务唤醒,都会把它置pdTRUE,最后只调用一次portYIELD_FROM_ISR即可。这是 FreeRTOS 推荐的写法。

简单说:它是 ISR 里"是否需要在中断退出时立刻切换上下文"的开关,由内核填写,由你在最后用portYIELD_FROM_ISR消费。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询