FreeRTOS学习 --- 列表和列表项

news/2025/2/8 2:59:08/

列表和列表项的简介

        列表是 FreeRTOS 中的一个数据结构,概念上和链表有点类似,列表被用来跟踪 FreeRTOS中的任务

        列表项就是存放在列表中的项目

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

        列表的特点:列表项间的地址非连续的,是人为的连接到一起的。列表项的数目是由后期添加的个数决定的,随时可以改变

        数组的特点:数组成员地址是连续的,数组在最初确定了成员数量后期无法改变

        在OS中任务的数量是不确定的,并且任务状态是会发生改变的,所以非常适用列表(链表)这种数据结构

列表和列表项的简介

        有关于列表的东西均在文件 list.c list.h 中,首先我们先看下在list.h中的,列表相关结构体:

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;

        1、在该结构体中, 包含了两个宏,这两个宏是确定的已知常量, FreeRTOS通过检查这两个常量的值,来判断列表的数据在程序运行过程中,是否遭到破坏 ,该功能一般用于调试, 默认是不开启的

        2、成员uxNumberOfItems,用于记录列表中列表项的个数(不包含 xListEnd

        3、成员 pxIndex 用于指向列表中的某个列表项,一般用于遍历列表中的所有列表项

        4、成员变量 xListEnd 是一个迷你列表项,排在最末尾

列表项

        列表项是列表中用于存放数据的地方,在 list.h 文件中,有列表项的相关结构体定义:

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; 	

        1、成员变量 xItemValue 为列表项的值,这个值多用于按升序对列表中的列表项进行排序

        2、成员变量 pxNext pxPrevious 分别用于指向列表中列表项的下一个列表项和上一个列表项

        3、成员变量 pxOwner 用于指向包含列表项的对象通常是任务控制块

        4、成员变量 pxContainer 用于指向列表项所在列表

 迷你列表项

        迷你列表项也是列表项,但迷你列表项仅用于标记列表的末尾和挂载其他插入列表中的列表项

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;

        1、成员变量 xItemValue 为列表项的值,这个值多用于按升序对列表中的列表项进行排序

        2、成员变量 pxNext pxPrevious 分别用于指向列表中列表项的下一个列表项和上一个列表项

        3、迷你列表项只用于标记列表的末尾和挂载其他插入列表中的列表项,因此不需要成员变量 pxOwner pxContainer,以节省内存开销

列表和列表项的关系

        列表初始状态,以及即将插入的两个列表项如下:

列表相关API函数介绍

 参考文档:FreeRTOS开发指南第七章 ——FreeRTOS列表和列表项”

初始化列表vListInitialise()

void vListInitialise(List_t * const pxList)
{/*  初始化时,列表中只有 xListEnd,因此 pxIndex 指向 xListEnd */pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );/* xListEnd 的值初始化为最大值0xffffffff,用于列表项升序排序时,排在最后 */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 );
} 

   

初始化列表项函数 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 );
}

 升序插入列表项函数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 ); 				/* 如果待插入列表项的值为最大值 */ if( xValueOfInsertion == portMAX_DELAY ){ pxIterator = pxList->xListEnd.pxPrevious; 				/* 插入的位置为列表 xListEnd 前面 */ } 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 )++;							/* 更新列表中列表项的数量 */ 
}

函数vListInsert(),是将待插入列表的列表项按照列表项值升序进行排序,有序地插入到列表中

 末尾插入链表项函数 vListInsertEnd()

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 )++;
}

        此函数用于将待插入列表的列表项插入到列表 pxIndex 指针指向的列表项前面,是一种无序的插入方法

列表项移除函数 uxListRemove()

UBaseType_t  uxListRemove (   ListItem_t *  const    pxItemToRemove )

        此函数用于将列表项从列表项所在列表中移除

 代码详解查看手册FreeRTOS开发指南第七章 ——FreeRTOS列表和列表项”

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; 
}

 


http://www.ppmy.cn/news/1570219.html

相关文章

CEF132 编译指南 Windows 篇 - 安装 Git 和 Python (三)

1. 引言 在之前的文章里&#xff0c;我们成功地安装并配置了 Visual Studio 2022&#xff0c;为编译 CEF 132 做好了基础准备。接下来&#xff0c;我们需要安装 Git 和 Python 这两个至关重要的工具。它们在 CEF 132 的编译过程中扮演着不可或缺的角色&#xff1a;Git 用于获取…

【产品小白】什么是微服务

在数字化浪潮汹涌澎湃的当下&#xff0c;软件系统的规模持续扩张&#xff0c;复杂度呈指数级攀升。如何高效地开发软件&#xff0c;确保其后续的维护轻松便捷&#xff0c;同时具备强大的扩展能力&#xff0c;已然成为广大开发者待攻克的核心难题。微服务作为一种应运而生的前沿…

数据结构(Java)—— 优先级队列(堆)

1. 概念 优先级队列是一种抽象数据类型&#xff08;ADT&#xff09;&#xff0c;它允许队列中维护的元素按优先级排序&#xff0c;优先级最高的元素会优先被处理。 2. 使用 2.1 优先级队列的构造 构造器 功能介绍 PriorityQueue() 创建一个空的优先级队列&#xff0c;默认容量…

基于单片机的智能安全插座(论文+源码)

1 系统整体方案设计 本课题基于单片机的智能安全插座设计&#xff0c;以STM32嵌入式单片机为主体&#xff0c;将计算机技术和检测技术有机结合&#xff0c;设计一款电量参数采集装置&#xff0c;实现电压、电流信号的数据采集任务&#xff0c;电压、电流和功率在上位机的显示任…

中国通信企业协会 通信网络安全服务能力评定 风险评估二级要求准则

通信网络安全服务能力评定要求是对通信网络安全服务单位的资格状况、经济实力、技术能力、服务队伍、服务过程能力等方面的具体衡量和评价。中国通信企业协会通信网络安全服务能力评定风险评估二级应达到风险评估服务一级能力要求的所有条款&#xff0c;并在以下方面增强或增加…

MATLAB实现多种群遗传算法

多种群遗传算法&#xff08;MPGA, Multi-Population Genetic Algorithm&#xff09;是一种改进的遗传算法&#xff0c;它通过将种群分成多个子种群并在不同的子种群之间进行交叉和交换&#xff0c;旨在提高全局搜索能力并避免早期收敛。下面是多种群遗传算法的主要步骤和流程&a…

Android性能调优之需要掌握Dalvik和ART的知识

在Android4.4时ART诞生&#xff0c;DVM和ART在4.4的版本中可以互替&#xff0c;在Android5.0后Android默认运行虚拟机为ART&#xff0c;至此&#xff0c;DVM退出历史舞台。 步入2020年&#xff0c;全球Android用户中&#xff0c;5.0以上的版本占据87~90%&#xff0c;就算DVM已…

在Ubuntu上使用Docker部署DeepSeek

在Ubuntu上使用Docker部署DeepSeek&#xff0c;并确保其可以访问公网网址进行对话&#xff0c;可以按照以下步骤进行&#xff1a; 一、安装Docker 更新Ubuntu的软件包索引&#xff1a; sudo apt-get update安装必要的软件包&#xff0c;这些软件包允许apt通过HTTPS使用存储库…