《FreeRTOS列表和列表项篇》
FreeRTOS列表和列表项
- 1. 什么是列表和列表项?
- 1.1 列表list
- 1.2 列表项list item
- 2. 列表和列表项的初始化
- 2.1 列表的初始化
- 2.2 列表项的初始化
- 3. 列表项的插入
- 4. 列表项末尾插入
- 5. 列表项的删除
- 6. 列表的遍历
列表和列表项是FreeRTOS的一个数据结构,是FreeRTOS的基石。
1. 什么是列表和列表项?
1.1 列表list
- 列表在概念上类似双向链表,用来追踪FreeRTOS中的任务。
/** Definition of the type of queue used by the scheduler.* 任务调度器使用的队列的定义*/
typedef struct xLIST
{listFIRST_LIST_INTEGRITY_CHECK_VALUEvolatile UBaseType_t uxNumberOfItems; /* 用来记录列表中列表项的个数,其中不包含末尾列表项。 */ListItem_t * configLIST_VOLATILE pxIndex; /* 用来记录当前列表项的索引号,用于遍历列表。 */MiniListItem_t xListEnd; /* 末尾列表项(迷你列表项),用来表示列表的结束。 */listSECOND_LIST_INTEGRITY_CHECK_VALUE
} List_t;
1.2 列表项list item
- 列表项指存放在列表中的对象,FreeRTOS提供了2个类型:列表项和迷你列表项。
/** Definition of the only type of object that a list can contain.* 定义列表可以包含的唯一对象类型*/
struct xLIST_ITEM
{listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUEconfigLIST_VOLATILE TickType_t xItemValue; /* 列表项的值,这用于按升序对列表进行排序 */struct xLIST_ITEM * configLIST_VOLATILE pxNext; /* 指向下一个列表项 */struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /* 指向上一个列表项 */void * pvOwner; /* 指向包含列表项的对象(通常是TCB)的指针。*/struct xLIST * configLIST_VOLATILE pxContainer; /* 用来记录此列表项属于哪个列表。 */listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
};
typedef struct xLIST_ITEM ListItem_t;
#if ( configUSE_MINI_LIST_ITEM == 1 ) /* 若为1,则为普通列表项,若为0,则为迷你列表项。 */struct xMINI_LIST_ITEM{listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUEconfigLIST_VOLATILE TickType_t xItemValue; /* 列表项的值,这用于按升序对列表进行排序 */struct xLIST_ITEM * configLIST_VOLATILE pxNext; /* 指向下一个列表项 */struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /* 指向上一个列表项 */};typedef struct xMINI_LIST_ITEM MiniListItem_t;
#elsetypedef struct xLIST_ITEM MiniListItem_t;
#endif
2. 列表和列表项的初始化
2.1 列表的初始化
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. * 列表结构体中包含一个用于标记列表的结束的列表项(即末尾列表项)。* 为了初始化列表,末尾列表项被插入作为唯一的列表条目。*/pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /* 列表的列表项索引号指向末尾列表项。*/listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) );/* 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; /* 0xFFFFFFFFUL *//* 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 );pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/* Initialize the remaining fields of xListEnd when it is a proper ListItem_t * 当末尾列表项是普通列表项时,初始化其剩余字段。*/#if ( configUSE_MINI_LIST_ITEM == 0 ){pxList->xListEnd.pvOwner = NULL;pxList->xListEnd.pxContainer = NULL;listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) );}#endifpxList->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 );
}
2.2 列表项的初始化
- 列表项的初始化此处只对pxContainer设置了初始值,其他成员变量需要根据实际使用情况初始化。
void vListInitialiseItem( ListItem_t * const pxItem )
{/* Make sure the list item is not recorded as being on a list. * 确保列表项未被记录为在列表中。*/pxItem->pxContainer = NULL;listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
}
3. 列表项的插入
- 注意,列表项的常规插入方式,指的是在待插入的列表List中找到比待插入的列表项ListItem的列表项值xItemValue大的列表项前边插入该列表项,列表中的所有列表项是按照其列表项值的大小手拉手链接在一起的。
void vListInsert( List_t * const pxList, /* 决定列表项要插入到哪一个列表中。 */ListItem_t * const pxNewListItem ) /* 准备插入列表中的列表项。要插入的位置由列表项中的成员变量xItemValue决定 */
{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;}else{for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ){/* 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->pxContainer = pxList; /* 将列表项的成员变量pxContainer赋值为插入的列表。 */( pxList->uxNumberOfItems )++; /* 列表的列表项总个数自增1 */
}
4. 列表项末尾插入
- 注意,列表项末尾插入的方式,指的是在列表的成员变量pxIndex所指向位置的前边插入待插入的列表项,与列表项的列表项值没有关系。
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 );pxNewListItem->pxNext = pxIndex;pxNewListItem->pxPrevious = pxIndex->pxPrevious;mtCOVERAGE_TEST_DELAY();pxIndex->pxPrevious->pxNext = pxNewListItem;pxIndex->pxPrevious = pxNewListItem;/* Remember which list the item is in. */pxNewListItem->pxContainer = pxList;( pxList->uxNumberOfItems )++;
}
5. 列表项的删除
- 如果这个列表项是动态分配内存的,列表项的删除只是将指定的列表项从列表中删除掉,并不会将这个列表项的内存释放掉。
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();if( pxList->pxIndex == pxItemToRemove ){pxList->pxIndex = pxItemToRemove->pxPrevious;}else{mtCOVERAGE_TEST_MARKER();}pxItemToRemove->pxContainer = NULL;( pxList->uxNumberOfItems )--;return pxList->uxNumberOfItems;
}
6. 列表的遍历
- 列表结构体中的成员变量pxIndex是用来遍历列表的。
- FreeRTOS提供了一个函数来完成列表的遍历,函数是listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )。每调用一次这个函数,列表的pxIndex变量就会指向下一个列表项,并且返回这个列表项的pvOwner变量值。
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \{ \List_t * const pxConstList = ( pxList ); \/* Increment the index to the next item and return the item, ensuring */ \/* we don't return the marker used at the end of the list. */ \( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \{ \( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \} \( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \}
相关文章:

《FreeRTOS列表和列表项篇》
FreeRTOS列表和列表项 1. 什么是列表和列表项?1.1 列表list1.2 列表项list item 2. 列表和列表项的初始化2.1 列表的初始化2.2 列表项的初始化 3. 列表项的插入4. 列表项末尾插入5. 列表项的删除6. 列表的遍历 列表和列表项是FreeRTOS的一个数据结构,是F…...

C++:哈希拓展-位图
目录 一.问题导入 二.什么是位图? 2.1如何确定目标数在哪个比特位? 2.2如何存放高低位 2.3位图模拟代码实现 2.3.1如何标记一个数 2.3.2如何重置标记 2.3.3如何检查一个数是否被标记 整体代码实现 标准库的Bitset 库中的bitset的缺陷 简单应用 一.问题导入 这道…...

【数据结构与算法】查找
文章目录 一.查找二.线性结构的查找2.1顺序查找2.2折半查找2.3分块查找 三.树型结构的查找3.1二叉排序树1.定义2.二叉排序树的常见操作3.性能分析 3.2平衡二叉树1.定义2.平衡二叉树的常见操作3.性能分析 3.3B树1.定义2.B树的相关操作 3.4B树1.定义2.B树与B树的比较 四.散列表1.…...

从零开始学习 sg200x 多核开发之 milkv-duo256 编译运行 sophpi
sophpi 是 算能官方针对 sg200x 系列的 SDK 仓库 https://github.com/sophgo/sophpi ,支持 cv180x、cv81x、sg200x 系列的芯片。 SG2002 简介 SG2002 是面向边缘智能监控 IP 摄像机、智能猫眼门锁、可视门铃、居家智能等多项产品领域而推出的高性能、低功耗芯片&a…...

LLM - 使用 LLaMA-Factory 微调大模型 Qwen2-VL SFT(LoRA) 图像数据集 教程 (2)
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/143725947 免责声明:本文来源于个人知识与公开资料,仅用于学术交流,欢迎讨论,不支持转载。 LLaMA-…...
基于STM32设计的大棚育苗管理系统(4G+华为云IOT)_265
文章目录 一、前言1.1 项目介绍【1】项目开发背景【2】设计实现的功能【3】项目硬件模块组成【4】设计意义【5】国内外研究现状【6】摘要1.2 设计思路1.3 系统功能总结1.4 开发工具的选择【1】设备端开发【2】上位机开发1.5 参考文献1.6 系统框架图1.7 系统原理图1.8 实物图1.9…...

深入浅出《钉钉AI》产品体验报告
1. 引言 随着人工智能技术的迅猛发展,企业协同办公领域迎来了新的变革。钉钉作为阿里巴巴集团旗下的企业级通讯与协同办公平台,推出了钉钉AI助理,旨在提高工作效率,优化用户体验。本报告将对钉钉AI助理进行全面的产品体验分析&am…...
2020年计挑赛往届真题(C++)
因为17号要开赛了,甚至是用云端编辑器,debuff拉满,只能临时抱佛脚了 各个选择题的选择项我就不标出来了,默认ABCD排,手打太麻烦了 目录 单选题: 1.阅读以下语句:double m0;for(int i3;i>0;i--)m1/i;…...
ES6进阶知识二
一、promise方法的案例 Promise对象通过new Promise()语法创建,它接受一个函数作为参数,该函数接受两个参数:resolve和reject。resolve表示异步操作成功,reject表示异步操作失败。 案例:异步加载图片 const loadIma…...
大语言模型通用能力排行榜(2024年10月8日更新)
数据来源SuperCLUE 榜单数据为通用能力排行榜 排名 模型名称 机构 总分 理科 文科 Hard 使用方式 发布日期 - o1-preview OpenAI 75.85 86.07 76.6 64.89 API 2024年11月8日 - Claude 3.5 Sonnet(20241022) Anthropic 70.88 82.4…...

第六节、Docker 方式部署指南 github 上项目 mkdocs-material
一、简介 MkDocs 可以同时编译多个 markdown 文件,形成书籍一样的文件。有多种主题供你选择,很适合项目使用。 MkDocs 是快速,简单和华丽的静态网站生成器,可以构建项目文档。文档源文件在 Markdown 编写,使用单个 YAML 配置文件配置。 MkDocs—markdown项目文档工具,…...
【MySQL】MySQL中的函数之JSON_REPLACE
在 MySQL 中,JSON_REPLACE() 函数用于在 JSON 文档中替换现有的值。如果指定的路径不存在,则 JSON_REPLACE() 不会修改 JSON 文档。如果需要添加新的键值对,可以使用 JSON_SET() 函数。 基本语法 JSON_REPLACE(json_doc, path, val[, path,…...
【大数据学习 | HBASE高级】hbase的API操作
首先引入hbase的依赖 <dependencies><dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-server</artifactId><version>2.4.13</version></dependency><dependency><groupId>org.slf4j<…...

C++(Qt)软件调试---内存泄漏分析工具MTuner (25)
C(Qt)软件调试—内存泄漏分析工具MTuner (25) 文章目录 C(Qt)软件调试---内存泄漏分析工具MTuner (25)[toc]1、概述🐜2、下载MTuner🪲3、使用MTuner分析qt程序内存泄漏🦧4、相关地址ὁ…...
python核心语法
目录 核⼼语法第⼀节 变量0.变量名规则1.下⾯这些都是不合法的变量名2.关键字3.变量赋值4.变量的销毁 第⼆节 数据类型0.数值1.字符串2.布尔值(boolean, bool)3.空值 None 核⼼语法 第⼀节 变量 变量的定义变量就是可变的量,对于⼀些有可能会经常变化的数据&#…...

MATLAB用CNN-LSTM神经网络的语音情感分类深度学习研究
全文链接:https://tecdat.cn/?p38258 在语音处理领域,对语音情感的分类是一个重要的研究方向。本文将介绍如何通过结合二维卷积神经网络(2 - D CNN)和长短期记忆网络(LSTM)构建一个用于语音分类任务的网络…...

智能网页内容截图工具:AI助力内容提取与可视化
我们每天都会接触到大量的网页内容。然而,如何从这些内容中快速提取关键信息,并有效地进行整理和分享,一直是困扰我们的问题。本文将介绍一款我近期完成的基于AI技术的智能网页内容截图工具,它能够自动分析网页内容,截…...

Axure设计之文本编辑器制作教程
文本编辑器是一个功能强大的工具,允许用户在图形界面中创建和编辑文本的格式和布局,如字体样式、大小、颜色、对齐方式等,在Web端实际项目中,文本编辑器的使用非常频繁。以下是在Axure中模拟web端富文本编辑器,来制作文…...

【MyBatis源码】深入分析TypeHandler原理和源码
🎮 作者主页:点击 🎁 完整专栏和代码:点击 🏡 博客主页:点击 文章目录 原始 JDBC 存在的问题自定义 TypeHandler 实现TypeHandler详解BaseTypeHandler类TypeReference类型参考器43个类型处理器类型注册表&a…...

号卡分销系统,号卡系统,物联网卡系统源码安装教程
号卡分销系统,号卡系统,物联网卡系统,,实现的高性能(PHP协程、PHP微服务)、高灵活性、前后端分离(后台),PHP 持久化框架,助力管理系统敏捷开发,长期持续更新中。 主要特性 基于Auth验证的权限…...

业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...

大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...