原始参考链接如下↓

Freertos 接收消息队列数据不对,是姿势不正确吗 - STM32H7 - 硬汉嵌入式论坛 - Powered by Discuz!

https://www.armbbs.cn/forum.php?mod=viewthread&tid=111900&highlight=%CF%FB%CF%A2%B6%D3%C1%D0


C 语言关于结构体做参数传递 | 菜鸟教程 https://www.runoob.com/w3cnote/c-the-structure-of-the-parameter.html


由于看到的FREERTOS的例程中关于消息队列的代码,大多数都是传递的一个字节的数值;

而在实际应用中,需要传递的数据类型可以是浮点数,也可以是数组,也可以是uint16数据,所以上述链接的传递结构体指针的思路很符合我的需求。

同时,使用RTOS+消息队列的处理方式,至少有以下两个优点:

1、便于开发,因为各个模块之间是通过消息队列进行数据交互,没有直接耦合,无需像裸机编程一样进行全局变量的引用

2、便于移植,代码复用率高,各个开发者之间沟通成本低

需要注意的点是:

1、将结构体作为指针传递时是4字节,指针传递时用到的局部变量会被释放。

2、printf函数打印float数据时需要使用%f格式字符



变量初始化

查看代码

typedef struct Msg {
uint8_t ucMessageID;
uint16_t usData[2];
uint32_t ulData[2];
float_t test_buf[3];
} MSG_T; MSG_T g_tMsg; /* 定义一个结构体用于消息队列 */

发送消息队列的代码示例


static void vTaskTaskUserIF(void* pvParameters)
static void vTaskTaskUserIF(void* pvParameters)
{
MSG_T* ptMsg;
uint8_t ucCount = 0;
uint8_t ucKeyCode;
uint8_t pcWriteBuffer[500]; /* 初始化结构体指针 */
ptMsg = &g_tMsg; /* 初始化数组 */
ptMsg->ucMessageID = 0;
ptMsg->ulData[0] = 0;
ptMsg->usData[0] = 0;
ptMsg->test_buf[0] = 0;
while (1) {
ucKeyCode = bsp_GetKey(); if (ucKeyCode != KEY_NONE) {
switch (ucKeyCode) {
/* K1键按下,向xQueue1发送数据 */
case KEY_DOWN_K1:
ptMsg->ucMessageID++;
ptMsg->ulData[0]++;
ptMsg->test_buf[0]++; /* 使用消息队列实现指针变量的传递 */
if (xQueueSend(xQueue2, /* 消息队列句柄 */
(void*)&ptMsg, /* 发送结构体指针变量ptMsg的地址 */
(TickType_t)10)
!= pdPASS) {
/* 发送失败,即使等待了10个时钟节拍 */
printf("K1键按下,向xQueue1发送数据失败,即使等待了10个时钟节拍\r\n");
} else {
/* 发送成功 */
printf("K1键按下,向xQueue1发送数据成功\r\n");
}
break;
/* K2键按下,向xQueue2发送数据 */
case KEY_DOWN_K2:
ptMsg->ucMessageID++;
ptMsg->ulData[0]++;
ptMsg->test_buf[0]++; /* 使用消息队列实现指针变量的传递 */
if (xQueueSend(xQueue2, /* 消息队列句柄 */
(void*)&ptMsg, /* 发送结构体指针变量ptMsg的地址 */
(TickType_t)10)
!= pdPASS) {
/* 发送失败,即使等待了10个时钟节拍 */
printf("K2键按下,向xQueue2发送数据失败,即使等待了10个时钟节拍\r\n");
} else {
/* 发送成功 */
printf("K2键按下,向xQueue2发送数据成功\r\n");
}
break;
/* 其他的键值不处理 */
default:
break;
}
} vTaskDelay(20);
}
}

接收消息队列的代码


static void vTaskLED(void* pvParameters)

static void vTaskLED(void* pvParameters)
{
MSG_T* ptMsg;
BaseType_t xResult;
const TickType_t xMaxBlockTime = pdMS_TO_TICKS(200); /* 设置最大等待时间为200ms */ while (1) {
xResult = xQueueReceive(xQueue2, /* 消息队列句柄 */
(void*)&ptMsg, /* 这里获取的是结构体的地址 */
(TickType_t)xMaxBlockTime); /* 设置阻塞时间 */ if (xResult == pdPASS) {
/* 成功接收,并通过串口将数据打印出来 */
printf("接收到消息队列数据ptMsg->ucMessageID = %d\r\n", ptMsg->ucMessageID);
printf("接收到消息队列数据ptMsg->ulData[0] = %d\r\n", ptMsg->ulData[0]);
printf("接收到消息队列数据ptMsg->testbuf[0] = %f\r\n", ptMsg->test_buf[0]);
} else {
/* 超时 */
bsp_LedToggle(2);
bsp_LedToggle(3);
}
}
}

基于STM32F4+FREERTOS进行结构体变量的传递的更多相关文章

  1. C语言结构体变量私有化

    操作系统 : CentOS7.3.1611_x64 gcc版本 :4.8.5 问题描述 C语言结构体定义中的变量默认是公有(Public)属性,如果实现成员变量的私有(Private)化? 解决方案 ...

  2. 结构体变量的 extern 使用方法,转--

    要求如下,在.h文件中这样定义: typedef struct typFNT_GB16     // 汉字字模数据结构 {     signed ];        // 汉字内码索引     ]; ...

  3. C结构体变量2种运算(比如链表的结点)(区别与java)

    a结构体变量,只能做两种运算, 整体引用(赋值,参数传递) 或访问成员(点运算—地址方式简化,地址方式)(见最后的图片) case万: 结论:java里面的class Node : Node p; p ...

  4. C语言中两个相同类型的结构体变量之间是可以相互直接赋值的

    C语言中,在相同类型的变量间赋值时是直接内存复制的,即将他们的内存进行复制,而两个同类型的结构体变量属于同一种变量,所以赋值时是按照他们的内存分布来直接拷贝的.所以,在C语言中两个相同类型的结构体变量 ...

  5. 结构体变量的sizeof计算

    结构体字节对齐准则: 1. 结构体变量的首地址能够被其最宽基本类型成员的大小所整除: 2. 结构体每个成员相对于结构体首地址的偏移量都是当前成员大小的整数倍,如有需要编译器会在成员之间加上填充字节: ...

  6. 在C代码中将结构体变量作为参数传递效率忒低

    在C语言编程中,我们几乎不可能看见有人将一个结构体变量作为参数进行传递,因为效率太低了.本文尝试从反汇编的角度给出其中的缘由. 对于C语言来说,所有的参数传递都是值传递.如果一个变量为指针,那么传递的 ...

  7. C语言 指向结构体变量的指针

    一个指向变量的指针表示的是占内存中起始位置 一个指向结构体的变量的指针表示的是这个结构体变量占内存中的起始位置,同样它也可以指向结构体变量数组 定义结构体变量的指针: //假设已有一个结构体名为Stu ...

  8. C语言中结构体变量之间赋值

    近期,我阅读了某新员工小刘写的C语言代码,发现其对结构体变量之间的赋值不是非常熟悉. 对于两个同样类型的结构体变量,他均採用的是逐个成员变量直接赋值的形式.例如以下的代码演示样例: 如上代码所看到的, ...

  9. C/C++中指向结构体变量的指针,调用指向的那个结构体中的成员

    设p是指向结构体变量的指针,则可以通过以下的方式,调用指向的那个结构体中的成员: (1)结构体变量.成员名.如,stu.num. (2)(*p).成员名.如,(*p).num. (3)p->成员 ...

  10. C语言结构体变量字节对齐问题总结

    结构体字节对齐 在用sizeof运算符求算某结构体所占空间时,并不是简单地将结构体中所有元素各自占的空间相加,这里涉及到内存字节对齐的问题.从理论上讲,对于任何 变量的访问都可以从任何地址开始访问,但 ...

随机推荐

  1. python的类机制

    python的类机制 参考:python面向对象 概念 方法重写/覆盖:若从父类继承的方法不能满足子类的需求,可以对其进行改写. 类变量:在实例化对象中是公用的,定义在类中,且在函数体之外,通常不作为 ...

  2. 牛客周赛 Round 77

    题目链接:牛客周赛 Round 77 A. 时间表 tag:签到 B. 数独数组 tag:签到 Description:给定n个数,每个数的范围为1-9,问能否经过排列,使其每个长度为9的连续子数组都 ...

  3. 《SpringBoot》EasyExcel实现百万数据的导入导出

    24年11月6日消息,阿里巴巴旗下的Java Excel工具库EasyExcel近日宣布,将停止更新,未来将逐步进入维护模式,将继续修复Bug,但不再主动新增功能. EasyExcel 是一款知名的 ...

  4. Luogu P7250 BalticOI 山峰 题解 [ 蓝 ] [ 模拟 ] [ 并查集 ] [ BFS ]

    Luogu P7250 BalticOI 山峰. 一道大模拟,很暴力,也很难写.建议紫或蓝,标签为模拟.广度优先搜索.并查集. 思路 首先观察到答案取决于路线上的最低点,所以我们可以把所有点的高度丢进 ...

  5. linux配置maven

    1.下载mavenhttps://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/ 中找到相应的版本wget https://mirrors.tun ...

  6. NFS服务器离线问题解决

    NFS服务器离线问题解决 NFS服务器挂了会导致挂载的NFS客户端主机卡顿延迟,或者提示找不到文件 因为在执行一些命令的时候会自动去同步,用作同步的NFS服务端挂了,命令执行就会卡住 不过听说NFS还 ...

  7. ABB机器人本体维修保养方法

    ABB机器人维修保养一般可以参照机器人保养手册里面的描述,这种保养一般分为两种计时方式,一两年内进行一次基础保养或者机器人运行时间不超过10000小时.在对机器人本体进行保养的时候,我们该如何操作呢? ...

  8. AD22 solder层开窗不见了什么原因?PCB阻焊层不显示阻焊。

    做回来的板子焊盘没有开窗! 3D上看也是没有的! 上网查了,在设计->规则->Mask->SolderMaskExpansion 将盖油勾选去掉即可. END

  9. 植物大战僵尸杂交版,最新安装包(PC+手机+苹果)+ 修改器+高清工具

    植物大战僵尸杂交版:全新游戏体验与创意碰撞 游戏简介 <植物大战僵尸杂交版>是由B站知名UP主潜艇伟伟迷基于经典游戏<植物大战僵尸>进行的一次大胆且富有创意的二次创作.这款游戏 ...

  10. JUC并发—13.Future模式和异步编程简介

    大纲 1.Runnable接口与Callable接口 (1)Runnable接口实现异步任务 (2)Callable接口实现异步任务 2.Future模式 (1)Future模式的概念 (2)Futu ...