信號量即Semaphore。信號量主要用于控制和保護任務對特定資源的訪問。FreeRTOS的信號量分為二值信號量、計數型信號量和互斥信號量。其中互斥信號量即Mutex在CMSIS API中被獨立;本文主要講解二值信號量和計數型信號量。
在FreeRTOS中,二值信號量和計數信號量在創建方式和功能上沒有差異,兩者區別僅為二值信號量token數為1;而計數信號量token>1。
- 信號量工作原理
圖示為CMSIS-RTOS的信號量抽象原理圖。系統創建信號量,一并指定信號量內token(object)數量。線程(任務)可進行拿取/放入token的操作。
①放入token:線程可以向信號量中放入token。調用一次相應函數即放入一個。若當前信號量已滿則報錯。
②拿取token: 線程向信號量中拿取token。和消息隊列一樣,取操作可以設置阻塞超時時間。當消息量中無token時,線程進入**BLOCK**狀態等待消息量被放入token。**在此期間當任務檢測到消息量放入token時,將自動由****BLOCK**態轉移為**READY**態。當等待的時間超過了指定的阻塞時間,即使隊列中尚無數據,任務也會自動從阻塞態轉移為**READY**態。此時程序會返回**osErrorTimeout**錯誤。若沒有設置**阻塞超時**且參數正確,返回**osErrorResource**錯誤**。**
- Semaphore APIs
①創建信號量
可以通過函數 **osSemaphoreNew() **創建信號量。在創建時,可以選擇信號量可容納token的數量、初始token數; 并且可以傳入配置結構體。當創建失敗時返回NULL。
當max_count為1時,將創建二值信號量。
osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr);/*
@param: max_count -信號量可容納token的數量
initial_count -信號量初始時刻含有的token數量;initial_count<=max_count
*attr -配置結構體
@retval -信號量ID(句柄);若創建失敗返回NULL
*/
②獲取信號量中token 【可在中斷中使用】
※當在中斷中使用該函數時,阻塞延時時間timeout應設置為0U,否則報Parameter錯誤。
線程調用該函數時,當消息量中無token時,線程進入BLOCK狀態等待消息量被放入token。在此期間當任務檢測到消息量放入token時,將自動由****BLOCK態轉移為READY態。當等待的時間超過了指定的阻塞時間,即使隊列中尚無數據,任務也會自動從阻塞態轉移為READY態。此時程序會返回osErrorTimeout錯誤。若沒有設置阻塞超時且參數正確,返回osErrorResource錯誤**。**
osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout);/* 獲取一個token
@param: semaphore_id -傳入信號量ID(句柄)
timeout -阻塞延時時間
@retval:
osOK: 操作成功
osErrorTimeout: the token could not be obtained in the given time.
osErrorResource: the token could not be obtained when no timeout was specified.
osErrorParameter: the parameter semaphore_id is NULL or invalid.*/
timeout參數:
== 0U //不設置阻塞超時時間
== osWaitForever //任務將一直阻塞直到空隊列被寫入/滿隊列被取出數據
== Ticks //設置具體等待時間,單位為RTOS心跳數(Ticks)
③ 向信號量放入一個token 【可在中斷中使用】
當信號量溢出時,函數返回**osErrorResource **。
osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id);/*放入一個token
@param: semaphore_id -傳入信號量ID(句柄)
@retval:
osOK: the token has been released and the count incremented.
osErrorResource: the token could not be released (maximum token count has been reached).
osErrorParameter: the parameter semaphore_id is NULL or invalid.
*/
④獲取狀態
uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id);/*獲取信號量中token數
*/
⑤清理(刪除)信號量
osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id);/*
@retval:
osOK: the semaphore object has been deleted.
osErrorParameter: the parameter semaphore_id is NULL or invalid.
osErrorResource: the semaphore is in an invalid state.
osErrorISR: osSemaphoreDelete cannot be called from interrupt service routines.
*/
-
CMSIS
+關注
關注
0文章
40瀏覽量
11943 -
FreeRTOS
+關注
關注
12文章
484瀏覽量
62399 -
延時器
+關注
關注
1文章
36瀏覽量
15158 -
串口中斷
+關注
關注
0文章
67瀏覽量
14010
發布評論請先 登錄
相關推薦
轉:freeRTOS信號量學習
第14章 信號量
信號量–使用許可的概念
信號量semphere概述
信號量機制怎么理解
![<b class='flag-5'>信號量</b>機制怎么理解](https://file1.elecfans.com//web2/M00/A6/E3/wKgZomUMQRaAdIqjAAAqdW6nQ38375.png)
Linux信號量(2):POSIX 信號量
淺談鴻蒙內核源碼的信號量運作原理
FreeRTOS 隊列 信號量 互斥量
![FreeRTOS 隊列 <b class='flag-5'>信號量</b> 互斥<b class='flag-5'>量</b>](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
ThreadX(六)------信號量semaphore
![ThreadX(六)------<b class='flag-5'>信號量</b><b class='flag-5'>semaphore</b>](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
評論