在 Arduino 中使用 FreeRTOS 的訊號量和互斥鎖
訊號量和互斥鎖是 FreeRTOS 中用於實現任務同步的工具/機制。通常,兩個任務需要共享資源,或者一個任務需要告訴另一個任務它處於空閒/等待狀態。訊號量和互斥鎖在這裡提供幫助。在本文中,我們將瞭解訊號量和互斥鎖的概念。
訊號量
訊號量是任務之間的一種同步機制。更具體地說,它是一種訊號機制。處於等待狀態的任務可能會收到一個訊號量,指示它執行某些工作。一旦任務完成該工作,它將返回訊號量。在實踐中,這是由整數維護的。訊號量有兩種型別:二進位制訊號量和計數訊號量。
二進位制訊號量
這類似於長度為 1 的佇列。它只能取 0 和 1 作為整數值。假設有兩個任務:任務 A 和任務 B。如果任務 A 需要向任務 B 傳送一些週期性通訊(例如資料交換),則它使用此二進位制訊號量進行通訊。當資料可用時,它將訊號量的值設定為 1(任務 A 在這裡“給出”訊號量)。持續監視訊號量的任務 B 將在值為 1 時讀取資料。然後它將佇列的值重置為 0(因此,任務 B“獲取”訊號量),並再次等待資料可用。透過這種方式,實現了任務 A 和任務 B 之間的同步。
計數訊號量
在這種情況下,對佇列長度沒有限制。這用於事件管理。每次發生事件時,事件處理程式都會透過增加計數器值來“給出”訊號量。每次任務處理事件時,它都會透過遞減計數器來指示它已“獲取”訊號量。任何給定時間的計數都顯示已發生事件數和已處理事件數之間的差。
互斥鎖
互斥鎖(互斥)是一種鎖定機制,可防止共享資源損壞。假設您有一個被多個任務訪問的 SD 卡。如果多個任務同時訪問它,則有可能損壞 SD 卡中的資料(兩者都可能寫入相同的記憶體區域,導致垃圾資料)。
為了避免這種情況,我們使用互斥鎖。它就像一個令牌。如果一個任務擁有此令牌,則只有該任務才能訪問特定資源。其他任務必須等到該任務釋放令牌。如果您有多個需要保護的資源(例如 OLED 螢幕、SD 卡、序列埠等),您可以為每個資源使用多個令牌。
實際上,互斥鎖使用與二進位制訊號量相同的 API 函式。唯一的區別是互斥鎖具有優先順序繼承。FreeRTOS 文件 將其描述為:
“如果高優先順序任務在嘗試獲取當前由低優先順序任務持有的互斥鎖(令牌)時阻塞,則持有令牌的任務的優先順序將暫時提高到阻塞任務的優先順序。此機制旨在確保高優先順序任務保持阻塞狀態的時間儘可能短,從而最大限度地減少已經發生的“優先順序反轉”。
為了檢視訊號量和互斥鎖的實際實現,您可以檢視 FreeRTOS 庫附帶的以下示例:Mutex、AnalogRead_DigitalRead、Interrupts。