FreeRTOS再學習——2nd——信號量和優先級反轉問題

信號量:

信號量是操作系統中重要的一部分,信號量一般用來進行資源管理和任務同步,FreeRTOS中信號量又分爲二值信號量、計數型信號量、互斥信號量和遞歸互斥信號量。
不同的信號量其應用場景不同,但有些應用場景是可以互換着使用的。

二值信號量只有0和1,表示信號量的兩個狀態,適用於立flag
信號量的另一個重要的應用場合就是任務同步,用於任務與任務或中斷與任務之間的同步。裸機編寫中斷服務函數的時候一般都只是在中斷服務函數中打個標記,然後在其他的地方根據標記來做具體的處理過程。在使用RTOS系統的時候我們就可以藉助信號量完成此功能,當中斷髮生的時候就釋放信號量,中斷服務函數不做具體的處理。具體的處理過程做成一個任務,這個任務會獲取信號量,如果獲取到信號量就說明中斷髮生了,那麼就開始完成相應的處理,這樣做的好處就是中斷執行時間很短
二值信號量,用來處理當某個事件產生後,標誌某位,讓某個任務進入運行態
還是上圖容易理解:(大用途)
在這裏插入圖片描述
由於任務函數一般都是一個大循環,所以在任務做完相關的處理以後就會再次調用函數xSemaphoreTake()獲取信號量。在執行完第三步以後二值信號量就已經變爲無效的了,所以任務將再次進入阻塞態,和第一步一樣, 直至中斷再次發生並且調用函數xSemaphoreGiveFromISR0釋放信號量。
創建二值信號量API:

在這裏插入圖片描述
釋放信號量API:
在這裏插入圖片描述
獲取信號量API:
在這裏插入圖片描述
使用總結:
當一個事件發生,釋放信號量,也即flag=1,有一個任務在獲取信號量,也就是一直在while(1),1就是信號量是否有效的標誌;當事件未產生時,任務不執行,也就是在阻塞態,當中斷或者其他任務釋放信號量,指定任務獲取到信號量,開始執行,也就是從阻塞態就如就緒態等待CPU的使用權(因爲有可能有別的優先級更高的任務在執行,如果此時它的優先級最高那就是進入運行態),相比裸機:裸機輪詢實時性更差點(我覺得)

計數型信號量:包括信號量和信號量值
適用於這種情況:相比二值信號量的立flag,這貨可以記錄立flag的次數,比如說停車場停車,停一輛車立一個flag,二值信號量只能說明有車停進來了,這貨可以記錄停進來幾輛車。
這貨是倒着計數的額,從信號量值開始倒着計數,當爲0時,說明木得資源了
創建計數型信號量API:
在這裏插入圖片描述
信號量的獲取和釋放和二值信號量一樣。

優先級反轉問題:
當前有三個任務的優先分別問1、2、3。
開始的時候,1和2在掛起狀態等待某一事件發生,優先級最低的3正在運行,當優先級最高的1的事件發生後,他開始運行,3先停下來,但是它訪問某一共享資源時,發現3之前在用,並且3使用的這一共享資源的信號量還被3佔用着,1只能等着3用完這個共享資源,CPU使用權暫時3用着,此時2的事件發生了,那麼CPU使用權給2,2要做的事不用3所用的共享資源,所以2就先執行完了,然後CPU使用權給3,當3使用完和1相同的共享資源後,1開始執行,3等着,然後1執行完,3再執行。
此時,優先級爲2的任務卻先在任務優先級更高的1任務執行完之前執行完了,1和2個優先級就反轉了。這是我的理解,看圖看圖
在這裏插入圖片描述

解決優先級反轉之互斥信號量:(不能在中斷服務函數中使用)
互斥訪問中互斥信號量相當於一個鑰匙,當任務想要使用資源的時候就必須先獲得這個鑰匙,當使用完資源以後就必須歸還這個鑰匙,這樣其他的任務就可以拿着這個鑰匙去使用資源。也就是說,只能訪問一次,訪問完,需要釋放

互斥信號量解決優先級反轉的問題的方法:

在這裏插入圖片描述
也就是說,任務1在等任務3使用那個共享資源的時候,把任務3的優先級變成1,等它使用完了再把它的優先級變回去,也就是說,2不能在1等待3執行訪問和1的共享資源的的時候先執行了,只是把影響降到最低,最後還是得等3先用完共享的資源。

創建互斥信號量API:
在這裏插入圖片描述

遞歸互斥信號量
可以看作是一個特殊的互斥信號量,已經獲取了互斥信號量的任務就不能再次獲取這個互斥信號量,但是遞歸互斥信號量不同,已經獲取了遞歸互斥信號量的任務可以再次獲取這個遞歸互斥信號量,而且次數不限!一個任務使用函數xSemaphore’ TakeRecursive()成功的獲取了多少次遞歸互斥信號量就得使用函數xSemaphoreGiveRecursive(釋放多少次!比如某個任務成功的獲取了5次遞歸信號量,那麼這個任務也得同樣的釋放5次遞歸信號量。
遞歸互斥信號量也有優先級繼承的機制,所以當任務使用完遞歸互斥信號量以後一定要記得釋放。同互斥信號量一樣,遞歸互斥信號量不能用在中斷服務函數中。
創建遞歸信號量API:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章