在討論 ISR(中斷服務例程)和 TCB(任務控制塊,Task Control Block)時,我們實際上是在探討 FreeRTOS 中兩個不同但又相互關聯的概念:一個是用于處理硬件或軟件觸發的中斷事件,另一個是操作系統用來管理任務的核心數據結構。下面我將詳細解釋這兩個概念及其關系。
1.?ISR (Interrupt Service Routine)
定義
- ISR?是一段專門編寫的小型程序代碼,用來處理特定類型的中斷請求。當中斷發生時,CPU 暫停當前執行的任務,轉而執行相應的 ISR 來響應這個中斷。ISR 必須快速完成其工作,以確保其他更高優先級的中斷能夠及時得到響應。
特點
- 高優先級:ISR 比普通任務具有更高的優先級。
- 非搶占性:在一個 ISR 執行期間,不會被另一個 ISR 或者普通任務所搶占,除非新來的中斷源設置了更高的優先級。
- 簡短高效:ISR 應盡可能快地完成,因為長時間運行的 ISR 可能會影響系統的實時性能和響應速度。
- 不能阻塞:ISR 內部不允許調用任何可能導致阻塞的操作(如?
vTaskDelay()
),因為這會導致整個系統陷入死鎖狀態。
在 FreeRTOS 中使用 ISR
- 發送消息給隊列:可以使用?
xQueueSendFromISR()
?函數將數據發送到隊列,但要注意避免阻塞。 - 喚醒任務:可以通過?
xSemaphoreGiveFromISR()
?或?xTaskResumeFromISR()
?喚醒等待的任務,同樣要避免阻塞。 - 檢查是否需要上下文切換:某些 ISR 函數有一個參數指向一個布爾變量,如果該變量被設為?
pdTRUE
,則表明有更高優先級的任務被喚醒,可能需要進行上下文切換。這時應該調用?portYIELD_FROM_ISR()
?來實現這一點。
2.?TCB (Task Control Block)
定義
- TCB?是 FreeRTOS 內核用于管理每個任務的數據結構。它包含了任務的所有信息,包括但不限于:
- 任務狀態:如就緒、運行、阻塞等。
- 任務堆棧指針:保存任務的寄存器狀態和局部變量。
- 任務優先級:定義了任務相對于其他任務的執行順序。
- 任務句柄:唯一標識符,用于從應用程序中引用任務。
- 任務延時計數器:用于定時阻塞任務。
- 消息隊列:如果任務使用了隊列,則包含相關隊列的信息。
功能
- 任務調度:FreeRTOS 使用 TCB 中的狀態信息來決定哪個任務應該獲得 CPU 時間片。
- 內存管理:每個 TCB 都有自己的堆棧空間,用于存儲任務執行期間的臨時數據。
- 同步與通信:通過 TCB,任務可以訪問和操作共享資源,如信號量、隊列等,從而實現任務間的同步和通信。
ISR 和 TCB 的關系
盡管 ISR 和 TCB 分別代表了不同的概念,但在實際應用中它們之間存在一定的交互:
-
從中斷上下文喚醒任務:當 ISR 處理完中斷后,它可能會改變某個任務的狀態(例如通過信號量或隊列)。此時,ISR 可以通知 FreeRTOS 內核有關任務狀態的變化,并可能觸發一次上下文切換,讓被喚醒的任務立即開始執行。這種情況下,ISR 會更新相關的 TCB,特別是那些涉及任務狀態轉換的部分。
-
任務創建與刪除:雖然 ISR 不直接參與任務的創建或刪除過程,但它可以在運行時影響哪些任務處于活動狀態。例如,ISR 可能會向隊列發送數據,導致原本處于阻塞狀態的任務變得可運行,進而改變了這些任務對應的 TCB 狀態。
-
上下文切換:當 ISR 結束時,如果檢測到有更高優先級的任務被喚醒,則會觸發一次上下文切換。這意味著當前正在執行的任務會被掛起,而新的最高優先級任務將接管 CPU。這一過程中,FreeRTOS 內核會根據各個任務的 TCB 來確定下一個要執行的任務,并相應地調整 CPU 上下文。