列表和列表项作为FreeRTOS源码的基本数据结构,相当于数据结构中的循环双链表。
1.定义:关于这部分的数据主要有三种结构(列表、列表项、迷你列表项)
列表
复制代码
1
2
3
4
5
6
7
8typedef struct xList { listFIRST_LIST_INTEGRITY_CHECK_VALUE //检查列表的完整性,是宏定义 configLIST_VOLATILE UBaseType_t uxNumberOfItems; //记录列表中列表项的数量 ListItem_t* configLIST_VOLATILE pxIndex; //记录当前列表项的索引号,用于遍历列表 MiniListItem_t xListEnd; //列表中最后一个列表项 listSECOND_LIST_INTEGRTIY_CHECK_VALUE //检查列表的完整性,是宏定义 }List_t;
列表项:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13struct xLIST_ITEM { listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE //检查列表项的完整性 configLIST_VOLATILE TickType_t xItemValue; //列表项的值 struct xLIST_ITEM* configLIST_VOLATILE pxNext; //指向下一个列表项 struct xLIST_ITEM* configLIST_VOLATILE pxPrevious; //指向上一个列表项 void* pvOwner; //列表项的归属,一般指向任务控制块 void* configLIST_VOLATILE pvContainer; //记录链表项属于哪个列表,比如空闲列表/就绪列表 listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE //检查列表项的完整性 }; typedef struct xLIST_ITEM ListItem_t;
迷你列表项
复制代码
1
2
3
4
5
6
7
8
9struct xMINI_LIST_ITEM { listFITRST_LIST_ITEM_INTEGRITY_CHECK_VALUE configLIST_VOLATILE TickType_t xItemValue; struct xLIST_ITEM* configLIST_VOLATILE pxNext; struct xLIST_ITEM* configLIST_VOLATILE pxPrevious; }; typedef struct xMINI_LIST_ITEM MiniListItem_t;
2、基本操作:
一般链表的操作包括链表的创建(初始化)、插入、删除、查找。
列表和列表项初始化:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21//列表初始化 void vListInitialise(List_t* const pxList) { pxList->pxIndex = (ListItem_t *) &(pxList->xListEnd); pxList->xListEnd.xItemValue = portMAX_DELAY; //portMAX_DELAY是个宏定义,STM32中式0xffffffffUL,表示列表数量的最大值 pxList->xListEnd.pxNext = (ListItem_t *) &(pxList->xListEnd); //列表项的下一项指向自身 pxList->xListEnd.pxPrevious = (ListItem_t *) &(pxList->xListEnd); pxList->uxNumberOfItems = (UBaseType_t) 0U; //当前列表中的列表项为0,自身不算 //如果configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES被置为1,执行下面语句 list_SET_LIST_INTEGRITY_CHECK_1_VALUE(pxList); list_SET_LIST_INTEGTITY_CHECK_2_VALUE(pxList); } //列表项初始化 void vListInitialiseItem(ListItem_t* const pxItem) { pxItem->pvContainer = NULL; listSET_FIRST_LIST_ITEM_ INTEGRITY_CHECK_VALUE(pxItem); listSET_FIRST_LIST_ITEM_INTERITY_CHECK_VALUE(pxItem); }
列表项插入:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36/*功能:向列表中插入列表项 *参数:pxList(列表项要插入的列表) pxNewListItem(要插入的列表项) *返回值:无 */ void vListInsert(List_t* const pxList, ListItem_t* const pxNewListItem) { ListItem_t *pxIterator; const TickType_t xValueOfInsertion = pxNewListItem->xItemValue; listTEST_LIST_INTEGRITY(pxList); /*检查列表完整性*/ listTEST_LIST_ITEM_INTEGRITY(pxNewListItem); //判断列表项中的值是否是最大值,如果是则将其指向最后一个列表项的前一个位置 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; //将新节点的后一个节点指向原来pxIterator的后一个节点 pxNewListItem->pxNext->pxPrevious = pxNewListItem; //将新节点的后一个节点的前一个指针指向新节点 pxNewListItem->pxPrevious = pxIterator; //将新节点的上一个节点指向原来的节点 pxIterator->pxNext = pxNewListItem; //将原来节点的下一个节点指针指向新节点 pxNewListItem->pvContainer = (void*) pxList; //新节点属于的队列 (pxList->uxNumberOfItems)++; //节点数加一 }
列表末尾插入:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19void vListInsertEnd(List_t* const pxList, ListItem_t* const pxNewListItem) { ListItem_t* const pxIndex = pxList->pxIndex; //当前列表中所指向的列表项 listTEST_LIST_INTEGRITY(pxList); //检查列表的完整性 listTEST_LIST_ITEM_INTEGRITY(pxNewListItem); //检查列表项的完整性 pxNewListItem->pxNext = pxIndex; //将新列表项的下一项指向列表头pxIndex pxNewListItem->previous = pxIndex->pxPrevious; mtCOVERAGE_TEST_DELAY(); pxIndex->pxPrevious->pxNext = pxNewListItem; //将列表尾指向新列表 pxIndex->pxPrevious = pxNewListItem; //将原来的头列表的上个节点指向新列表 pxNewListItem->pvContainer = (void *)pxList; (pxList->uxNumberOfItems)++; }
列表项的删除操作:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22UBaseType_t uxListRemove(ListItem_t* const pxItemToRemove) { List_t* const pxList = (List_t*)pxItemToRemove->pvContainer; //确定所在列表 pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; pxItemToRemove->pxPrevious->next = pxItemToRemove->pxNext; mCOVERAGE_TEST_DELAY(); if(pxList->pxIndex == pxItemToRemove) //如果删除的是表头 { pxList->pxIndex = pxItemToRemove->pxPrevious; } else { mtCOVERAGE_TEST_MARKER(); } pxItemToRemove->pvContainer = NULL; (pxList->uxNumberOfItems)--; return pxList->uxNumberOfItems; }
列表的遍历:listGET_OWNER_OF_NEXT_ENTRY(pxTCB, pxList)
该函数是利用列表中pxIndex项来遍历整个列表,大家可以试试。
最后
以上就是犹豫帽子最近收集整理的关于FreeRTOS的列表和列表项的全部内容,更多相关FreeRTOS内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复