版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
消息隊列FreeRTOS內(nèi)核實現(xiàn)與應用開發(fā)實戰(zhàn)指南淘寶:論壇:掃描進入淘寶店鋪01消息隊列刪除02消息隊列發(fā)送消息03消息隊列讀取消息參考資料:《FreeRTOS內(nèi)核實現(xiàn)與應用開發(fā)實戰(zhàn)指南》主講內(nèi)容03消息隊列使用注意事項vQueueDelete()隊列刪除函數(shù)是根據(jù)消息隊列句柄直接刪除的,刪除之后這個消息隊列的所有信息都會被系統(tǒng)回收清空,而且不能再次使用這個消息隊列了。xQueue是vQueueDelete()函數(shù)的形參,是消息隊列句柄,表示的是要刪除哪個想隊列。注意:
在消息隊列有消息的時候、有任務阻塞在消息隊列上等待消息的時候,盡量不要刪除它,雖然源碼并沒有禁止刪除的操作,但是為了代碼健壯性,還是需要注意的
。向消息隊列發(fā)送消息任務或者中斷服務程序都可以給消息隊列發(fā)送消息,當發(fā)送消息時,如果隊列未滿或者允許覆蓋入隊,F(xiàn)reeRTOS會將消息拷貝到消息隊列隊尾,否則,會根據(jù)用戶指定的阻塞超時時間進行阻塞,在這段時間中,如果隊列一直不允許入隊,該任務將保持阻塞狀態(tài)以等待隊列允許入隊。xQueueSend()函數(shù)BaseType_txQueueSend(QueueHandle_txQueue,constvoid*pvItemToQueue,TickType_txTicksToWait);功能用于向隊列尾部發(fā)送一個隊列消息。參數(shù)xQueue隊列句柄。pvItemToQueue指針,指向要發(fā)送到隊列尾部的消息。xTicksToWait隊列滿時,等待隊列空閑的最大超時時間。如果隊列滿并且xTicksToWait被設置成0,函數(shù)立刻返回。超時時間的單位為系統(tǒng)節(jié)拍周期,常量portTICK_PERIOD_MS用于輔助計算真實的時間,單位為ms。如果INCLUDE_vTaskSuspend設置成1,并且指定延時為portMAX_DELAY將導致任務掛起(沒有超時)。返回值消息發(fā)送成功成功返回pdTRUE,否則返回errQUEUE_FULL。xQueueSend()用于向隊列尾部發(fā)送一個隊列消息。消息以拷貝的形式入隊,而不是以引用的形式。xQueueSendToFron()xQueueSendToFron()是一個宏,宏展開也是調(diào)用函數(shù)xQueueGenericSend()。用于向隊列隊首發(fā)送一個消息。消息以拷貝的形式入隊,而不是以引用的形式。函數(shù)BaseType_txQueueSendToFront(QueueHandle_txQueue,constvoid*pvItemToQueue,
TickType_txTicksToWait);功能于向隊列隊首發(fā)送一個消息。參數(shù)xQueue隊列句柄。pvItemToQueue指針,指向要發(fā)送到隊首的消息。xTicksToWait隊列滿時,等待隊列空閑的最大超時時間。如果隊列滿并且xTicksToWait被設置成0,函數(shù)立刻返回。超時時間的單位為系統(tǒng)節(jié)拍周期,常量portTICK_PERIOD_MS用于輔助計算真實的時間,單位為ms。如果INCLUDE_vTaskSuspend設置成1,并且指定延時為portMAX_DELAY將導致任務無限阻塞(沒有超時)。返回值發(fā)送消息成功返回pdTRUE,否則返回errQUEUE_FULL。xQueueGenericSend()上面看到的那些在任務中發(fā)送消息的函數(shù)都是xQueueGenericSend()展開的宏定義,真正起作用的就是xQueueGenericSend()函數(shù),根據(jù)指定的參數(shù)不一樣,發(fā)送消息的結果就不一樣。#define xQueueSend(xQueue,pvItemToQueue,xTicksToWait) \ xQueueGenericSend((xQueue),(pvItemToQueue), \ (xTicksToWait),queueSEND_TO_BACK
)#define xQueueSendToFront(xQueue,pvItemToQueue,xTicksToWait)\ xQueueGenericSend((xQueue),(pvItemToQueue), \ (xTicksToWait),queueSEND_TO_FRONT
)xQueueGenericSend()總結:如果阻塞時間不為0,則任務會因為等待入隊而進入阻塞,在將任務設置為阻塞的過程中,系統(tǒng)不希望有其它任務和中斷操作這個隊列的xTasksWaitingToReceive列表和xTasksWaitingToSend列表,因為可能引起其它任務解除阻塞,這可能會發(fā)生優(yōu)先級翻轉。因此FreeRTOS使用掛起調(diào)度器禁止其它任務操作隊列,因為掛起調(diào)度器意味著任務不能切換并且不準調(diào)用可能引起任務切換的API函數(shù)。但掛起調(diào)度器并不會禁止中斷,中斷服務函數(shù)仍然可以操作隊列事件列表,可能會解除任務阻塞、可能會進行上下文切換,這也是不允許的。于是,解決辦法是不但掛起調(diào)度器,還要給隊列上鎖,禁止任何中斷來操作隊列。xQueueGenericSend()xQueueSendFromISR()函數(shù)BaseType_txQueueSendFromISR(QueueHandle_txQueue,constvoid*pvItemToQueue,BaseType_t*pxHigherPriorityTaskWoken);功能在中斷服務程序中用于向隊列尾部發(fā)送一個消息。參數(shù)xQueue隊列句柄。pvItemToQueue指針,指向要發(fā)送到隊列尾部的消息。pxHigherPriorityTaskWoken如果入隊導致一個任務解鎖,并且解鎖的任務優(yōu)先級高于當前被中斷的任務,則將*pxHigherPriorityTaskWoken設置成pdTRUE,然后在中斷退出前需要進行一次上下文切換,去執(zhí)行被喚醒的優(yōu)先級更高的任務。從FreeRTOSV7.3.0起,pxHigherPriorityTaskWoken作為一個可選參數(shù),可以設置為NULL。返回值消息發(fā)送成功返回pdTRUE,否則返回errQUEUE_FULL。xQueueSendFromISR()是一個宏,展開后是xQueueGenericSendFromISR()。它是xQueueSend()的中斷保護版本,用于在中斷中發(fā)送消息。xQueueSendToFrontFromISR()函數(shù)BaseType_txQueueSendToFrontFromISR(QueueHandle_txQueue,constvoid*pvItemToQueue,BaseType_t*pxHigherPriorityTaskWoken);功能在中斷服務程序中用于向消息隊列隊首發(fā)送一個消息。參數(shù)xQueue隊列句柄。pvItemToQueue指針,指向要發(fā)送到隊首的消息。pxHigherPriorityTaskWoken如果入隊導致一個任務解鎖,并且解鎖的任務優(yōu)先級高于當前被中斷的任務,則將*pxHigherPriorityTaskWoken設置成pdTRUE,然后在中斷退出前需要進行一次上下文切換,去執(zhí)行被喚醒的優(yōu)先級更高的任務。從FreeRTOSV7.3.0起,pxHigherPriorityTaskWoken作為一個可選參數(shù),可以設置為NULL。返回值消息發(fā)送成功返回pdTRUE,否則返回errQUEUE_FULL。xQueueSendToFrontFromISR()是一個宏,展開后是xQueueGenericSendFromISR()。它是xQueueSendToFront()的中斷保護版本,用于在中斷中發(fā)送消息到隊列首部。xQueueGenericSendFromISR()xQueueGenericSendFromISR()函數(shù)只能用于中斷中執(zhí)行,是不帶阻塞機制的。當成功入隊后,如果有因為等待出隊而阻塞的任務,系統(tǒng)會將該任務解除阻塞,要注意的是,解除了任務并不是會馬上運行的,只是任務會被掛到就緒列表中。在執(zhí)行解除阻塞操作之前,會判斷隊列是否上鎖。如果沒有上鎖,則可以解除被阻塞的任務,然后根據(jù)任務優(yōu)先級情況來決定是否需要進行任務切換;如果隊列已經(jīng)上鎖,則不能解除被阻塞的任務,只能是記錄xTxLock的值,表示隊列上鎖期間消息入隊的個數(shù),也用來記錄可以解除阻塞任務的個數(shù),在隊列解鎖中會將任務解除阻塞。讀取消息當任務試圖讀隊列中的消息時,可以指定一個阻塞超時時間,當且僅當消息隊列中有消息的時候,任務才能讀取到消息。在這段時間中,如果隊列為空,該任務將保持阻塞狀態(tài)以等待隊列數(shù)據(jù)有效。當其它任務或中斷服務程序往其等待的隊列中寫入了數(shù)據(jù),該任務將自動由阻塞態(tài)轉為就緒態(tài)。當任務等待的時間超過了指定的阻塞時間,即使隊列中尚無有效數(shù)據(jù),任務也會自動從阻塞態(tài)轉移為就緒態(tài)。xQueueReceive()xQueueReceive()是一個宏,宏展開是調(diào)用函數(shù)xQueueGenericReceive()。xQueueReceive()用于從一個隊列中接收消息并把消息從隊列中刪除。接收的消息是以拷貝的形式進行的,所以我們必須提供一個足夠大空間的緩沖區(qū)來存儲讀取到的數(shù)據(jù)。函數(shù)原型BaseType_txQueueReceive(QueueHandle_txQueue,void*pvBuffer,TickType_txTicksToWait);功能用于從一個隊列中接收消息,并把接收的消息從隊列中刪除。參數(shù)xQueue隊列句柄。pvBuffer指針,指向接收到要保存的數(shù)據(jù)。xTicksToWait隊列空時,阻塞超時的最大時間。如果該參數(shù)設置為0,函數(shù)立刻返回。超時時間的單位為系統(tǒng)節(jié)拍周期,常量portTICK_PERIOD_MS用于輔助計算真實的時間,單位為ms。如果INCLUDE_vTaskSuspend設置成1,并且指定延時為portMAX_DELAY將導致任務無限阻塞。返回值隊列項接收成功返回pdTRUE,否則返回pdFALSE。xQueuePeek()其實這個函數(shù)與xQueueReceive()函數(shù)的實現(xiàn)方式一樣,連使用方法都一樣,只不過xQueuePeek()函數(shù)接收消息完畢不會刪除消息隊列中的消息而已。#define xQueueReceive(xQueue,pvBuffer,xTicksToWait) \ xQueueGenericReceive((xQueue),(pvBuffer), \ (xTicksToWait),pdFALSE)#define xQueuePeek(xQueue,pvBuffer,xTicksToWait) \ xQueueGenericReceive((xQueue),(pvBuffer), \ (xTicksToWait),pdTRUE)xQueueGenericReceive()任務調(diào)用接收函數(shù)收取隊列消息,函數(shù)首先判斷當前隊列是否有未讀消息,如果沒有,則會判斷參數(shù)xTicksToWait,決定直接返回函數(shù)還是阻塞等待。如果隊列中有消息未讀,首先會把待讀的消息復制到傳進來的指針所指內(nèi),然后判斷函數(shù)參數(shù)xJustPeeking==pdFALSE的時候,符合的話,說明這個函數(shù)讀取了數(shù)據(jù),需要把被讀取的數(shù)據(jù)做出隊處理,如果不是,則只是查看一下(peek),只是返回數(shù)據(jù),但是不會把數(shù)據(jù)清除。對于正常讀取數(shù)據(jù)的操作,清除數(shù)據(jù)后隊列會空出空位,所以查看隊列中的等待列表中是否有任務等發(fā)送數(shù)據(jù)而被掛起,有的話恢復一個任務就緒,并根據(jù)優(yōu)先級判斷是否需要出進行任務切換。對于只是查看數(shù)據(jù)的,由于沒有清除數(shù)據(jù),所以沒有空間新空出,不需要檢查發(fā)送等待鏈表,但是會檢查接收等待鏈表,如果有任務掛起會切換其到就緒并判斷是否需要切換。消息隊列使用注意事項在使用FreeRTOS提供的消息隊列函數(shù)的時候,需要了解以下幾點:使用xQueueSend()、xQueueSendFromISR()、xQueueReceive()等這些函數(shù)之前應先創(chuàng)建需消息隊列,并根據(jù)隊列句柄進行操作。隊列讀取采用的是先進先出(FIFO)模式,會先讀取先存儲在隊列中的數(shù)據(jù)。當然也FreeRTOS也支持后進先出(LIFO)模式,那么讀取的時候就會讀取到后進隊列的數(shù)據(jù)。在獲取隊列中的消息時候,我們必須要定義一個存儲讀取數(shù)據(jù)的地方,并且該數(shù)據(jù)區(qū)域大小不小于消息大小,否則,很可能引發(fā)地址非法的錯誤。無論是發(fā)送或者是接收消息都是以拷貝的方式進行,如果消息過于龐大,可以將消息的地址作為消息進行發(fā)送、接收。隊列是具有自己獨立權限的內(nèi)核對象,并不屬于任何任務。所有任務都可以向同一隊列寫入和讀出。一個隊列由多任務或中斷寫入是經(jīng)常的事,但由多
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度住宅小區(qū)車位維修保養(yǎng)合同范本3篇
- 2024物流轉包商服務質(zhì)量評價體系合同
- 2024牛肉產(chǎn)業(yè)技術創(chuàng)新與研發(fā)合作合同
- 2025年度大理石石材工程環(huán)保評估與施工合同3篇
- 2025年度新能源項目打樁工程合作合同4篇
- 2025年度智能窗簾控制系統(tǒng)研發(fā)與集成承包合同4篇
- 2024年電商平臺運營服務外包合同
- 2024版項目股權出售合同:公司權益轉讓協(xié)議
- 2025年度新能源電池產(chǎn)品進出口合同4篇
- 2025年度房地產(chǎn)租賃權轉讓合同3篇
- 服裝板房管理制度
- 2024年縣鄉(xiāng)教師選調(diào)進城考試《教育學》題庫及完整答案(考點梳理)
- 車借給別人免責協(xié)議書
- 河北省興隆縣盛嘉恒信礦業(yè)有限公司李杖子硅石礦礦山地質(zhì)環(huán)境保護與治理恢復方案
- 第七章力與運動第八章壓強第九章浮力綜合檢測題(一)-2023-2024學年滬科版物理八年級下學期
- 醫(yī)療機構診療科目名錄(2022含注釋)
- 微視頻基地策劃方案
- 光伏項目質(zhì)量評估報告
- 八年級一本·現(xiàn)代文閱讀訓練100篇
- 2023年電池系統(tǒng)測試工程師年度總結及下一年計劃
- 應急預案評分標準表
評論
0/150
提交評論