隊(duì)列是為了任務(wù)與任務(wù)、任務(wù)與中斷之間的通信而準(zhǔn)備的,可以在任務(wù)與任務(wù)、任務(wù)與中斷之間傳遞消息,隊(duì)列中可以存儲有限的、大小固定的數(shù)據(jù)項(xiàng)目。任務(wù)與任務(wù)、任務(wù)與中斷之間要交流的數(shù)據(jù)保存在隊(duì)列中,叫做隊(duì)列項(xiàng)目。隊(duì)列所能保存的最大數(shù)據(jù)項(xiàng)目數(shù)量叫做隊(duì)列的長度,創(chuàng)建隊(duì)列的時候會指定數(shù)據(jù)項(xiàng)目的大小和隊(duì)列的長度。
通常隊(duì)列采用先進(jìn)先出(FIFO)的存儲緩沖機(jī)制,也就是往隊(duì)列發(fā)送數(shù)據(jù)的時候(也叫入隊(duì))永遠(yuǎn)都是發(fā)送到隊(duì)列的尾部,而從隊(duì)列提取數(shù)據(jù)的時候(也叫出隊(duì))是從隊(duì)列的頭部提取的。但是也可以使用
LIFO 的存儲緩沖,也就是后進(jìn)先出,FreeRTOS 中的隊(duì)列也提供了 LIFO 的存儲緩沖機(jī)制。
數(shù)據(jù)發(fā)送到隊(duì)列中會導(dǎo)致數(shù)據(jù)拷貝,也就是將要發(fā)送的數(shù)據(jù)拷貝到隊(duì)列中,這就意味著在隊(duì)列中存儲的是數(shù)據(jù)的原始值,而不是原數(shù)據(jù)的引用(即只傳遞數(shù)據(jù)的指針),這個也叫做值傳遞。UCOS
的消息隊(duì)列采用的是引用傳遞,傳遞的是消息指針。采用引用傳遞的話消息內(nèi)容就必須一直保持可見性,也就是消息內(nèi)容必須有效,那么局部變量這種可能會隨時被刪掉的東西就不能用來傳遞消息,但是采用引用傳遞會節(jié)省時間??!因?yàn)椴挥眠M(jìn)行數(shù)據(jù)拷貝。
采用值傳遞的話雖然會導(dǎo)致數(shù)據(jù)拷貝,會浪費(fèi)一點(diǎn)時間,但是一旦將消息發(fā)送到隊(duì)列中原始的數(shù)據(jù)緩沖區(qū)就可以刪除掉或者覆寫,這樣的話這些緩沖區(qū)就可以被重復(fù)的使用。FreeRTOS中使用隊(duì)列傳遞消息的話雖然使用的是數(shù)據(jù)拷貝,但是也可以使用引用來傳遞消息啊,我直接往隊(duì)列中發(fā)送指向這個消息的地址指針不就可以了!這樣當(dāng)我要發(fā)送的消息數(shù)據(jù)太大的時候就可以直接發(fā)送消息緩沖區(qū)的地址指針,比如在網(wǎng)絡(luò)應(yīng)用環(huán)境中,網(wǎng)絡(luò)的數(shù)據(jù)量往往都很大的,采用數(shù)據(jù)拷貝的話就不現(xiàn)實(shí)。
1、多任務(wù)訪問
隊(duì)列不是屬于某個特別指定的任務(wù)的,任何任務(wù)都可以向隊(duì)列中發(fā)送消息,或者從隊(duì)列中提取消息。
2、出隊(duì)阻塞
當(dāng)任務(wù)嘗試從一個隊(duì)列中讀取消息的時候可以指定一個阻塞時間,這個阻塞時間就是當(dāng)任務(wù)從隊(duì)列中讀取消息無效的時候任務(wù)阻塞的時間。出隊(duì)就是就從隊(duì)列中讀取消息,出隊(duì)阻塞是針對從隊(duì)列中讀取消息的任務(wù)而言的。
比如任務(wù) A 用于處理串口接收到的數(shù)據(jù),串口接收到數(shù)據(jù)以后就會放到隊(duì)列 Q 中,任務(wù) A 從隊(duì)列 Q 中讀取數(shù)據(jù)。但是如果此時隊(duì)列 Q
是空的,說明還沒有數(shù)據(jù),任務(wù) A 這時候來讀取的話肯定是獲取不到任何東西,那該怎么辦呢?任務(wù) A
現(xiàn)在有三種選擇,一:二話不說扭頭就走,二:要不我在等等吧,等一會看看,說不定一會就有數(shù)據(jù)了,三:死等,死也要等到你有數(shù)據(jù)!選哪一個就是由這個阻塞時間決定的,這個阻塞時間單位是時鐘節(jié)拍數(shù)。阻塞時間為
0 的話就是不阻塞,沒有數(shù)據(jù)的話就馬上返回任務(wù)繼續(xù)執(zhí)行接下來的代碼,對應(yīng)第一種選擇。如果阻塞時間為 0~
portMAX_DELAY,當(dāng)任務(wù)沒有從隊(duì)列中獲取到消息的話就進(jìn)入阻塞態(tài),阻塞時間指定了任務(wù)進(jìn)入阻塞態(tài)的時間,當(dāng)阻塞時間到了以后還沒有接收到數(shù)據(jù)的話就退出阻塞態(tài),返回任務(wù)接著運(yùn)行下面的代碼,如果在阻塞時間內(nèi)接收到了數(shù)據(jù)就立即返回,執(zhí)行任務(wù)中下面的代碼,這種情況對應(yīng)第二種選擇。當(dāng)阻塞時間設(shè)置為portMAX_DELAY
的話,任務(wù)就會一直進(jìn)入阻塞態(tài)等待,直到接收到數(shù)據(jù)為止!這個就是第三種選擇。
3、入隊(duì)阻塞
入隊(duì)說的是向隊(duì)列中發(fā)送消息,將消息加入到隊(duì)列中。和出隊(duì)阻塞一樣,當(dāng)一個任務(wù)向隊(duì)列發(fā)送消息的話也可以設(shè)置阻塞時間。比如任務(wù) B 向消息隊(duì)列 Q
發(fā)送消息,但是此時隊(duì)列 Q 是滿的,那肯定是發(fā)送失敗的。此時任務(wù) B 就會遇到和上面任務(wù) A 一樣的問題,這兩種情況的處理過程是類似的,只不過一個是向隊(duì)列 Q
發(fā)送消息,一個是從隊(duì)列 Q 讀取消息而已。
4、隊(duì)列操作過程圖示
-
嵌入式
+關(guān)注
關(guān)注
5148文章
19651瀏覽量
317122 -
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
7254瀏覽量
91776 -
FreeRTOS
+關(guān)注
關(guān)注
12文章
492瀏覽量
64247
發(fā)布評論請先 登錄
基于FreeRTOS的STM32F103系統(tǒng)—隊(duì)列

轉(zhuǎn):第20章 FreeRTOS消息隊(duì)列
FreeRTOS創(chuàng)建消息隊(duì)列問題如何解決
FreeRTOS消息隊(duì)列有何作用
FreeRTOS源碼介紹
FreeRTOS消息隊(duì)列和RT-Thread消息隊(duì)列的使用注意事項(xiàng)介紹
FreeRTOS消息隊(duì)列 & ESP32使用

FreeRTOS學(xué)習(xí)(五)消息隊(duì)列和二值信號量 xQueue / xSemaphore

FreeRTOS消息隊(duì)列 傳遞結(jié)構(gòu)體指針和結(jié)構(gòu)體異同

FreeRTOS 隊(duì)列 信號量 互斥量

FreeRTOS高級篇5---FreeRTOS隊(duì)列分析

FreeRTOS系列第18篇---FreeRTOS隊(duì)列API函數(shù)

FreeRTOS的消息隊(duì)列

FreeRTOS消息隊(duì)列結(jié)構(gòu)體

評論