
static void NHS2x34_InterruptHandler(void){BaseType_t xHigherPriorityTaskWoken pdFALSE;xSemaphoreGiveFromISR(s_intSem, xHigherPriorityTaskWoken);portYIELD_FROM_ISR(xHigherPriorityTaskWoken);NHS2x34_PAL_DisableInterrupts();}第 1 步:初值pdFALSE表示目前還沒發(fā)現(xiàn)需要切換的任務(wù)。第 2 步:xSemaphoreGiveFromISR會修改它內(nèi)核在 give 信號量時會檢查:被喚醒的IrqTask(阻塞在這個信號量上)的優(yōu)先級,是否嚴(yán)格高于中斷打斷的那個任務(wù)?是→ 內(nèi)核把這個變量置為pdTRUE,表示中斷返回后應(yīng)該立刻切到IrqTask。否→ 保持pdFALSE,中斷返回原任務(wù)。為什么要傳入指針?因為 give 信號量的 API 不能有返回值(ISR 版本不能返回pdPASS/pdFAIL那套),所以用out 參數(shù)把是否需要切換這個結(jié)果帶出來。第 3 步:portYIELD_FROM_ISR(xHigherPriorityTaskWoken)參數(shù)為pdTRUE→ 中斷退出時強制觸發(fā)一次 PendSV,立刻切到IrqTask。參數(shù)為pdFALSE→ 什么都不做,正常返回被中斷的任務(wù)。為什么需要它考慮一個場景:中斷發(fā)生時,CPU 正在跑一個低優(yōu)先級任務(wù)(比如 Idle 或某個后臺任務(wù))。IrqTask的優(yōu)先級是configMAX_PRIORITIES - 1(最高,見 第23行)。如果不 yield:中斷返回后還會繼續(xù)跑那個低優(yōu)先級任務(wù),直到下一次 tick 才可能切換 →增加延遲。如果 yield:中斷一退出立刻切到IrqTask去處理中斷 →低延遲。反過來,如果中斷發(fā)生時 CPU 正在跑一個比IrqTask還高優(yōu)先級的任務(wù),那xHigherPriorityTaskWoken會是pdFALSE,不會打斷那個高優(yōu)先級任務(wù)——這正是我們想要的語義。多個...FromISR的累積如果在同一個 ISR 里調(diào)用了多次...FromISR(比如 give 了多個信號量/隊列),要復(fù)用同一個xHigherPriorityTaskWoken變量,每次都傳它的地址。任何一次 give 觸發(fā)了更高優(yōu)先級任務(wù)喚醒,都會把它置pdTRUE,最后只調(diào)用一次portYIELD_FROM_ISR即可。這是 FreeRTOS 推薦的寫法。簡單說:它是 ISR 里是否需要在中斷退出時立刻切換上下文的開關(guān),由內(nèi)核填寫,由你在最后用portYIELD_FROM_ISR消費。