列表和列表项

一、列表和列表项简介

列表是 FreeRTOS 中的一个数据结构,列表被用来跟踪 FreeRTOS中的任务(任务当前的状态),列表项就是存放在列表中的项目

列表相当于链表,列表项相当于节点,FreeRTOS 中的列表是一个双向循环链表

列表项间的地址非连续的,列表项的数目随时可以改变

列表项的指向前一个、后一个指针 ,就相当于人的左右手 ,整个列表就相当于N个人互相拉着手,围**成一个圈,**而列表是管理这个圈

二、 列表与列表项

2.1 列表结构体

复制代码
typedef struct xLIST
{
  	 listFIRST_LIST_INTEGRITY_CHECK_VALUE		    /* 校验值 */
   	 volatile UBaseType_t uxNumberOfItems;			/* 列表中的列表项数量 */
   	 ListItem_t * configLIST_VOLATILE pxIndex		/* 用于遍历列表项的指针 */
   	 MiniListItem_t xListEnd					    /* 末尾列表项 */
   	 listSECOND_LIST_INTEGRITY_CHECK_VALUE		    /* 校验值 */
} List_t;

成员说明:

|----------------------------------------------------------------------------|----------------------------------------------------------------------------|
| 成员 | 描述 |
| listFIRST_LIST_INTEGRITY_CHECK_VALUE listSECOND_LIST_INTEGRITY_CHECK_VALUE | 具有确定已知常量的宏 FreeRTOS通过检查这两个常量的值,来判断列表的数据在程序运行过程中,是否遭到破坏 ,该功能一般用于调试, 默认是不开启的 |
| uxNumberOfItems | 用于记录列表中列表项的个数(不包含 xListEnd) |
| pxIndex | 用于指向列表中的某个列表项,一般用于遍历列表中的所有列表项 |
| xListEnd | 一个迷你列表项,排在最末尾 |

列表结构示意图:

2.2 列表项结构体

复制代码
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							            /* 列表项的拥有者 */
    	struct xLIST * configLIST_VOLATILE pxContainer; 	/* 列表项所在列表 */
    	listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE			/* 用于检测列表项的数据完整性*/
};
typedef struct xLIST_ITEM ListItem_t; 

成员说明:

|-------------------------------------------------------------------------------------|----------------------------|
| 成员 | 描述 |
| listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALU | 用于检测列表项的数据完整性 |
| xItemValue | 列表项的值,多用于将列表中的列表项按升序排序 |
| pxNext | 指向列表中列表项的下一个列表项 |
| pxPrevious | 指向列表中列表项的上一个列表项 |
| pvOwner | 用于指向包含列表项的对象(通常是任务控制块) |
| pxContainer | 用于指向列表项所在列表 |

列表项结构示意图:

2.3 迷你列表项(末尾列表项)

迷你列表项也是列表项,但迷你列表项仅用于标记列表的末尾和挂载其他插入列表中的列表项(将要插入的列表项连接在一起

复制代码
struct xMINI_LIST_ITEM
{
    listFIRST_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;

成员说明:

|-------------------------------------------|--------------------------|
| 成员 | 描述 |
| listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE | 用于检测数据完整性 |
| xItemValue | 列表项的值,多用于按升序对列表中的列表项进行排序 |
| pxNext pxPrevious | 用于指向列表中列表项的下一个列表项和上一个列表项 |

与正常列表项,缺少列表项拥有者、列表项所在列表成员 ,以节省内存开销

迷你列表项结构示意图:

三、列表相关API函数

|-----------------------|---------------|
| 函数 | 描述 |
| vListInitialise() | 初始化列表 |
| vListInitialiseItem() | 初始化列表项 |
| vListInsertEnd() | 列表末尾插入列表项 |
| vListInsert() | 列表插入列表项(升序插入) |
| uxListRemove() | 列表移除列表项 |

3.1 初始化列表:vListInitialise( )

复制代码
void vListInitialise( List_t * const pxList )
{
    /*  初始化时,列表中只有 xListEnd,因此 pxIndex 指向 xListEnd */
    pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); 
    listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) );

    /* xListEnd 的值初始化为最大值,用于列表项升序排序时,排在最后 */
    pxList->xListEnd.xItemValue = portMAX_DELAY;

    /* 初始化时,列表中只有 xListEnd,因此上一个和下一个列表项都为 xListEnd 本身 */
    pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );    
    pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd ); 

    /* 初始化时,列表中的列表项数量为 0(不包含 xListEnd) */
    pxList->uxNumberOfItems = ( UBaseType_t ) 0U;

    /* 检查数据的完整性 */
    listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
    listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
}

参数说明:

|--------|---------|
| 参数 | 说明 |
| pxList | 待初始化的列表 |

列表初始化后的结构示意图:

3.2 列表项初始化:vListInitialiseItem()

复制代码
void vListInitialiseItem( ListItem_t * const pxItem )
{
    /* 初始化时,列表项所在列表设为空  */
    pxItem->pxContainer = NULL;

    /* 初始化用于检测列表项数据完整性的校验值  */
    listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
    listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
}

其他成员变量根据实际使用情况进行初始化

参数说明:

|--------|----------|
| 参数 | 说明 |
| pxItem | 待初始化的列表项 |

列表初始化后的结构示意图:

3.3 列表插入列表项(升序插入):vListInsert()

函数功能:将待插入列表的列表项按照列表项值升序插入,有序地插入到列表中

复制代码
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 );

    /* 如果待插入列表项的值为最大值,插入的位置为列表 xListEnd 前面  */
    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->pxContainer = pxList;
    
    /* 更新列表中列表项的数量 */ 
    ( pxList->uxNumberOfItems )++;
}

参数说明:

|---------------|--------|
| 参数 | 说明 |
| pxList | 列表 |
| pxNewListItem | 待插入列表项 |

3.4 列表末尾插入: vListInsertEnd()

函数功能:将待插入列表的列表项插入到列表 pxIndex 指针指向的列表项前面(初始化时:pxIndex指向迷你列表项),是一种无序的插入方法

复制代码
void vListInsertEnd (  List_t * const pxList ,   ListItem_t * const pxNewListItem  )
{
	 /* 获取列表 pxIndex 指向的列表项 */
	ListItem_t * const pxIndex = pxList->pxIndex;

	/* 更新待插入列表项的指针成员变量 */	
    pxNewListItem->pxNext = pxIndex;	
    pxNewListItem->pxPrevious = pxIndex->pxPrevious;
 	
    /* 更新列表中原本列表项的指针成员变量 */	
    pxIndex->pxPrevious->pxNext = pxNewListItem;
    pxIndex->pxPrevious = pxNewListItem;

    /* 更新待插入列表项的所在列表成员变量 */	
    pxNewListItem->pxContainer = pxList;

    /* 更新列表中列表项的数量 */
    ( pxList->uxNumberOfItems )++;
} 

参数说明:

|---------------|--------|
| 参数 | 说明 |
| pxList | 列表 |
| pxNewListItem | 待插入列表项 |

2.5 移出列表项:uxListRemove()

复制代码
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) 
{
	List_t * const pxList = pxItemToRemove->pxContainer; 

    /* 从列表中移除列表项 */ 
	pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
	pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; 	
 
    /*如果 pxIndex 正指向待移除的列表项 */ 
	if( pxList->pxIndex == pxItemToRemove ) 
	{
        /*pxIndex 指向上一个列表项*/ 
	 	pxList->pxIndex = pxItemToRemove->pxPrevious;
	} 
    else 
	{ 
		mtCOVERAGE_TEST_MARKER(); 
	} 

    /*将待移除的列表项的所在列表指针清空*/ 
	pxItemToRemove->pxContainer = NULL; 

    /*更新列表中列表项的数量*/ 
	( pxList->uxNumberOfItems )--; 

	return pxList->uxNumberOfItems; 
}

参数说明:

|----------------|----------------|
| 参数 | 说明 |
| pxItemToRemove | 待移出的列表项 |
| 返回值 | 移除后,列表剩余的列表项数量 |

相关推荐
cpsvps_net9 小时前
美国服务器环境下Windows容器工作负载智能弹性伸缩
windows
甄超锋10 小时前
Java ArrayList的介绍及用法
java·windows·spring boot·python·spring·spring cloud·tomcat
cpsvps12 小时前
美国服务器环境下Windows容器工作负载基于指标的自动扩缩
windows
网硕互联的小客服15 小时前
Apache 如何支持SHTML(SSI)的配置方法
运维·服务器·网络·windows·php
etcix15 小时前
implement copy file content to clipboard on Windows
windows·stm32·单片机
许泽宇的技术分享16 小时前
Windows MCP.Net:基于.NET的Windows桌面自动化MCP服务器深度解析
windows·自动化·.net
非凡ghost17 小时前
AMS PhotoMaster:全方位提升你的照片编辑体验
windows·学习·信息可视化·软件需求
mortimer18 小时前
一次与“顽固”外部程序的艰难交锋:subprocess 调用exe踩坑实录
windows·python·ai编程
gameatp20 小时前
从 Windows 到 Linux 服务器的全自动部署教程(免密登录 + 压缩 + 上传 + 启动)
linux·服务器·windows
穷人小水滴20 小时前
在 windows 运行 flatpak 应用 (WSL)
linux·windows·ubuntu