Queue概述
Queue即消息隊(duì)列是通過(guò)RTOS內(nèi)核提供的一種服務(wù)。它是一種線程間同步數(shù)據(jù)的安全方法。
隊(duì)列(Queue)是與棧對(duì)應(yīng)的概念;棧是FILO結(jié)構(gòu),而隊(duì)列是FIFO結(jié)構(gòu)。FreeRTOS原生的隊(duì)列支持從高位添加新數(shù)據(jù),但CMSIS簡(jiǎn)化刪去了這一功能,即只能從隊(duì)列底部推入數(shù)據(jù)并且對(duì)數(shù)據(jù)類(lèi)型有限制,這一簡(jiǎn)化一般不影響使用。
- RTOS中Queue的工作原理:
- API Description:
1.使用**osMessageQueueNew() 創(chuàng)建隊(duì)列
該函數(shù)會(huì)涉及osMessageQueueAttr_t **配置結(jié)構(gòu)體;主要用于配置Control Block和名稱(chēng);一旦使用該結(jié)構(gòu)體將導(dǎo)致只能使用靜態(tài)方式創(chuàng)建隊(duì)列;一般傳入NULL即可
osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr);/*
創(chuàng)建新的Queue隊(duì)列
@retval -隊(duì)列地址(Queue Identifier)
@param msg_count -隊(duì)列可容納的消息(變量)數(shù)量
@param msg_size -消息(變量)占用的空間[通常用sizeof()填入]
@param *attr -配置結(jié)構(gòu)體對(duì)象,一般為NULL。 當(dāng)傳入NULL時(shí),僅使用xQueueCreate()動(dòng)態(tài)創(chuàng)建對(duì)應(yīng)大小、數(shù)量的隊(duì)列;
*/
2.使用**osMessageQueueDelete() **刪除隊(duì)列
該函數(shù)能釋放隊(duì)列占用的空間并清除其中內(nèi)容和任務(wù)規(guī)劃。隊(duì)列刪除后可通過(guò)**osMessageQueueNew() **重新創(chuàng)建。
osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id);/*刪除隊(duì)列
@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.獲取隊(duì)列配置信息
uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id );
/*獲取隊(duì)列可容納的消息(變量)數(shù)量; []
*/
uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id );
/* 獲取消息(變量)占用的空間 [單位byte]
*/
uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id );/*
查詢(xún)隊(duì)列中空位(未填入變量)的數(shù)量
*/
uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id );/*
查詢(xún)隊(duì)列中已寫(xiě)入的消息(變量)數(shù)量
*/
4.※ 讀取(取出)/寫(xiě)入隊(duì)列
關(guān)于阻塞超時(shí)時(shí)間:
①讀取(取出)阻塞超時(shí):當(dāng)任務(wù)讀一個(gè)消息隊(duì)列時(shí),可通過(guò)osMessageQueueGet()設(shè)置阻塞超時(shí)時(shí)間。在這段時(shí)間中,如果隊(duì)列為空(無(wú)變量),該任務(wù)將保持BLOCK狀態(tài)以等待隊(duì)列數(shù)據(jù)有效。在此期間當(dāng)任務(wù)檢測(cè)到其等待的隊(duì)列中寫(xiě)入了數(shù)據(jù)時(shí),將自動(dòng)由BLOCK態(tài)轉(zhuǎn)移為READY態(tài)。當(dāng)?shù)却臅r(shí)間超過(guò)了指定的阻塞時(shí)間,即使隊(duì)列中尚無(wú)數(shù)據(jù),任務(wù)也會(huì)自動(dòng)從阻塞態(tài)轉(zhuǎn)移為READY態(tài)。此時(shí)程序會(huì)返回osErrorTimeout錯(cuò)誤。若沒(méi)有設(shè)置阻塞超時(shí)且參數(shù)正確,返回osErrorResource錯(cuò)誤**。**
由于隊(duì)列可以被多個(gè)任務(wù)讀取,所以對(duì)單個(gè)隊(duì)列而言,也可能有多個(gè)任務(wù)處于BLOCK
狀態(tài)以等待隊(duì)列數(shù)據(jù)有效。這種情況下,一旦隊(duì)列數(shù)據(jù)有效,所有等待任務(wù)中優(yōu)先級(jí)最高的任務(wù)被執(zhí)行。而如果所有等待任務(wù)的優(yōu)先級(jí)相同,那么被解除阻塞的任務(wù)將是等待最久的任務(wù)。
②寫(xiě)入阻塞超時(shí): 同讀隊(duì)列一樣,任務(wù)也可以在寫(xiě)隊(duì)列時(shí)指定一個(gè)阻塞超時(shí)時(shí)間。這個(gè)時(shí)間是當(dāng)被寫(xiě)隊(duì)列已滿(mǎn)時(shí),任務(wù)進(jìn)入BLOCK態(tài)以等待隊(duì)列空間有效的最長(zhǎng)時(shí)間。當(dāng)?shù)却臅r(shí)間超過(guò)了指定的阻塞時(shí)間,即使隊(duì)列中尚無(wú)數(shù)據(jù),任務(wù)也會(huì)自動(dòng)從BLOCK態(tài)轉(zhuǎn)移為READY態(tài)。此時(shí)程序會(huì)返回osErrorTimeout錯(cuò)誤。若沒(méi)有設(shè)置阻塞超時(shí)且參數(shù)正確,返回osErrorResource錯(cuò)誤。由于隊(duì)列可以被多個(gè)任務(wù)寫(xiě)入,所以對(duì)單個(gè)隊(duì)列而言,也可能有多個(gè)任務(wù)處于BLOCK
狀態(tài)以等待隊(duì)列空間有效。這種情況下,一旦隊(duì)列空間有效,所有等待任務(wù)中優(yōu)先級(jí)最高的任務(wù)被執(zhí)行。而如果所有等待任務(wù)的優(yōu)先級(jí)相同,那么被解除阻塞的任務(wù)將是等待最久的任務(wù)。
阻塞超時(shí)時(shí)間(timeout 變量)有三種配置:
== 0U //不設(shè)置阻塞超時(shí)時(shí)間,若出現(xiàn)上述隊(duì)列異常函數(shù)將直接報(bào)錯(cuò)返回
== osWaitForever //任務(wù)將一直阻塞直到空隊(duì)列被寫(xiě)入/滿(mǎn)隊(duì)列被取出數(shù)據(jù)
== Ticks //設(shè)置具體等待時(shí)間,單位為RTOS心跳數(shù)(Ticks)
①用 osMessageQueueGet() 取出數(shù)據(jù)**【※可在中斷中使用】**
osStatus_t osMessageQueueGet ( osMessageQueueId_t mq_id,
void * msg_ptr, //儲(chǔ)存讀取結(jié)果的變量地址
uint8_t * msg_prio, // ==NULL
uint32_t timeout //阻塞超時(shí)時(shí)間
);
①用 osMessageQueuePut() 寫(xiě)入**【※可在中斷中使用】**
osStatus_t osMessageQueuePut ( osMessageQueueId_t mq_id,
const void * msg_ptr, //儲(chǔ)存寫(xiě)入內(nèi)容的變量地址
uint8_t msg_prio, //==0U
uint32_t timeout //阻塞超時(shí)時(shí)間
);
讀出/寫(xiě)入的返回狀態(tài)值:
-osOK: 取出/寫(xiě)入成功
-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.清空隊(duì)列
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
+關(guān)注
關(guān)注
0文章
40瀏覽量
11907 -
RTOS
+關(guān)注
關(guān)注
22文章
813瀏覽量
119643 -
FreeRTOS
+關(guān)注
關(guān)注
12文章
484瀏覽量
62181 -
Queue
+關(guān)注
關(guān)注
0文章
16瀏覽量
7262 -
FIFO存儲(chǔ)
+關(guān)注
關(guān)注
0文章
103瀏覽量
5979
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論