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例程4-串口DMA收发不定长数据

    FreeRTOS例程4 串口DMA收发不定长数据 知乎 zhihu com
  • 基于HAL库的FREERTOS----------二.任务API函数

    任务API函数览概 CUBEMX对 做了API的封装 很多 的函数没有封装到位 可以用原函数调用 任务API函数分别介绍 1 uxTaskPriorityGet 此函数用来获取指定任务的优先级 要使用此函数的话宏 INCLUDE uxTas
  • FreeRTOS软件定时器创建、复位、开始和停止(备忘)

    目录 一 简介 1 1 开发环境 1 2 摘要 二 STM32CubeIDE配置 三 创建定时器 3 1 头文件声明 3 2 工程文件定义 3 3 创建定时器 3 4 开启 复位 和关闭定时器 四 定时器回调函数 一 简介 1 1 开发环境
  • FreeRTOS学习笔记 6 - 互斥量

    目录 1 创建 2 获取 3 释放 4 测试 FreeRTOS不支持调度方式的设置 所以下面2个宏定义可以随意设置值 define RTOS IPC FLAG FIFO 0x00 define RTOS IPC FLAG PRIO 0x01
  • FreeRTOS学习(八) 延时函数

    声明及感谢 跟随正点原子资料学习 在此作为学习的记录和总结 环境 keil stm32f103 FreeRTOS延时函数有两个 分别是 vTaskDelay vTaskDelayUntil 1 vTaskDelay 任务相对延时 函数原型
  • Freertos中vTaskDelay()是怎么用的

    1 常见的使用场景 void vLED Task void pvParameters while 1 Heartbeat LED vTaskDelay 1000 portTICK RATE MS 说明 上面这段代码的意思是 led翻转后经过
  • 【FreeRTOS】队列的使用

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

    FreeRTOS临界区是指那些必须完整运行 不能被打断的代码段 比如有的外设的初始化需要严格的时序 初始化过程中不能被打断 FreeRTOS 在进入临界区代码的时候需要关闭中断 当处理完临界区代码以后再打开中断 FreeRTOS 系统本身就
  • 【FreeRTOS(三)】任务状态

    文章目录 任务状态 任务挂起 vTaskSuspend 取消任务挂起 vTaskResume 挂起任务调度器 vTaskSuspendAll 取消挂起任务调度器 xTaskResumeAll 代码示例 任务挂起 取消任务挂起 代码示例 挂起
  • 【FreeRTOS】任务通知的使用

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

    线程安全 多线程程序处于一个多变的环境 可访问的全局变量和堆数据随时可能被其他的线程改变 多个线程同时访问一个共享数据 可能造成严重的后果 出现问题的是之前移植了一个freemodbus的从站 多个任务访问全局变量保持寄存器区 导致最后读出
  • FreeRTOS之事件

    FreeRTOS之事件 声明 本人按照正点原子的FreeRTOS例程进行学习的 欢迎各位大佬指责和批评 谢谢 一 事件定义 事件 事件集 与高数上的集合意义差不多 事件啊 其实是实现任务间通信的机制 主要用于实现多任务间的同步 但是事件类型
  • 基于STM32的FreeRTOS学习之中断测试实验(五)

    记录一下 方便以后翻阅 本章内容是接着上一章节进行的实际演练 1 实验目的 FreeRTOS可以屏蔽优先级低于configMAX SYSCALL INTERRUPT PRIORITY的中断 不会屏蔽高于其的中断 本次实验就是验证这个说法 本
  • FreeRTOS笔记(十)中断

    中断 当CPU在执行某一事件A时 发生另外一个更重要紧急的事件B请求CPU去处理 产生了中断 于是CPU暂时中断当前正在执行的事件A任务而对对事件B进行处理 CPU处理完事件B后再返回之前中断的位置继续执行原来的事件A 这一过程统称为中断
  • [FreeRTOS入门学习笔记]定时器

    定时器的使用步骤 1 定义一个handle xTimerCreate创建 2 启动定时器 在Task1中调用 通过队列通知守护任务来执行定时器任务 要再config头文件中定义守护任务相关配置 虽然定时器是在task1中启动 但是定时器的任
  • 单片机通信数据延迟问题排查

    1 问题说明 笔者在最近的项目中 发现系统的响应延迟较高 经过排查 排除了单片机运行卡死的问题 2 原因分析 具体排查过程这里就不细致说明了 直接给出排查后原因 任务执行周期规划不合理 导致freertos队列发送接收到的命令有延迟 为了便
  • FreeRTOS之系统配置

    1 FreeRTOS的系统配置文件为FreeRTOSConfig h 在此配置文件中可以完成FreeRTOS的裁剪和配置 在官方的demo中 每个工程都有一个该文件 2 先说一下 INCLUDE 开始的宏 使用 INCLUDE 开头的宏用来
  • FreeRTOS 配置TICK_RATE_HZ

    我使用的是带有 5 4 版 FreeRTOS 的 MSP430f5438 我有一个有趣的问题 我无法弄清楚 基本上 当我将 configTICK RATE HZ 设置为不同的值时 LED 闪烁得更快或更慢 它应该保持相同的速率 我将 con
  • 使用 GCC 编译器的 ARM 内核的堆栈回溯(当存在 MSP 到 PSP 切换时)

    核心 ARM Cortex M4 编译器 GCC 5 3 0 ARM EABI 操作系统 免费 RTOS 我正在使用 gcc 库函数 Unwind Reason Code Unwind Backtrace Unwind Trace Fn v
  • 小型 ARM 微控制器的 RTOS 内核之间的可量化差异 [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 有许多不同的 RTOS 可用于微控制器 我专门寻找支持 ARM Cortex M 处理器的 RTOS 另外 我对闭源解决方案不感兴趣 试图从网站

随机推荐

  • 渗透测试工具之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 更新时调用对应的回