互斥鎖的概念
互斥鎖是一種特殊的二值信號量,因為它解決了優先級翻轉的問題。可以通過優先級繼承機制來解決:當另外一個的任務試圖獲取同一個互斥鎖時,已經獲得互斥鎖的任務將繼承該任務的優先級。
互斥鎖有一個比較明顯的特點,即它必須哪一個線程申請,就由該線程來釋放。而在二值信號量中,釋放和獲取token的線程可以不一致。因此,在處理線程之間占用同一硬件資源的問題時首先考慮使用互斥鎖。
API Description 【互斥鎖不能在中斷中使用】
①創建互斥鎖
在CMSIS-RTOS中,互斥鎖通過 ***osMutexNew() *** 函數和配置結構體 *osMutexAttr_t *建立。
1)配置結構體osMutexAttr_t
在osMutexAttr_t 中功能參數 *attr_bits ***用于配置互斥鎖的功能特性,相當重要;參數相關定義包括: **
1.* osMutexRecursive * - 創建遞歸互斥鎖。當上鎖開鎖的程序段遞歸時,會出現多重加鎖的情況,并從深處向外解鎖。此時應當引入對遞歸的支持。本參數配置了一個遞歸計數機制,允許同一個線程多重加鎖;調用一次計數+1,釋放-1;當計數回到0時此鎖解開。
2.osMutexPrioInherit - 優先級繼承機制。可以防止優先級翻轉。
- *osMutexRobust * - 互斥鎖回收機制。當加鎖的線程被 osThreadExit() 或 *osThreadTerminate() *終止而未能解鎖時,鎖將會自動回收。
上述三個參數可以通過邏輯或( | )組合傳入結構體。
typedef struct {
const char *name; ///名稱,僅標識用
uint32_t attr_bits; ///功能參數;重要
void *cb_mem; /// memory for control block;Default ==NULL
uint32_t cb_size; /// Default==0U
} osMutexAttr_t;
@param attr_bits: -參數配置;可通過邏輯或 輸入復數的參數
/ osMutexPrioInherit -使用優先級繼承
/ osMutexRecursive -遞歸互斥鎖
/ osMutexRobust -自回收;當線程終止時自動釋放持有的token
- 通過 ***osMutexNew() ***創建目標互斥鎖
osMutexId_t osMutexNew (const osMutexAttr_t *attr);/*創建互斥鎖
@param *attr -osMutexAttr_t互斥鎖配置結構體
@retval -句柄(地址)
==NULL 創建失敗*/
**②刪除互斥鎖 **osMutexDelete()
osStatus_t osMutexDelete( osMutexId_t mutex_id );/*刪除互斥鎖
@retval: -osOK //成功
-osErrorParameter: parameter mutex_id is NULL or invalid.
-osErrorResource: the mutex is in an invalid state.(其他錯誤)
-osErrorISR: 在中斷調用導致的錯誤
*/
③獲取互斥鎖token osMutexAcquire()
互斥鎖token的獲取與二值信號量基本一致。 線程調用該函數時,當鎖中無token時,線程進入BLOCK狀態等待消息量被放入token;。在此期間當任務檢測到消息量放入token時,將自動由****BLOCK態轉移為READY態。當等待的時間超過了指定的阻塞時間,即使隊列中尚無數據,任務也會自動從阻塞態轉移為READY態。此時程序會返回osErrorTimeout錯誤。若沒有設置阻塞超時且參數正確,返回osErrorResource錯誤**。**
osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout);/*取得token;
@param timeout 阻塞等待時間
@retval -osOK: the mutex has been obtained.
-osErrorTimeout: the mutex could not be obtained in the given time.
-osErrorResource: the mutex could not be obtained when no timeout was specified.
-osErrorParameter: parameter mutex_id is NULL or invalid.
-osErrorISR: cannot be called from interrupt service routines.
*/
timeout參數:
== 0U //不設置阻塞超時時間,若出現異常函數將直接報錯返回
== osWaitForever //任務將一直阻塞直到鎖中token被相應線程歸還
== Ticks //設置具體等待時間,單位為RTOS心跳數(Ticks)
④歸還互斥鎖tokenosMutexRelease() ****
注意互斥鎖的token歸還只能由獲取的線程進行,否則系統會報Resource錯誤。
osStatus_t osMutexRelease (osMutexId_t mutex_id);/*歸還互斥鎖
@retval -osOK: 成功
-osErrorResource: 無法歸還(當前token沒有被獲取 或 本線程不持有互斥鎖的token)
-osErrorParameter: parameter mutex_id is NULL or invalid.
-osErrorISR: 在中斷中調用了本函數
*/
```**⑤查詢當前互斥鎖token的擁有者(線程)**** ***osMutexGetOwner()*********
osThreadId_t osMutexGetOwner (osMutexId_t mutex_id)/*
@retval -持有互斥鎖token的線程句柄(ID);
若token未被持有或 發生錯誤,則返回NULL
*/
-
處理器
+關注
關注
68文章
19295瀏覽量
230001 -
RTOS
+關注
關注
22文章
814瀏覽量
119686 -
ISR
+關注
關注
0文章
38瀏覽量
14441
發布評論請先 登錄
相關推薦
評論