08_FreeRTOS列表和列表项讲解

news2024/11/15 17:17:49

目录

列表和列表项的简介

列表

列表项 

迷你列表项

列表和列表项的关系 

列表相关API函数介绍

 初始化列表vListInitialise函数详解

列表项的初始化函数vListInitialiseItem函数

列表项的插入vListInsert函数

列表项末尾插入vListInsertEnd函数

列表项的删除函数uxListRemove函数


列表和列表项的简介

列表是 FreeRTOS 中的一个数据结构,概念上和链表有点类似,列表被用来跟踪 FreeRTOS中的任务。列表项就是存放在列表中的项目示意图:

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

列表的特点:列表项间的地址非连续的,是人为的连接到一起的。列表项的数目是由后期添加的个数决定的,随时可以改变可以理解为列表就是就绪列表,列表项里面存的是某个任务就绪。

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

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

列表

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

 

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

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

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

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

列表项 

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

 1.同样2个用于检测列表项的数据完整性不用管,是调试时候用。

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

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

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

5.成员变量pxContainer用于指向列表项所在列表。

 

迷你列表项

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

 

1.用于检测数据完整性同样是调试用。

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

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

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

列表和列表项的关系 

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

列表成员:

 初始化时数量是0,索引指向末尾列表项(迷你列表)前和后都指向自己:

 插入列表项1,数值是10会插入到末尾列表项前面,又因为是双向的所以互指,此时列表的数量uxNumberOfltems = 1:

 插入列表项2也是同理,数值是20会插入到末尾列表项前面列表项1后面,此时列表的数量uxNumberOfltems = 2:

最后的结果就是如下图所示: 

 

列表相关API函数介绍

 初始化列表vListInitialise函数详解

 

void vListInitialise( List_t * const pxList )
{
	/* The list structure contains a list item which is used to mark the
	end of the list.  To initialise the list the list end is inserted
	as the only list entry. */
	
	/*初始化时列表中只有末尾列表项因此pxIndex指向末尾列表项*/
	pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );			/*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. */

	/* The list end value is the highest possible value in the list to
	ensure it remains at the end of the list. */
	
	/*末尾列表项数值赋值为最大,用于列表升序排序*/
	pxList->xListEnd.xItemValue = portMAX_DELAY;

	/* The list end next and previous pointers point to itself so we know
	when the list is empty. */
	
	/*列表中只有末尾列表项所以前和后都指向自己*/
	pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );	/*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. */
	pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. */
	
	/*末尾列表项不算在列表项里面,列表数量值为0*/
	pxList->uxNumberOfItems = ( UBaseType_t ) 0U;

	/* Write known values into the list if
	configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
	
	/*检查数据的完整性的校验*/
	listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
	listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
}

 

列表项的初始化函数vListInitialiseItem函数

 

void vListInitialiseItem( ListItem_t * const pxItem )
{
	/* Make sure the list item is not recorded as being on a list. */
	
	/*初始化时,列表项所在列表设为空*/
	pxItem->pvContainer = NULL;

	/* Write known values into the list item if
	configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
	
	/*初始化用于检测列表项数据完整性的校验值*/
	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;

	/* Only effective when configASSERT() is also defined, these tests may catch
	the list data structures being overwritten in memory.  They will not catch
	data errors caused by incorrect configuration or use of FreeRTOS. */
	
	/*检查参数是否正确*/
	listTEST_LIST_INTEGRITY( pxList );
	listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );

	/* Insert the new list item into the list, sorted in xItemValue order.

	If the list already contains a list item with the same item value then the
	new list item should be placed after it.  This ensures that TCB's which are
	stored in ready lists (all of which have the same xItemValue value) get a
	share of the CPU.  However, if the xItemValue is the same as the back marker
	the iteration loop below will not end.  Therefore the value is checked
	first, and the algorithm slightly modified if necessary. */
	
	/*判断数值是不是最大值*/
	if( xValueOfInsertion == portMAX_DELAY )
	{
		/*插入的位置为列表xListEnd前面*/
		pxIterator = pxList->xListEnd.pxPrevious;
	}
	else
	{
		/* *** NOTE ***********************************************************
		If you find your application is crashing here then likely causes are
		listed below.  In addition see http://www.freertos.org/FAQHelp.html for
		more tips, and ensure configASSERT() is defined!
		http://www.freertos.org/a00110.html#configASSERT

			1) Stack overflow -
			   see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
			2) Incorrect interrupt priority assignment, especially on Cortex-M
			   parts where numerically high priority values denote low actual
			   interrupt priorities, which can seem counter intuitive.  See
			   http://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition
			   of configMAX_SYSCALL_INTERRUPT_PRIORITY on
			   http://www.freertos.org/a00110.html
			3) Calling an API function from within a critical section or when
			   the scheduler is suspended, or calling an API function that does
			   not end in "FromISR" from an interrupt.
			4) Using a queue or semaphore before it has been initialised or
			   before the scheduler has been started (are interrupts firing
			   before vTaskStartScheduler() has been called?).
		**********************************************************************/
		
		/*遍历列表中的列表项,找到插入的位置*/
		for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd );
		pxIterator->pxNext->xItemValue <= xValueOfInsertion;
		pxIterator = pxIterator->pxNext )
		
		/*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. */
		{
			/* There is nothing to do here, just iterating to the wanted
			insertion position. */
		}
	}
	/*将待插入的列表项插入指定位置,双向链表的插入*/
	pxNewListItem->pxNext = pxIterator->pxNext;
	pxNewListItem->pxNext->pxPrevious = pxNewListItem;
	pxNewListItem->pxPrevious = pxIterator;
	pxIterator->pxNext = pxNewListItem;

	/* Remember which list the item is in.  This allows fast removal of the
	item later. */
	
	/*更新待插入列表项所在列表*/
	pxNewListItem->pvContainer = ( void * ) pxList;
	/*更新列表中列表项的数量*/
	( pxList->uxNumberOfItems )++;
}

列表项末尾插入vListInsertEnd函数

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

 

void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )
{
	
	ListItem_t * const pxIndex = pxList->pxIndex;

	/* Only effective when configASSERT() is also defined, these tests may catch
	the list data structures being overwritten in memory.  They will not catch
	data errors caused by incorrect configuration or use of FreeRTOS. */
	
	/*检查参数是否正确*/
	listTEST_LIST_INTEGRITY( pxList );
	listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );

	/* Insert a new list item into pxList, but rather than sort the list,
	makes the new list item the last item to be removed by a call to
	listGET_OWNER_OF_NEXT_ENTRY(). */
	
	/*更新待插入列表项的指针成员变量*/
	pxNewListItem->pxNext = pxIndex;
	pxNewListItem->pxPrevious = pxIndex->pxPrevious;

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

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

	/* Remember which list the item is in. */
	/*更新待插入列表项的所在列表成员变量*/
	pxNewListItem->pvContainer = ( void * ) pxList;
	/* 更新列表中列表项的数量*/
	( pxList->uxNumberOfItems )++;
}

列表项的删除函数uxListRemove函数

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

 

 

UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
{
/* The list item knows which list it is in.  Obtain the list from the list
item. */
	List_t * const pxList = ( List_t * ) pxItemToRemove->pvContainer;
	/*从列表中移除列表项*/
	pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
	pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;

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

	/* Make sure the index is left pointing to a valid item. */
	
	/*如果 pxindex 正指向待移除的列表项*/
	if( pxList->pxIndex == pxItemToRemove )
	{	
		/*pxIndex 指向上一个列表项*/
		pxList->pxIndex = pxItemToRemove->pxPrevious;
	}
	else
	{
		/*为实现函数*/
		mtCOVERAGE_TEST_MARKER();
	}

	/*将待移除的列表项的所在列表指针清空*/
	pxItemToRemove->pvContainer = NULL;
	/*更新列表中列表项的数量*/
	( pxList->uxNumberOfItems )--;
	/*返回移除后的列表中列表项的数量*/
	return pxList->uxNumberOfItems;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

零入门容器云网络实战-5->路由知识总结

本篇文章主要用于收集、整理、总结路由相关知识点。 1、路由分为几种&#xff1f; 直连路由静态路由&#xff08;基本静态路由&#xff0c;等价静态路由&#xff0c;活动静态路由&#xff0c;缺省静态路由&#xff09;动态路由 通过路由协议从相邻路由器学习到的。路由协议&am…

一,SpringMVC入门

0 MVC设计模式 View&#xff08;视图&#xff09;&#xff1a;页面&#xff08;jsp、html&#xff09;&#xff0c;接收用户数据和显示结果。 Controller&#xff08;控制器&#xff09;&#xff1a;action&#xff0c;接收请求&#xff0c;决定程序执行流程。 Model&#xf…

【深度学习】——循环神经网络RNN及实例气温预测

引言 密集连接网络和卷积神经网络都有主要的特点&#xff0c;那就是它们没有记忆。它们单独处理每个输入&#xff0c;在输入和输入之间没有保存任何状态。举个例子&#xff1a;当你在阅读一个句子的时候&#xff0c;你需要记住之前的内容&#xff0c;我们才能动态的了解这个句子…

三、SqlSession的创建以及执行流程

简介 SqlSession接口提供了查询&#xff0c;插入&#xff0c;更新&#xff0c;删除方法&#xff0c;Mybatis中所有的数据库交互都由SqlSession来完成。SqlSession 对象完全包含以数据库为背景的所有执行 SQL 操作的方法&#xff0c;它的底层封装了 JDBC 连接&#xff0c;可以用…

微服务链路追踪SkyWalking学习笔记

目录 1、skywalking是什么 1.2 链路追踪框架对比 1.3 性能对比 1.4 Skywalking主要功能特性 2、 SkyWalking 环境搭建部署 2.1 下载 SkyWalking 2.2 搭建SkyWalking OAP 服务 2.3 SkyWalking中三个概念 3、 SkyWalking 接入微服务 3.1 linux环境—通过jar包方式接入 …

SAP ADM100-2.5 系统启动:日志文件

本节将介绍SAP ABAP系统启动时最重要的log文件和Trce文件,以掌握通过使用系统启动log文件和trace文件分析系统问题。 1、记录系统启动过程 启动过程是一个特别重要的阶段,因此该过程将被操作系统、SAP系统、数据库记录。如果SAP系统没有启动,那么你将在log日志文件中发现相…

C#使用IronPython调用Python

一、前言以下摘自百度百科&#xff1a;IronPython 是一种在 NET 和 Mono 上实现的 Python 语言&#xff0c;由 Jim Hugunin&#xff08;同时也是 Jython 创造者&#xff09;所创造。1.0 版于2006年9月5日发布。随后&#xff0c;在 2007 年&#xff0c;开发者决定改写架构&#…

音视频xxxx

文章目录前言编解码硬件解码(高级)软解码(低级)软、硬解码对比视频解码有四个步骤Android 系统中编解码器的命名方式查看当前设备支持的硬解码基础知识RGB色彩空间常见的格式对比YUV索引格式分离RGB24像素数据中的R、G、B分量BMP 文件格式格式组成像素排列顺序RGB24格式像素数据…

Apache Solr 9.1-(三)集群模式下通过Http API操作Apache Solr

Apache Solr 9.1-&#xff08;三&#xff09;集群模式下通过Http API操作Apache Solr Solr是一个基于Apache Lucene的搜索服务器&#xff0c;Apache Lucene是开源的、基于Java的信息检索库&#xff0c;Solr能为用户提供无论在任何时候都可以根据用户的查询请求返回结果&#xf…

网络原理(TCP/IP)(3)

4)滑动窗口 1)咱们滑动窗口的效果就是说在我们尽可能地保证可靠性的情况下&#xff0c;尽可能的提高传输效率2)况且咱们进行发送滑动窗口的本质就是说进行批量的发送数据&#xff0c;咱们尽可能说是把等待ACK的时间总体进行缩短&#xff0c;咱们可以把等待一份ACK的时间变成等待…

凸优化学习:PART1凸集

凸优化学习PART1 一、引言&#xff1a;优化问题简介 优化问题的定义 凸优化是优化的一种&#xff0c;是优化中比较容易的问题。在讲解优化问题前&#xff0c;首先说明什么是优化/数学规划&#xff08;Optimization/Mathematical Planning&#xff09;。 优化&#xff1a;从一…

搭建electron开发环境

electron是使用js,html,css构建桌面端应用程序的框架&#xff0c;可以使用electron开发Windows和Mac端应用。 安装nodejs,npm,cnpm 首先需要安装nodejs,npm和cnpm&#xff0c;安装后在命令行输入 node -v 和npm -v&#xff0c;如果输出了版本号&#xff0c;说明已经正常安装。…

数据仓库-数据模型建设方法总结(全)

一、大数据领域建模综述 1.1 为什么需要数据建模 有结构地分类组织和存储是我们面临的一个挑战。 数据模型强调从业务、数据存取和使用角度合理存储数据。 数据模型方法&#xff0c;以便在性能、成本、效率之间取得最佳平衡 成本&#xff1a;良好的数据模型能极大地减少不必…

MyBatis:批量添加记录

MyBatis&#xff0c;一款优秀的ORM映射框架&#xff0c;可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO&#xff08;Plain Old Java Objects&#xff0c;普通老式 Java 对象&#xff09;为数据库中的记录。同时&#xff0c;MyBatis提供了动态SQL特性&#x…

梦熊杯-十二月月赛-白银组题解-C.永恒

C. Problem C.永恒&#xff08;eternity.cpp&#xff09; 内存限制&#xff1a;256 MiB 时间限制&#xff1a;1000 ms 标准输入输出 题目类型&#xff1a;传统 评测方式&#xff1a;文本比较 题目描述: 「稻妻」是「永恒」的国度。 巴尔泽布认为&#xff0c;如果一个数…

感知机与门电路

前言&#xff1a;简述单层感知机特征及三种表示方式&#xff0c;并用单层感知机描述门电路&#xff0c;借由单层感知机无法处理非线性空间的问题&#xff0c;引出多层感知机。 单层感知机 感知机&#xff08;preceptron&#xff09;接收多个输入信号&#xff0c;输出一个信号…

【Kubernetes 企业项目实战】05、基于云原生分布式存储 Ceph 实现 K8s 数据持久化(上)

目录 一、分布式存储 Ceph 基本介绍 1.1 块存储&#xff08;rbd&#xff09; 1.2 文件系统 cephfs 1.3 对象存储 1.4 分布式存储的优点 二、Ceph 核心组件介绍 三、准备安装 Ceph 高可用集群的实验环境 3.1 机器配置 3.2 初始化环境 3.3 配置互信 3.4 配置 Ceph 安…

【精选博客】反爬过程中 x-ca-nonce、x-ca-signature 参数的解密过程

本篇博客在 请求头 x-ca-key、x-ca-nonce、x-ca-signature 加密分析第一篇 的基础上继续编写&#xff0c;大家学习时可以从上一篇入手。 文章目录x-ca-nonce 代码实现python 实现 uuidx-ca-signature代码实现在上一篇博客我们已经捕获了参数的JS代码&#xff0c;这篇博客重点要…

Java设计模式-策略模式Strategy

介绍 策略模式&#xff08;Strategy Pattern&#xff09;中&#xff0c;定义算法族&#xff08;策略组&#xff09;&#xff0c;分别封装起来&#xff0c;让他们之间可以互相替换&#xff0c;此模式让算法的变化独立于使用算法的客户。这算法体现了几个设计原则&#xff0c;第…

这些学习技巧学起来

技巧一&#xff1a;组合多个对象 在PPT页面插入多个图形后&#xff0c;想要移动这些元素时&#xff0c;很多小伙伴会挨个拖动进行位置调整。其实&#xff0c;我们大可以使用快捷键【CtrlG】将多个同类的元素进行组合&#xff0c;使其成为一个图形元素&#xff0c;这样就可以方…