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

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

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

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

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

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

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

FreeRTOS的消息隊(duì)列

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

評(píng)論