信號量即Semaphore。信號量主要用于控制和保護(hù)任務(wù)對特定資源的訪問。FreeRTOS的信號量分為二值信號量、計數(shù)型信號量和互斥信號量。其中互斥信號量即Mutex在CMSIS API中被獨(dú)立;本文主要講解二值信號量和計數(shù)型信號量。
在FreeRTOS中,二值信號量和計數(shù)信號量在創(chuàng)建方式和功能上沒有差異,兩者區(qū)別僅為二值信號量token數(shù)為1;而計數(shù)信號量token>1。
- 信號量工作原理
圖示為CMSIS-RTOS的信號量抽象原理圖。系統(tǒng)創(chuàng)建信號量,一并指定信號量內(nèi)token(object)數(shù)量。線程(任務(wù))可進(jìn)行拿取/放入token的操作。
①放入token:線程可以向信號量中放入token。調(diào)用一次相應(yīng)函數(shù)即放入一個。若當(dāng)前信號量已滿則報錯。
②拿取token: 線程向信號量中拿取token。和消息隊列一樣,取操作可以設(shè)置阻塞超時時間。當(dāng)消息量中無token時,線程進(jìn)入**BLOCK**狀態(tài)等待消息量被放入token。**在此期間當(dāng)任務(wù)檢測到消息量放入token時,將自動由****BLOCK**態(tài)轉(zhuǎn)移為**READY**態(tài)。當(dāng)?shù)却臅r間超過了指定的阻塞時間,即使隊列中尚無數(shù)據(jù),任務(wù)也會自動從阻塞態(tài)轉(zhuǎn)移為**READY**態(tài)。此時程序會返回**osErrorTimeout**錯誤。若沒有設(shè)置**阻塞超時**且參數(shù)正確,返回**osErrorResource**錯誤**。**
- Semaphore APIs
①創(chuàng)建信號量
可以通過函數(shù) **osSemaphoreNew() **創(chuàng)建信號量。在創(chuàng)建時,可以選擇信號量可容納token的數(shù)量、初始token數(shù); 并且可以傳入配置結(jié)構(gòu)體。當(dāng)創(chuàng)建失敗時返回NULL。
當(dāng)max_count為1時,將創(chuàng)建二值信號量。
osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr);/*
@param: max_count -信號量可容納token的數(shù)量
initial_count -信號量初始時刻含有的token數(shù)量;initial_count<=max_count
*attr -配置結(jié)構(gòu)體
@retval -信號量ID(句柄);若創(chuàng)建失敗返回NULL
*/
②獲取信號量中token 【可在中斷中使用】
※當(dāng)在中斷中使用該函數(shù)時,阻塞延時時間timeout應(yīng)設(shè)置為0U,否則報Parameter錯誤。
線程調(diào)用該函數(shù)時,當(dāng)消息量中無token時,線程進(jìn)入BLOCK狀態(tài)等待消息量被放入token。在此期間當(dāng)任務(wù)檢測到消息量放入token時,將自動由****BLOCK態(tài)轉(zhuǎn)移為READY態(tài)。當(dāng)?shù)却臅r間超過了指定的阻塞時間,即使隊列中尚無數(shù)據(jù),任務(wù)也會自動從阻塞態(tài)轉(zhuǎn)移為READY態(tài)。此時程序會返回osErrorTimeout錯誤。若沒有設(shè)置阻塞超時且參數(shù)正確,返回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參數(shù):
== 0U //不設(shè)置阻塞超時時間
== osWaitForever //任務(wù)將一直阻塞直到空隊列被寫入/滿隊列被取出數(shù)據(jù)
== Ticks //設(shè)置具體等待時間,單位為RTOS心跳數(shù)(Ticks)
③ 向信號量放入一個token 【可在中斷中使用】
當(dāng)信號量溢出時,函數(shù)返回**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.
*/
④獲取狀態(tài)
uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id);/*獲取信號量中token數(shù)
*/
⑤清理(刪除)信號量
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
+關(guān)注
關(guān)注
0文章
40瀏覽量
11904 -
FreeRTOS
+關(guān)注
關(guān)注
12文章
484瀏覽量
62178 -
延時器
+關(guān)注
關(guān)注
1文章
36瀏覽量
15100 -
串口中斷
+關(guān)注
關(guān)注
0文章
64瀏覽量
13897
發(fā)布評論請先 登錄
相關(guān)推薦
評論