STM32的UCOS訊號量和互斥訊號量

四葉草聽雪發表於2020-10-16

二值訊號量作用:任務通過OSSemPend()函式獲得一個訊號量,如果訊號量有效(不為0),則任務繼續執行,否則進入等待狀態。互斥訊號量作用:任務通過OSMutexPend()函式獲得互斥訊號量,如果互斥訊號有效(不為0)則繼續執行,否則進入等待。


那麼他們之間區別在哪?
假設有三個任務A,B,C,他們的優先順序分別為10、20、30,而任務A和C共同使用一個二值訊號量。現在任務C得到訊號進入執行,這時候任務B也進入就緒,由於B優先順序比C高,就會剝奪任務C的CPU控制權,如果這時候任務A需要執行,可是因為訊號量被任務C獲得還沒釋放被任務B掛起,所以A得不到執行,這樣即使任務A優先順序比B高也無法得到執行,這就是優先順序反轉。如果任務A是比較緊急的任務,那麼就會影響實時性。
為了解決二值訊號帶來的這個問題,於是出現了互斥訊號,

它的機制就是:

當一個優先順序較低的任務獲得了一個互斥訊號時,系統會把這個任務的優先順序提高到最高,讓它不被搶佔,這樣這個任務就會更快執行完而釋放互斥訊號提交給更高的任務使用,之後這個任務的優先順序就會回到原來的等級。還是A、B、C舉例,任務C首先得到一個互斥訊號,這時系統會把C的優先順序提高到最高,這樣就不會被B搶佔,從而儘快執行完釋放訊號,之後回到原來優先順序。期間即使A任務需要執行,也能夠儘快得到訊號執行。不過也看出互斥訊號只是緩解了優先順序反轉問題而已,如果任務A很緊急,也還是要等任務C執行完才可以執行,還是沒能很好解決實時性的問題。

 

互斥訊號量主要是為了解決訊號量出現的優先順序反轉的情況:任務的執行取決於優先順序和獲得訊號量2個條件,並且獲得訊號量又優先於設定的優先順序。剝奪性核心對訊號量進行獨佔訪問,就有可能出現先獲得訊號量的低優先順序任務在獨佔訊號量過程中被高優先順序任務剝奪CPU控制權而掛起,不能及時釋放訊號量,而高優先順序任務又需要該訊號量從而出現優先順序反轉。
解決的辦法:引入互斥訊號量,在任務獲得共享訊號量過程中提升置最高優先順序不被打斷(通過將訊號量計數器分成高8位作為提升優先順序,低8位作為佔用標誌0XFF表明未佔用),從而使低優先順序任務及時釋放共享訊號量。其它與訊號量相同。
一建立互斥訊號量: OS_EVENT *OSMutexCreat(INT8U prio,INT8U &err)//從任務連結串列中取得一個任務控制塊賦值型別為OS_Event_TYPE_MUXTEX,然後給任務計數器的高8位賦值優先順序,第八位賦值0XFF表明未被佔用。
二申請互斥訊號量:void OSMutexPend(OS_EVENT *P, INT16U timeout,INT8U &err)//訪問任務計數器若為0xff則獲得執行權,否則進入等待列表,timeout用於指定等待時間。

OSMutexAccept(OS_EVENT *P,INT8U &err)//無等待的請求一個訊號量。
三傳送(釋放)互斥訊號量:INT8U OSMutexPost(OS_EVENT *P)
四獲得互斥型訊號量的當前狀態:INT8U OSMutexQuery(OS_EVENT *P,OS_MUTEX_DATA *pdata)//需事先定義一個儲存互斥型訊號量狀態的變數。
五刪除互斥型訊號量:OS_EVENT *OSMutexDel(OS_EVENT *P, INT8U opt,INT8U &err)//opt為刪除的選擇項:立即刪除、等待無任務等待時再刪除。

相關文章