FreeRTOS——列表及列表项

目录

一、概念及其应用

1.1列表List_t

1.2列表项ListItem_t

1.3迷你列表项MiniListItem_t

二、相关API

三、实现原理

3.1列表初始化

3.2列表项初始化

3.3插入列表项

3.4尾插列表项

3.5列表项的删除

3.6列表的遍历


一、概念及其应用

作为多任务的核心,列表和列表项在FreeRTOS中被大量使用,功不可没

列表和列表项是一个数据结构,简单地说,列表是一个结构体列表项也是一个结构体但它作为列表的一个成员,而在freertos中的列表和列表项构成的是双向链表结构

1.1列表List_t

typedef struct xLIST
{
	listFIRST_LIST_INTEGRITY_CHECK_VALUE	 /*列表完整性检查1*/
	volatile UBaseType_t uxNumberOfItems;    //列表中的列表项数量
	ListItem_t * configLIST_VOLATILE pxIndex;/*列表项索引,用于列表的遍历*/
	MiniListItem_t xListEnd;				 /*< 迷你列表项 列表中的最后一个列表项  列表尾*/
	listSECOND_LIST_INTEGRITY_CHECK_VALUE	 /*列表完整性检查2*/
} List_t;

1.2列表项ListItem_t

struct xLIST_ITEM
{
	listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE			/*列表完整性检查1*/
	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			/*列表完整性检查2*/
};
typedef struct xLIST_ITEM ListItem_t;

对于pvOwner、pxContainer 可以简单理解成,列表项是文件,pxContainer是文件夹,pvOwner是执行程序

1.3迷你列表项MiniListItem_t

struct xMINI_LIST_ITEM
{
	listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE			/* 列表完整性检查1*/
	configLIST_VOLATILE TickType_t xItemValue;          /* 列表项的值*/
	struct xLIST_ITEM * configLIST_VOLATILE pxNext;     /* 指向下一个列表项*/
	struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /* 指向上一个列表项*/
};
typedef struct xMINI_LIST_ITEM MiniListItem_t;

二、相关API

#inlcude "list.h"

/*初始化列表*/
void vListInitialise(List_t * const pxList)
/*初始化列表项*/
void vListInitialiseItem(List_t * const pxItem)
/*插入列表项  根据成员 xItemValue来寻找插入点*/
void vListInset(List_t *const pxList, ListItem_t * const pxNewListItem)
/*尾插列表项 可简单理解 一般插入按升序 而尾插是倒序 可用于同一优先级插入就序列表*/
void vListInsetEnd(List_t *const pxList, ListItem_t * const pxNewListItem)
/*删除列表项  只需要列表项指针,因为列表项成员pxContainer表示了它归属的列表  成功返回列表项个数*/
UBaseType_t uxListRemove(ListItem_t * const pxNewListItem)

三、实现原理

3.1列表初始化

void vListInitialise( List_t * const pxList )
{
	/* 因为xListEnd是迷你列表项表示列表尾,而Index索引列表项,初始化时只能指向列表尾*/
	pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );		

	/* 列表尾的值赋值最大 便于查找*/
	pxList->xListEnd.xItemValue = portMAX_DELAY;

	/* next指向自己 previous也指向自己*/
	pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );	
	pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );

	pxList->uxNumberOfItems = ( UBaseType_t ) 0U;//列表中列表项数量为0

	/* 列表完整性检查*/
	listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
	listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
}

3.2列表项初始化

void vListInitialiseItem( ListItem_t * const pxItem )
{
	/* 列表项初始化当然还没有归属哪个列表,因而赋值NULL */
	pxItem->pxContainer = NULL;

	/* 列表项完整性检查*/
	listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
	listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
}

3.3插入列表项

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; //待插入列表项的next继承插入点的next
	pxNewListItem->pxNext->pxPrevious = pxNewListItem;//待插入列表项的next的previous更新为待插入列表项
	pxNewListItem->pxPrevious = pxIterator; //待插入列表项的previous更新为插入点
	pxIterator->pxNext = pxNewListItem;  //插入点的next更新为previous
 
//至此,升序  插入点、待插入列表项、待插入列表项后的列表项 中间的关系全部整理完毕  很严谨!   
   
	/* 待插入列表项的归属赋值为要插入进的列表 */
	pxNewListItem->pxContainer = pxList;

	( pxList->uxNumberOfItems )++; //列表中列表项数量+1
}

3.4尾插列表项

void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )
{
ListItem_t * const pxIndex = pxList->pxIndex; //获取列表的索引

	/* 列表和列表项完整性检查 */
	listTEST_LIST_INTEGRITY( pxList );
	listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );

	/*pxIndex 指向列表中的第一个列表项 尾插则会更新第一个列表项为待尾插的列表项 */
	pxNewListItem->pxNext = pxIndex;
	pxNewListItem->pxPrevious = pxIndex->pxPrevious;

	/* Only used during decision coverage testing. */
	mtCOVERAGE_TEST_DELAY();

    /*更新列表的索引*/
	pxIndex->pxPrevious->pxNext = pxNewListItem; 
	pxIndex->pxPrevious = pxNewListItem;

	/* 标记列表项归属 */
	pxNewListItem->pxContainer = pxList;

	( pxList->uxNumberOfItems )++;//列表中列表项数量+1
}

3.5列表项的删除

UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
{

List_t * const pxList = pxItemToRemove->pxContainer; //获取列表项的归属列表

    /*修改前后指向*/
	pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; 
	pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;

	/* Only used during decision coverage testing. */
	mtCOVERAGE_TEST_DELAY();

	/*确保pxIndex指向第一个列表项*/
	if( pxList->pxIndex == pxItemToRemove )
	{
		pxList->pxIndex = pxItemToRemove->pxPrevious;
	}
	else
	{
		mtCOVERAGE_TEST_MARKER();
	}

	pxItemToRemove->pxContainer = NULL;//待删除列表项的归属 赋值NULL
	( pxList->uxNumberOfItems )--;     //列表中列表项数量-1

	return pxList->uxNumberOfItems;    //返回列表项数量
}

3.6列表的遍历

前面说列表结构体List_t中的成员变量pxIndex用来遍历列表

FreeRTOS提供了一个函数来完成列表的遍历

listGET_OWNER_OF_NEXT_ENTRY()

每调用一次这个函数列表的 pxIndex变量就会指向下一个列表项,并且返回这个列表项的pxOwner变量值。

这个函数本质上是一个宏,list.h 中如下定义:

#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )										\
{																			 				\
List_t * const pxConstList = ( pxList );  									                \
					                                                                        \                 	/*获取列表 列表的索引更新为索引的next */                                                     \
	( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;                            \
    /*如果索引指向了列表尾,更新为第一个列表项*/                                                   \
	if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) )	\
	{																						\
		( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;						\
	}                                           			                                \
	( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; /*返回列表项的任务控制块归属 赋值给传入的pxTCB*/\										                                                                    \
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/926412.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

搭建AD域服务器

搭建AD域服务器 使用深信服HCI搭建AD域服务器 1、新建虚拟机 2、填写参数 3、省略安装过程 4、进入服务器管理器 5、 6、 7、 8、 9、 10、 11、 12、 13、 14、 15、 16、 17、 18、 19、 20、 21、 22、 23、

【iOS】设计模式的六大原则

【iOS】设计模式的六大原则 文章目录 【iOS】设计模式的六大原则前言开闭原则——OCP单一职能原则——SRP里氏替换原则——LSP依赖倒置原则——DLP接口隔离原则——ISP迪米特法则——LoD小结 前言 笔者这段时间看了一下有关于设计模式的七大原则&#xff0c;下面代码示例均为OC…

一个实用的 Maven localRepository 工具

目录 1 现状2 当前解决3 更好的解决3.1 下载 Maven localRepository 工具包3.2 上传本地 localRepository 包3.3 清理 localRepository 中指定后缀的文件 1 现状 在使用 Maven 时&#xff0c;我们可能会经常与本地仓库和私服仓库打交道。 例如对于本地仓库&#xff0c;因为某…

【linux学习指南】详解Linux进程信号保存

文章目录 &#x1f4dd;保存信号&#x1f320; 信号其他相关常⻅概念&#x1f309;在内核中的表⽰ &#x1f320; sigset_t&#x1f320;信号集操作函数&#x1f309;sigprocmask&#x1f309;sigpending &#x1f6a9;总结 &#x1f4dd;保存信号 &#x1f320; 信号其他相关常…

【C++】 算术操作符与数据类型溢出详解

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;C 算术操作符详解基本算术操作符整数除法与取模行为类型转换在算术运算中的作用自增与自减操作符 &#x1f4af;数值溢出&#xff1a;当值超出类型范围时数据类型的取值范围…

【继承】—— 我与C++的不解之缘(十九)

前言&#xff1a; 面向对象编程语言的三大特性&#xff1a;封装、继承和多态 本篇博客来学习C中的继承&#xff0c;加油&#xff01; 一、什么是继承&#xff1f; ​ 继承(inheritance)机制是⾯向对象程序设计使代码可以复⽤的最重要的⼿段&#xff0c;它允许我们在保持原有类…

使用redis-plus-plus库连接redis

使用redis-plus-plus库连接redis 一、安装redis-plus-plus1.1安装hiredis1.2编译安装redis-plus-plus 二、redis的连接使用2.1创建redis对象2.2向redis中添加元素2.3判断元素是否存在2.4获取元素2.5设置获取过期时间2.6获取类型2.7 删除当前数据库 一、安装redis-plus-plus C …

JMeter 并发策略-针对准点秒杀场景的压测实现

一、场景的压测实现 1&#xff0c;创建线程组&#xff0c;10并发用户执行5次&#xff1b; 2&#xff0c;创建 Synchronizing Timer 元件,用于同步线程&#xff0c;设置同步元件 Synchronizing Timer 3&#xff0c;创建 http 请求4&#xff0c;创建 view results in table 元件…

记一次搞校园网的经历

接教室的校园网&#xff0c;到另一个屋子玩电脑&#xff0c;隔墙想放大一下AP的信号&#xff0c;发现死活不行 这是现状 由于校园网认证的存在&#xff0c;无法用桥接&#xff0c;桥接需要路由器有IP&#xff0c;而这个IP无法用未刷机的路由器来打开校园网页面认证 解决 将一…

打latex公式可以练到像手写一样快吗?

这里分享两个Python Latex工具latexify和handcalcs。 latexify生成LaTeX 数学公式 import math import latexify @latexify.with_latex #调用latexify的装饰器 def solve(a, b, c):return (-b + math.sqrt(b**2 - 4*a*c)) / (2*a)solve 更多例子.......

【Linux】常用命令二

1、cat 用于查看内容较少的纯文本文件。 参数-n可以显示行号。 2、more 用于查看内容较多的纯文本文件。 它会在最下面使用百分比的形式来提示你已经月读了多少内容&#xff0c;你可以使用空格键或回车键向下翻页。 3、head 用于查看纯文本文档的前N行。 4、tail 用于查看…

SolarCube: 高分辨率太阳辐照预测基准数据集

太阳能作为清洁能源在减缓气候变化中的作用日益凸显&#xff0c;其稳定的供应对电网管理至关重要。然而&#xff0c;太阳辐照受云层和天气变化的影响波动较大&#xff0c;给光伏电力的管理带来挑战&#xff0c;尤其是在调度、储能和备用系统管理方面。因此&#xff0c;精确的太…

第三方Express 路由和路由中间件

文章目录 1、Express 应用使用回调函数的参数&#xff1a; request 和 response 对象来处理请求和响应的数据。2、Express路由1.路由方法2.路由路径3.路由处理程序 3. 模块化路由4. Express中间件1.中间件简介2.中间件分类3.自定义中间件 1、Express 应用使用回调函数的参数&am…

nginx+php压测及报错优化

测试环境&#xff1a;虚拟机centos7&#xff0c;nginxphp 压测工具&#xff1a;Apipost 访问的php程序中添加sleep()增加程序执行时长&#xff0c;使用Apipost进行压测&#xff0c;根据服务器配置设置一个大概可能触发报错的并发和轮训次数&#xff0c;若无报错逐渐增加并发和…

探索Python词云库WordCloud的奥秘

文章目录 探索Python词云库WordCloud的奥秘1. 背景介绍&#xff1a;为何选择WordCloud&#xff1f;2. WordCloud库简介3. 安装WordCloud库4. 简单函数使用方法5. 应用场景示例6. 常见Bug及解决方案7. 总结 探索Python词云库WordCloud的奥秘 1. 背景介绍&#xff1a;为何选择Wo…

AOSP的同步问题

repo sync同步时提示出错: error: .repo/manifests/: contains uncommitted changesRepo command failed due to the following UpdateManifestError errors: contains uncommitted changes解决方法&#xff1a; 1、cd 进入.repo/manifests cd .repo/manifests2、执行如下三…

Shell脚本小练习

学习了这么长时间Shell脚本&#xff0c;总得来一次小小的练习吧&#xff0c;那么请看下文&#xff01; 1.用Shell写一个小计算器。 通过read命令获取用户输入的表达式&#xff0c;表达式的格式设定为操作数1 运算符 操作数2&#xff0c;例如53&#xff0c;然后利用设计的脚本…

k8s Init:ImagePullBackOff 的解决方法

kubectl describe po (pod名字) -n kube-system 可查看pod所在的节点信息 例如&#xff1a; kubectl describe po calico-node-2lcxx -n kube-system 执行拉取前先把用到的节点的源换了 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-EOF {"re…

Git 快速入门:全面了解与安装步骤

Git 快速入门&#xff1a;全面了解与安装步骤 一、关于Git 1.1 简介 Git 是一个开源的分布式版本控制系统&#xff0c;由 Linus Torvalds 于 2005 年创建&#xff0c;最初是为了更好地管理 Linux 内核开发而设计。 Git用于跟踪计算机文件的变化&#xff0c;特别是源代码文件…

springboot358智慧社区居家养老健康管理系统(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 智慧社区居家养老健康管理系统设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&…