FreeRTOS列表与列表项相关知识总结以及列表项的插入与删除实战

news2025/3/3 18:24:08

1.列表与列表项概念及结构体介绍

1.1列表项简介

列表相当于链表,列表项相当于节点,FreeRTOS 中的列表是一个双向环形链表
在这里插入图片描述

1.2 列表、列表项、迷你列表项结构体

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;
2)迷你结构体
迷你列表项也是列表项,但迷你列表项仅用于标记列表的末尾和挂载其他插入列表中的列表项
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;

2.列表相关API函数介绍

1)void vListInitialise(List_t * const pxList)
形参:pxList 待初始化列表项
描述:初始化列表,pxIndex 指向 xListEnd,xListEnd为oxFFFFFF
2)void vListInitialiseItem( ListItem_t * const pxItem )
形参: pxItem 带初始化列表项
描述: 初始化列表项,列表项所在列表为空,pxItem->pxContainer = NULL
3void vListInsertEnd ( List_t * const pxList , ListItem_t * const pxNewList)
形参:pxList 列表
pxNewListItem 待插入列表项 ,,无序的插入方法
描述:列表末尾插入列表项
4)void vListInsert ( List_t * const pxList , ListItem_t * const pxNewListItem )
形参:pxList 列表
pxNewListItem 待插入列表项
描述: 列表插入列表项,有序地插入到列表中
5)UBaseType_t uxListRemove ( ListItem_t * const pxItemToRemove )
形参:pxItemToRemove 待移除列表项
返回值:整数: 待移除列表项移除后,所在列表剩余列表项的数量
描述:列表移除列表项

3,列表项的插入和删除实验free_

3.1freertos_demo.h

#ifndef __FREERTOS_DEMO_H
#define __FREERTOS_DEMO_H

//定义freeRTOS实验函数
void freertos_demo(void);

#endif

3.1freertos_demo.c


#include "freertos_demo.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"

///******************************************************************************************************/
//1.定义start_task配置与task任务配置以及声明列表项1.2.3
//1.1 start_task任务配置、包括栈大小、任务优先级、任务句柄以及start_task()函数定义
#define START_TASK_PRIO            1
#define START_STK_SIZE           128
TaskHandle_t  g_start_task_handler;
void start_task(void* pvParameters);

//1.2 task1任务配置
#define TASK1_PRIO                 2
#define TASK1_SIZE               128
TaskHandle_t  g_task1_handler;
void task1(void* pvParameters);

//1.3 列表与列表项1、2、3声明
List_t           test_list;
ListItem_t     list_item1;
ListItem_t     list_item2;
ListItem_t     list_item3;


//2.创建freertos_demo()函数,在此函数中创建start_task任务,并开始任务调度
void freertos_demo(void)
{
    //2.1创建任务satrt_task
     xTaskCreate( (TaskFunction_t)    start_task,                //函数地址
                   (char *)           "start_task",              //函数名称
                   (uint16_t)         START_STK_SIZE,            //栈大小
                   (void *)           NULL,                      //传递给任务函数参数
                   (UBaseType_t)      START_TASK_PRIO,           //任务优先级
                   (TaskHandle_t *)   &g_start_task_handler );   //任务句柄
    //2.2 开启任务调度器
     vTaskStartScheduler();
}


//3.创建start_task()函数中创建任务task1,并删除start_task任务
void start_task(void* pvParameters)
{
    //3.2 设置临界代码保护
    taskENTER_CRITICAL();
    //3.1创建任务task1
       xTaskCreate( (TaskFunction_t)    task1,               //函数地址
                   (char *)            "task1",              //函数名称
                   (uint16_t)         TASK1_SIZE,            //栈大小
                   (void *)           NULL,                  //传递给任务函数参数
                   (UBaseType_t)      TASK1_PRIO,            //任务优先级
                   (TaskHandle_t *)   &g_task1_handler );    //任务句柄
    
    
    //3.3 删除任务start_task
     vTaskDelete(g_start_task_handler);
                   
     taskEXIT_CRITICAL();

}


//4.在task1()函数中进行列表项与列表项的初始化、地址打印、插入与删除
void task1(void* pvParameters)
{
    //4.1 初始化列表和列表项的地址
    vListInitialise(&test_list);
    vListInitialiseItem(&list_item1);
    vListInitialiseItem(&list_item2);
    vListInitialiseItem(&list_item3);
    //4.2打印列表和各列表项的地址
    printf("/**************第二步:打印列表和列表项的地址**************/\r\n");
    printf("项目\t\t\t地址\r\n");
    printf("test_list\t\t0x%p\t\r\n", &test_list);
    printf("test_list->pxIndex\t0x%p\t\r\n", test_list.pxIndex);
    printf("test_list->xListEnd\t0x%p\t\r\n", (&test_list.xListEnd));
    printf("list_item1\t\t0x%p\t\r\n", &list_item1);
    printf("list_item2\t\t0x%p\t\r\n", &list_item2);
    printf("list_item3\t\t0x%p\t\r\n", &list_item3);
    printf("/**************************结束***************************/\r\n");
    
    //4.3设置key0,插入列表项1,2,3,打印列表及列表项地址
    printf("按下KEY0键继续!\r\n\r\n\r\n");
    while(key_scan(0) != KEY0_PRES)
    {
        vTaskDelay(10);
    }
    printf("/**************第三步:插入列表项1,2,3打印列表和列表项的地址**************/\r\n");
    vListInsert(&test_list,&list_item1);
    vListInsert(&test_list,&list_item2);
    vListInsert(&test_list,&list_item3);
    
    printf("项目\t\t\t\t地址\r\n");
    printf("test_list->xListEnd->pxNext\t0x%p\r\n", (test_list.xListEnd.pxNext));
    printf("test_list->xListEnd->pxPrevious\t0x%p\r\n", (test_list.xListEnd.pxPrevious));
    printf("list_item1->pxNext\t\t0x%p\r\n",     (list_item1.pxNext));
    printf("list_item1->pxPrevious\t\t0x%p\r\n", (list_item1.pxPrevious));
    printf("list_item2->pxNext\t\t0x%p\r\n",     (list_item2.pxNext));
    printf("list_item2->pxPrevious\t\t0x%p\r\n", (list_item2.pxPrevious));
    printf("list_item3->pxNext\t\t0x%p\r\n",     (list_item3.pxNext));
    printf("list_item3->pxPrevious\t\t0x%p\r\n", (list_item3.pxPrevious));
    printf("/**************************结束***************************/\r\n");
    
    
    //4.4设置key0,删除列表项2,打印列表及列表项地址
    printf("按下KEY0键继续!\r\n\r\n\r\n");
    while(key_scan(0) != KEY0_PRES)
    {
        vTaskDelay(10);
    }
    printf("/*******************第六步:移除列表项2********************/\r\n");
    
    uxListRemove(&list_item2);
    
    printf("项目\t\t\t\t地址\r\n");
    printf("test_list->xListEnd->pxNext\t0x%p\r\n", (test_list.xListEnd.pxNext));
    printf("test_list->xListEnd->pxPrevious\t0x%p\r\n", (test_list.xListEnd.pxPrevious));
    printf("list_item1->pxNext\t\t0x%p\r\n", (list_item1.pxNext));
    printf("list_item1->pxNext\t\t0x%p\r\n", (list_item1.pxNext));
    printf("list_item3->pxPrevious\t\t0x%p\r\n", (list_item3.pxPrevious));
    printf("list_item3->pxPrevious\t\t0x%p\r\n", (list_item3.pxPrevious));
    printf("/**************************结束***************************/\r\n");
    //4.5设置key0,尾插法插入列表项3,打印列表及列表项地址
    printf("按下KEY0键继续!\r\n\r\n\r\n");
    while(key_scan(0) != KEY0_PRES)
    {
        vTaskDelay(10);
    }
    printf("/*******************第六步:尾差法插入列表项2********************/\r\n");
    
    vListInsertEnd(&test_list,&list_item2);
    
    printf("项目\t\t\t\t地址\r\n");
    printf("test_list->xListEnd->pxNext\t0x%p\r\n", (test_list.xListEnd.pxNext));
    printf("test_list->xListEnd->pxPrevious\t0x%p\r\n", (test_list.xListEnd.pxPrevious));
    printf("list_item1->pxNext\t\t0x%p\r\n", (list_item1.pxNext));
    printf("list_item1->pxNext\t\t0x%p\r\n", (list_item1.pxNext));
    printf("list_item3->pxPrevious\t\t0x%p\r\n", (list_item3.pxPrevious));
    printf("list_item3->pxPrevious\t\t0x%p\r\n", (list_item3.pxPrevious));
    printf("list_item2->pxPrevious\t\t0x%p\r\n", (list_item2.pxPrevious));
    printf("list_item2->pxPrevious\t\t0x%p\r\n", (list_item2.pxPrevious));
    printf("/**************************结束***************************/\r\n");
}

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

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

相关文章

我的 2023 年终总结

时间太瘦,指缝太宽,岁月就这样匆匆流逝,似乎年初许愿时的憧憬还在眼前,转瞬就到了年尾,对2023年做个简单的回顾吧 我的 2022 年终总结 我的 2019 年终总结 总结2022年展望2023年 2023年的目标 参与晋升,希望…

机器学习、人工智能、深度学习的关系

人工智能(Artificial Intelligence,AI) 人工智能范围很广,它是一门新的科学与工程,是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的技术科学,研究内容涵盖语音识别、图像识别、自然语言处理、智能搜索和…

ssm基于冲突动态监测算法的健身房预约系统的设计与实现论文

摘 要 传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此,在计算机上安装健身房预约系统软件来发挥其高效地信息处理的作用&#xff…

【哈希数组】697. 数组的度

697. 数组的度 解题思路 首先创建一个IndexMap 键表示元素 值表示一个列表List list存储该元素在数组的所有索引之后再次创建一个map1 针对上面的List 键表示列表的长度 值表示索引的差值遍历indexmap 将所有的list的长度 和 索引的差值存储遍历map1 找到最大的key 那么这个Ke…

MySQL:子查询

子查询 子查询是嵌套在较大查询中的 SQL 查询,也称内部查询或内部选择,包含子查询的语句也称为外部查询或外部选择。简单来说,子查询就是指将一个 select 查询(子查询)的结果作为另一个 SQL 语句(主查询&a…

C# 如何使用?、? 和 ??的区别和使用案例

目录 ? 运算符 使用案例 ?? 运算符 使用案例 总结 在 C# 中,? 和 ?? 运算符在处理 null 值时起着不同的作用,并且具有特定的使用场景。 ? 运算符 ? 运算符,也称为空条件运算符,在 C# 6.0 及更高版本中引入。它允许…

C语言实例_生成6位数的随机密码

一、前言 随着数字化时代的到来,人们在各个方面需要使用密码来保护个人隐私和敏感信息的安全。为了确保密码的安全性,密码应该是足够强大和难以猜测的,这就需要密码生成器来帮助用户生成高强度的随机密码。 随机密码生成器是一种计算机程序…

界面控件DevExpress v23.2全新发布 - 全新升级的UI本地化API

DevExpress拥有.NET开发需要的所有平台控件,包含600多个UI控件、报表平台、DevExpress Dashboard eXpressApp 框架、适用于 Visual Studio的CodeRush等一系列辅助工具。屡获大奖的软件开发平台DevExpress 今年第一个重要版本v23.1正式发布,该版本拥有众多…

给idea添加右键打开功能

添加文件夹右键程序打开 开始运行regedit 找到 HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\shell 1、右键shell目录新建项Idea 2、右键Idea新建command 3、选择Idea 右侧空白出新建字符串 名字为Icon 值填入idea的运行程序地址 4、选择command 默认项填入idea的运行…

kubeadm来搭建k8s集群。

我们采用了二进制包搭建出的k8s集群,本次我们采用更为简单的kubeadm的方式来搭建k8s集群。 二进制的搭建更适合50台主机以上的大集群,kubeadm更适合中小型企业的集群搭建 主机配置建议:2c 4G 主机节点 IP …

[年终总结]人生就是大闹一场

讲真的,感觉过去这一年的体验,非常精彩,哈哈哈哈 体验了 裸辞,并没有想象中那么可怕,也没有想象中那么焦虑 经历了 入职之后又被裁员,心情没有那么大的起伏 解锁了 深圳/佛山/珠海/澳门/昆明/大理/新疆/成都 ,见了很多人,碰撞出了很多 idea 体会了 没有目的的去做一件事情,是什…

20231231_小米音箱接入chatgpt

参考资料: GitHub - yihong0618/xiaogpt: Play ChatGPT and other LLM with Xiaomi AI Speaker 小爱音箱ChatGPT的折腾记录:win平台部署并运行成功_哔哩哔哩_bilibili GitHub - chatanywhere/GPT_API_free: Free ChatGPT API Key,免费Chat…

Unity Window安装包制作

Unity Window安装包制作 介绍一、RAR自解压方式1、找到Unity打包的可执行程序2.创建自解压文件3.配置设置4、最后点击确定等待压缩完成即可(默认生成位置为你选中文件右键点击添加到压缩文件时的路径) 二、Setup Factory工具安装制作Window安装包相关常用…

2023最新租号平台系统源码支持单独租用或合租使用

这是一款租号平台源码,采用常见的租号模式。目前网络上还很少见到此类类型的源码。 平台的主要功能如下: 支持单独租用或采用合租模式; 采用易支付通用接口进行支付; 添加邀请返利功能,以便站长更好地推广&#xf…

uniapp 安卓模拟器链接

下载genymotion 安装 配置adb路径 模拟端口设为 5307

进阶学习——Linux系统服务器硬件认识与RAID磁盘

目录 一、服务器知识补充 1.硬件 2.服务器常见故障 二、认识RAID 1.什么是RAID 2.RAID的优点 3.RAID的实现方式 三、RAID磁盘陈列 1.RAID 0 磁盘陈列介绍——RAID 0 2.RAID 1 磁盘陈列介绍——RAID 1 3.RAID 5 磁盘陈列介绍——RAID 5 4.RAID 6 磁盘陈列介绍——RA…

用通俗易懂的方式讲解大模型:LangChain Agent 原理解析

LangChain 是一个基于 LLM(大型语言模型)的编程框架,旨在帮助开发人员使用 LLM 构建端到端的应用程序。它提供了一套工具、组件和接口,可以简化创建由 LLM 和聊天模型提供支持的应用程序的过程。 LangChain 由几大组件构成&#…

03 HAL库下UART的使用

引言: 需要使用到的uart调试工具在文章最后的资料里面 题外话:uart和usart的区别 UART(Universal Asynchronous Receiver/Transmitter)和USART(Universal Synchronous/Asynchronous Receiver/Transmitter)…

Halcon腐蚀erosion_circle/erosion_rectanglel

Halcon腐蚀 文章目录 Halcon腐蚀 腐蚀操作是对所选区域进行“收缩”的一种操作,可以用于消除边缘和杂点。腐蚀区域的大小与结构元素的大小和形状相关。其原理是使用,个自定义的结构元素,如矩形、圆形等,在二值图像上进行类似于“滤…

最简单的基于 SDL2 的音频播放器

最简单的基于 SDL2 的音频播放器 最简单的基于 SDL2 的音频播放器正文工程文件下载 参考雷霄骅博士的文章,链接:最简单的基于FFMPEGSDL的音频播放器:拆分-解码器和播放器 最简单的基于 SDL2 的音频播放器 正文 SDL2 音频播放器实现了播放 …