從0開始學FreeRTOS-(列表&列表項)-6
阿新 • • 發佈:2019-10-15
# 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