在freertos中任務和就緒列表就像衣架一樣由根節點和節點那樣構成
實時性操作系統中鏈表的數據結構
鏈表
cpp
/* 链表结构体定义 */
typedef struct xLIST
{
UBaseType_t uxNumberOfItems; /* 链表节点计数器 */
ListItem_t * pxIndex; /* 链表节点索引指针 */
MiniListItem_t xListEnd; /* 链表最后一个节点 */
} List_t;

鏈表下面主要由
1.節點計數器,不包含節點
2.節點索引指針
3.根節點組成
其中根節點一般表示一個就緒任務集合還有阻塞任務集合,用以串聯起該任務的
1.輔助值用以升序排序,一般設爲最大值
2.根節點的前後指針
節點項

節點項可以表示一個任務
1.是輔助值用以升序排序
2.是節點項的上一項和下一項的指針
3.是TCB任務塊的指針
4.是所屬根節點
實時性操作系統中鏈表的操作函數
初始化鏈表

cpp
//初始化一個根節點
void vListInitialise(list_t * const pxList)
{
pxList->pxIndex = (ListItem_t *) & (pxList->xListEnd);
pxList->xListEnd.xItemValue = portMax_DELAY; //確保根節點是最大的節點
pxList->xListEnd.pxNext = (ListItem_t *) & (pxList->xListEnd);
pxList->xListEnd.pxPrevious = (ListItem_t *) &(pxList->xListEnd);
}
初始化節點

cpp
//初始化一個節點
void vListInitialiseItem(ListItem_t * const pxItem)
{
pxItem->pvContainer = NULL;
}
將節點插入鏈表的尾部

cpp
void vListInserEnd(list_t * const pxList, ListItem_t *const pxNewListItem)
{
ListItem_t * const pxIndex = pxList->pxIndex;
pxNewListItem->pxNext = pxIndex;
pxNewListItem->pxPrevious = pxIndex->pxPrevious;
pxIndex->pxPrevious->pxNext = pxNewListItem;
pxIndex->pxPrevious = pxNewListItem;
pxNewListItem->pvContainer = (void *)pxList;
(pxList->uxNumberOfItems)++;
}
聽著有點拗口,實際上一個鏈表長這樣 INDEX -> A -> B -> INDEX
INDEX是固定的,INDEX->pxPrevious表示當前鏈表的最後一項
1.首先將當前插入的項的前後相分別指向鏈表的頭相和尾項
2.然後解決之前鏈表的最後一項,讓它指向鏈表要新插入的相,因爲鏈表之前最後一項的上一項沒有變化所以不用改變
3.最後把鏈表相挂在在鏈表中,并且計數器加1
按順序將節點插入鏈表
cpp
#include "list.h"
void vListInsert(list_t * const pxList,ListItem_t *const pxNewListItem)
{
ListItem_t * pxIterator;
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
if(xValueOfInsertion == portMAX_DELAY){
pxIterator = pxList->xListEnd.pxPrevious;
}
else{
for(pxIterator = (ListItem_t *) &(pxList->xListEnd);
pxIterator->pxNext->xItemValue <= xValueOfInsertion;
pxIterator = pxIterator->pxNext)
{
//找到空閑節點
}
}
pxNewListItem->pxNext = pxIterator->pxNext;
pxNewListItem->pxNext ->pxPrevious = pxNewListItem;
pxNewListItem->pxPrevious = pxIterator;
pxIterator->pxNext = pxNewListItem;
pxNewListItem->pvContainer = (void *)pxList;
(pxList->uxNumberOfItems)++;
}
講解如下:
刪除一個鏈表
cpp
UBaseType_t uxListRemove(ListItem_t * const pxItemToRemove)
{
list_t * const pxList = (list_t *) pxItemToRemove->pvContainer;
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
if(pxList->pxIndex == pxItemToRemove)
{
pxList->pxIndex = pxItemToRemove->pxPrevious;
}
pxItemToRemove->pvContainer = NULL;
(pxList->uxNumberOfItems)--;
return pxList->uxNumberOfItems;
}