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

《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 */
}

初始化列表中插入列表项值为40的列表项
列表中插入列表项值为60的列表项
列表中插入列表项值为50的列表项

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 )++;
}

默认列表
在默认列表中进行末尾插入列表项值为30的列表项
在这里插入图片描述

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;
}

列表删除列表项2

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. 什么是列表和列表项&#xff1f;1.1 列表list1.2 列表项list item 2. 列表和列表项的初始化2.1 列表的初始化2.2 列表项的初始化 3. 列表项的插入4. 列表项末尾插入5. 列表项的删除6. 列表的遍历 列表和列表项是FreeRTOS的一个数据结构&#xff0c;是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 &#xff0c;支持 cv180x、cv81x、sg200x 系列的芯片。 SG2002 简介 SG2002 是面向边缘智能监控 IP 摄像机、智能猫眼门锁、可视门铃、居家智能等多项产品领域而推出的高性能、低功耗芯片&a…...

LLM - 使用 LLaMA-Factory 微调大模型 Qwen2-VL SFT(LoRA) 图像数据集 教程 (2)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/143725947 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 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. 引言 随着人工智能技术的迅猛发展&#xff0c;企业协同办公领域迎来了新的变革。钉钉作为阿里巴巴集团旗下的企业级通讯与协同办公平台&#xff0c;推出了钉钉AI助理&#xff0c;旨在提高工作效率&#xff0c;优化用户体验。本报告将对钉钉AI助理进行全面的产品体验分析&am…...

2020年计挑赛往届真题(C++)

因为17号要开赛了&#xff0c;甚至是用云端编辑器&#xff0c;debuff拉满&#xff0c;只能临时抱佛脚了 各个选择题的选择项我就不标出来了&#xff0c;默认ABCD排&#xff0c;手打太麻烦了 目录 单选题&#xff1a; 1.阅读以下语句:double m0;for(int i3;i>0;i--)m1/i;…...

ES6进阶知识二

一、promise方法的案例 Promise对象通过new Promise()语法创建&#xff0c;它接受一个函数作为参数&#xff0c;该函数接受两个参数&#xff1a;resolve和reject。resolve表示异步操作成功&#xff0c;reject表示异步操作失败。 案例&#xff1a;异步加载图片 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&#xff08;20241022&#xff09; Anthropic 70.88 82.4…...

第六节、Docker 方式部署指南 github 上项目 mkdocs-material

一、简介 MkDocs 可以同时编译多个 markdown 文件,形成书籍一样的文件。有多种主题供你选择,很适合项目使用。 MkDocs 是快速,简单和华丽的静态网站生成器,可以构建项目文档。文档源文件在 Markdown 编写,使用单个 YAML 配置文件配置。 MkDocs—markdown项目文档工具,…...

【MySQL】MySQL中的函数之JSON_REPLACE

在 MySQL 中&#xff0c;JSON_REPLACE() 函数用于在 JSON 文档中替换现有的值。如果指定的路径不存在&#xff0c;则 JSON_REPLACE() 不会修改 JSON 文档。如果需要添加新的键值对&#xff0c;可以使用 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 &#xff08;25&#xff09; 文章目录 C(Qt)软件调试---内存泄漏分析工具MTuner &#xff08;25&#xff09;[toc]1、概述&#x1f41c;2、下载MTuner&#x1fab2;3、使用MTuner分析qt程序内存泄漏&#x1f9a7;4、相关地址&#x1f41…...

python核心语法

目录 核⼼语法第⼀节 变量0.变量名规则1.下⾯这些都是不合法的变量名2.关键字3.变量赋值4.变量的销毁 第⼆节 数据类型0.数值1.字符串2.布尔值(boolean, bool)3.空值 None 核⼼语法 第⼀节 变量 变量的定义变量就是可变的量&#xff0c;对于⼀些有可能会经常变化的数据&#…...

MATLAB用CNN-LSTM神经网络的语音情感分类深度学习研究

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

智能网页内容截图工具:AI助力内容提取与可视化

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

Axure设计之文本编辑器制作教程

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

【MyBatis源码】深入分析TypeHandler原理和源码

&#x1f3ae; 作者主页&#xff1a;点击 &#x1f381; 完整专栏和代码&#xff1a;点击 &#x1f3e1; 博客主页&#xff1a;点击 文章目录 原始 JDBC 存在的问题自定义 TypeHandler 实现TypeHandler详解BaseTypeHandler类TypeReference类型参考器43个类型处理器类型注册表&a…...

号卡分销系统,号卡系统,物联网卡系统源码安装教程

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

大模型上下文窗口管理技巧:突破长度限制的艺术

大模型上下文窗口管理技巧&#xff1a;突破长度限制的艺术 前言 大模型的上下文窗口&#xff08;Context Window&#xff09;是指模型能够处理的最大输入长度。目前主流模型的上下文窗口从 4K 到 128K 不等&#xff0c;GPT-4 Turbo 甚至达到了 128K tokens。然而&#xff0c;随…...

公域卖课佣金高、粉丝留不住?这套私域打法,完课率提升了3倍

公域卖课的两大痛点痛点一&#xff1a;佣金太高&#xff0c;利润被吃掉一大块。相信在公域卖过课的朋友都有体会。平台抽成、分销佣金、投流成本……七七八八算下来&#xff0c;到手的钱可能连一半都不到。你辛辛苦苦打磨的课程&#xff0c;大头却被别人拿走了。这感觉&#xf…...

光猫拨号下,如何把二级路由器变成‘透明网桥’?一个设置让NAS、打印机全屋可见

光猫拨号下的家庭网络优化&#xff1a;二级路由器透明化实战指南 家里NAS里的电影在客厅电视上死活刷不出来&#xff1f;书房电脑找不到卧室的无线打印机&#xff1f;这些问题往往源于家庭网络中多台路由器形成的"局域网套娃"。本文将手把手教你如何将二级路由器转化…...

急救场景下的志愿者调度与AED就近匹配

急救场景下的志愿者调度与AED就近匹配——120急救通的设计思路 一、问题的起点&#xff1a;黄金4分钟 心脏骤停后&#xff0c;每延迟1分钟&#xff0c;存活率下降7%-10%。医学上公认的黄金抢救时间是4分钟。 而现实是&#xff1a;城市中120救护车平均到达时间超过10分钟&#x…...

从RTL到GDS:STA工程师的一天,如何用DC工具修复时序违例(以Setup Violation为例)

从RTL到GDS&#xff1a;STA工程师的一天&#xff0c;如何用DC工具修复时序违例&#xff08;以Setup Violation为例&#xff09; 时钟刚过上午9点&#xff0c;咖啡的香气弥漫在工位周围。作为数字后端工程师&#xff0c;我习惯在晨会前先快速扫描昨晚综合运行的日志文件。今天的…...

华为昇腾Atlas200边缘设备开箱即用指南:从CANN环境到YOLOv8模型部署的保姆级避坑教程

华为昇腾Atlas200边缘设备实战&#xff1a;YOLOv8模型部署全流程避坑指南 第一次拿到华为昇腾Atlas200边缘计算设备时&#xff0c;那种既兴奋又忐忑的心情记忆犹新。作为一款专为AI推理设计的边缘设备&#xff0c;Atlas200凭借其强大的算力和紧凑的体型&#xff0c;在智能安防…...

用Python和Matplotlib搞定高光谱图像可视化:从.mat文件到伪彩色图(附完整代码)

PythonMatplotlib高光谱图像可视化实战&#xff1a;从.mat文件到伪彩色合成 高光谱图像处理正逐渐从专业遥感领域走向更广泛的工业应用场景。当一位农业科技公司的算法工程师第一次拿到作物生长监测的高光谱数据时&#xff0c;面对.mat格式文件中那个神秘的三维矩阵&#xff0c…...

图吧工具箱下载安装和使用保姆级教程(2026实测)

图吧工具箱全名图拉丁吧硬件检测工具箱&#xff0c;简称 “图吧工具箱”&#xff0c;是国内硬件爱好者社区 “图拉丁吧” 开发维护的免费开源工具合集&#xff0c;2014 年首发&#xff0c;至今持续更新&#xff0c;是 DIY 玩家、装机员、普通用户公认的 “电脑硬件全能管家”。…...

深度观察:从静态路牌到智能交互,城市导视系统的三次进化

当我们谈论智慧城市时&#xff0c;往往会聚焦于自动驾驶、智慧安防、数字政务这些宏大的叙事&#xff0c;却常常忽略了一个最贴近普通人生活的基础设施 —— 导视系统。作为城市空间的 "无声语言"&#xff0c;导视系统连接着人与空间&#xff0c;影响着每一个人的出行…...

Linux内核同步机制:从原子操作到RCU的实战指南

1. 项目概述&#xff1a;为什么我们需要同步机制&#xff1f;想象一下&#xff0c;你正在一个繁忙的十字路口指挥交通。如果没有红绿灯和交通规则&#xff0c;车辆和行人随意穿行&#xff0c;结果必然是混乱、拥堵&#xff0c;甚至发生事故。在操作系统的核心——Linux内核中&a…...