FreeRTOS-任务间共享数据的管理框架

2023-05-16

本文章介绍一种在FreeRTOS项目中任务间共享数据的管理框架,思路比较简单

任务在更新和获取共享数据时利用互斥量进行上锁保护数据,操作完之后进行解锁,并且当共享数据使用setting()更新时调用对应的回调函数,后续可以根据回调函数判断数据是否发生变化来进行另外的程序操作。

框架实现的程序思路:

 一、回调函数接口

typedef void (*Callback)(EventType *ev); //回调函数指针

//事件类型枚举
typedef enum
{
    EV_NONE     = 0x00, 
    EV_UPDATED  = 0x01,    //数据更新
} EventType;

//回调相关结构体
typedef struct __attribute__((packed))  
{
    EventType  event; //回调事件
    Callback  cb;     //回调函数
} CallbackType;

创建回调函数要用到的队列,其他接口用到的信号量

static xQueueHandle mQueue;
static xSemaphoreHandle mMutex;

uint8_t CallbackInitialize(void)
{    
    mMutex = xSemaphoreCreateRecursiveMutex();
    if(mMutex == NULL)
    {
        return 1;
    }

    // Create event queue
    mQueue = xQueueCreate(20, sizeof(CallbackType));
    xQueueReset(mQueue);
}

注册回调函数接口,将对用的回调函数绑定回调handle

uint32_t CallbackRegister(CallbackType *handle, EventType event, Callback cb)
{
	handle->cb = cb;
	handle->event = event;
	return 0;
}

队列发送回handle接口

uint32_t CallbackQueue(CallbackType *handle)
{
	CallbackType callbackInfo;
	memcpy(&callbackInfo, handle, sizeof(CallbackType));
	uint32_t result = xQueueSend(mQueue, &callbackInfo, 0);
	return result; 
}

创建一个CallbackTask任务,用于轮询 队列接收回调handle并调用对应回调函数,避免回调函数中需要阻塞或者代码量过大影响到更新数据的任务

void CallbackTask(void * pvParameters)
{
    CallbackType evInfo;
    int limit = SEND_QUEUELENGTH;

    while(1)
    {
        if(xQueueReceive(mQueue, &evInfo, 0) == pdTRUE)
        {
            if(evInfo.cb != 0)
            {
                evInfo.cb(&evInfo.event); 
            }
        }
    }
}

二、Setting接口

互斥量上锁,将要更新的数据覆盖共享数据地址,调用CallbackQueue(),通过CallbackTask处理回调函数,最后互斥量解锁

uint32_t GlobalDataSet(CallbackType *handle,  uint8_t *srcdata,const void *dataIn, uint32_t offset,uint32_t size)
{
    // Lock
    xSemaphoreTakeRecursive(mMutex, portMAX_DELAY);
    //更新数据
    memcpy(srcdata + offset, dataIn, size);
    handle->event = EV_UPDATED;
    //触发回调函数
    CallbackQueue(handle);
    // unLock
    xSemaphoreGiveRecursive(mMutex);
    return 0;
}

三、Getting接口

互斥量上锁,取出共享数据,最后互斥量解锁

uint32_t GlobalDataGet(CallbackType *handle, const uint8_t *srcdata, void *datout, uint32_t offset,uint32_t size)
{
    // Lock
    xSemaphoreTakeRecursive(mMutex, portMAX_DELAY);
    //取出目标地址数据到放进来的地址
    memcpy(datout, srcdata + offset, size);
    // unLock
    xSemaphoreGiveRecursive(mMutex);
	return 0;
}

四、使用例程

将共享数据封装成结构体类型,方便数据管理

typedef struct __attribute__ ((__packed__)) 
{
	uint8_t data;
} Data1;//共享数据1

typedef struct __attribute__ ((__packed__)) 
{
	uint8_t data[2];
} Data2;//共享数据2

typedef struct __attribute__ ((__packed__)) 
{
	Data1 data1;
	Data2 data2;
} GloblaDataType;//共享数据结构体类型

static GloblaDataType global_data; //声明一个全局共享数据,用于提供接口的共享数据源地址
static CallbackType handle;       //声明一个全局数据的回调handle,用于回调函数

再次封装一次setting,getting接口,只需要定义一个·Data1,Data2类型的变量,将地址传进接口。传入&handle用于回调函数,使用offsetof()获取全局数据结构成员相对于结构开头的字节偏移量。

void GlobalData1Setting(Data1 *NewData)//更新data1数据
{
	GlobalDataSet(&handle,(uint8_t *)&global_data,(void *)NewData, offsetof(GloblaDataType, data1), sizeof(Data1));
}
void GlobalData1Getting(Data1 *NewData)//获取data1数据
{
	GlobalDataGet(&handle,(uint8_t *)&global_data,(void *)NewData, offsetof(GloblaDataType, data1), sizeof(Data1));
}

void GlobalData2Setting(Data2 *NewData)//更新Data2数据
{
	GlobalDataSet(&handle,(uint8_t *)&global_data,(void *)NewData, offsetof(GloblaDataType, data2), sizeof(Data2));
}
void GlobalData2Getting(Data2 *NewData)//获取data2数据
{
	GlobalDataGet(&handle,(uint8_t *)&global_data,(void *)NewData, offsetof(GloblaDataType, data2), sizeof(Data2));
}

注册回调函数GlobalDataUpdateCb(),在AppTask1和AppTask2中更新data1和data2,回调函数中打印data1和data2的值。

void GlobalDataUpdateCb(EventType *ev)
{
    Data1 data1;
    Data2 data2;
    GlobalData1Getting(&data1);
    GlobalData1Getting(&data2);
    PRINTF("GlobalData1Getting data1%d",data1);
    PRINTF("GlobalData2Getting data2%d,%d",data2[0],data2[1]);
}

void AppTask1(void * pvParameters)
{
    CallbackRegister(&GlobalDataUpdateCb);
    Data1 data1 = 1;
	while(1)
	{
        GlobalData1Setting(&data1);
    }
}

void AppTask2(void * pvParameters)
{
    Data2 data2 = {1,1};
    while(1)
	{
        GlobalData2Setting(&data2);
    }
}

五、总结

本文章只是简单的介绍这个任务间更新和获取数据的框架,可能在某些应用中才比较使用,在接口上可能对数据地址的偏移没有做保护,用于出现地址越界等情况,后续还会在应用中进行完善。

备注:本文章的编写思路来源于一个开源项目,如有侵权请联系删除文章。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FreeRTOS-任务间共享数据的管理框架 的相关文章

  • FreeRTOS快速上手

    FreeRTOS使用 一 源码下载和移植文件提取 1 1 源码下载 在网站https sourceforge net projects freertos 可以找到freertos最新的源码 1 2 移植文件提取 根据第一步 我们会得到一个f
  • 【FreeRTOS 信号量】互斥信号量

    互斥信号量与二值信号量类似 但是互斥信号量可以解决二值信号量出现的优先级翻转问题 解决办法就是优先级继承 普通互斥信号量创建及运行 参阅安富莱电子demo 互斥信号量句柄 static SemaphoreHandle t xMutex NU
  • FreeRTOS记录(七、FreeRTOS信号量、事件标志组、邮箱和消息队列、任务通知的关系)

    我们在前面单独介绍过FreeRTOS的任务通知和消息队列 但是在FreeRTOS中任务间的通讯还有信号量 邮箱 事件组标志等可以使用 这篇文章就这些成员与消息队列和任务通知的关系进行说明分析 增加邮箱部分 任务通知发送消息 Demo 202
  • FreeRTOS 软件定时器的使用

    FreeRTOS中加入了软件定时器这个功能组件 是一个可选的 不属于freeRTOS内核的功能 由定时器服务任务 其实就是一个定时器任务 来提供 软件定时器是当设定一个定时时间 当达到设定的时间之后就会执行指定的功能函数 而这个功能函数就叫
  • 一文教你学会keil软件仿真

    仿真在我们调试代码中是非常重要的 通过仿真 我们可以快速定位到错误代码 或者错误逻辑的地方 这里我就以上一篇博客为例 教大家如何软件仿真 软件仿真不需要单片机 直接通过keil软件进行代码调试 一 打开工具 二 选择软件仿真 三 开始仿真
  • FreeRTOS系列

    本文主要介绍如何在任务或中断中向队列发送消息或者从队列中接收消息 使用STM32CubeMX将FreeRTOS移植到工程中 创建两个任务以及两个消息队列 并开启两个中断 两个任务 Keyscan Task 读取按键的键值 并将键值发送到队列
  • freertos---软定时器

    一 软件定时器介绍 freeRTOS软件定时器的时基是基于系统时钟节拍实现的 可以创建很多个 在硬件定时器资源不充足的情况下非常有用 软件定时器一般用作周期性地执行函数 在创建软件定时器时指定软件定时器的回调函数 在回调函数中实现相应的功能
  • 【FreeRTOS】队列的使用

    作者主页 凉开水白菜 作者简介 共同学习 互相监督 热于分享 多加讨论 一起进步 专栏资料 https pan baidu com s 1nc1rfyLiMyw6ZhxiZ1Cumg pwd free 点赞 收藏 再看 养成习惯 订阅的粉丝
  • FreeRTOS_中断

    传送门 博客汇总帖 传送门 Cortex M3 中断 异常 传送门 Cortex M3笔记 基础 笔记内容参考 正点原子的FreeRTOS开发手册 cortex m3权威指南 Cortex M3和Cortex M4权威指南等 文中stm32
  • Error: L6218E: Undefined symbol vApplicationGetIdleTaskMemory (referred from tasks.o).

    我用的是F103ZET6的板子 移植成功后 编译出现两个错误是关于stm32f10x it c 里 void SVC Handler void void PendSV Handler void 两个函数的占用问题 随后编译出现以下两个问题
  • FreeRTOS临界段和开关中断

    http blog sina com cn s blog 98ee3a930102wg5u html 本章教程为大家讲解两个重要的概念 FreeRTOS的临界段和开关中断 本章教程配套的例子含Cortex M3内核的STM32F103和Co
  • STM32F103移植FreeRTOS必须搞明白的系列知识---2(FreeRTOS任务优先级)

    STM32F103移植FreeRTOS必须搞明白的系列知识 1 Cortex CM3中断优先级 STM32F103移植FreeRTOS必须搞明白的系列知识 2 FreeRTOS任务优先级 STM32F103移植FreeRTOS必须搞明白的系
  • 啊哈C的简单使用

    打开啊哈C 新建一个程序输出hello world include
  • FreeRTOS轻量级同步--任务通知

    1 简介 在FreeRTOS的配置参数中的configUSE TASK NOTIFICATIONS宏打开 一般RTOS会默认打开 如图1所示 图1 notify宏开关 RTOS在创建任务时 会创建一个32位的通知值ulNotifiedVal
  • FreeRTOS实时操作系统(三)任务挂起与恢复

    系列文章 FreeRTOS实时操作系统 一 RTOS的基本概念 FreeRTOS实时操作系统 二 任务创建与任务删除 HAL库 FreeRTOS实时操作系统 三 任务挂起与恢复 FreeRTOS实时操作系统 四 中断任务管理 FreeRTO
  • FreeRTOS之系统配置

    1 FreeRTOS的系统配置文件为FreeRTOSConfig h 在此配置文件中可以完成FreeRTOS的裁剪和配置 在官方的demo中 每个工程都有一个该文件 2 先说一下 INCLUDE 开始的宏 使用 INCLUDE 开头的宏用来
  • 如何更改 FreeRTOS 中任务的最大可用堆大小?

    我通过以下方式在任务中创建元素列表 l dllist pvPortMalloc sizeof dllist dlllist 有 32 字节大 我的嵌入式系统有 60kB SRAM 所以我希望系统可以轻松处理我的 200 个元素列表 我发现在
  • 如何将 void* 转换为函数指针?

    我在 FreeRTOS 中使用 xTaskCreate 其第四个参数 void const 是传递给新线程调用的函数的参数 void connect to foo void const task params void on connect
  • 防止GCC LTO删除函数

    我使用 GCC ARM Embedded 和 FreeRTOS FreeRTOS具有的功能vTaskSwitchContext 仅在某些情况下使用 内联汇编代码 问题是 当我使用LTO时 GCC不考虑内联汇编代码并认为该函数没有被使用 因此
  • 有关 CMake 错误的问题:没有为目标提供源

    我正在尝试使用 cmake 和 eclipse 将 FreeRtos 添加到我的项目中 但出现错误 我运行的是 debian 10 我的 cmake 版本是 3 13 4 cmake 的文件可以在以下位置找到这个 git 仓库 https

随机推荐

  • 渗透测试工具之Metasploit Framework(MSF)

    一 Metasploit Framework xff08 MSF xff09 简介 Metasploit是当前信息安全与渗透测试领域最流行的术语 xff0c 它的出现颠覆了以往的已有的渗透测试的方式 几乎所有流行的操作系统都支持Metasp
  • Test Case Framework (TCF) 简介

    TCF is a system that simplifies the creation and execution of test cases automation for that matter with minimal setup e
  • 小菜鸡的第一天

    1 CPU分配 xff0c i5四核所以给Linux分配两个核 2 内存分配 xff0c 有16GB所以分配8个g 3 硬盘 xff0c 需要创立一个独立的分区 xff0c 最好300G以上 xff08 由于个人原因分配了60G xff09
  • 小菜鸡的第二天

    绝对路径 xff1a 以 开头 代表当前路径 xff0c 或者 代表上一级目录 xff0c 或者 插入U盘之后 xff0c 在 dev文件夹下输入 ls sd 可以看到U盘信息 xff0c 要想知道插入的U盘是哪个 xff0c 重新插拔再次
  • 小菜鸡的第三天

    压缩与解压 tar vcjf 43 文件名 tar bz2 xxx xxx是要压缩的文件名 压缩命令 tar vxjf 43 xxx tar bz2 xxx是要解压缩的文件名 解压缩命令 f xff1a 使用归档文件或ARCHIVE设备 c
  • 初级算法:判断数组是否存在重复元素

    qsort函数原型是 void qsort xff08 void base size t num size t width int cdecl compare const void const void xff09 4个参数 xff1a v
  • 初级算法:删除排序数组中的重复项

    因为数组是排序的 xff0c 只要是相同的肯定是挨着的 xff0c 我们只需要遍历所有数组 xff0c 然后前后两两比较 xff0c 如果有相同的就把后面的给删除 双指针解决 使用两个指针 xff0c 右指针始终往右移动 xff0c 如果右
  • 运算符重载

    加号运算符重载 作用 xff1a 实现两个自定义数据类型相加的运算 span class token keyword class span span class token class name Person span span class
  • .在python中的作用

    的作用 点把前后连起来 xff0c 构成一种索引机制 前面是库 后面是函数 ex xff1a pybullet setAdditionalSearchPath是指在pybullet的库中引用setAdditionalSearchPath这个
  • ROS服务通信(七)C++、Python实现

    目录 简介 理论模型 服务通信自定srv 创建srv 编辑配置文件 C 43 43 实现 vscode配置 服务端实现 客户端实现 优化 Python实现 服务端实现 客户端实现 简介 服务通信也是ROS中一种极其常用的通信模式 xff0c
  • ROS中的API:C++、Python(十)实现及理解

    目录 简介 C 43 43 初始化 话题与服务相关对象 回旋函数 ros xff1a xff1a spinOnce xff08 xff09 ros xff1a xff1a spin xff08 xff09 时间相关API 时刻 持续时间 持
  • ROS Gazebo安装入门及仿真室内环境和小车实现(十九)

    目录 安装 简介 URDF与Gazebo基本集成流程 创建功能包 编写URDF文件 启动Gazebo并显示模型 launch 文件实现 命令行启动 xff08 去掉launch中的第三行加载模型 xff09 集成到launch里启动 URD
  • Test Case Framework (TCF) tcf 参数

    root 64 embargo ww13 tcf help usage tcf h v log pid tid log time config file CONFIG FILE py p CONFIG PATH state path STA
  • 第一章操作系统引论测验错题整理(二)

    中断和特权级 计算机系统中判断是否有外部中断事件发生应该在 xff09 A 进程切换时 B 执行完一条指令后 C 执行一条指令过程中 D 由用户态转入内核态时 B 解析 xff1a 因果关系 xff0c 指令执行了才知道 从用户态到内核态的
  • 多旋翼飞行器设计与控制(三)—— 机架设计

    多旋翼飞行器设计与控制 xff08 三 xff09 机架设计 一 布局设计 1 机身基本布局 共有三种 xff1a 环型 43 字型 X字型 常用X字型 xff1a 机动性更强前视相机的视场角不容易被遮挡 环形的特点 xff1a 刚性更大避
  • 路径规划与轨迹优化 —— Dijkstra算法寻找最短路径

    一 算法思路 Dijkstra算法是一种用来寻找最短路径的算法 xff0c 其中涉及的思想有贪心 动态规划 广度优先搜索等 图中g n 代表的时代价 xff0c 在机器人路径规划中可以理解为距离 二 代码 源码来源于Github xff0c
  • VSCode远程连接免密登录

    配置了VSCode远程连接服务器 xff0c 但每次打开project都需要重新输入密码 xff0c 比较麻烦 xff0c 所以下面就介绍一下如何免密码登入 在上一篇blog里面配置好VSCode远程连接服务器之后按照如下操作 步骤如下 x
  • raspberry(树莓派)的简介及实验

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 树莓派是什么 xff1f 二 使用步骤 1 主要Pin脚的编号2 使用硬件3 连接树莓派Pin位4 使用代码实验 总结
  • 深度学习环境配置Anaconda+cuda+cudnn+PyTorch——李沐大神《动手学深度学习》环境配置(巨详细,持续迭代)

    李沐大神 动手学深度学习 安装篇 通用AI 深度学习 机器学习环境 Anaconda 43 cuda 43 cudnn 43 Pytorch 手把手教你安装深度学习环境 xff09 这里是GPU 43 PyTorch版本 文章目录 李沐大神
  • FreeRTOS-任务间共享数据的管理框架

    本文章介绍一种在FreeRTOS项目中任务间共享数据的管理框架 xff0c 思路比较简单 任务在更新和获取共享数据时利用互斥量进行上锁保护数据 xff0c 操作完之后进行解锁 xff0c 并且当共享数据使用setting 更新时调用对应的回