FreeRTOS的列表和列表项

news2024/11/18 5:44:14

目录

列表和列表项的简介

列表和列表项的关系

列表相关API函数介绍

函数vListInitialiseI()

函数vListInitialiseItem()

 函数vListInsert()

函数vListInsertEnd()

函数uxListRemove()


列表和列表项的简介

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

 列表相当于链表,列表项相当于节点,FreeRTOS中的列表是一个双向环形链表。

列表的特点:列表项间的地址是非连续的,是人为连接到一起的,列表项的数目是由后期添加的个数决定的,随时可以改变。

数组的特点:数组成员地址是连续的,数组在最初确定了成员数量后期无法改变。

在OS中任务的数量是不确定的,并且任务状态是会发生改变的,所以非常适合用列表(链表)这种数据结构。

有关于列表的东西均在文件list.c和list.h中,首先看list.h中的和列表相关的结构体:

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;

 列表结构示意图:

1、在该结构体中,包含了两个宏,这两个宏是确定的已知常量,FreeRTOS通过检查这两个常量的值,来判断列表的数据在程序运行过程中,是否遭受到破坏,该功能一般用于调试,默认是不开启的。

2、成员 uxNumberOfitems,用于记录列表中列表项的个数( 不包含xListEnd)

3、成员pxIndex用于指向列表中的某个列表项,一般用于遍历列表中的所有列表项。

4、成员变量xListEnd是一个迷你列表项,排在最末尾。

列表项

列表项是列表中用于存放数据的地方,在List.h文件中,有关列表项的相关结构体定义:

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;            

列表项结构示意图

 1、成员变量xItemValue为列表项的值,这个值多用于按升序对列表中的列表项进行排序。

2、成员变量pxNext和pxPrevious分别用于指向列表中列表项的下一个列表项和上一个列表项。

3、成员变量pxOwner用于指向包含列表项的对象(通常是任务控制块)

4、成员变量pxContainer用于指向列表项所在列表

迷你列表项

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;

 迷你列表项的结构示意图

由名字就可以知道,迷你列表项就是比列表项少了一些东西,即少了一些结构体变量。

 1、成员变量xItemValue为列表项的值,这个值多用于按升序对列表中的列表项进行排序。

2、成员变量pxNext和pxPrevious分别用于指向列表中列表项的下一个列表项和上一个列表项

3、迷你列表项只用于标记列表的末尾和挂载其他插入列表中的列表项,因此不需要成员变量pxOwner和pxContainer,以节省内存开销。、

列表和列表项的关系

列表初始状态,以及即将插入的两个列表项如下:

列表即相当于一个链表,列表项相当于链表中的节点,其中,插入列表项相当于形成一个双向循环链表。

列表相关API函数介绍

函数      描述
vListInitialise()       初始化列表
vListInitialiseItem()初始化列表项
vListInsertEnd()列表末尾插入列表项
vListInsert()列表插入列表项
uxListRemove()列表移除列表项

函数vListInitialiseI()

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

上述函数中的形参为pxList,即待初始化列表

函数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 );
}

 函数vListInsert()

每个列表项对象从结构体中都可以看出来有一个列表项值(xItemValue),通常是一个被追踪的任务优先级或是一个调度事件的计数器值。调用API函数vListInsert可以将pxNewListItem指向的列表项插入到pxList指向的列表中,列表项在列表的位置由pxNewListItem->xItemValue决定,按照升序排列。

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 ) 
        {
            /* 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;

    ( pxList->uxNumberOfItems )++;
}

函数vListInsert(0,是将待插入列表的列表项按照列表项的升序进行排列,有序的插入到列表中,这是一种有序插入。 

函数vListInsertEnd()

void vListInsertEnd( List_t * const pxList,
                     ListItem_t * const pxNewListItem )
{
    /*获取列表pxIndex指向的列表项*/
    ListItem_t * const pxIndex = pxList->pxIndex;

    /* Only effective when configASSERT() is also defined, these tests may catch
     * the list data structures being overwritten in memory.  They will not catch
     * data errors caused by incorrect configuration or use of FreeRTOS. */
    listTEST_LIST_INTEGRITY( pxList );
    listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );

    /* 更新待插入列表项的指针成员变量*/
    pxNewListItem->pxNext = pxIndex;
    pxNewListItem->pxPrevious = pxIndex->pxPrevious;

    /* Only used during decision coverage testing. */
    mtCOVERAGE_TEST_DELAY();
    /*更新列表中原本列表项的指针成员变量*/
    pxIndex->pxPrevious->pxNext = pxNewListItem;
    pxIndex->pxPrevious = pxNewListItem;

    /* 更新待插入列表项的所在列表成员变量*/
    pxNewListItem->pxContainer = pxList;
    /*更新列表中列表项的数量*/
    ( pxList->uxNumberOfItems )++;
}

函数vListInsertEnd(),是将待插入的列表项插入到列表pxIndex指针指向的列表项前面;它是一种无序的插入方法。

函数uxListRemove()

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

参考相关博客

FreeRTOS高级篇1---FreeRTOS列表和列表项_研究是为了理解的博客-CSDN博客_freertos列表

 

 

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

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

相关文章

电脑的安全模式安全吗?如何进入安全模式?

“怎么进安全模式&#xff1f;”这条留言成功引起了驱动哥的注意。 在遇到电脑蓝屏、黑屏等系统问题的时候&#xff0c;如何在更安全且不损失电脑文件的情况下修复故障&#xff1f;系统早已为大家准备好了相应的修复策略。 没错&#xff01;电脑也有属于自己的Plan B——安全…

我工作5年测试才8K,应届生刚毕业就拿16K?凭什么

我从事手工测试五年了&#xff0c;还拿着8K的死工资&#xff0c;家里还几张嘴需要喂养&#xff0c;我很累&#xff0c;也很迷茫…【某个粉丝跟我的诉说】 为什么手工测试会迷茫呢&#xff1f; 自动化测试、性能测试倒是不会迷茫。 我认为手工测试的迷茫基于两个原因&#xf…

数据分析与SAS学习笔记5

DATALINES语句&#xff1a; 相当于CARS语句&#xff1b; 该语句必须是数据步的最后一条语句&#xff1b; MISSOVER处理&#xff1b; DATA TEMP; INFILE DATALINES MISSOVER; INPUT X Y Z; DATALINES; 1 10 100 2 20 3 30 300 ; PROC PRINT; RUN; 代码说明&#xff1a; 1&am…

生物信息场景下的用户需求

背景分析概念定义基因测序是一种新型基因检测技术&#xff0c;是基因检测的方法之一&#xff0c;其又叫基因谱测序&#xff0c;是国际上公认的一种基因检测标准。基因测序技术能锁定病变基因&#xff0c;提前预防和治疗。过长的测序周期以及上万美元的仪器成本&#xff0c;成了…

第二章:unity性能优化之drawcall优化-1

目录 前言&#xff1a; 一、什么是drawcall 二、如何合批 1、什么是合批&#xff1f; 2、静态批处理 1、什么是静态批处理&#xff1a; 2、静态合批的规则 3、动态批处理 4、GPU Instancing 1、GPU instancing的定义 2、编写支持GPU instancing Shader步骤 5、…

Blazor 托管模型 BlazorWebAssembly和Blazor Server

BlazorWebAssembly 应用 BlazorWebAssembly 应用使用基于 WebAssembly 的 .NET 运行时在浏览器中直接执行。 BlazorWebAssembly 应用的工作方式类似于 Angular 和 React 等前端 JavaScript 框架。 但不是编写 JavaScript&#xff0c;而是编写 C#。 .NET 运行时与应用、应用程序…

day18_常用API之String类丶Object类

String概述 java.lang.String 类代表字符串&#xff0c;String类定义的变量可以用于指向字符串对象&#xff0c;同时String类提供了很多操作字符串的功能&#xff0c;我们可以直接使用。Java 程序中的所有字符串文字&#xff08;例如“abc”&#xff09;都为此类的对象 特点:St…

【STM32笔记】低功耗模式下GPIO、外设、时钟省电配置避坑

【STM32笔记】低功耗模式下GPIO、外设、时钟省电配置避坑 前文&#xff1a; blog.csdn.net/weixin_53403301/article/details/128216064 【STM32笔记】HAL库低功耗模式配置&#xff08;ADC唤醒无法使用、低功耗模式无法烧录解决方案&#xff09; blog.csdn.net/weixin_534033…

最强找茬小程序

文章目录准备工作环境要求安装步骤效果展示源码下载最强找茬小程序&#xff0c;支持好友对战 准备工作 准备一个Linux系统的云服务器 centos7或ubuntu 安装宝塔面板&#xff08;不是必需的&#xff0c;建议安装这个&#xff09; 买一个域名&#xff0c;并配置ssl证书&#x…

NX二次开发编译时dll自动数字签名及拷贝

前言 在UG5.0开始&#xff0c;所有基于UG二次开发的DLL都要“签名”后才能被客户端上正版的NX调用。 一、基于C# 开发签名 1、添加资源文件 &#xff08;1&#xff09;项目类库上右键–>属性–>资源–>添加资源右边小三角–>添加现有文件–>切换到UG安装目录下…

Java SSM 笔记(一)重置版

Spring核心技术 **前置课程要求&#xff1a;**请各位小伙伴先完成《JavaWeb》篇、《Java 9-17新特性》篇视频教程之后&#xff0c;再来观看此教程。 **建议&#xff1a;**对Java开发还不是很熟悉的同学&#xff0c;最好先花费半个月到一个月时间大量地去编写小项目&#xff0…

Source lnsight工具的简单使用

多文件编程推荐用Source lnsight工具来进行编写 一、Source lnsight工具的简单使用 1、在桌面上新建一个文件夹factory&#xff0c;在文件夹里新建一个cat.c文件和si文件夹 2、打开Source lnsight工具&#xff0c;点击上方Project--->New Project 3、把文件夹factory中si文…

2023年初级会计职称考试《经济法基础》大纲变动内容

整体变动:2023年度考试大纲主要作了以下调整:1. 第四章中增加了增值税出口退税和地方教育附加相关内容;2. 第五章中增加了企业重组业务企业所得税处理&#xff0c;企业所得税特别纳税调整和纳税电报表相关内容;3. 第六章中增加了印花税相关内容。具体变动:第一章 总论无变化第二…

QML矩形(Rectangle)

Rectangle 用于绘制矩形 常见的属性&#xff1a; 填充颜色&#xff1a;纯色&#xff1a;color 渐变 &#xff1a;Gradient类 渐变的优先级大于纯色Gradient&#xff08;渐变色&#xff09;&#xff1a; 渐变由多种颜色定义&#xff0c;这些颜色将无缝混合&#xff0c…

【前端基础问题】浏览器调起桌面通知功能 Notification

浏览器调起桌面通知功能 Notification一、Notification二、注意事项三、使用步骤1、向用户发起权限请求2、调用 Notification API 进行推送消息四、完整代码五、效果一、Notification Notifications API 允许网页或应用程序在系统级别发送在页面外部显示的通知;这样即使应用程序…

【Servlet+Jsp+Mybatis+Maven】WEB图书馆管理系统

web图书馆管理系统一、绪论二、流程和其页面展示效果流程页面效果项目结构三、具体实现第一步&#xff1a;备数据库表第二步&#xff1a;编写登录前端代码第三步&#xff1a;利用过滤器处理安全问题第四步&#xff1a;控制层去实现相关调用第五步&#xff1a;实现持久化层与数据…

教你如何搭建人事OA-薪资管理系统,demo可分享

1、简介1.1、案例简介本文将介绍&#xff0c;如何搭建人事OA-薪资管理。1.2、应用场景根据设置薪资基础及考勤和绩效的数据计算得到各个员工工资详情。2、设置方法2.1、表单搭建1&#xff09;新建表单【工资表】&#xff0c;字段设置如下&#xff1b;名称类型名称类型人员资料分…

一款私有化部署的企业级在线文档和知识库

项目介绍基础说明&#xff1a;无忧企业文档是JVS体系下的一款企业协同在线文档&#xff0c;主要服务客群为企业用户&#xff0c;解决企业内部文档编辑、知识沉淀、知识协同等痛点。项目主要采用Java开发&#xff0c;基础框架采用JVS&#xff08;spring cloudVue&#xff09;适用…

基于微信小程序的一款小程序版知乎

从零开始开发的一款小程序&#xff0c;所以没有使用任何框架及UI库&#xff0c;记录一下本次开发中踩过的坑吧~展示效果(界面样式设计与交互来自iOS 4.8.0版本知乎App)&#xff1a;项目地址&#xff1a;https://download.csdn.net一、开始前的准备申请账号&#xff1a;根据小程…

钉钉配置事件订阅(Python)

钉钉配置事件订阅 0.需求分析 需要实现钉钉企业通讯录同步至企业微信通讯录&#xff0c;这就需要用到钉钉的事件与回调 1.配置应用 登陆开放平台 https://open-dev.dingtalk.com/去企业内部开发里面&#xff0c;先创建个应用&#xff0c;后面都借用这个应用来调接口 创建完…