互斥鎖的概念
互斥鎖是一種特殊的二值信號(hào)量,因?yàn)樗鉀Q了優(yōu)先級(jí)翻轉(zhuǎn)的問(wèn)題。可以通過(guò)優(yōu)先級(jí)繼承機(jī)制來(lái)解決:當(dāng)另外一個(gè)的任務(wù)試圖獲取同一個(gè)互斥鎖時(shí),已經(jīng)獲得互斥鎖的任務(wù)將繼承該任務(wù)的優(yōu)先級(jí)。
互斥鎖有一個(gè)比較明顯的特點(diǎn),即它必須哪一個(gè)線程申請(qǐng),就由該線程來(lái)釋放。而在二值信號(hào)量中,釋放和獲取token的線程可以不一致。因此,在處理線程之間占用同一硬件資源的問(wèn)題時(shí)首先考慮使用互斥鎖。
API Description 【互斥鎖不能在中斷中使用】
①創(chuàng)建互斥鎖
在CMSIS-RTOS中,互斥鎖通過(guò) ***osMutexNew() *** 函數(shù)和配置結(jié)構(gòu)體 *osMutexAttr_t *建立。
1)配置結(jié)構(gòu)體osMutexAttr_t
在osMutexAttr_t 中功能參數(shù) *attr_bits ***用于配置互斥鎖的功能特性,相當(dāng)重要;參數(shù)相關(guān)定義包括: **
1.* osMutexRecursive * - 創(chuàng)建遞歸互斥鎖。當(dāng)上鎖開(kāi)鎖的程序段遞歸時(shí),會(huì)出現(xiàn)多重加鎖的情況,并從深處向外解鎖。此時(shí)應(yīng)當(dāng)引入對(duì)遞歸的支持。本參數(shù)配置了一個(gè)遞歸計(jì)數(shù)機(jī)制,允許同一個(gè)線程多重加鎖;調(diào)用一次計(jì)數(shù)+1,釋放-1;當(dāng)計(jì)數(shù)回到0時(shí)此鎖解開(kāi)。
2.osMutexPrioInherit - 優(yōu)先級(jí)繼承機(jī)制。可以防止優(yōu)先級(jí)翻轉(zhuǎn)。
- *osMutexRobust * - 互斥鎖回收機(jī)制。當(dāng)加鎖的線程被 osThreadExit() 或 *osThreadTerminate() *終止而未能解鎖時(shí),鎖將會(huì)自動(dòng)回收。
上述三個(gè)參數(shù)可以通過(guò)邏輯或( | )組合傳入結(jié)構(gòu)體。
typedef struct {
const char *name; ///名稱(chēng),僅標(biāo)識(shí)用
uint32_t attr_bits; ///功能參數(shù);重要
void *cb_mem; /// memory for control block;Default ==NULL
uint32_t cb_size; /// Default==0U
} osMutexAttr_t;
@param attr_bits: -參數(shù)配置;可通過(guò)邏輯或 輸入復(fù)數(shù)的參數(shù)
/ osMutexPrioInherit -使用優(yōu)先級(jí)繼承
/ osMutexRecursive -遞歸互斥鎖
/ osMutexRobust -自回收;當(dāng)線程終止時(shí)自動(dòng)釋放持有的token
- 通過(guò) ***osMutexNew() ***創(chuàng)建目標(biāo)互斥鎖
osMutexId_t osMutexNew (const osMutexAttr_t *attr);/*創(chuàng)建互斥鎖
@param *attr -osMutexAttr_t互斥鎖配置結(jié)構(gòu)體
@retval -句柄(地址)
==NULL 創(chuàng)建失敗*/
**②刪除互斥鎖 **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.(其他錯(cuò)誤)
-osErrorISR: 在中斷調(diào)用導(dǎo)致的錯(cuò)誤
*/
③獲取互斥鎖token osMutexAcquire()
互斥鎖token的獲取與二值信號(hào)量基本一致。 線程調(diào)用該函數(shù)時(shí),當(dāng)鎖中無(wú)token時(shí),線程進(jìn)入BLOCK狀態(tài)等待消息量被放入token;。在此期間當(dāng)任務(wù)檢測(cè)到消息量放入token時(shí),將自動(dòng)由****BLOCK態(tài)轉(zhuǎn)移為READY態(tài)。當(dāng)?shù)却臅r(shí)間超過(guò)了指定的阻塞時(shí)間,即使隊(duì)列中尚無(wú)數(shù)據(jù),任務(wù)也會(huì)自動(dòng)從阻塞態(tài)轉(zhuǎn)移為READY態(tài)。此時(shí)程序會(huì)返回osErrorTimeout錯(cuò)誤。若沒(méi)有設(shè)置阻塞超時(shí)且參數(shù)正確,返回osErrorResource錯(cuò)誤**。**
osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout);/*取得token;
@param timeout 阻塞等待時(shí)間
@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參數(shù):
== 0U //不設(shè)置阻塞超時(shí)時(shí)間,若出現(xiàn)異常函數(shù)將直接報(bào)錯(cuò)返回
== osWaitForever //任務(wù)將一直阻塞直到鎖中token被相應(yīng)線程歸還
== Ticks //設(shè)置具體等待時(shí)間,單位為RTOS心跳數(shù)(Ticks)
④歸還互斥鎖tokenosMutexRelease() ****
注意互斥鎖的token歸還只能由獲取的線程進(jìn)行,否則系統(tǒng)會(huì)報(bào)Resource錯(cuò)誤。
osStatus_t osMutexRelease (osMutexId_t mutex_id);/*歸還互斥鎖
@retval -osOK: 成功
-osErrorResource: 無(wú)法歸還(當(dāng)前token沒(méi)有被獲取 或 本線程不持有互斥鎖的token)
-osErrorParameter: parameter mutex_id is NULL or invalid.
-osErrorISR: 在中斷中調(diào)用了本函數(shù)
*/
```**⑤查詢當(dāng)前互斥鎖token的擁有者(線程)**** ***osMutexGetOwner()*********
osThreadId_t osMutexGetOwner (osMutexId_t mutex_id)/*
@retval -持有互斥鎖token的線程句柄(ID);
若token未被持有或 發(fā)生錯(cuò)誤,則返回NULL
*/
-
處理器
+關(guān)注
關(guān)注
68文章
19160瀏覽量
229119 -
RTOS
+關(guān)注
關(guān)注
21文章
809瀏覽量
119432 -
ISR
+關(guān)注
關(guān)注
0文章
38瀏覽量
14405
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論