基于STM32F4+FREERTOS进行结构体变量的传递
原始参考链接如下↓
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进行结构体变量的传递的更多相关文章
- C语言结构体变量私有化
操作系统 : CentOS7.3.1611_x64 gcc版本 :4.8.5 问题描述 C语言结构体定义中的变量默认是公有(Public)属性,如果实现成员变量的私有(Private)化? 解决方案 ...
- 结构体变量的 extern 使用方法,转--
要求如下,在.h文件中这样定义: typedef struct typFNT_GB16 // 汉字字模数据结构 { signed ]; // 汉字内码索引 ]; ...
- C结构体变量2种运算(比如链表的结点)(区别与java)
a结构体变量,只能做两种运算, 整体引用(赋值,参数传递) 或访问成员(点运算—地址方式简化,地址方式)(见最后的图片) case万: 结论:java里面的class Node : Node p; p ...
- C语言中两个相同类型的结构体变量之间是可以相互直接赋值的
C语言中,在相同类型的变量间赋值时是直接内存复制的,即将他们的内存进行复制,而两个同类型的结构体变量属于同一种变量,所以赋值时是按照他们的内存分布来直接拷贝的.所以,在C语言中两个相同类型的结构体变量 ...
- 结构体变量的sizeof计算
结构体字节对齐准则: 1. 结构体变量的首地址能够被其最宽基本类型成员的大小所整除: 2. 结构体每个成员相对于结构体首地址的偏移量都是当前成员大小的整数倍,如有需要编译器会在成员之间加上填充字节: ...
- 在C代码中将结构体变量作为参数传递效率忒低
在C语言编程中,我们几乎不可能看见有人将一个结构体变量作为参数进行传递,因为效率太低了.本文尝试从反汇编的角度给出其中的缘由. 对于C语言来说,所有的参数传递都是值传递.如果一个变量为指针,那么传递的 ...
- C语言 指向结构体变量的指针
一个指向变量的指针表示的是占内存中起始位置 一个指向结构体的变量的指针表示的是这个结构体变量占内存中的起始位置,同样它也可以指向结构体变量数组 定义结构体变量的指针: //假设已有一个结构体名为Stu ...
- C语言中结构体变量之间赋值
近期,我阅读了某新员工小刘写的C语言代码,发现其对结构体变量之间的赋值不是非常熟悉. 对于两个同样类型的结构体变量,他均採用的是逐个成员变量直接赋值的形式.例如以下的代码演示样例: 如上代码所看到的, ...
- C/C++中指向结构体变量的指针,调用指向的那个结构体中的成员
设p是指向结构体变量的指针,则可以通过以下的方式,调用指向的那个结构体中的成员: (1)结构体变量.成员名.如,stu.num. (2)(*p).成员名.如,(*p).num. (3)p->成员 ...
- C语言结构体变量字节对齐问题总结
结构体字节对齐 在用sizeof运算符求算某结构体所占空间时,并不是简单地将结构体中所有元素各自占的空间相加,这里涉及到内存字节对齐的问题.从理论上讲,对于任何 变量的访问都可以从任何地址开始访问,但 ...
随机推荐
- 开发者新选择:用DeepSeek实现Cursor级智能编程的免费方案
前言 去年下半年 cursor 非常火,让很多一行代码都不懂的小白,也可以做自己的网站和搭 App,当时一下子就引爆了独立开发的热潮. 不过每月20dollar的价格也不算便宜,这时候可以使用 cli ...
- xshell连接服务器无法用password登录,只能用public key的解决办法
xshell无法用password登录服务器,只能用public key的解决办法 只能用public key登录, 那么我们用阿里云后台的远程连接按钮进入服务器,进入后 修改/etc/ssh/ssh ...
- Visual Studio各个版本密钥
1.VS2012 旗舰版:YKCW6-BPFPF-BT8C9-7DCTH-QXGWC 2.VS2013 旗舰版:BWG7X-J98B3-W34RT-33B3R-JVYW9 专业版:XDM3T-W3T3 ...
- Kali 切换中文模式
Kali 切换中文模式 在桌面打开终端,输入sudo dpkg-reconfigure locales命令,然后输入kali的密码 在选择栏目找到 zh_CN.UTF-8 UTF-8 找到之后按 空格 ...
- Q:ORACLE 之无法删除正在连接的用户?
首先用户名必须用单引号引起来且必须大写,如下是失效的 1.查询用户进程 SELECT SID,SERIAL# FROM V$SESSION WHERE USERNAME='V7HIS_1'; 2.删除 ...
- 表治理-Iceberg元数据合并-metadata.json文件
一.背景描述 元数据文件随时间增多,导致查询变慢.通过如下方式可以指定metadata个数,超过指定数量自动清理. metadata文件对应Iceberg概念是Snapshots 二.解决方案 1.在 ...
- 在线客服的独立产品之路:如何将复杂的 .NET 系统打包到 Docker 镜像,使之能一键上线
我在业余时间开发了一款自己的独立产品:升讯威在线客服与营销系统.陆陆续续开发了几年,从一开始的偶有用户尝试,到如今线上环境和私有化部署均有了越来越多的稳定用户,在这个过程中,我也积累了不少如何开发运营 ...
- 「ximagine」业余爱好者的非专业显示器测试流程规范,同时也是本账号输出内容的数据来源!如何测试显示器?荒岛整理总结出多种测试方法和注意事项,以及粗浅的原理解析!
> 由于网页编辑器简陋,无法实现原文档的精心排版,如需原文档可联系... 序 「ximagine」在本篇文章中将介绍「荒岛」目前所使用的显示器测试流程及标准,我们主要使用Calman.Displ ...
- 解决 Docker 容器镜像拉取难题:全面指南
一.引言 在使用 Docker 容器的过程中,经常会遇到镜像拉取慢甚至无法下载的问题,这给开发和部署工作带来了不小的困扰.本文将深入探讨这一问题的原因,并提供多种有效的解决方案. 二.问题原因分析 网 ...
- sql server 使用sql语句导出二进制文件到本地磁盘
sp_configure 'show advanced options', 1;GORECONFIGURE;GOsp_configure 'Ole Automation Procedures', 1; ...