引言

在嵌入式开发领域,STM32与FreeRTOS的结合应用极为广泛。本文将探讨如何在STM32上使用FreeRTOS实现消息队列功能,助力高效任务通信与系统协作。

消息队列定义

消息队列是一种在 FreeRTOS 中用于任务间通信的机制。它允许任务将消息发送到队列中,其他任务可以从队列中接收这些消息。消息队列可以存储多种类型的数据,如整数、指针或结构体等。通过消息队列,任务之间可以实现解耦,提高系统的可维护性和可扩展性。在 STM32 系统中,合理使用消息队列可以有效协调多个任务的运行,优化资源分配,确保系统的高效稳定运行。

创建消息队列

跟前面创建任务一样,在起始函数中创建消息队列

void MyTask(void *arg)            //开始创建任务函数
{taskENTER_CRITICAL();           //进入临界区	/* 创建Task_Queue */Task_Queue = xQueueCreate(QUEUE_LEN,QUEUE_SIZE);//xQueueCreate(队列消息的长度,队列消息的大小)xTaskCreate(MyTask1,"MyTask1",50,NULL,2,&MyTask1Handler);//动态方法创建任务1xTaskCreate(Receive_task,"Receive_task",50,NULL,3,&ReceiveTask_Handler);//创建接收消息任务xTaskCreate(Send_task,"Send_task",50,NULL,4,&SendTask_Handler);  //创建发送消息任务vTaskDelete(MyTaskHandler);    //删除开始任务taskEXIT_CRITICAL();           //退出临界区
}

xQueueCreate(*队列长度,*队列消息大小)

xQueueCreate()是FreeRTOS中用于创建消息队列的函数,其函数原型为:

QueueHandle_t xQueueCreate(
UBaseType_t uxQueueLength,
UBaseType_t uxItemSize
);

参数uxQueueLength是队列的长度,即队列可以容纳的最大消息数量。参数uxItemSize表示队列中每个消息的大小,通常以字节为单位。该函数还有一个返回值,如果队列创建成功,则返回队列的句柄;如果失败则返回NULL。

创建发送队列消息任务函数

同样先创建任务函数,然后调用xQueueSend()发送队列消息函数,其函数原型如下:

BaseType_t xQueueSend(
QueueHandle_t xQueue,
const void *pvItemToQueue,
TickType_t xTicksToWait
)

xQueueSend()是FreeRTOS 中用于向消息队列发送消息的函数。它允许任务将数据发送到队列中,供其他任务接收。参数xQueue指向要发送消息的队列的句柄,这个句柄是用户通过xQueueCreate创建时返回的。在上面已经定义成Task_Queue;参数*pvItemToQueue是一个指针类型,指向要发送到队列的数据的值。参数xTicksToWait表示等待时间,这个时间通常是由systick滴答定时器提供,前面的文章已经讲过,这里不再论述。如果队列已满,xTicksToWait()的行为取决于xTicksToWait()的值,如果为0,则函数返回pdFAIL;如果为非0值,任务将阻塞直到队列有空间或等待时间已到,函数才会返回pdFAIL。(pdFAIL表示发送队列消息失败)

创建接收队列消息任务函数

跟前面一样,这里直接跳过。然后调用xQueueReceive()接收队列消息函数。其函数原型为:

BaseType_t xQueueReceive(
QueueHandle_t xQueue,    // 队列的句柄
void *pvBuffer,          // 用于存储接收到的数据的缓冲区
TickType_t xTicksToWait  // 等待队列可用的时间
)

xQueueReceive()是 FreeRTOS 提供的一个函数,用于从队列中接收数据。它通常用于任务之间通过队列进行通信。参数xQueue表示队列的句柄,指向要从中接收数据的队列;参数*pvBuffer指向一个缓冲区,用于存储从队列中接收到的数据,缓冲区的大小尽量与队列中存储的数据大小一致。参数xTicksToWait  跟上面一样。

示例代码

#include "myfreertos.h"
#include "FreeRTOS.h"
#include "semphr.h"
#include "queue.h"
#include "Usart.h"
#include "oled.h"
#include "Task.h"
#include "led.h"
#include "key.h"#define  QUEUE_LEN    4   /* 队列的长度,最大可包含多少个消息 */
#define  QUEUE_SIZE   4   /* 队列中每个消息大小(字节) */QueueHandle_t Task_Queue =NULL; //消息队列句柄TaskHandle_t MyTaskHandler;//任务句柄TaskHandle_t MyTask1Handler;//任务1句柄TaskHandle_t SendTask_Handler;  //发送消息句柄TaskHandle_t ReceiveTask_Handler;//接收消息句柄void MyTask(void *pvParameters);    //声明启动函数void MyTask1(void *pvParameters);   //声明任务1函数void Send_task(void *pvParameters);  //声明发送消息函数void Receive_task(void *pvParameters);  //声明接收消息函数void Start_Task(void)
{xTaskCreate(MyTask,"MyTask",128,NULL,1,&MyTaskHandler);//动态方法创建任务vTaskStartScheduler();//启动任务调动		
}void MyTask(void *arg)            //开始创建任务函数
{taskENTER_CRITICAL();           //进入临界区	/* 创建Task_Queue */Task_Queue = xQueueCreate(QUEUE_LEN,QUEUE_SIZE);//xQueueCreate(队列消息的长度,队列消息的大小)xTaskCreate(MyTask1,"MyTask1",50,NULL,2,&MyTask1Handler);//动态方法创建任务1xTaskCreate(Receive_task,"Receive_task",50,NULL,3,&ReceiveTask_Handler);//创建接收消息任务xTaskCreate(Send_task,"Send_task",50,NULL,4,&SendTask_Handler);  //创建发送消息任务vTaskDelete(MyTaskHandler);    //删除开始任务taskEXIT_CRITICAL();           //退出临界区
}void MyTask1(void *arg)     //任务1函数体
{
//	u32 cnt=0;                //定义变量while(1){OLED_ShowString(1,1,"Runing Task1");GPIO_ResetBits(GPIOC,GPIO_Pin_13);vTaskDelay(300);GPIO_SetBits(GPIOC,GPIO_Pin_13);vTaskDelay(900);
//		if(++cnt>=10)     //如果超过10次
//		{
//			 if(MyTask1Handler!=NULL)  //判断句柄是否有效
//			 {
//				  vTaskDelete(MyTask1Handler);  //删除任务1
//				  MyTask1Handler=NULL;          //清空句柄
//			 }
//		}}	
}//接收队列消息任务函数
void Receive_task(void *pvParameters)
{BaseType_t xReturn = pdTRUE;/* 定义一个创建信息返回值,默认为pdTRUE */uint32_t r_queue;	/* 定义一个接收消息的变量 */while(1){xReturn = xQueueReceive(Task_Queue,&r_queue,portMAX_DELAY); //xQueueReceive(队列消息句柄,接收队列消息的内容,等待时间)if(pdTRUE == xReturn)  //判断是否接收到消息OLED_ShowNum(2,1,r_queue,1); //显示接收的消息}
}//发送队列消息任务函数
void Send_task(void *pvParameters)
{BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */uint32_t send_data1 = 1;    //定义发送的数据uint32_t send_data2 = 2;    //定义发送的数据while(1){if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)==1){xReturn = xQueueSend(Task_Queue,&send_data1,10);//向队列发送数据			if(pdPASS == xReturn)                           //判断是否发送成功{OLED_ShowString(3,1,"Send_OK ");}}else{   xReturn = xQueueSend( Task_Queue,&send_data2,10);  OLED_ShowString(3,1,"Send_OFF");}vTaskDelay(20);}
}

总结

本文介绍了 STM32 中 FreeRTOS 操作系统的消息队列功能,包括其创建、发送、接收等操作方法,以及在嵌入式开发中的应用实例,有助于提高多任务通信效率(如有不足,欢迎指出)。

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

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

相关文章

【开题答辩全过程】以 C语言程序设计课程网站为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人,语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…

手机上有哪些比较好用的待办事项提醒工具

在快节奏的现代工作中,我们每天都要面对大量的任务与事务。从项目截止日期、客户会议,到日常的工作安排,琐碎的事项容易让人顾此失彼。 手机待办事项工具早已突破传统“记事本”的局限,成为移动办公场景下的效率核心。它们通过任务…

Mysql数据库事务全解析:概念、操作与隔离级别

MySQL系列 文章目录MySQL系列一、什么是事务1.1事务的核心概念1.2、 事务的四大属性(ACID)1.2.1 原子性(Atomicity)1.2.2 一致性(Consistency)1.2.3 隔离性(Isolation)1.2.4 持久性&…

【MCU EEPROM开发教程】

简单来说把eeprom芯片当成一个传感器来使用,通过IIC/SPI等协议对芯片进行读写操作,具体的读写操作涉及到一些算法—怎么样读写更加快速,以及一些异常错误处理。 应用场景: 对于一些掉电也不能丢失的数据要存在eeprom/flash中&…

Docker将镜像搬移到其他服务上的方法

导出/加载镜像(保留分层、标签)和导出/导入容器快照(仅文件系统,丢失镜像历史与标签)。 一、把镜像打包带走(推荐) 适合把一个或多个镜像搬到离线/内网机器,保留分层与标签。 在源服…

Ubuntu 系统安装 Miniconda 完整方法与注意事项

一、完整安装步骤 1. 下载 Miniconda 安装包 Miniconda 安装包为 .sh 格式脚本,下载途径分两种: 方式 1:浏览器下载(适合新手) 访问 Miniconda 官方下载页,选择对应系统版本(Ubuntu 选 Miniconda3-latest-Linux-x86_64.sh),默认保存到用户目录的 ~/Downloads 文件夹…

【后端】数据库四大范式详细解析

梳理一下 MySQL(或关系型数据库)中的第一、二、三、四范式,这是数据库设计中非常重要的规范化理论。1️⃣ 第一范式 (1NF:First Normal Form)定义:字段具有原子性,不可再分。数据表中每一列都必须是不可分割…

HarmonyOS后台任务调度:JobScheduler与WorkManager实战指南

本文将深入探讨HarmonyOS 5(API 12)中的后台任务调度机制,重点讲解JobScheduler和WorkManager的使用方法、适用场景及最佳实践,帮助开发者实现高效、智能的后台任务管理。 1. 后台任务调度概述 HarmonyOS提供了两种主要的后台任务…

Prompt工程实践

你在写prompt时候,是不是总觉得大模型它不听话。要么答非所问、要么一堆废话。扒开思考过程仔细阅读时而觉得它聪明绝顶,时而又觉得它愚蠢至极。明明已经对了怎么又推理到错的地方去了,明明在提示词中提醒过了不要这么思考它怎么就瞎想了。这…

基于springboot的毕业旅游一站式定制系统

博主介绍:java高级开发,从事互联网行业六年,熟悉各种主流语言,精通java、python、php、爬虫、web开发,已经做了多年的设计程序开发,开发过上千套设计程序,没有什么华丽的语言,只有实…

输入1.8V~5.5V 输出28V DCDC升压芯片TLV61046A

今天来一款TI的升压芯片TLV61046A。输入电压范围1.8V~5.5V。最高可以输出28V。开关电流980mA,那具体能输出多大的电流就得看输入输出的电压了。以上面的输入3.6V输出12V为例,效率是85%,那最高可以输出的电流就差不多只有200mA左右。封装也是非…

ubuntu22.04源码安装ffmpeg-4.4

# ubuntu22.04源码安装ffmpeg-4.4cd /tmpwget https://ffmpeg.org/releases/ffmpeg-4.4.6.tar.xztar -xvf ffmpeg-4.4.6.tar.xzcd ffmpeg-4.4.6apt updateapt install -y yasm pkg-config libx264-dev libx265-dev libvpx-dev libfdk-aac-dev libmp3lame-dev libopus-dev libav…

Pyhon中字符串常用的函数

一、字符串的格式化1.format()方法format()是 Python 中用于字符串格式化的方法,通过占位符(如 {})动态插入变量或表达式。name小明 age18 grade99.556245585 information"我是{},今年{}岁了,考试得分:{:.2f}&quo…

小迪安全v2023学习笔记(八十一讲)—— 框架安全ThinkPHPLaravelStruts2SpringBootCVE复现

文章目录前记服务攻防——第八十一天开发框架安全&SpringBoot&Struts2&Laravel&ThinkPHP&CVE复现开发框架 - 常见语言开发框架PHP - 框架安全-Thinkphp&LaravelLaravel漏洞介绍漏洞复现CVE-2021-3129ThinkPHP漏洞介绍漏洞复现CVE-2018-1002015QVD-2022…

从音频到Token:构建原神角色语音识别模型的完整实践

本文将带你从零实现一个基于音频Token化的角色语音识别系统,完整复现原神角色语音分类任务,包含数据处理、模型训练和推理全流程。音频波形通过滑动窗口转换为数值Token序列的过程 一、为什么需要音频Token化? 传统音频处理通常依赖MFCC、频谱…

关于TCP和UDP两种网络协议的区别

1、tcp协议TCP (Transmission Control Protocol - 传输控制协议)TCP 的核心目标是为应用层提供一条可靠的、无差错的、有序的字节流通道。主要特点:面向连接:在数据传输之前,必须通过“三次握手”建立稳定的连接,传输结束后通过“…

Alibaba Lens:阿里巴巴推出的 AI 图像搜索浏览器扩展,助力B2B采购

本文转载自:https://www.hello123.com/alibaba-lens ** 一、🌟 一键截图,轻松找货:采购神器 Alibaba Lens 详解 Alibaba Lens 是阿里巴巴集团专为全球 B2B 采购商打造的一款智能浏览器插件(支持 Chrome 等主流浏览器…

WPF常见问题清单

1.Grid 内容自动换行及自适应行高 <DataGrid Grid.Row"1" FontSize"14" IsReadOnly"True" VerticalScrollBarVisibility"Auto" RowHeight"NaN" ItemsSource"{Binding List}" AutoGenerateColumns"False…

Linux驱动开发笔记(十)——中断

视频&#xff1a;第13.1讲 Linux中断实验-Linux内核中断框架简介_哔哩哔哩_bilibili 文档&#xff1a;《【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.81.pdf》五十一章 1. 中断API函数 每个中断都有一个中断号&#xff0c;通过中断号即可区分不同的中断。在Linux 内核中使用一…

ubuntu18.04安装PCL1.14

简化版说明 1. 安装依赖库&#xff1a; (1) boost1.84 &#xff08;https://www.boost.org/releases/1.84.0/&#xff09; tar vxf boost_xxx.tar.gz ./bootstrap.sh --prefix/usr/local/ ./b2 sudo ./b2 install (2) vtk9.1.0 &#xff08;https://vtk.org/files/releas…