目录
一、列表项
二、列表结构
三、迷你列表项
四、列表与列表项API函数功能
五、补充
注明:此学习笔记只针对于移植应用,不作过多详解。
为方便理解,先谈及列表项,它属于列表的子部分,一个列表可含有多个列表项,每个列表项都有一个指针指向列表。列表项有两种,全功能的列表项xLIST_ITEM和迷你列表xMINI_LIST_ITEM。
struct 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; //指向被属对象,通常任务TCB
void * configLIST_VOLATILE pvContainer; //指向包含该列表项的列表
listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE //用于检测列表项数据是否完整
};
typedef struct xLIST_ITEM ListItem_t;
列表属于FreeRTOS操作系统的数据结构,在Python中,列表属于Python的内置对象之一,包含若干连续内存空间,具有自动收缩和扩张功能。而在此,列表概念上与链表相似,在操作系统中,列表被FreeRTOS调度器使用,用来跟踪FreeRTOS任务等。
下面是关于列表List_t结构体:
typedef struct xLIST
{
listFIRST_LIST_INTEGRITY_CHECK_VALUE
//默认不开启,用来检查列表完整性,开启功能前提将宏定
//configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES设置为1
configLIST_VOLATILE UBaseType_t uxNumberOfItems;
//用来记录当前列表项的索引号
ListItem_t * configLIST_VOLATILE pxIndex;
//用来遍历列表
MiniListItem_t xListEnd;
listSECOND_LIST_INTEGRITY_CHECK_VALUE
//同于listFIRST_LIST_INTEGRITY_CHECK_VALUE
} List_t;
注解已经简单说明了,MiniListItem_t xListEnd,是列表中最后一个列表项,用来表示列表结束,初始定义时为空。MiniListItem_t 是迷你列表项的变量类型。
左图为列表在内存单元中的存储模型,uxNumberOfItems记录挂在此列表中的列表项数。xItemValue、pxNext、pxPrevious三个子变量属于xListEnd。xListEnd是整个列表的末位,实际上相当于一个空的迷你列表项。另外pxNext指向下一列表项,pxPrevious相反指向前一个列表项,这两指针变量是形成双向链表的关键。
struct xMINI_LIST_ITEM
{
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE (1)
configLIST_VOLATILE TickType_t xItemValue; (2)
struct xLIST_ITEM * configLIST_VOLATILE pxNext; (3)
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; (4)
};
typedef struct xMINI_LIST_ITEM MiniListItem_t;
显而易见,根据迷你列表项的结构体定义,“迷你”指的是全功能列表项的放小版,无需检查完整性,便于直接应用,其他形式不变。
关于列表与列表项初始化应用:
void vListInitialise( List_t * const pxList ) //列表初始化
/*pxList为列表指针*/
vListInitialise(&TestList); //初始化名为TestList的原始列表
void vListInitialiseItem( ListItem_t * const pxItem ) //列表项初始化
/*pxItem为列表项指针*/
vListInitialiseItem(&ListItem1); //初始化名为ListItem1的原始列表项
ListItem1.xItemValue=40; //ListItem1列表项值为40
/*xItemValue通常是一个被跟踪的任务优先级或是一个调度事件的计数器值*/
关于列表与列表项联合:
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )
/*pxList为目标列表对象,pxNewListItem 为插入到列表项*/
//通过vListInsert向列表中插入列表项
vListInsert(&TestList,&ListItem1); //向列表TestList插入列表项ListItem1
//向列表TestList添加列表项ListItem1
这里说明下插入新列表项的列表与原始相比有何改观:
列表因新列表项的插入首先记录变量uxNumberOFItem实现加一,索引更新,位于列表末位的迷你列表项与其发生互联。xListEnd子变量pxNext和pxPrevious指向ListItem1首位,同时ListItem1的pxNext与pxPrevious指向xListEnd首位。
同样操作,继续插入新列表项ListItem2:
列表项按照升序形式接上,与之前不同方式,xListEnd、ListItem1、ListItem2发生了新的互联,差别不大,三者之间形成了个双向链表,首尾相连 。
另一种插入方式,列表尾部插入:
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem );
//列表末尾添加列表项,pxList为目标对象列表,pxNewListItem 为要插入的对象
vListInsertEnd(&TestList,&ListItem2);
//列表末尾添加列表项ListItem2
与直接插入不同,在列表末位插入,不会按照升序的顺序接在了xListEnd的后面,而且直接改变之前插入列表项的指向定位,其次,不难看出,pxIndex用于遍历列表的位置变量并没有发生改变,因此通常使用此API时 ,需加入TestList.pxIndex=TestList.pxIndex->pxNext;进行移位操作。
其他API函数调用:
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove );
/* The list item knows which list it is in. Obtain the list from the list
item. 删除列表项API函数调用*/
uxListRemove(&ListItem2); //删除列表项ListItem2
ListGET_OWNER_OF_NEXT_ENTRY();
/*通过列表TestList-->pxIndex实现对列表的遍历*/
向列表中插入新列表项,并不会引起列表项在内存存储间的位置变化,通过指针变量连接,将他们系统地构成个列表整体。感兴趣的,下面是增添新列表项的指针变量指向内存地址变化。
项目 地址
TestList 0x200000b4
TestList->pxIndex 0x200000bc
TestList->xListEnd 0x200000bc
ListItem1 0x200000c8
ListItem2 0x200000dc
ListItem3 0x200000f0
/******************添加列表项ListItem1*****************/
项目 地址
TestList->xListEnd->pxNext 0x200000c8
ListItem1->pxNext 0x200000bc
/*******************前后向连接分割线********************/
TestList->xListEnd->pxPrevious 0x200000c8
ListItem1->pxPrevious 0x200000bc
/******************添加列表项ListItem2*****************/
项目 地址
TestList->xListEnd->pxNext 0x200000c8
ListItem1->pxNext 0x200000dc
ListItem2->pxNext 0x200000bc
/*******************前后向连接分割线********************/
TestList->xListEnd->pxPrevious 0x200000dc
ListItem1->pxPrevious 0x200000bc
ListItem2->pxPrevious 0x200000c8
/******************删除列表项ListItem2*****************/
项目 地址
TestList->xListEnd->pxNext 0x200000c8
ListItem1->pxNext 0x200000f0
ListItem3->pxNext 0x200000bc
/*******************前后向连接分割线********************/
TestList->xListEnd->pxPrevious 0x200000f0
ListItem1->pxPrevious 0x200000bc
ListItem3->pxPrevious 0x200000c8
/***************在末尾添加列表项ListItem2***************/
项目 地址
TestList->pxIndex 0x200000c8
TestList->xListEnd->pxNext 0x200000dc
ListItem2->pxNext 0x200000c8
ListItem1->pxNext 0x200000f0
ListItem3->pxNext 0x200000bc
/*******************前后向连接分割线********************/
TestList->xListEnd->pxPrevious 0x200000f0
ListItem2->pxPrevious 0x200000bc
ListItem1->pxPrevious 0x200000dc
ListItem3->pxPrevious 0x200000c8
/************************结束**************************/ 2022/4/8 22:03