原始参考链接如下↓

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. RSA的原理和简单实践

    RSA加密是一种非对称加密,原理是: 使⽤算法可以⽣成两把钥匙 A 和 B 使⽤ A 加密的信息,使⽤ B 可以解开 使⽤ B 加密的信息,使⽤ A 可以解开 ⽇常使⽤中,我们把⼀把作为公钥公开发布. ...

  2. FIDO 密钥登录

    FIDO 密匙登录 [1]介绍了一些基础密码知识,科普性较好,在此摘抄一下: 说起密码,你会想起什么? 密码太多,记不住? 图省事所有网站用同一个密码,一个泄露了,手忙脚乱地去改密码? 网站被脱库,数 ...

  3. c++:-8

    上一节学习了C++的STL库和范型:c++:-7,本节学习c++的输入输出和流类库. I/O流 (1)程序与外界环境的信息交换 当程序与外界环境进行信息交换时,存在着两个对象:程序中的对象.文件对象. ...

  4. Python代码将大量遥感数据的值缩放指定倍数的方法

      本文介绍基于Python中的gdal模块,批量读取大量多波段遥感影像文件,分别对各波段数据加以数值处理,并将所得处理后数据保存为新的遥感影像文件的方法.   首先,看一下本文的具体需求.我们现有一 ...

  5. 金泰克S300固态硬盘 SM2256K开卡量产

    开卡原因:固态硬盘出现开机正常,用一会就找不到硬盘了,电脑冷启动后又可以识别硬盘,决定根据网上教程进行开卡量产修复试试. 硬盘型号:tigo S300 120GB,主控芯片SM2256K AB,闪存颗 ...

  6. 3 x 2 + 1 !安 全 能 力 权 威 认 可 !

    近日,由XOps大会组委会主办的"2024第三届XOps产业创新发展论坛"在北京召开.大会主论坛公布了2024上半年XOps最新评估结果,天翼云顺利通过ITU DevOps国际标准 ...

  7. Linux Bridge和Tap关系详解

    本文分享自天翼云开发者社区<Linux Bridge和Tap关系详解>,作者:x****n Linux Bridge介绍 Bridge(桥)是Linux上用来做TCP/IP二层协议交换的设 ...

  8. FOFA 图标哈希值大全

    FOFA 图标哈希值大全 服务 图标 哈希值 默认端口 Atlassian Crowd icon_hash="-1231308448" 8095 CouchDB icon_hash ...

  9. linux--安装zeppelin

    可以下载源码安装也可以用docker安装 http://zeppelin.apache.org/download.html Zeppelin 安装目录的bin文件夹下,使用以下命令启动进程: /opt ...

  10. CAD内核的奥秘 | 工业软件发展史 (转)

    CAD内核的奥秘 | 工业软件发展史 (声明:此文非本人原著,仅供交流,如果侵犯到原作者权利,立即删除) 如果一个产业要寻根,就会发现一个万千世界,最后会聚焦到一个点上. "一沙一世界&qu ...