FreeRTOS實時操作系統(tǒng)的列表與列表項操作示例
前言
FreeRTOS列表與列表項其實就是鏈表和節(jié)點,在list.c和list.h實現(xiàn)
列表項數(shù)據(jù)結(jié)構(gòu)
//列表項數(shù)據(jù)結(jié)構(gòu)
typedef struct xLIST_ITEM
{
TickType_t xItemValue; //輔助值,用作節(jié)點做順序排序
struct xLIST_ITEM * pxNext;//后繼指針
struct xLIST_ITEM * pxPrevious;//前驅(qū)指針
void * pvOwner; //指向擁有該列表項的內(nèi)核對象,通常是TCB
void * pvContainer; //指向該列表項所在的列表
}ListItem_t;
列表項初始化
void vListInitialiseItem(ListItem_t * const pxItem)
{
//初始化該列表項所在列表指針指向NULL,表示還沒插入任何列表
pxItem->pvContainer = NULL;
}
列表數(shù)據(jù)結(jié)構(gòu)
typedef struct xLIST
{
UBaseType_t uxNumberOfItems; //指示這條列表上有多少個列表項
ListItem_t * pxIndex; //列表項索引指針
MiniListItem_t xListEnd; //列表最后一個列表項
}List_t;
其中MiniListItem_t數(shù)據(jù)結(jié)構(gòu)如下
typedef struct xMINI_LIST_ITEM
{
TickType_t xItemValue;//輔助值,用作節(jié)點做順序排序
struct xLIST_ITEM * pxNext;//后繼指針
struct xLIST_ITEM * pxPrevious;//前驅(qū)指針
}MiniListItem_t;
可以看到是列表項數(shù)據(jù)結(jié)構(gòu)去掉了pvOwner和pvContainer成員
列表初始化
void vListInitialise(List_t * const pxList)
{
//列表索引指向最后一個節(jié)點
pxList->pxIndex = (ListItem_t *) &(pxList->xListEnd);
//將列表最后一個節(jié)點輔助值設(shè)置為最大,確保該節(jié)點是最后節(jié)點
pxList->xListEnd.xItemValue = portMAX_DELAY;
//將最后一個節(jié)點的前驅(qū)和后繼指針指向自己,表示列表此時為空
pxList->xListEnd.pxNext = (ListItem_t*) &(pxList->xListEnd);
pxList->xListEnd.pxPrevious = (ListItem_t*) &(pxList->xListEnd);
//表示此時列表中有0個列表項
pxList->uxNumberOfItems = (UBaseType_t)0U;
}
如下圖

將列表項插入列表尾部
void vListInsertEnd(List_t * const pxList,ListItem_t * const pxNewListItem)
{
//取列表項索引指針,此時該指針指向最后一個節(jié)點
ListItem_t * const pxIndex = pxList->pxIndex;
//新插入的列表項前驅(qū)指針指向最后一個節(jié)點
pxNewListItem->pxNext = pxIndex;
//新插入的列表項的后繼指針也指向最后一個節(jié)點
pxNewListItem->pxPrevious = pxIndex->pxPrevious;
//列表的最后一個節(jié)點的后繼指針指向新插入的列表項
pxNewListItem->pxPrevious->pxNext = pxNewListItem;
//列表的最后一個節(jié)點的前驅(qū)指針也指向新插入的列表項
pxIndex->pxPrevious = pxNewListItem;
//新插入的列表項是輸入該列表的
pxNewListItem->pvContainer = (void*) pxList;
//該列表中列表項數(shù)目+1
(pxList->uxNumberOfItems)++;
}
如下

將列表項按照升序排列插入到列表
假如向現(xiàn)有的2個列表項序輔助值分別是 1 和 3的列表插入輔助值是2個列表項
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)
{
}
}
//對于下圖此時pxIterator指向List_item1
//此時pxIterator->pxNext是List_item3地址
pxNewListItem->pxNext = pxIterator->pxNext;//1
//pxNewListItem->pxNext->pxPrevious是item3的前驅(qū)指針指向新列表項item2
pxNewListItem->pxNext->pxPrevious = pxNewListItem;
//新列表項item2的前驅(qū)指針指向pxIterator即item1
pxNewListItem->pxPrevious = pxIterator;
//pxIterator即item1的后繼指向新列表項item2
pxIterator->pxNext = pxNewListItem;
pxNewListItem->pvContainer = (void*) pxList;
(pxList->uxNumberOfItems)++;
}
如圖,注意2、3步的指針箭頭,野火的pdf畫的有誤

將列表項從列表刪除
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;
}
下面是測試代碼即仿真結(jié)果
List_t List_Test;
ListItem_t List_Item1;
ListItem_t List_Item2;
ListItem_t List_Item3;
int main(void)
{
//初始化列表
vListInitialise(&List_Test);
//初始化列表項
vListInitialiseItem(&List_Item1);
List_Item1.xItemValue = 1;
vListInitialiseItem(&List_Item2);
List_Item2.xItemValue = 2;
vListInitialiseItem(&List_Item3);
List_Item3.xItemValue = 3;
vListInsert(&List_Test,&List_Item1);
vListInsert(&List_Test,&List_Item3);
vListInsert(&List_Test,&List_Item2);
while(1);
}

以上就是FreeRTOS實時操作系統(tǒng)的列表與列表項操作示例的詳細內(nèi)容,更多關(guān)于FreeRTOS列表與列表項操作的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
FreeRTOS實時操作系統(tǒng)多任務(wù)管理基礎(chǔ)知識
這篇文章主要為大家介紹了FreeRTOS實時操作系統(tǒng)多任務(wù)管理的基礎(chǔ)知識,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪2022-04-04
FreeRTOS實時操作系統(tǒng)Cortex-M內(nèi)核使用注意事項
這篇文章主要為大家介紹了FreeRTOS實時操作系統(tǒng)Cortex-M內(nèi)核使用注意事項,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪2022-04-04
freertos實時操作系統(tǒng)臨界段保護開關(guān)中斷及進入退出
這篇文章主要介紹了freertos實時操作系統(tǒng)臨界段保護開關(guān)中斷及進入退出,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪2022-04-04
FreeRTOS實時操作系統(tǒng)的任務(wù)通知方法
這篇文章主要為大家介紹了FreeRTOS實時操作系統(tǒng)的任務(wù)通知方法示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪2022-04-04
FreeRTOS動態(tài)內(nèi)存分配管理heap_1示例
這篇文章主要為大家介紹了FreeRTOS動態(tài)內(nèi)存分配管理heap_1的示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪2022-04-04

