FreeRTOS 計數信號量
本章節開始講解 FreeRTOS 任務間的同步和資源共享機制,計數信號量。 FreeRTOS 中計數信號量的源碼實現是基於消息隊列實現的。
信號量的概念及其作用
信號量(semaphores)是 20 世紀 60 年代中期 Edgser Dijkstra 發明的。 使用信號量的最初目的是
為了給共享資源建立一個標誌,該標誌表示該共享資源被占用情況。這樣,當一個任務在訪問共享資源之
前,就可以先對這個標誌進行查詢,從而在了解資源被占用的情況之後,再來決定自己的行為。
實際的應用中,信號量的作用又該如何體現呢?比如有個 30 人的電腦機房,我們就可以創建信號量
的初始化值是 30,表示 30 個可用資源,不理解的初學者表示信號量還有初始值?是的,信號量說白了就
是共享資源的數量。 另外我們要求一個同學使用一臺電腦,這樣每有一個同學使用一臺電腦,那麽信號量
的數值就減一,直到 30 臺電腦都被占用,此時信號量的數值就是 0。 如果此時還有幾個同學沒有電腦可
以使用,那麽這幾個同學就得等待,直到有同學離開。 有一個同學離開,那麽信號量的數值就加 1,有兩
個就加 2,依此類推。剛才沒有電腦用的同學此時就有電腦可以用了,有幾個同學用,信號量就減幾,直
到再次沒有電腦可以用,這麽一個過程就是使用信號量來管理共享資源的過程。
平時使用信號量主要實現以下兩個功能:
? 兩個任務之間或者中斷函數跟任務之間的同步功能,這個和前面章節講解的事件標誌組是類似的。其
實就是共享資源為 1 的時候。
? 多個共享資源的管理,就像上面舉的機房上機的例子。
針對這兩種功能,FreeRTOS 分別提供了二值信號量和計數信號量,其中二值信號量可以理解成計數
信號量的一種特殊形式,即初始化為僅有一個資源可以使用,只不過 FreeRTOS 對這兩種都提供了 API
函數,而像 RTX,uCOS-II 和 III 是僅提供了一個信號量功能,設置不同的初始值就可以分別實現二值信
號量和計數信號量。 當然,FreeRTOS 使用計數信號量也能夠實現同樣的效果。
實際上信號量還有很多其它用法,而且極具挑戰性,可以大大的開拓大家的視野,有興趣的同學可以
閱讀一下《The Little Book Of Semaphores》 ,作者是 Allen B. Downy。
任務間信號量的實現是指各個任務之間使用信號量實現任務的同步或者資源共享功能。 下面我們通過
如下的框圖來說明一下 FreeRTOS 計數信號量的實現,讓大家有一個形象的認識。
運行條件:
? 創建 2 個任務 Task1 和 Task2。
? 創建計數信號量可用資源為 1。
運行過程描述如下:
? 任務 Task1 運行過程中調用函數 xSemaphoreTake 獲取信號量資源,如果信號量沒有被任務 Task2
占用,Task1 將直接獲取資源。 如果信號量被 Task2 占用,任務 Task1 將由運行態轉到阻塞狀態,
等待資源可用。一旦獲取了資源並使用完畢後會通過函數 xSemaphoreGive 釋放掉資源。
? 任務 Task2 運行過程中調用函數 xSemaphoreTake 獲取信號量資源,如果信號量沒有被任務 Task1
占用,Task2 將直接獲取資源。 如果信號量被 Task1 占用,任務 Task2 將由運行態轉到阻塞狀態,
等待資源可用。一旦獲取了資源並使用完畢後會通過函數 xSemaphoreGive 釋放掉資源。
FreeRTOS 計數信號量