FreeRTOS實(shí)時(shí)操作系統(tǒng)的列表與列表項(xiàng)操作示例
前言
FreeRTOS列表與列表項(xiàng)其實(shí)就是鏈表和節(jié)點(diǎn),在list.c
和list.h
實(shí)現(xiàn)
列表項(xiàng)數(shù)據(jù)結(jié)構(gòu)
//列表項(xiàng)數(shù)據(jù)結(jié)構(gòu) typedef struct xLIST_ITEM { TickType_t xItemValue; //輔助值,用作節(jié)點(diǎn)做順序排序 struct xLIST_ITEM * pxNext;//后繼指針 struct xLIST_ITEM * pxPrevious;//前驅(qū)指針 void * pvOwner; //指向擁有該列表項(xiàng)的內(nèi)核對(duì)象,通常是TCB void * pvContainer; //指向該列表項(xiàng)所在的列表 }ListItem_t;
列表項(xiàng)初始化
void vListInitialiseItem(ListItem_t * const pxItem) { //初始化該列表項(xiàng)所在列表指針指向NULL,表示還沒插入任何列表 pxItem->pvContainer = NULL; }
列表數(shù)據(jù)結(jié)構(gòu)
typedef struct xLIST { UBaseType_t uxNumberOfItems; //指示這條列表上有多少個(gè)列表項(xiàng) ListItem_t * pxIndex; //列表項(xiàng)索引指針 MiniListItem_t xListEnd; //列表最后一個(gè)列表項(xiàng) }List_t;
其中MiniListItem_t
數(shù)據(jù)結(jié)構(gòu)如下
typedef struct xMINI_LIST_ITEM { TickType_t xItemValue;//輔助值,用作節(jié)點(diǎn)做順序排序 struct xLIST_ITEM * pxNext;//后繼指針 struct xLIST_ITEM * pxPrevious;//前驅(qū)指針 }MiniListItem_t;
可以看到是列表項(xiàng)數(shù)據(jù)結(jié)構(gòu)去掉了pvOwner
和pvContainer
成員
列表初始化
void vListInitialise(List_t * const pxList) { //列表索引指向最后一個(gè)節(jié)點(diǎn) pxList->pxIndex = (ListItem_t *) &(pxList->xListEnd); //將列表最后一個(gè)節(jié)點(diǎn)輔助值設(shè)置為最大,確保該節(jié)點(diǎn)是最后節(jié)點(diǎn) pxList->xListEnd.xItemValue = portMAX_DELAY; //將最后一個(gè)節(jié)點(diǎn)的前驅(qū)和后繼指針指向自己,表示列表此時(shí)為空 pxList->xListEnd.pxNext = (ListItem_t*) &(pxList->xListEnd); pxList->xListEnd.pxPrevious = (ListItem_t*) &(pxList->xListEnd); //表示此時(shí)列表中有0個(gè)列表項(xiàng) pxList->uxNumberOfItems = (UBaseType_t)0U; }
如下圖
將列表項(xiàng)插入列表尾部
void vListInsertEnd(List_t * const pxList,ListItem_t * const pxNewListItem) { //取列表項(xiàng)索引指針,此時(shí)該指針指向最后一個(gè)節(jié)點(diǎn) ListItem_t * const pxIndex = pxList->pxIndex; //新插入的列表項(xiàng)前驅(qū)指針指向最后一個(gè)節(jié)點(diǎn) pxNewListItem->pxNext = pxIndex; //新插入的列表項(xiàng)的后繼指針也指向最后一個(gè)節(jié)點(diǎn) pxNewListItem->pxPrevious = pxIndex->pxPrevious; //列表的最后一個(gè)節(jié)點(diǎn)的后繼指針指向新插入的列表項(xiàng) pxNewListItem->pxPrevious->pxNext = pxNewListItem; //列表的最后一個(gè)節(jié)點(diǎn)的前驅(qū)指針也指向新插入的列表項(xiàng) pxIndex->pxPrevious = pxNewListItem; //新插入的列表項(xiàng)是輸入該列表的 pxNewListItem->pvContainer = (void*) pxList; //該列表中列表項(xiàng)數(shù)目+1 (pxList->uxNumberOfItems)++; }
如下
將列表項(xiàng)按照升序排列插入到列表
假如向現(xiàn)有的2個(gè)列表項(xiàng)序輔助值分別是 1 和 3的列表插入輔助值是2個(gè)列表項(xiàng)
void vListInsert(List_t * const pxList,ListItem_t * const pxNewListItem) { ListItem_t *pxIterator; //獲取新插入列表項(xiàng)的輔助值 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) { } } //對(duì)于下圖此時(shí)pxIterator指向List_item1 //此時(shí)pxIterator->pxNext是List_item3地址 pxNewListItem->pxNext = pxIterator->pxNext;//1 //pxNewListItem->pxNext->pxPrevious是item3的前驅(qū)指針指向新列表項(xiàng)item2 pxNewListItem->pxNext->pxPrevious = pxNewListItem; //新列表項(xiàng)item2的前驅(qū)指針指向pxIterator即item1 pxNewListItem->pxPrevious = pxIterator; //pxIterator即item1的后繼指向新列表項(xiàng)item2 pxIterator->pxNext = pxNewListItem; pxNewListItem->pvContainer = (void*) pxList; (pxList->uxNumberOfItems)++; }
如圖,注意2、3步的指針箭頭,野火的pdf畫的有誤
將列表項(xiàng)從列表刪除
UBaseType_t uxListRemove(ListItem_t * const pxItemToRemove) { //獲取列表項(xiàng)所在列表 List_t * const pxList = (List_t*)pxItemToRemove->pvContainer; //把要?jiǎng)h除的列表項(xiàng)從列表中摘出來 pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; if(pxList->pxIndex == pxItemToRemove) { pxList->pxIndex = pxItemToRemove->pxPrevious; } //該列表項(xiàng)所有者置空 pxItemToRemove->pvContainer = NULL; (pxList->uxNumberOfItems)--; return pxList->uxNumberOfItems; }
下面是測(cè)試代碼即仿真結(jié)果
List_t List_Test; ListItem_t List_Item1; ListItem_t List_Item2; ListItem_t List_Item3; int main(void) { //初始化列表 vListInitialise(&List_Test); //初始化列表項(xiàng) 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實(shí)時(shí)操作系統(tǒng)的列表與列表項(xiàng)操作示例的詳細(xì)內(nèi)容,更多關(guān)于FreeRTOS列表與列表項(xiàng)操作的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- FreeRTOS信號(hào)量API函數(shù)基礎(chǔ)教程
- FreeRTOS實(shí)時(shí)操作系統(tǒng)信號(hào)量基礎(chǔ)
- FreeRTOS實(shí)時(shí)操作系統(tǒng)隊(duì)列的API函數(shù)講解
- FreeRTOS實(shí)時(shí)操作系統(tǒng)隊(duì)列基礎(chǔ)
- FreeRTOS實(shí)時(shí)操作系統(tǒng)之可視化追蹤調(diào)試
- FreeRTOS使用任務(wù)通知實(shí)現(xiàn)命令行解釋器
- FreeRTOS實(shí)時(shí)操作系統(tǒng)的任務(wù)通知方法
- FreeRTOS進(jìn)階列表和列表項(xiàng)示例分析
相關(guān)文章
FreeRTOS實(shí)時(shí)操作系統(tǒng)多任務(wù)管理基礎(chǔ)知識(shí)
這篇文章主要為大家介紹了FreeRTOS實(shí)時(shí)操作系統(tǒng)多任務(wù)管理的基礎(chǔ)知識(shí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04FreeRTOS實(shí)時(shí)操作系統(tǒng)Cortex-M內(nèi)核使用注意事項(xiàng)
這篇文章主要為大家介紹了FreeRTOS實(shí)時(shí)操作系統(tǒng)Cortex-M內(nèi)核使用注意事項(xiàng),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04freertos實(shí)時(shí)操作系統(tǒng)臨界段保護(hù)開關(guān)中斷及進(jìn)入退出
這篇文章主要介紹了freertos實(shí)時(shí)操作系統(tǒng)臨界段保護(hù)開關(guān)中斷及進(jìn)入退出,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04FreeRTOS進(jìn)階信號(hào)量示例的完全解析
這篇文章主要為大家介紹了FreeRTOS進(jìn)階信號(hào)量示例操作的完全解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04FreeRTOS實(shí)時(shí)操作系統(tǒng)的任務(wù)通知方法
這篇文章主要為大家介紹了FreeRTOS實(shí)時(shí)操作系統(tǒng)的任務(wù)通知方法示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04FreeRTOS進(jìn)階列表和列表項(xiàng)示例分析
這篇文章主要為大家介紹了FreeRTOS進(jìn)階系列之列表和列表項(xiàng)示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04FreeRTOS實(shí)時(shí)操作系統(tǒng)臨界段保護(hù)場(chǎng)合示例
這篇文章主要為大家介紹了FreeRTOS實(shí)時(shí)操作系統(tǒng)臨界段保護(hù)場(chǎng)合示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04FreeRTOS動(dòng)態(tài)內(nèi)存分配管理heap_1示例
這篇文章主要為大家介紹了FreeRTOS動(dòng)態(tài)內(nèi)存分配管理heap_1的示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04