
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消费。