RTOS2:通用入隊函數xQueueGenericSend


大概記錄下這個函數的過程以便於繼續分析,類似於偽代碼

xQueue: 隊列句柄,指明要向哪個隊列發送數據,創建隊列成功以后會返回此隊列的 隊列句柄。

pvItemToQueue:指向要發送的消息,發送的過程中會將這個消息拷貝到隊列中。

xTicksToWait : 阻塞時間。

xCopyPosition: 入隊方式

有三種入隊方式:

queueSEND_TO_BACK: 后向入隊

queueSEND_TO_FRONT: 前向入隊

queueOVERWRITE: 覆寫入隊。

隊列結構體主要部分(省略了隊列集):

 

 進入臨界段后:

uxMessagesWaiting<uxLength 判斷隊列是否滿,(或覆寫入隊不考慮這個,但是一般不用覆寫入隊)

1 若隊列滿,且沒有阻塞時間,直接退出臨界段返回隊列滿。

2 若隊列未滿,則寫memcpy入隊,分為前入隊  后入隊  覆寫入隊 (deemo用的back)

后:寫入位置:pcWriteTo //初始化為隊列起始pcHead。 隨后更新pcWriteTo

前:寫入位置:u.pcReadFrom //初始化為隊列末尾pcTail(-1)。隨后更新u.pcReadFrom

覆寫:寫入位置:u.pcReadFrom //初始化為隊列末尾 ,隨后更新u.pcReadFrom並uxMessagesWaiting-- 因為覆寫不會改變長度

最后更新uxMessagesWaiting。當前隊列中消息數

入隊之后,相當於更新了隊列,需要判斷等待消息阻塞列表 list中 ,有沒有在等消息的任務,

有的話,因為剛剛消息已經入隊了,可以將其移除並放到就緒任務列表中,判斷移除的任務與當前任務的優先級,是否進行任務切換。

(若需要,則立即進行任務切換pendSV,與xTaskIncrementTick不同,這個是執行完之后再切換)

假如此時調度器上鎖,則不判斷優先級並將其放到掛起就緒列表。//uxSchedulerSuspended判斷是否上鎖

以上涉及到的幾個list:

xTasksWaitingToReceivexTimerQueue成員)//等待消息阻塞列表 ,或稱等待接受消息的任務列表

pxReadyTasksLists(全局)// 就緒列表,注意是加到對應優先級的就緒列表

xPendingReadyList(全局)//掛起就緒列表

從列表中移除任務的過程:先獲取TCB,( (&( ( xTasksWaitingToSend )->xListEnd ))->pxNext->pvOwner )

然后鏈表操作,刪除TCB中的事件列表項 xEventListItem(列表項知道自己在那個列表,調度過程中會判斷是否在等待某個事件,刪除為NULL)

(列表按照升值排列列表項)

在這里退出臨界段。

3 若隊列滿,且設置了阻塞時間,阻塞時間為最大值

任務掛起vTaskSuspendAll,隊列上鎖,將狀態列表項 pxCurrentTCB->xGenericListItem掛到掛起列表xSuspendedTaskList  隊列上鎖

4若隊列滿,且設置了阻塞時間,阻塞時間為某個值

任務掛起vTaskSuspendAll,隊列上鎖,將狀態列表項 pxCurrentTCB->xGenericListItem掛到延時列表pxDelayedTaskList 隊列上鎖並開始等待

 有關延時列表和溢出延時列表暫不展開

等待:檢測隊列是否滿,檢測是否到達預定阻塞時間

計時方式:

獲取當前xTickCount 以及xNumOfOverflows

判斷當前時間是否達到預計時間, 若達到解鎖隊列,恢復調度器xTaskResumeAll

預計時間xTicksToWait會在每次獲取xTickCount 后更新減少。因為后續會會在新的xTickCount 的基礎上計算xTimeToWake

xTickCount 是系統滴答定時器會在中斷服務里遞增。(xTaskIncrementTick

若在等待的過程中,隊列有空閑,解鎖隊列,恢復調度器(每次進入 入隊函數會嘗試發送,try again)

以上涉及到的list

掛起列表xSuspendedTaskList

延時列表pxDelayedTaskList

 

溢出延時列表pxOverflowDelayedTaskList


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM