Queue概述
Queue即消息隊列是通過RTOS內核提供的一種服務。它是一種線程間同步數據的安全方法。
隊列(Queue)是與棧對應的概念;棧是FILO結構,而隊列是FIFO結構。FreeRTOS原生的隊列支持從高位添加新數據,但CMSIS簡化刪去了這一功能,即只能從隊列底部推入數據并且對數據類型有限制,這一簡化一般不影響使用。
- RTOS中Queue的工作原理:
- API Description:
1.使用**osMessageQueueNew() 創建隊列
該函數會涉及osMessageQueueAttr_t **配置結構體;主要用于配置Control Block和名稱;一旦使用該結構體將導致只能使用靜態方式創建隊列;一般傳入NULL即可
osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr);/*
創建新的Queue隊列
@retval -隊列地址(Queue Identifier)
@param msg_count -隊列可容納的消息(變量)數量
@param msg_size -消息(變量)占用的空間[通常用sizeof()填入]
@param *attr -配置結構體對象,一般為NULL。 當傳入NULL時,僅使用xQueueCreate()動態創建對應大小、數量的隊列;
*/
2.使用**osMessageQueueDelete() **刪除隊列
該函數能釋放隊列占用的空間并清除其中內容和任務規劃。隊列刪除后可通過**osMessageQueueNew() **重新創建。
osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id);/*刪除隊列
@retval -osOK: the message queue object has been deleted.
-osErrorParameter: parameter mq_id is NULL or invalid.
-osErrorResource: the message queue is in an invalid state.
-osErrorISR: osMessageQueueDelete cannot be called from interrupt service routines.
*/
3.獲取隊列配置信息
uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id );
/*獲取隊列可容納的消息(變量)數量; []
*/
uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id );
/* 獲取消息(變量)占用的空間 [單位byte]
*/
uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id );/*
查詢隊列中空位(未填入變量)的數量
*/
uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id );/*
查詢隊列中已寫入的消息(變量)數量
*/
4.※ 讀取(取出)/寫入隊列
關于阻塞超時時間:
①讀取(取出)阻塞超時:當任務讀一個消息隊列時,可通過osMessageQueueGet()設置阻塞超時時間。在這段時間中,如果隊列為空(無變量),該任務將保持BLOCK狀態以等待隊列數據有效。在此期間當任務檢測到其等待的隊列中寫入了數據時,將自動由BLOCK態轉移為READY態。當等待的時間超過了指定的阻塞時間,即使隊列中尚無數據,任務也會自動從阻塞態轉移為READY態。此時程序會返回osErrorTimeout錯誤。若沒有設置阻塞超時且參數正確,返回osErrorResource錯誤**。**
由于隊列可以被多個任務讀取,所以對單個隊列而言,也可能有多個任務處于BLOCK
狀態以等待隊列數據有效。這種情況下,一旦隊列數據有效,所有等待任務中優先級最高的任務被執行。而如果所有等待任務的優先級相同,那么被解除阻塞的任務將是等待最久的任務。
②寫入阻塞超時: 同讀隊列一樣,任務也可以在寫隊列時指定一個阻塞超時時間。這個時間是當被寫隊列已滿時,任務進入BLOCK態以等待隊列空間有效的最長時間。當等待的時間超過了指定的阻塞時間,即使隊列中尚無數據,任務也會自動從BLOCK態轉移為READY態。此時程序會返回osErrorTimeout錯誤。若沒有設置阻塞超時且參數正確,返回osErrorResource錯誤。由于隊列可以被多個任務寫入,所以對單個隊列而言,也可能有多個任務處于BLOCK
狀態以等待隊列空間有效。這種情況下,一旦隊列空間有效,所有等待任務中優先級最高的任務被執行。而如果所有等待任務的優先級相同,那么被解除阻塞的任務將是等待最久的任務。
阻塞超時時間(timeout 變量)有三種配置:
== 0U //不設置阻塞超時時間,若出現上述隊列異常函數將直接報錯返回
== osWaitForever //任務將一直阻塞直到空隊列被寫入/滿隊列被取出數據
== Ticks //設置具體等待時間,單位為RTOS心跳數(Ticks)
①用 osMessageQueueGet() 取出數據**【※可在中斷中使用】**
osStatus_t osMessageQueueGet ( osMessageQueueId_t mq_id,
void * msg_ptr, //儲存讀取結果的變量地址
uint8_t * msg_prio, // ==NULL
uint32_t timeout //阻塞超時時間
);
①用 osMessageQueuePut() 寫入**【※可在中斷中使用】**
osStatus_t osMessageQueuePut ( osMessageQueueId_t mq_id,
const void * msg_ptr, //儲存寫入內容的變量地址
uint8_t msg_prio, //==0U
uint32_t timeout //阻塞超時時間
);
讀出/寫入的返回狀態值:
-osOK: 取出/寫入成功
-osErrorTimeout: the message could not be retrieved from/put into the queue in the given time (timed-wait semantics).
-osErrorResource: nothing to get from the queue or no space to push.
-osErrorParameter: parameter mq_id is NULL or invalid, non-zero timeout specified in an ISR.
5.清空隊列
osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id);/*
@retval: -osOK: the message queue has been rest.
-osErrorParameter: parameter mq_id is NULL or invalid.
-osErrorResource: the message queue is in an invalid state.
-osErrorISR: osMessageQueueReset cannot be called from interrupt service routines.
*/
-
CMSIS
+關注
關注
0文章
39瀏覽量
11826 -
RTOS
+關注
關注
20文章
804瀏覽量
119120 -
FreeRTOS
+關注
關注
12文章
483瀏覽量
61732 -
Queue
+關注
關注
0文章
16瀏覽量
7246 -
FIFO存儲
+關注
關注
0文章
103瀏覽量
5946
發布評論請先 登錄
相關推薦
評論