正点原子FreeRTOS学习笔记——列表与列表项

目录

一、什么是列表和列表项

1、概念

2、FreeRTOS代码

(1)列表

(2)列表项

(3)迷你列表项 

二、列表与列表项初始化

1、列表初始化

2、列表项初始化

三、列表插入与删除列表项

1、原理解释

2、升序插入列表项

3、末尾插入列表项

4、移除列表项


一、什么是列表和列表项

1、概念

在FreeRTOS中,有三个列表分别是就绪列表、阻塞列表与挂起列表。当任务状态改变就会迁移到其他列表中。

列表是一个双向环形链表,而链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。链表可以任意的插入与删除节点,并且不限制元素的数量。

列表项是存放在列表中的项目,用来存放FreeRTOS中的任务。

以右图举例,三个人组成的整体就作为一个列表,而每个人是这个列表中的列表项。列表项之间地址是非连续,是人为的连接到一起的。是依靠列表项中的pxNext(指向下一个地址指针)、pxPrevious(指向上一个地址指针)互相连接。相当于右图中的胳膊互相拉着。     

2、FreeRTOS代码

(1)列表

typedef struct xLIST
{listFIRST_LIST_INTEGRITY_CHECK_VALUE      /*用来检测列表完整性*/volatile UBaseType_t uxNumberOfItems;     /*列表中列表项个数*/ListItem_t * configLIST_VOLATILE pxIndex; /*指向列表项的指针 */MiniListItem_t xListEnd;                  /*末尾列表项,由迷你列表项定义*/listSECOND_LIST_INTEGRITY_CHECK_VALUE     /*用来检测列表完整性*/
} List_t;

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

(3)迷你列表项 

struct xMINI_LIST_ITEM
{listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */configLIST_VOLATILE TickType_t xItemValue;struct xLIST_ITEM * configLIST_VOLATILE pxNext;struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
};
typedef struct xMINI_LIST_ITEM MiniListItem_t;

                                                                                                                                                           

二、列表与列表项初始化

1、列表初始化

#define portMAX_DELAY    ( TickType_t ) 0xffffffffUL/*形参:待初始化列表*/
void vListInitialise( List_t * const pxList ) 
{/*列表的pxIndex指向末尾列表项*/pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );/*将末尾列表项数值设为最大*/pxList->xListEnd.xItemValue = portMAX_DELAY;/*列表的末尾列表项上一个下一个都指向自己,因为初始化只有末尾列表项*/pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );     pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*列表中列表项个数设为0,末尾列表项不计入*/pxList->uxNumberOfItems = ( UBaseType_t ) 0U;/*检测数据完整性*/listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
}

2、列表项初始化

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

                                                                                                                                                            

三、列表插入与删除列表项

1、原理解释

在小红和小黑之间加入小蓝。小红的pxNext对应小黑,小黑的pxPrevious对应小红。现在小蓝加入列表之中,小红先把pxNext接上小蓝,小蓝把pxPrevious接上小红,小蓝就和小红牵上手;小黑把pxPrevious接上小蓝,小蓝又把pxNext接上小黑,小蓝就和小黑牵上手。这样小蓝这个列表项就加入到列表之中。

2、升序插入列表项

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 )//是末尾列表项{   /* 插入的位置为末尾列表项前面*/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 )++;
}

3、末尾插入列表项

形参:待插入的列表,插入列表项
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;/* 更新待插入列表项的所在成员变量 */pxNewListItem->pxContainer = pxList;/* 更新列表中列表项的数量 */( pxList->uxNumberOfItems )++;
}

4、移除列表项

形参:待移除的列表项
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
{/* 获取所在的列表 */List_t * const pxList = pxItemToRemove->pxContainer;/* 从列表中移除列表项 */pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;/* Only used during decision coverage testing. */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;
}

                                                                                                                                                            

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

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

相关文章

详解xlsxwriter 操作Excel的常用API

我们知道可以通过pandas 对excel 中的数据进行处理分析&#xff0c;但是pandas本身对格式化数据方面提供了很少的支持&#xff0c;如果我们想对pandas进行数据分析后的数据进行格式化相关操作&#xff0c;我们可以使用xlsxwriter&#xff0c;本文就对xlsxwriter的常见excel格式…

从0到1,百亿级任务调度平台的架构与实现

尼恩&#xff1a;百亿级海量任务调度平台起源 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;经常性的指导小伙伴们改造简历。 经过尼恩的改造之后&#xff0c;很多小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试机会&#x…

28、查看Qt源码

一、方法1 在安装Qt时&#xff0c;需要勾选“Sources” 在Qt的安装目录Qt5.12.10\5.12.10\Src中可以找到Qt的源码 二、方法2 访问如下网址&#xff08;需要翻墙&#xff09; https://codebrowser.dev/ 在搜索框中输入要查找的信息&#xff0c;如&#xff1a;QMainWindow&…

中腾食品上海食堂承包创新食堂空间,构建企业第三文化沙龙

在快节奏的现代职场生活中&#xff0c;企业食堂已不再是简单的餐饮供应地&#xff0c;而是逐渐演变成为员工休息休闲、互动体验、阅读思考的重要场所。中腾国际团餐产业集团通过专业的定制化食堂承包&#xff0c;在企业食堂内部打造企业第三文化空间&#xff0c;为员工提供一个…

机器视觉中的打光技巧、选择光源的流程

目录 基本原则选择照明的考虑因素明场照明和暗场照明全明场照明&#xff08;漫射照明&#xff09;技术 特定光源1. 环形光源2. 条形光源3. 同轴光源3.1 何时使用同轴照明&#xff1f;3.2 何时不使用同轴照明&#xff1f; 4. 背光源5. 远心照明6. 点光源7. 穹顶光源8. 线光源9. …

Mixtral

文章目录 一、关于 MixtralMistral AI、 La PlateformeMistral AI LLMs 二、Mistral AI API账户设置 三、Mixtral 说明通过稀疏架构推动开放模型的前沿表现Instructed 模型使用开源部署堆栈部署 Mixtral在我们的平台上使用 Mixtral。 一、关于 Mixtral 官网&#xff1a;https:…

网站有存在哪些类型的漏洞,网站漏洞存在哪些危害,该怎么解决网站漏洞问题

在数字化日益发展的今天&#xff0c;随着互联网的普及和深入&#xff0c;网站安全已成为企业、组织乃至个人都必须高度重视的安全问题。而网站漏洞作为威胁网站安全的重要因素之一&#xff0c;其类型多种多样&#xff0c;不仅可能导致数据泄露、系统崩溃&#xff0c;还可能为黑…

在 Cython 中高效访问 scipy lil_matrix

在 Cython 中高效地访问 scipy 的 lil_matrix&#xff08;LInked List format&#xff09;可以通过以下步骤实现&#xff1a; 导入所需的模块&#xff1a; 首先&#xff0c;导入必要的模块&#xff0c;包括 numpy 和 scipy.sparse 中的 lil_matrix。定义函数原型&#xff1a; …

Python邮件处理库之flanker使用详解

概要 Flanker是一个开源的邮件处理库,专门设计用于解析、验证和构建电子邮件地址和MIME消息。由Mailgun开发,它旨在提高邮件处理的效率和准确性,尤其适用于需要高效邮件验证和解析的应用程序。 安装 安装Flanker非常简单,可以通过Python的包管理器pip进行安装: pip ins…

基于uniapp+vue3+ts开发微信小程序项目实战

&#x1f680; 作者 &#xff1a;“二当家-小D” &#x1f680; 博主简介&#xff1a;⭐前荔枝FM架构师、阿里资深工程师||曾任职于阿里巴巴担任多个项目负责人&#xff0c;8年开发架构经验&#xff0c;精通java,擅长分布式高并发架构,自动化压力测试&#xff0c;微服务容器化k…

重磅消息!OpenAI取消短信验证码注册账号!

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

Leetcode—3148. 矩阵中的最大得分【中等】

2024每日刷题&#xff08;137&#xff09; Leetcode—3148. 矩阵中的最大得分 算法思想 实现代码 class Solution { public:int maxScore(vector<vector<int>>& grid) {int m grid.size();int n grid[0].size();int ans INT_MIN;vector<vector<int&…

Elasticsearch 在滴滴的应用与实践

滴滴 Elasticsearch 简介 简介 Elasticsearch 是一个基于 Lucene 构建的开源、分布式、RESTful 接口的全文搜索引擎&#xff0c;其每个字段均可被索引&#xff0c;且能够横向扩展至数以百计的服务器存储以及处理 TB 级的数据&#xff0c;其可以在极短的时间内存储、搜索和分析大…

用HAL库改写江科大的stm32入门例子4-1 OLED

大体 步骤&#xff1a; step1&#xff1a;使用STM32CubeMX初始化I2C1&#xff0c;生成初始化代码 step2&#xff1a;将任意一个库导入到工程&#xff0c;配置好编译路径 step3&#xff1a;调用函数即可 IIC原理图&#xff1a; 接线图&#xff1a; 先设置clock&#xff1a; 开…

Vue3使用datav3报错的三个问题解决

我这里写的是按需引入 报错问题Cannot find module dataview/datav-vue3 修改datav源码中的package.json文件 修改为 "module": "./es/index.mjs", 然就就会遇见新的报错问题 报错问题TypeError: Cannot read properties of null (reading $el) 然后修改…

【源码+文档+调试讲解】微信小程序家政项目小程序

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了微信小程序家政项目小程序的开发全过程。通过分析微信小程序家政项目小程序管理的不足&#xff0c;创建了一个计算机管理微信小程序家政项目小程序的方案。文章介…

GPT 4o意味着什么?OpenAI加苹果,AI手机势不可挡!

ChatGPT带飞Siri? 当地时间5月13日上午10点&#xff0c;OpenAI在春季发布会上发布了GPT-4的迭代版本——GPT-4o。据悉&#xff0c;GPT-4o的速度是上一代的两倍&#xff0c;并且对用户更友好&#xff1a;语音唤起、实时对话、无需注册、免费使用。 OpenAI表示&#xff0c;GPT…

AR项目开发的技术难点

AR项目开发涉及多种技术&#xff0c;例如计算机视觉、图形学、传感器融合和人机交互。因此&#xff0c;AR项目开发存在以下难点&#xff0c;AR项目开发是一项具有挑战性的工作。但是&#xff0c;随着技术的进步和标准的完善&#xff0c;AR项目开发将会变得更加容易。北京木奇移…

Milvus 快速入门

引言 在本篇文章中&#xff0c;我们将介绍 Milvus 的基本概念&#xff0c;并通过一个简单的示例展示如何在 Milvus 中创建集合、插入向量和执行搜索。最后&#xff0c;我们将概览 Milvus 提供的 API。 一、基本概念 1.1 集合 (Collection) 在 Milvus 中&#xff0c;集合类似…

12.snmp协议监控

snmp协议监控 安装snmp服务器端 yum install net-snmp -y服务器端&#xff1a;配置&#xff08;centos&#xff09; vim /etc/snmp/snmpd.conf com2sec notConfigUser default public view systemview included .1服务器端&#xff1a;配置&#xff0c;瑞数防护系统botgate&…