当前位置: 首页 > news >正文

【学习FreeRTOS】第8章——FreeRTOS列表和列表项

1.列表和列表项的简介

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

在这里插入图片描述

  • 列表相当于链表,列表项相当于节点,FreeRTOS 中的列表是一个双向环形链表
  • 列表的特点:列表项间的地址非连续的,是人为的连接到一起的。列表项的数目是由后期添加的个数决定的,随时可以改变
  • 数组的特点:数组成员地址是连续的,数组在最初确定了成员数量后期无法改变
  • 在OS中任务的数量是不确定的,并且任务状态是会发生改变的,所以非常适用列表(链表)这种数据结构

1.1.列表的数据结构

typedef struct xLIST
{listFIRST_LIST_INTEGRITY_CHECK_VALUE	/* 校验值 */volatile UBaseType_t 					uxNumberOfItems;			/* 列表中的列表项数量 */ListItem_t * c							onfigLIST_VOLATILE pxIndex	/* 用于遍历列表项的指针 */MiniListItem_t 							xListEnd					/* 末尾列表项 */listSECOND_LIST_INTEGRITY_CHECK_VALUE	/* 校验值 */
} List_t;
  • 在该结构体中, 包含了两个宏,这两个宏是确定的已知常量, FreeRTOS通过检查这两个常量的值,来判断列表的数据在程序运行过程中,是否遭到破坏 ,该功能一般用于调试, 默认是不开启的
  • 成员uxNumberOfItems:用于记录列表中列表项的个数(不包含 xListEnd)
  • 成员 pxIndex:用于指向列表中的某个列表项,一般用于遍历列表中的所有列表项
  • 成员xListEnd:是一个迷你列表项,排在最末尾

1.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; 	
  • xItemValue为列表项的值,这个值多用于按升序对列表中的列表项进行排序
  • pxNext 和 pxPrevious分别用于指向列表中列表项的下一个列表项和上一个列表项
  • pxOwner 用于指向包含列表项的对象(通常是任务控制块)
  • pxContainer 用于指向列表项所在列表。

1.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;
  • xItemValue为列表项的值,这个值多用于按升序对列表中的列表项进行排序 (一般为0xFFFFFFFF)
  • pxNext 和 pxPrevious 分别用于指向列表中列表项的下一个列表项和上一个列表项
  • 迷你列表项只用于标记列表的末尾和挂载其他插入列表中的列表项,因此不需要成员变量 pxOwner 和 pxContainer,以节省内存开销

1.4.列表、列表项、迷你列表项的关系

在这里插入图片描述
在这里插入图片描述

2.列表相关API函数介绍

2.1.初始化列表vListInitialise()

void vListInitialise( List_t * const pxList) 
{ /* 初始化时,列表中只有xListEnd,因此pxIndex指向xListEnd */ pxList->pxIndex = ( ListItem_t * ) &( 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 ); 
}
  • 形参:待初始化列表
    在这里插入图片描述

2.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 );
}
  • 形参:待初始化列表项

2.3.列表末尾插入列表项vListInsertEnd()

void vListInsertEnd(List_t * const pxList,ListItem_t * const pxNewListItem)
{/* 获取列表pxIndex 指向的列表项 */ListItem_t * const pxIndex = pxList->pxIndex;/* 检查参数是否正确 */listTEST_LIST_INTEGRITY( pxList );listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );/* 更新待插入列表项的指针成员变量 */pxNewListItem->pxNext = pxIndex;pxNewListItem->pxPrevious = pxIndex->pxPrevious;/* 测试使用,不用理会 */mtCOVERAGE_TEST_DELAY();/* 更新列表中原本列表项的指针成员变量 */pxIndex->pxPrevious->pxNext = pxNewListItem;pxIndex->pxPrevious = pxNewListItem;/* 更新待插入列表项的所在列表成员变量 */pxNewListItem->pxContainer = pxList;/* 更新列表中列表项的数量 */( pxList->uxNumberOfItems )++;
}
  • 形参:列表、待插入列表项
  • 此函数用于将待插入列表的列表项插入到列表 pxIndex 指针指向的列表项前面,是一种无序的插入方法
    在这里插入图片描述

2.4.列表插入列表项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 ) { /* 插入的位置为列表xListEnd前面 */ 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 )++; 
}
  • 形参:列表、待插入列表项
  • 此函数用于将待插入列表的列表项按照列表项值升序进行排序,有序地插入到列表中
    在这里插入图片描述

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;/* 测试使用,不用理会 */mtCOVERAGE_TEST_DELAY();/* 如果pxIndex 正指向待移除的列表项 */if( pxList->pxIndex == pxItemToRemove ){/* pxIndex 指向上一个列表项 */pxList->pxIndex = pxItemToRemove->pxPrevious;}else{mtCOVERAGE_TEST_MARKER();}/* 将待移除列表项的所在列表指针清空 */pxItemToRemove->pxContainer = NULL;/* 更新列表中列表项的数量 */( pxList->uxNumberOfItems )--;/* 返回列表项移除后列表中列表项的数量 */return pxList->uxNumberOfItems;
}
  • 形参:待移除列表项
  • 返回值:待移除列表项移除后,所在列表剩余列表项的数量
  • 此函数用于将列表项从列表项所在列表中移除
    在这里插入图片描述

3.列表项的插入和删除实验

  • 实验目的:学会对FreeRTOS 列表和列表项的操作函数使用,并观察运行结果和理论分析是否一致
  • 实验设计:将设计三个任务:start_task、task1、task2
    start_task:用来创建其他的2个任务
    task1:实现LED0每500ms闪烁一次,用来提示系统正在运行
    task2:调用列表和列表项相关API函数,并且通过串口输出相应的信息,进行观察

在这里插入图片描述

相关文章:

【学习FreeRTOS】第8章——FreeRTOS列表和列表项

1.列表和列表项的简介 列表是 FreeRTOS 中的一个数据结构&#xff0c;概念上和链表有点类似&#xff0c;列表被用来跟踪 FreeRTOS中的任务。列表项就是存放在列表中的项目。 列表相当于链表&#xff0c;列表项相当于节点&#xff0c;FreeRTOS 中的列表是一个双向环形链表列表的…...

分布式图数据库 NebulaGraph v3.6.0 正式发布,强化全文索引能力

本次 v3.6.0 版本&#xff0c;主要强化全文索引能力&#xff0c;以及优化部分场景下的 MATCH 性能。 强化 强化增强全文索引功能&#xff0c;具体 pr 参见&#xff1a;#5567、#5575、#5577、#5580、#5584、#5587 优化 支持使用 MATCH 子句检索 VID 或属性索引时使用变量&am…...

在 ubuntu 18.04 上使用源码升级 OpenSSH_7.6p1到 OpenSSH_9.3p1

1、检查系统已安装的当前 SSH 版本 使用命令 ssh -V 查看当前 ssh 版本&#xff0c;输出如下&#xff1a; OpenSSH_7.6p1 Ubuntu-4ubuntu0.7, OpenSSL 1.0.2n 7 Dec 20172、安装依赖&#xff0c;依次执行以下命令 sudo apt update sudo apt install build-essential zlib1g…...

python中可以处理word文档的模块:docx模块

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 话不多说&#xff0c;直接开搞&#xff0c;如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码 一.docx模块 Python可以利用python-docx模块处理word文档&#xff0c;处理方式是面向对象的。 也就是说python-docx模块…...

TikTok或将于8月底关闭半闭环、速卖通或将推出“半托管”模式

《出海周报》是运营坛为外贸企业主和外贸人独家打造的重要资讯栏目&#xff0c;聚焦企业出海、海外市场动态、海外监管政策等方面&#xff0c;以简捷的方式&#xff0c;提升读者获取资讯的效率。 接下来运营坛为大家带来第15期出海周报&#xff0c;快来看看这周国内外市场发生了…...

《凤凰架构》第二章——访问远程服务

前言 这章挺难的&#xff0c;感觉离我比较远&#xff0c;不太好懂&#xff0c;简单记录吧。 这章主要讲访问远程服务&#xff0c;主要对比了RPC和REST的区别&#xff0c;可以结合知乎上的文章《既然有 HTTP 请求&#xff0c;为什么还要用 RPC 调用&#xff1f;》 这篇文章进行…...

【Diffusion】李宏毅2023机器学习Diffusion笔记

文章目录 1 想法概述2 实际过程阶段1 Add Noise阶段2 Denoise 3 数学原理4 为什么推理时要额外加入noise5 一些不知道对不对的Summary 1 想法概述 从一张充满噪声的图中不断denoise&#xff0c;最终得到一张clear的图片。为了确定当前图片中噪声占比的大小&#xff0c;同时输入…...

CloudEvents—云原生事件规范

我们的系统中或多或少都会用到如下两类业务技术&#xff1a; 异步任务&#xff0c;用于降低接口时延或削峰&#xff0c;提升用户体验&#xff0c;降低系统并发压力&#xff1b;通知类RPC&#xff0c;用于微服务间状态变更&#xff0c;用户行为的联动等场景&#xff1b; 以上两种…...

神经网络基础-神经网络补充概念-51-局部最优问题

概念 局部最优问题是在优化问题中常见的一个挑战&#xff0c;特别是在高维、非凸、非线性问题中。局部最优问题指的是算法在优化过程中陷入了一个局部最小值点&#xff0c;而不是全局最小值点。这会导致优化算法在某个局部区域停止&#xff0c;而无法找到更好的解。 解决方案…...

深度学习中,什么是batch-size?如何设置?

什么是batch-size? batch-size 是深度学习模型在训练过程中一次性输入给模型的样本数量。它在训练过程中具有重要的意义&#xff0c;影响着训练速度、内存使用以及模型的稳定性等方面。 以下是 batch-size 大小的一些影响和意义&#xff1a; 训练速度&#xff1a;较大的 bat…...

[保研/考研机试] KY26 10进制 VS 2进制 清华大学复试上机题 C++实现

题目链接&#xff1a; 10进制 VS 2进制http://www.nowcoder.com/share/jump/437195121691738172415 描述 对于一个十进制数A&#xff0c;将A转换为二进制数&#xff0c;然后按位逆序排列&#xff0c;再转换为十进制数B&#xff0c;我们称B为A的二进制逆序数。 例如对于十进制…...

JSP-学习笔记

文章目录 1.JSP介绍2 JSP快速入门3 JSP 脚本3.1 JSP脚本案例3.2 JSP缺点 4 EL表达式4.1 快速入门案例 5. JSTL标签6. MVC模式和三层架构6.1 MVC6.2 三层架构 7. 案例-基于MVC和三层架构实现商品表的增删改查 1.JSP介绍 概念 JSP&#xff08;JavaServer Pages&#xff09;是一种…...

Golang协程,通道详解

进程、线程以及并行、并发 关于进程和线程 进程&#xff08;Process&#xff09;就是程序在操作系统中的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff0c;进程是一个动态概念&#xff0c;是程序在执行过程中分配和管理资源的基本单位&#xff0c;每一…...

unity 之 Vector 数据类型

文章目录 Vector 1Vector 2Vector 3Vector 4 Vector 1 在Unity中&#xff0c;Vector1 并不是一个常见的向量类型。 如果您需要表示标量&#xff08;单个值&#xff09;或者只需要一维的数据&#xff0c;通常会直接使用浮点数&#xff08;float&#xff09;或整数&#xff08;in…...

私密数据采集:隧道爬虫IP技术的保密性能力探究

作为一名专业的爬虫程序员&#xff0c;今天要和大家分享一个关键的技术&#xff0c;它能够为私密数据采集提供保密性能力——隧道爬虫IP技术。如果你在进行敏感数据采集任务时需要保护数据的私密性&#xff0c;那么这项技术将是你的守护神。 在进行私密数据采集任务时&#xff…...

使用git rebase 之后的如何恢复到原始状态

我们常常喜欢使用git rebase去切换分支提交代码,操作流程就是: 先切换分支:比如当前是master 我们修改了一堆代码产生一个commit id :5555555567777 那么我们常常比较懒就直接切换了:git checkout dev 然后呢?使用命令git rebase 5555555567777,想把这笔修改提交到d…...

matlab相机标定知识整理

matlab相机标定知识整理 单目相机标定 单目相机标定 内参矩阵&#xff1a;cameraParams.Intrinsics.K 或者 cameraParams.K旋转矩阵&#xff1a;cameraParams.RotationMatrices 有待确定 cameraParams.RotationVectors平移矩阵&#xff1a;cameraParams.TranslationVectors径向…...

win11安装ubuntu 子系统安装过程及注意事项

第一步 &#xff1a;安装系统必须组件 由于子系统是系统自带组件&#xff0c;需要安装软件支持 第二步&#xff1a;应用商店安装 ubuntu 编辑 编辑 这个时候打开会报错 第三步&#xff0c;运行linux子系统 选择Windows PowerShell 以管理员身份运行&#xff09; 输入&#…...

torch.cat((A,B),dim=1)解析

官方说明torch.cat 引用自&#xff1a;Pytorch中的torch.cat()函数 torch.cat(tensors, dim0, *, outNone) → Tensor # 连接给定维数的给定序列的序列张量。所有张量要么具有相同的形状(除了连接维度)&#xff0c;要么为空。示例 输入&#xff1a; import torch a torch.Tens…...

apache配置安全证书https踩坑记录

apache配置安全证书有如下几步 一、申请证书 这个网上有很多免费的&#xff0c;我用的是阿里云的服务器&#xff0c;在阿里云后台就可以申请免费证书。 二、上传证书 申请好证书后&#xff0c;根据服务器用的什么软件&#xff0c;是apache还是ngnix&#xff0c;下载相应的证书…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...

Linux系统部署KES

1、安装准备 1.版本说明V008R006C009B0014 V008&#xff1a;是version产品的大版本。 R006&#xff1a;是release产品特性版本。 C009&#xff1a;是通用版 B0014&#xff1a;是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存&#xff1a;1GB 以上 硬盘&#xf…...

Python 高效图像帧提取与视频编码:实战指南

Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...

如何配置一个sql server使得其它用户可以通过excel odbc获取数据

要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据&#xff0c;你需要完成以下配置步骤&#xff1a; ✅ 一、在 SQL Server 端配置&#xff08;服务器设置&#xff09; 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到&#xff1a;SQL Server 网络配…...

恶补电源:1.电桥

一、元器件的选择 搜索并选择电桥&#xff0c;再multisim中选择FWB&#xff0c;就有各种型号的电桥: 电桥是用来干嘛的呢&#xff1f; 它是一个由四个二极管搭成的“桥梁”形状的电路&#xff0c;用来把交流电&#xff08;AC&#xff09;变成直流电&#xff08;DC&#xff09;。…...

前端开发者常用网站

Can I use网站&#xff1a;一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use&#xff1a;Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站&#xff1a;MDN JavaScript权威网站&#xff1a;JavaScript | MDN...