野火freertos內(nèi)核實(shí)現(xiàn)與應(yīng)用開發(fā)實(shí)戰(zhàn)指南3-課件第15節(jié)_第1頁
野火freertos內(nèi)核實(shí)現(xiàn)與應(yīng)用開發(fā)實(shí)戰(zhàn)指南3-課件第15節(jié)_第2頁
野火freertos內(nèi)核實(shí)現(xiàn)與應(yīng)用開發(fā)實(shí)戰(zhàn)指南3-課件第15節(jié)_第3頁
野火freertos內(nèi)核實(shí)現(xiàn)與應(yīng)用開發(fā)實(shí)戰(zhàn)指南3-課件第15節(jié)_第4頁
野火freertos內(nèi)核實(shí)現(xiàn)與應(yīng)用開發(fā)實(shí)戰(zhàn)指南3-課件第15節(jié)_第5頁
已閱讀5頁,還剩15頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

消息隊(duì)列FreeRTOS內(nèi)核實(shí)現(xiàn)與應(yīng)用開發(fā)實(shí)戰(zhàn)指南淘寶:論壇:掃描進(jìn)入淘寶店鋪01消息隊(duì)列刪除02消息隊(duì)列發(fā)送消息03消息隊(duì)列讀取消息參考資料:《FreeRTOS內(nèi)核實(shí)現(xiàn)與應(yīng)用開發(fā)實(shí)戰(zhàn)指南》主講內(nèi)容03消息隊(duì)列使用注意事項(xiàng)vQueueDelete()隊(duì)列刪除函數(shù)是根據(jù)消息隊(duì)列句柄直接刪除的,刪除之后這個(gè)消息隊(duì)列的所有信息都會(huì)被系統(tǒng)回收清空,而且不能再次使用這個(gè)消息隊(duì)列了。xQueue是vQueueDelete()函數(shù)的形參,是消息隊(duì)列句柄,表示的是要?jiǎng)h除哪個(gè)想隊(duì)列。注意:

在消息隊(duì)列有消息的時(shí)候、有任務(wù)阻塞在消息隊(duì)列上等待消息的時(shí)候,盡量不要?jiǎng)h除它,雖然源碼并沒有禁止刪除的操作,但是為了代碼健壯性,還是需要注意的

。向消息隊(duì)列發(fā)送消息任務(wù)或者中斷服務(wù)程序都可以給消息隊(duì)列發(fā)送消息,當(dāng)發(fā)送消息時(shí),如果隊(duì)列未滿或者允許覆蓋入隊(duì),F(xiàn)reeRTOS會(huì)將消息拷貝到消息隊(duì)列隊(duì)尾,否則,會(huì)根據(jù)用戶指定的阻塞超時(shí)時(shí)間進(jìn)行阻塞,在這段時(shí)間中,如果隊(duì)列一直不允許入隊(duì),該任務(wù)將保持阻塞狀態(tài)以等待隊(duì)列允許入隊(duì)。xQueueSend()函數(shù)BaseType_txQueueSend(QueueHandle_txQueue,constvoid*pvItemToQueue,TickType_txTicksToWait);功能用于向隊(duì)列尾部發(fā)送一個(gè)隊(duì)列消息。參數(shù)xQueue隊(duì)列句柄。pvItemToQueue指針,指向要發(fā)送到隊(duì)列尾部的消息。xTicksToWait隊(duì)列滿時(shí),等待隊(duì)列空閑的最大超時(shí)時(shí)間。如果隊(duì)列滿并且xTicksToWait被設(shè)置成0,函數(shù)立刻返回。超時(shí)時(shí)間的單位為系統(tǒng)節(jié)拍周期,常量portTICK_PERIOD_MS用于輔助計(jì)算真實(shí)的時(shí)間,單位為ms。如果INCLUDE_vTaskSuspend設(shè)置成1,并且指定延時(shí)為portMAX_DELAY將導(dǎo)致任務(wù)掛起(沒有超時(shí))。返回值消息發(fā)送成功成功返回pdTRUE,否則返回errQUEUE_FULL。xQueueSend()用于向隊(duì)列尾部發(fā)送一個(gè)隊(duì)列消息。消息以拷貝的形式入隊(duì),而不是以引用的形式。xQueueSendToFron()xQueueSendToFron()是一個(gè)宏,宏展開也是調(diào)用函數(shù)xQueueGenericSend()。用于向隊(duì)列隊(duì)首發(fā)送一個(gè)消息。消息以拷貝的形式入隊(duì),而不是以引用的形式。函數(shù)BaseType_txQueueSendToFront(QueueHandle_txQueue,constvoid*pvItemToQueue,

TickType_txTicksToWait);功能于向隊(duì)列隊(duì)首發(fā)送一個(gè)消息。參數(shù)xQueue隊(duì)列句柄。pvItemToQueue指針,指向要發(fā)送到隊(duì)首的消息。xTicksToWait隊(duì)列滿時(shí),等待隊(duì)列空閑的最大超時(shí)時(shí)間。如果隊(duì)列滿并且xTicksToWait被設(shè)置成0,函數(shù)立刻返回。超時(shí)時(shí)間的單位為系統(tǒng)節(jié)拍周期,常量portTICK_PERIOD_MS用于輔助計(jì)算真實(shí)的時(shí)間,單位為ms。如果INCLUDE_vTaskSuspend設(shè)置成1,并且指定延時(shí)為portMAX_DELAY將導(dǎo)致任務(wù)無限阻塞(沒有超時(shí))。返回值發(fā)送消息成功返回pdTRUE,否則返回errQUEUE_FULL。xQueueGenericSend()上面看到的那些在任務(wù)中發(fā)送消息的函數(shù)都是xQueueGenericSend()展開的宏定義,真正起作用的就是xQueueGenericSend()函數(shù),根據(jù)指定的參數(shù)不一樣,發(fā)送消息的結(jié)果就不一樣。#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()總結(jié):如果阻塞時(shí)間不為0,則任務(wù)會(huì)因?yàn)榈却腙?duì)而進(jìn)入阻塞,在將任務(wù)設(shè)置為阻塞的過程中,系統(tǒng)不希望有其它任務(wù)和中斷操作這個(gè)隊(duì)列的xTasksWaitingToReceive列表和xTasksWaitingToSend列表,因?yàn)榭赡芤鹌渌蝿?wù)解除阻塞,這可能會(huì)發(fā)生優(yōu)先級(jí)翻轉(zhuǎn)。因此FreeRTOS使用掛起調(diào)度器禁止其它任務(wù)操作隊(duì)列,因?yàn)閽炱鹫{(diào)度器意味著任務(wù)不能切換并且不準(zhǔn)調(diào)用可能引起任務(wù)切換的API函數(shù)。但掛起調(diào)度器并不會(huì)禁止中斷,中斷服務(wù)函數(shù)仍然可以操作隊(duì)列事件列表,可能會(huì)解除任務(wù)阻塞、可能會(huì)進(jìn)行上下文切換,這也是不允許的。于是,解決辦法是不但掛起調(diào)度器,還要給隊(duì)列上鎖,禁止任何中斷來操作隊(duì)列。xQueueGenericSend()xQueueSendFromISR()函數(shù)BaseType_txQueueSendFromISR(QueueHandle_txQueue,constvoid*pvItemToQueue,BaseType_t*pxHigherPriorityTaskWoken);功能在中斷服務(wù)程序中用于向隊(duì)列尾部發(fā)送一個(gè)消息。參數(shù)xQueue隊(duì)列句柄。pvItemToQueue指針,指向要發(fā)送到隊(duì)列尾部的消息。pxHigherPriorityTaskWoken如果入隊(duì)導(dǎo)致一個(gè)任務(wù)解鎖,并且解鎖的任務(wù)優(yōu)先級(jí)高于當(dāng)前被中斷的任務(wù),則將*pxHigherPriorityTaskWoken設(shè)置成pdTRUE,然后在中斷退出前需要進(jìn)行一次上下文切換,去執(zhí)行被喚醒的優(yōu)先級(jí)更高的任務(wù)。從FreeRTOSV7.3.0起,pxHigherPriorityTaskWoken作為一個(gè)可選參數(shù),可以設(shè)置為NULL。返回值消息發(fā)送成功返回pdTRUE,否則返回errQUEUE_FULL。xQueueSendFromISR()是一個(gè)宏,展開后是xQueueGenericSendFromISR()。它是xQueueSend()的中斷保護(hù)版本,用于在中斷中發(fā)送消息。xQueueSendToFrontFromISR()函數(shù)BaseType_txQueueSendToFrontFromISR(QueueHandle_txQueue,constvoid*pvItemToQueue,BaseType_t*pxHigherPriorityTaskWoken);功能在中斷服務(wù)程序中用于向消息隊(duì)列隊(duì)首發(fā)送一個(gè)消息。參數(shù)xQueue隊(duì)列句柄。pvItemToQueue指針,指向要發(fā)送到隊(duì)首的消息。pxHigherPriorityTaskWoken如果入隊(duì)導(dǎo)致一個(gè)任務(wù)解鎖,并且解鎖的任務(wù)優(yōu)先級(jí)高于當(dāng)前被中斷的任務(wù),則將*pxHigherPriorityTaskWoken設(shè)置成pdTRUE,然后在中斷退出前需要進(jìn)行一次上下文切換,去執(zhí)行被喚醒的優(yōu)先級(jí)更高的任務(wù)。從FreeRTOSV7.3.0起,pxHigherPriorityTaskWoken作為一個(gè)可選參數(shù),可以設(shè)置為NULL。返回值消息發(fā)送成功返回pdTRUE,否則返回errQUEUE_FULL。xQueueSendToFrontFromISR()是一個(gè)宏,展開后是xQueueGenericSendFromISR()。它是xQueueSendToFront()的中斷保護(hù)版本,用于在中斷中發(fā)送消息到隊(duì)列首部。xQueueGenericSendFromISR()xQueueGenericSendFromISR()函數(shù)只能用于中斷中執(zhí)行,是不帶阻塞機(jī)制的。當(dāng)成功入隊(duì)后,如果有因?yàn)榈却鲫?duì)而阻塞的任務(wù),系統(tǒng)會(huì)將該任務(wù)解除阻塞,要注意的是,解除了任務(wù)并不是會(huì)馬上運(yùn)行的,只是任務(wù)會(huì)被掛到就緒列表中。在執(zhí)行解除阻塞操作之前,會(huì)判斷隊(duì)列是否上鎖。如果沒有上鎖,則可以解除被阻塞的任務(wù),然后根據(jù)任務(wù)優(yōu)先級(jí)情況來決定是否需要進(jìn)行任務(wù)切換;如果隊(duì)列已經(jīng)上鎖,則不能解除被阻塞的任務(wù),只能是記錄xTxLock的值,表示隊(duì)列上鎖期間消息入隊(duì)的個(gè)數(shù),也用來記錄可以解除阻塞任務(wù)的個(gè)數(shù),在隊(duì)列解鎖中會(huì)將任務(wù)解除阻塞。讀取消息當(dāng)任務(wù)試圖讀隊(duì)列中的消息時(shí),可以指定一個(gè)阻塞超時(shí)時(shí)間,當(dāng)且僅當(dāng)消息隊(duì)列中有消息的時(shí)候,任務(wù)才能讀取到消息。在這段時(shí)間中,如果隊(duì)列為空,該任務(wù)將保持阻塞狀態(tài)以等待隊(duì)列數(shù)據(jù)有效。當(dāng)其它任務(wù)或中斷服務(wù)程序往其等待的隊(duì)列中寫入了數(shù)據(jù),該任務(wù)將自動(dòng)由阻塞態(tài)轉(zhuǎn)為就緒態(tài)。當(dāng)任務(wù)等待的時(shí)間超過了指定的阻塞時(shí)間,即使隊(duì)列中尚無有效數(shù)據(jù),任務(wù)也會(huì)自動(dòng)從阻塞態(tài)轉(zhuǎn)移為就緒態(tài)。xQueueReceive()xQueueReceive()是一個(gè)宏,宏展開是調(diào)用函數(shù)xQueueGenericReceive()。xQueueReceive()用于從一個(gè)隊(duì)列中接收消息并把消息從隊(duì)列中刪除。接收的消息是以拷貝的形式進(jìn)行的,所以我們必須提供一個(gè)足夠大空間的緩沖區(qū)來存儲(chǔ)讀取到的數(shù)據(jù)。函數(shù)原型BaseType_txQueueReceive(QueueHandle_txQueue,void*pvBuffer,TickType_txTicksToWait);功能用于從一個(gè)隊(duì)列中接收消息,并把接收的消息從隊(duì)列中刪除。參數(shù)xQueue隊(duì)列句柄。pvBuffer指針,指向接收到要保存的數(shù)據(jù)。xTicksToWait隊(duì)列空時(shí),阻塞超時(shí)的最大時(shí)間。如果該參數(shù)設(shè)置為0,函數(shù)立刻返回。超時(shí)時(shí)間的單位為系統(tǒng)節(jié)拍周期,常量portTICK_PERIOD_MS用于輔助計(jì)算真實(shí)的時(shí)間,單位為ms。如果INCLUDE_vTaskSuspend設(shè)置成1,并且指定延時(shí)為portMAX_DELAY將導(dǎo)致任務(wù)無限阻塞。返回值隊(duì)列項(xiàng)接收成功返回pdTRUE,否則返回pdFALSE。xQueuePeek()其實(shí)這個(gè)函數(shù)與xQueueReceive()函數(shù)的實(shí)現(xiàn)方式一樣,連使用方法都一樣,只不過xQueuePeek()函數(shù)接收消息完畢不會(huì)刪除消息隊(duì)列中的消息而已。#define xQueueReceive(xQueue,pvBuffer,xTicksToWait) \ xQueueGenericReceive((xQueue),(pvBuffer), \ (xTicksToWait),pdFALSE)#define xQueuePeek(xQueue,pvBuffer,xTicksToWait) \ xQueueGenericReceive((xQueue),(pvBuffer), \ (xTicksToWait),pdTRUE)xQueueGenericReceive()任務(wù)調(diào)用接收函數(shù)收取隊(duì)列消息,函數(shù)首先判斷當(dāng)前隊(duì)列是否有未讀消息,如果沒有,則會(huì)判斷參數(shù)xTicksToWait,決定直接返回函數(shù)還是阻塞等待。如果隊(duì)列中有消息未讀,首先會(huì)把待讀的消息復(fù)制到傳進(jìn)來的指針?biāo)竷?nèi),然后判斷函數(shù)參數(shù)xJustPeeking==pdFALSE的時(shí)候,符合的話,說明這個(gè)函數(shù)讀取了數(shù)據(jù),需要把被讀取的數(shù)據(jù)做出隊(duì)處理,如果不是,則只是查看一下(peek),只是返回?cái)?shù)據(jù),但是不會(huì)把數(shù)據(jù)清除。對(duì)于正常讀取數(shù)據(jù)的操作,清除數(shù)據(jù)后隊(duì)列會(huì)空出空位,所以查看隊(duì)列中的等待列表中是否有任務(wù)等發(fā)送數(shù)據(jù)而被掛起,有的話恢復(fù)一個(gè)任務(wù)就緒,并根據(jù)優(yōu)先級(jí)判斷是否需要出進(jìn)行任務(wù)切換。對(duì)于只是查看數(shù)據(jù)的,由于沒有清除數(shù)據(jù),所以沒有空間新空出,不需要檢查發(fā)送等待鏈表,但是會(huì)檢查接收等待鏈表,如果有任務(wù)掛起會(huì)切換其到就緒并判斷是否需要切換。消息隊(duì)列使用注意事項(xiàng)在使用FreeRTOS提供的消息隊(duì)列函數(shù)的時(shí)候,需要了解以下幾點(diǎn):使用xQueueSend()、xQueueSendFromISR()、xQueueReceive()等這些函數(shù)之前應(yīng)先創(chuàng)建需消息隊(duì)列,并根據(jù)隊(duì)列句柄進(jìn)行操作。隊(duì)列讀取采用的是先進(jìn)先出(FIFO)模式,會(huì)先讀取先存儲(chǔ)在隊(duì)列中的數(shù)據(jù)。當(dāng)然也FreeRTOS也支持后進(jìn)先出(LIFO)模式,那么讀取的時(shí)候就會(huì)讀取到后進(jìn)隊(duì)列的數(shù)據(jù)。在獲取隊(duì)列中的消息時(shí)候,我們必須要定義一個(gè)存儲(chǔ)讀取數(shù)據(jù)的地方,并且該數(shù)據(jù)區(qū)域大小不小于消息大小,否則,很可能引發(fā)地址非法的錯(cuò)誤。無論是發(fā)送或者是接收消息都是以拷貝的方式進(jìn)行,如果消息過于龐大,可以將消息的地址作為消息進(jìn)行發(fā)送、接收。隊(duì)列是具有自己獨(dú)立權(quán)限的內(nèi)核對(duì)象,并不屬于任何任務(wù)。所有任務(wù)都可以向同一隊(duì)列寫入和讀出。一個(gè)隊(duì)列由多任務(wù)或中斷寫入是經(jīng)常的事,但由多

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論