【学习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 中的一个数据结构,概念上和链表有点类似,列表被用来跟踪 FreeRTOS中的任务。列表项就是存放在列表中的项目。 列表相当于链表,列表项相当于节点,FreeRTOS 中的列表是一个双向环形链表列表的…...
分布式图数据库 NebulaGraph v3.6.0 正式发布,强化全文索引能力
本次 v3.6.0 版本,主要强化全文索引能力,以及优化部分场景下的 MATCH 性能。 强化 强化增强全文索引功能,具体 pr 参见:#5567、#5575、#5577、#5580、#5584、#5587 优化 支持使用 MATCH 子句检索 VID 或属性索引时使用变量&am…...
在 ubuntu 18.04 上使用源码升级 OpenSSH_7.6p1到 OpenSSH_9.3p1
1、检查系统已安装的当前 SSH 版本 使用命令 ssh -V 查看当前 ssh 版本,输出如下: OpenSSH_7.6p1 Ubuntu-4ubuntu0.7, OpenSSL 1.0.2n 7 Dec 20172、安装依赖,依次执行以下命令 sudo apt update sudo apt install build-essential zlib1g…...
python中可以处理word文档的模块:docx模块
前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 话不多说,直接开搞,如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码 一.docx模块 Python可以利用python-docx模块处理word文档,处理方式是面向对象的。 也就是说python-docx模块…...
TikTok或将于8月底关闭半闭环、速卖通或将推出“半托管”模式
《出海周报》是运营坛为外贸企业主和外贸人独家打造的重要资讯栏目,聚焦企业出海、海外市场动态、海外监管政策等方面,以简捷的方式,提升读者获取资讯的效率。 接下来运营坛为大家带来第15期出海周报,快来看看这周国内外市场发生了…...
《凤凰架构》第二章——访问远程服务
前言 这章挺难的,感觉离我比较远,不太好懂,简单记录吧。 这章主要讲访问远程服务,主要对比了RPC和REST的区别,可以结合知乎上的文章《既然有 HTTP 请求,为什么还要用 RPC 调用?》 这篇文章进行…...
【Diffusion】李宏毅2023机器学习Diffusion笔记
文章目录 1 想法概述2 实际过程阶段1 Add Noise阶段2 Denoise 3 数学原理4 为什么推理时要额外加入noise5 一些不知道对不对的Summary 1 想法概述 从一张充满噪声的图中不断denoise,最终得到一张clear的图片。为了确定当前图片中噪声占比的大小,同时输入…...
CloudEvents—云原生事件规范
我们的系统中或多或少都会用到如下两类业务技术: 异步任务,用于降低接口时延或削峰,提升用户体验,降低系统并发压力;通知类RPC,用于微服务间状态变更,用户行为的联动等场景; 以上两种…...
神经网络基础-神经网络补充概念-51-局部最优问题
概念 局部最优问题是在优化问题中常见的一个挑战,特别是在高维、非凸、非线性问题中。局部最优问题指的是算法在优化过程中陷入了一个局部最小值点,而不是全局最小值点。这会导致优化算法在某个局部区域停止,而无法找到更好的解。 解决方案…...
深度学习中,什么是batch-size?如何设置?
什么是batch-size? batch-size 是深度学习模型在训练过程中一次性输入给模型的样本数量。它在训练过程中具有重要的意义,影响着训练速度、内存使用以及模型的稳定性等方面。 以下是 batch-size 大小的一些影响和意义: 训练速度:较大的 bat…...
[保研/考研机试] KY26 10进制 VS 2进制 清华大学复试上机题 C++实现
题目链接: 10进制 VS 2进制http://www.nowcoder.com/share/jump/437195121691738172415 描述 对于一个十进制数A,将A转换为二进制数,然后按位逆序排列,再转换为十进制数B,我们称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(JavaServer Pages)是一种…...
Golang协程,通道详解
进程、线程以及并行、并发 关于进程和线程 进程(Process)就是程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位,进程是一个动态概念,是程序在执行过程中分配和管理资源的基本单位,每一…...
unity 之 Vector 数据类型
文章目录 Vector 1Vector 2Vector 3Vector 4 Vector 1 在Unity中,Vector1 并不是一个常见的向量类型。 如果您需要表示标量(单个值)或者只需要一维的数据,通常会直接使用浮点数(float)或整数(in…...
私密数据采集:隧道爬虫IP技术的保密性能力探究
作为一名专业的爬虫程序员,今天要和大家分享一个关键的技术,它能够为私密数据采集提供保密性能力——隧道爬虫IP技术。如果你在进行敏感数据采集任务时需要保护数据的私密性,那么这项技术将是你的守护神。 在进行私密数据采集任务时ÿ…...
使用git rebase 之后的如何恢复到原始状态
我们常常喜欢使用git rebase去切换分支提交代码,操作流程就是: 先切换分支:比如当前是master 我们修改了一堆代码产生一个commit id :5555555567777 那么我们常常比较懒就直接切换了:git checkout dev 然后呢?使用命令git rebase 5555555567777,想把这笔修改提交到d…...
matlab相机标定知识整理
matlab相机标定知识整理 单目相机标定 单目相机标定 内参矩阵:cameraParams.Intrinsics.K 或者 cameraParams.K旋转矩阵:cameraParams.RotationMatrices 有待确定 cameraParams.RotationVectors平移矩阵:cameraParams.TranslationVectors径向…...
win11安装ubuntu 子系统安装过程及注意事项
第一步 :安装系统必须组件 由于子系统是系统自带组件,需要安装软件支持 第二步:应用商店安装 ubuntu 编辑 编辑 这个时候打开会报错 第三步,运行linux子系统 选择Windows PowerShell 以管理员身份运行) 输入&#…...
torch.cat((A,B),dim=1)解析
官方说明torch.cat 引用自:Pytorch中的torch.cat()函数 torch.cat(tensors, dim0, *, outNone) → Tensor # 连接给定维数的给定序列的序列张量。所有张量要么具有相同的形状(除了连接维度),要么为空。示例 输入: import torch a torch.Tens…...
apache配置安全证书https踩坑记录
apache配置安全证书有如下几步 一、申请证书 这个网上有很多免费的,我用的是阿里云的服务器,在阿里云后台就可以申请免费证书。 二、上传证书 申请好证书后,根据服务器用的什么软件,是apache还是ngnix,下载相应的证书…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
实战三:开发网页端界面完成黑白视频转为彩色视频
一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 二、实现思路 总体思路: 用户通过Gradio界面上…...
【HarmonyOS 5】鸿蒙中Stage模型与FA模型详解
一、前言 在HarmonyOS 5的应用开发模型中,featureAbility是旧版FA模型(Feature Ability)的用法,Stage模型已采用全新的应用架构,推荐使用组件化的上下文获取方式,而非依赖featureAbility。 FA大概是API7之…...
