消息队列应用示例MessageQueues-STM32CubeMX-FreeRTOS《嵌入式系统设计》P343-P347

在这里插入图片描述

消息队列

使用信号量、事件标志组和线标志进行任务同步时,只能提供同步的时刻信息,无法在任务之间进行数据传输。要实现任务间的数据传输,一般使用两种方式:

1. 全局变量

在 RTOS 中使用全局变量时,必须保证每个任务对全局变量的互斥访问,一般借助互斥量来实现。另一个方法是在任务设计时,设计成只有一个任务修改这个全局变量,其他任务只是读取这个全局变量,而不修改它的值,并在全局变量前面加上 volatile 的关键字修饰,以避免编泽器的优化。

2. 消息队列

消息队列类似于一个数据缓冲区,可以保存有限个、具有确定大小的数据。通常情况下,消息队列按照 FI FO(先进先出)的模式使用,即数据由队尾写入,从队首读出。
任务向消息队列中放人消息时,需要判断消息队列是否有多余的空间:如果有空间,则放人一个新的消息;如果消息队列已经存满,该任务将进人到阻塞态,直到消息队列中有多余的空间。
任务从消息队列中获取消息时,需要判断消息队列是否有消息:如果消息队列中没有消息,该任务将进人到阻塞态。当消息队列中有新的消息时,处于阻塞态的任务将被唤醒并获得该消息。任务在获取消息时,需要提前定义存放消息的缓冲区,这个缓冲区的大小不能小于消息队列中单个消息的大小。
注意: FreeRTOS 利用消息队列进行消息传递时,放入消息队列的是实际的数据,而不是数据的地址。例如,串口一次接收 10 字节的数据,如果使用消息队列来传递串口接收的数据,则应该将消息队列的单个消息大小设置为 10 字节,以便一次性存放串口接收的10 字节数据。
消息队列和全局变量相比,解决了多任务访问共享资源的冲突问题,还提供了任务的同步和超时处理等机制,并且可以实现中断服务程序和任务之间的数据传递。例如,多个任务都要使用串口进行数据传输时,可以采用两种方法:一种方法是利用互斥量实现对串口的互斥访问;另一种方法是创建一个消息队列和一个负责串口数据收发的任务。任务 A 发送的数据放人消息队列,任务 B 发送的数据也放人消息队列,串口发送任务则按照 FIFO 的原则从消息队列中取出消息发送。
在实际应用时,由于消息队列采用数据复制的方式传输数据,而不是传输存放数据的地址。如果任务间传输的数据量较大时,使用消息队列的效率会比较低。这时,可以考虑使用全局变量来实现任务间的通信,只是要注意全局变量的互斥访问(利用互斥量实现)。

应用示例

利用消息队列传输串口接收的数据。串口采用中断方式接收 10 字节的数据,并放入消息队列。数据处理任务从消息队列中取出数据并发送到 PC 显示。消息队列设置为可以容纳 5 个消息,每个消息的大小为10 字节。
修改HAL库的时间基准
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

// main.h
/*** @file main.h* @brief 主程序头文件,包含系统所需的基本定义和声明*//* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>			// 标准输入输出头文件,用于printf和fputc
#include "cmsis_os2.h"		// CMSIS RTOS2,支持FreeRTOS
#include "usart.h"			// USART头文件,包含串口相关函数
#define LENGTH 10			// 缓冲区长度
extern uint8_t RxBuf[LENGTH];	// 串口接收缓冲区,用于存储接收到的数据
extern uint8_t TxBuf[LENGTH];	// 串口发送缓冲区,用于存储待发送的数据
extern osMessageQueueId_t ComQueueHandle;	// RTOS消息队列句柄,用于任务间通信
/* USER CODE END Includes */
// main.c
/*** @file main.c* @brief 主程序源文件,包含系统初始化和中断回调函数*//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/*** @brief 重定向printf函数相关配置* @note 支持不同编译器(ARMCC、GNUC)下的printf功能实现*/
/* suport printf function, usemicrolib is unnecessary */
#if (__ARMCC_VERSION > 6000000)
__asm (".global __use_no_semihosting\n\t");
void _sys_exit(int x)
{x = x;
}
/* __use_no_semihosting was requested, but _ttywrch was */
void _ttywrch(int ch)
{ch = ch;
}
FILE __stdout;
#else
#ifdef __CC_ARM
#pragma import(__use_no_semihosting)
struct __FILE
{int handle;
};
FILE __stdout;
void _sys_exit(int x)
{x = x;
}
#endif
#endif
#if defined ( __GNUC__ ) && !defined (__clang__)
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif/*** @brief  Retargets the C library printf function to the USART.* @param  None* @retval None*/
PUTCHAR_PROTOTYPE
{	// 采用轮询方式发送1字节数据,使用阻塞方式,超时时间设置为无限等待HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);return ch;
}int fgetc(FILE *f)
{	// 采用轮询方式接收1字节数据,使用阻塞方式,超时时间设置为无限等待uint8_t ch;	HAL_UART_Receive( &huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY );return ch;
}
/* USER CODE END 0 *//* USER CODE BEGIN 2 */printf("/**  FreeRTOS for task creat  **/\n");HAL_UART_Receive_IT(&huart1,RxBuf,LENGTH);		// 启动串口中断接收功能,接收长度为 LENGTH 的数据到 RxBuf 缓冲区
/* USER CODE END 2 *//* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)	
{	// 串口接收完成中断回调函数,当串口接收到指定长度的数据后,会触发此回调函数if(huart->Instance==USART1)	// 检查触发中断的串口是否为 USART1{	// 将收到的数据放入消息队列 ComQueueHandle中osMessageQueuePut(ComQueueHandle, (void *)RxBuf,0,0);	HAL_UART_Receive_IT(&huart1,RxBuf,LENGTH);	// 重新开始串口中断接收,准备接收下一组数据}
}
/* USER CODE END 4 */
// app_freertos.c/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
uint8_t RxBuf[LENGTH];	// 串口接收缓冲区
uint8_t TxBuf[LENGTH];	// 串口发送缓冲区
/* USER CODE END Variables *//* USER CODE BEGIN Header_StartProcessTask */
/**
* @brief Function implementing the ProcessTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartProcessTask */
void StartProcessTask(void *argument)
{/* USER CODE BEGIN StartProcessTask *//* Infinite loop */for(;;){		// 从消息队列中获取数据,无限等待if(osMessageQueueGet(ComQueueHandle,(void *)TxBuf,NULL,osWaitForever)==osOK){	// 通过UART1发送数据HAL_UART_Transmit(&huart1,(void *)&TxBuf,LENGTH,HAL_MAX_DELAY);}}/* USER CODE END StartProcessTask */
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/894424.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【NLP251】Transformer精讲 残差链接与层归一化

精讲部分&#xff0c;主要是对Transformer的深度理解方便日后从底层逻辑进行创新&#xff0c;对于仅应用需求的小伙伴可以跳过这一部分&#xff0c;不影响正常学习。 1. 残差模块 何凯明在2015年提出的残差网络&#xff08;ResNet&#xff09;&#xff0c;Transformer在2016年…

Android学习制作app(ESP8266-01S连接-简单制作)

一、理论 部分理论见arduino学习-CSDN博客和Android Studio安装配置_android studio gradle 配置-CSDN博客 以下直接上代码和效果视频&#xff0c;esp01S的收发硬件代码目前没有分享&#xff0c;但是可以通过另一个手机网络调试助手进行模拟。也可以直接根据我的代码进行改动…

图书管理系统 Axios 源码__新增图书

目录 功能介绍 核心代码解析 源码&#xff1a;新增图书功能 总结 本项目基于 HTML、Bootstrap、JavaScript 和 Axios 开发&#xff0c;实现了图书的增删改查功能。以下是新增图书的功能实现&#xff0c;适合前端开发学习和项目实践。 功能介绍 用户可以通过 模态框&#xf…

DeepSeek Janus-Pro:多模态AI模型的突破与创新

近年来&#xff0c;人工智能领域取得了显著的进展&#xff0c;尤其是在多模态模型&#xff08;Multimodal Models&#xff09;方面。多模态模型能够同时处理和理解文本、图像等多种类型的数据&#xff0c;极大地扩展了AI的应用场景。DeepSeek(DeepSeek-V3 深度剖析&#xff1a;…

AJAX XML

AJAX XML 引言 随着互联网技术的不断发展,Web应用对用户交互性和实时性的要求越来越高。AJAX(Asynchronous JavaScript and XML)技术的出现,为Web应用开发提供了强大的支持。AJAX技术允许Web应用在不重新加载整个页面的情况下,与服务器进行异步通信。XML作为数据传输格式…

OpenGL学习笔记(五):Textures 纹理

文章目录 纹理坐标纹理环绕方式纹理过滤——处理纹理分辨率低的情况多级渐远纹理Mipmap——处理纹理分辨率高的情况加载与创建纹理 &#xff08; <stb_image.h> &#xff09;生成纹理应用纹理纹理单元练习1练习2练习3练习4 通过上一篇着色部分的学习&#xff0c;我们可以…

代理模式——C++实现

目录 1. 代理模式简介 2. 代码示例 1. 代理模式简介 代理模式是一种行为型模式。 代理模式的定义&#xff1a;由于某些原因需要给某对象提供一个代理以控制该对象的访问。这时&#xff0c;访问对象不适合或者不能直接访问引用目标对象&#xff0c;代理对象作为访问对象和目标…

Vue3 表单:全面解析与最佳实践

Vue3 表单&#xff1a;全面解析与最佳实践 引言 随着前端技术的发展&#xff0c;Vue.js 已经成为最受欢迎的前端框架之一。Vue3 作为 Vue.js 的最新版本&#xff0c;带来了许多改进和新的特性。其中&#xff0c;表单处理是 Vue 应用中不可或缺的一部分。本文将全面解析 Vue3 …

C++11新特性之范围for循环

1.介绍 C11标准之前&#xff0c;使用for循环遍历数组或容器&#xff0c;只能使用以下结构&#xff1a; for&#xff08;表达式1&#xff1b;表达式2&#xff1b;表达式3&#xff09;{ 循环体 } 那么在C11标准中&#xff0c;除了上面的方法外&#xff0c;又引入了一种全新的语…

攻防世界 fileclude

代码审计 WRONG WAY! <?php include("flag.php"); highlight_file(__FILE__);//高亮显示文件的源代码 if(isset($_GET["file1"]) && isset($_GET["file2"]))//检查file1和file2参数是否存在 {$file1 $_GET["file1"];$fi…

图书管理系统 Axios 源码__获取图书列表

目录 核心功能 源码介绍 1. 获取图书列表 技术要点 适用人群 本项目是一个基于 HTML Bootstrap JavaScript Axios 开发的图书管理系统&#xff0c;可用于 添加、编辑、删除和管理图书信息&#xff0c;适合前端开发者学习 前端交互设计、Axios 数据请求 以及 Bootstrap 样…

Vue 响应式渲染 - 列表布局和v-html

Vue 渐进式JavaScript 框架 基于Vue2的学习笔记 - Vue 响应式渲染 - 列表布局和v-html 目录 列表布局 简单渲染列表 显示索引值 点击变色 V-html 作用 注意 采用策略 应用 总结 列表布局 简单渲染列表 Data中设置状态&#xff0c;是一个数组格式的默认信息。 然后…

如何实现一个CLI命令行功能 | python 小知识

如何实现一个CLI命令行功能 | python 小知识 在现代软件开发中&#xff0c;命令行界面&#xff08;CLI&#xff09;的设计与交互至关重要。Click是一个强大的Python库&#xff0c;专门用于快速创建命令行界面&#xff0c;以其简单易用性和丰富的功能赢得了开发者的青睐。本文将…

[SAP ABAP] Debug Skill

SAP ABAP Debug相关资料 [SAP ABAP] DEBUG ABAP程序中的循环语句 [SAP ABAP] 静态断点的使用 [SAP ABAP] 在ABAP Debugger调试器中设置断点 [SAP ABAP] SE11 / SE16N 修改标准表(慎用)

kamailio-Core 说明书 版本:Kamailio SIP Server v6.0.x(稳定版)

Core 说明书 版本&#xff1a;Kamailio SIP Server v6.0.x&#xff08;稳定版&#xff09; 概述 本教程收集了 Kamailio 导出的函数和参数 core 添加到配置文件中。 注意&#xff1a;此页面上的参数不按字母顺序排列。 结构 kamailio.cfg 的结构可以看作是三个部分&#xff…

.Net / C# 繁体中文 与 简体中文 互相转换, 支持地方特色词汇

版本号 Nuget 搜索 “OpenCCNET”, 注意别找错, 好多库的名字都差不多 支持 “繁,简” 的互相转换, 支持多个地区常用词汇的转换, 还支持 日文的新旧转换. OpenCC 在 .Net 中的实现 https://github.com/CosineG/OpenCC.NET <PackageReference Include"OpenCCNET"…

Redis脑裂问题详解及解决方案

Redis是一种高性能的内存数据库&#xff0c;广泛应用于缓存、消息队列等场景。然而&#xff0c;在分布式Redis集群中&#xff0c;脑裂问题&#xff08;Split-Brain&#xff09;是一个需要特别关注的复杂问题。本文将详细介绍Redis脑裂问题的成因、影响及解决方案。 一、什么是…

LLMs之OpenAI o系列:OpenAI o3-mini的简介、安装和使用方法、案例应用之详细攻略

LLMs之OpenAI o系列&#xff1a;OpenAI o3-mini的简介、安装和使用方法、案例应用之详细攻略 目录 相关文章 LLMs之o3&#xff1a;《Deliberative Alignment: Reasoning Enables Safer Language Models》翻译与解读 LLMs之OpenAI o系列&#xff1a;OpenAI o3-mini的简介、安…

女生年薪12万,算不算属于高收入人群

在繁华喧嚣的都市中&#xff0c;我们时常会听到关于收入、高薪与生活质量等话题的讨论。尤其是对于年轻女性而言&#xff0c;薪资水平不仅关乎个人价值的体现&#xff0c;更直接影响到生活质量与未来的规划。那么&#xff0c;女生年薪12万&#xff0c;是否可以被划入高收入人群…

AI开发学习之——PyTorch框架

PyTorch 简介 PyTorch &#xff08;Python torch&#xff09;是由 Facebook AI 研究团队开发的开源机器学习库&#xff0c;广泛应用于深度学习研究和生产。它以动态计算图和易用性著称&#xff0c;支持 GPU 加速计算&#xff0c;并提供丰富的工具和模块。 PyTorch的主要特点 …