最簡實時性操作系統之任務鏈表
在freertos中任務和就緒列表就像衣架一樣由根節點和節點那樣構成
實時性操作系統中鏈表的數據結構
鏈表
/* 链表结构体定义 */
typedef struct xLIST
{UBaseType_t uxNumberOfItems; /* 链表节点计数器 */ListItem_t * pxIndex; /* 链表节点索引指针 */MiniListItem_t xListEnd; /* 链表最后一个节点 */
} List_t;
鏈表下面主要由
1.節點計數器,不包含節點
2.節點索引指針
3.根節點組成
其中根節點一般表示一個就緒任務集合還有阻塞任務集合,用以串聯起該任務的
1.輔助值用以升序排序,一般設爲最大值
2.根節點的前後指針
節點項
節點項可以表示一個任務
1.是輔助值用以升序排序
2.是節點項的上一項和下一項的指針
3.是TCB任務塊的指針
4.是所屬根節點
實時性操作系統中鏈表的操作函數
初始化鏈表
//初始化一個根節點
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);
}
初始化節點
//初始化一個節點
void vListInitialiseItem(ListItem_t * const pxItem)
{pxItem->pvContainer = NULL;
}
將節點插入鏈表的尾部
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
按順序將節點插入鏈表
#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)++;
}
講解如下:
向链表的尾部插入一个项_哔哩哔哩_bilibili
刪除一個鏈表
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;
}