1. 程式人生 > >從0開始學FreeRTOS-(列表&列表項)-6

從0開始學FreeRTOS-(列表&列表項)-6

# FreeRTOS列表&列表項的原始碼解讀 第一次看列表與列表項的時候,感覺很像是連結串列,雖然我自己的連結串列也不太會,但是就是感覺很像。 在FreeRTOS中,列表與列表項使用得非常多,是FreeRTOS的一個數據結構,學習過資料結構的同學都知道,資料結構能使我們處理資料更加方便快速,能快速找到資料,在FreeRTOS中,這種列表與列表項更是必不可少的,能讓我們的系統跑起來更加流暢迅速。 言歸正傳,FreeRTOS中使用了大量的列表(List)與列表項(Listitem),在FreeRTOS排程器中,就是用到這些來跟著任務,瞭解任務的狀態,處於掛起、阻塞態、還是就緒態亦或者是執行態。這些資訊都會在各自任務的列表中得到。 看任務控制塊(tskTaskControlBlock)中的兩個列表項: ```js ListItem_t xStateListItem; /* <任務的狀態列表專案引用的列表表示該任務的狀態(就緒,已阻止,暫停)。*/ ListItem_t xEventListItem; /* <用於從事件列表中引用任務。*/ ``` 一個是狀態的列表項,一個是事件列表項。他們在建立任務就會被初始化,列表項的初始化是根據實際需要來初始化的,下面會說。 # FreeRTOS列表&列表項的結構體 既然知道列表與列表項的重要性,那麼我們來解讀FreeRTOS中的list.c與list.h的原始碼吧。從標頭檔案lsit.h開始,看到定義了一些結構體: ```js struct xLIST_ITEM { listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /* <如果configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES設定為1,則設定為已知值。*/ configLIST_VOLATILE TickType_t xItemValue; /* <正在列出的值。在大多數情況下,這用於按降序對列表進行排序。 */ struct xLIST_ITEM * configLIST_VOLATILE pxNext; /* <指向列表中下一個ListItem_t的指標。 */ struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /* <指向列表中前一個ListItem_t的指標。 */ void * pvOwner; /* <指向包含列表專案的物件(通常是TCB)的指標。因此,包含列表專案的物件與列表專案本身之間存在雙向連結。 */ void * configLIST_VOLATILE pvContainer; /* <指向此列表專案所在列表的指標(如果有)。 */ listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /* <如果configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES設定為1,則設定為已知值。*/ }; typedef struct xLIST_ITEM ListItem_t; /* 由於某種原因,lint希望將其作為兩個單獨的定義。 */ ``` 列表項結構體的一些注意的地方: **xItemValue** 用於列表項的排序,類似1—2—3—4 **pxNext** 指向下一個列表項的指標 **pxPrevious** 指向上(前)一個列表項的指標 這兩個指標實現了類似雙向連結串列的功能 **pvOwner** 指向包含列表專案的物件(通常是任務控制塊TCB)的指標。因此,包含列表專案的物件與列表專案本身之間存在雙向連結。 **pvContainer** 記錄了該列表項屬於哪個列表,說白點就是這個兒子是誰生的。。。          同時定義了一個MINI的列表項的結構體,MINI列表項是刪減版的列表項,因為很多時候不需要完全版的列表項。就不用浪費那麼多記憶體空間了,這或許就是FreeRTOS是輕量級作業系統的原因吧,能省一點是一點。MINI列表項: ```js struct xMINI_LIST_ITEM {    listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE           /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */    configLIST_VOLATILE TickType_t xItemValue;    struct xLIST_ITEM * configLIST_VOLATILE pxNext;    struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; }; typedef struct xMINI_LIST_ITEM MiniListItem_t; ``` 再定義了一個列表的結構體,可能看到這裡,一些同學已經蒙了,列表與列表項是啥關係啊,按照傑傑的理解,是類似父子關係的,一個列表中,包含多個列表項,就像一個父親,生了好多孩子,而列表就是父親,列表項就是孩子。 ```js typedef struct xLIST { listFIRST_LIST_INTEGRITY_CHECK_VALUE /* <如果configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES設定為1,則設定為已知值。*/ configLIST_VOLATILE UBaseType_t uxNumberOfItems; ListItem_t * configLIST_VOLATILE pxIndex; /* <用於遍歷列表。 指向由listGET_OWNER_OF_NEXT_ENTRY()呼叫返回的後一個列表項。*/ MiniListItem_t xList