0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何使用消息队列进行通信

汽车电子技术 来源:物联网知识 作者:跋扈洋 2023-01-20 16:32 次阅读

引言

我们在裸机开发中,每个函数之间进行数据通信往往采用全局变量。而在嵌入式开发中。我们在进行进程间通信的时候,往往采用消息队列。对于操作系统来说,消息队列是非常重要的一个数据结构。本文将介绍一下,如何使用消息队列进行通信。

介绍

消息队列概念

队列又称消息队列,是一种常用于任务间通信的数据结构,队列可以在任务与任务间、中断和任务间传递信息,实现了任务接收来自其他任务或中断的不固定长度的消息,任务能够从队列里面读取消息,当队列中的消息是空时,读取消息的任务将被阻塞,用户还可以指定阻塞的任务时间 xTicksToWait,在这段时间中,如果队列为空,该任务将保持阻塞状态以等待队列数据有效。当队列中有新消息时,被阻塞的任务会被唤醒并处理新消息;当等待的时间超过了指定的阻塞时间,即使队列中尚无有效数据,任务也会自动从阻塞态转为就绪态。消息队列是一种异步的通信方式。

FreeRTOS中的消息队列函数

  1. 设定消息队列的格式:osMessageQDef(myQueue, len, size);
  • myQueue是消息队列的名称。
  • len是消息队列的长度(有几个消息)
  • size是每个消息的大小,也就是每个元素的格式
  1. 创建消息:osMessageCreate(osMessageQ(myQueue01), NULL);

    创建消息的函数,实际上是调用了FreeRTOS的osMessageCreate()函数,只不过HAL库进行了封装。

  2. 向消息队列发送消息

    我们这里来介绍在中断中发送消息。使用函数xQueueSendFromISR(QueueHandle,&Res,time);

    其中:

  • QueueHandle:消息队列的句柄
  • &Res:要发送的数据的地址
  • time:阻塞时间,就是如果消息队列满的时候,任务应该阻塞多久
  1. 接收消息队列中的消息

    xQueueReceive(QueueHandle,&queue_buffer,time);

  • QueueHandle:消息队列的句柄
  • &queue_buffer:接收的消息要存放在的地址
  • time:阻塞时间,就是如果消息队列空的时候,任务应该阻塞多久
  1. 查询消息队列中消息的数量

    uxQueueMessagesWaiting(myQueue01Handle),可以返回消息队列(句柄为myQueue01Handle)中消息的数量,返回值为整数。

实例

需求分析

此样例我们使用PC充当上位机,上位机发送数据后,在串口中断函数中将接收到的PC数据发送在消息队列myQueue01Handle中,之后在一个接收线程中接收这个消息的内容,并通过串口将接受到的消息的大小和内容输出出来。

发送消息

当上位机PC下发数据后,串口中断函数将接收到的数据发送在消息队列中。

void USART3_IRQHandler(void)
{
	uint8_t Res;
if(__HAL_UART_GET_FLAG(&huart3,UART_FLAG_RXNE)!=RESET)//检测到有单个字节的中断
{
	HAL_UART_Receive(&huart3,&Res,1,0Xffff); 
	xQueueSendFromISR(myQueue01Handle,&Res,0)//发送消息
}
else if(__HAL_UART_GET_FLAG(&huart3,UART_FLAG_IDLE)!=RESET)//空闲中断(代表这一帧数据传输完了)
{
	printf(" Receive a frame data.");
	__HAL_UART_CLEAR_IDLEFLAG(&huart3)
}

接收消息

我们创建一个任务,此任务的重要功能就是接收消息队列中的消息。我们将接受到的消息的大小和内容通过串口发送出来。没有消息的时候,一直实现LED的闪烁。

void LEDToggleTesk(void const * argument)
{
  /* USER CODE BEGIN LEDToggleTesk */
  BaseType_t xReturn=pdTRUE;//定义一个创建消息返回值,默认为pdTRUE
  UBaseType_t num_queue ;
  uint8_t Res[20];//存放我们接收到的一包数据
  uint8_t queue_buffer;
  int i=0;//接收数组下标
  for(;;)
  {
    i=0;
    HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
    num_queue=uxQueueMessagesWaiting(myQueue01Handle);//获取消息队列中有多少数据
    while(num_queue--)
    {
      xReturn=xQueueReceive(myQueue01Handle,&queue_buffer,0);//将消息队列中的数据放在queue_buffer中
      if(xReturn)
      Res[i++]=queue_buffer;  
    }
    if(i!=0)
    printf(" count %d,LEDTask Receive %s",i,Res);//输出接收消息的大小和内容
    osDelay(500);
  }
}

现象

PC端发送123456789,MCU回复

Receive a frame data

count 8,LEDTask Receive 12345678!

微信截图_20230105161930.png

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5082

    文章

    19104

    浏览量

    304816
  • 操作系统
    +关注

    关注

    37

    文章

    6801

    浏览量

    123285
  • 消息队列
    +关注

    关注

    0

    文章

    33

    浏览量

    2972
收藏 人收藏

    评论

    相关推荐

    Linux下进程通讯消息队列

    进行通信。 消息队列与 FIFO 很相似,都是一个队列结构,都可以有多个进程往队列里面写信息,多个进程从
    的头像 发表于 08-19 19:56 1815次阅读
    Linux下进程通讯消息<b class='flag-5'>队列</b>

    不同VI间的队列通信问题

    使用生产者消费者循环做多VI间的数据通信,VI1中处理的数据进入VI2的队列中,请问VI2的队列如何在VI1中引用?点队列引用右键创建常量么?
    发表于 12-25 14:32

    dsp与labview进行串口实时通信,每次接受的数据存在数组里还是存在队列里呢?

    dsp与labview进行串口实时通信,每次接受的数据存在数组里还是存在队列里呢?
    发表于 03-26 18:07

    使用队列进行多串口通信的数据储存有什么好方法?

    两个串口通信,现需要将通讯获得的数据存进EXCEL同一SHEET里面,想尝试使用队列但无法解决存进EXCEL的同一行,想问问有无更好的解决发放,现在两个通信程序皆可正常运行,仅数据储存模块不知怎么解决。
    发表于 05-03 14:40

    请问ESP32单核如何使用FreeRTOS测试队列进行任务间通信

    请问ESP32单核如何使用FreeRTOS测试队列进行任务间通信
    发表于 01-14 07:12

    请问ESP32双核如何使用队列进行任务间通信

    队列是什么?ESP32双核如何使用队列进行任务间通信
    发表于 01-14 07:24

    FreeRTOS队列创建任务间通信的基本应用程序

    应用程序 : 此代码是 FreeRTOS 队列创建任务间通信的基本应用程序 。 BSP 版本: M480系列 BSP CMSIS V3.04.000 硬件: NuMaker-PFM-M487
    发表于 08-22 07:12

    FreeRTOS队列创建任务间通信的基本应用程序

    应用程序 : 此代码是 FreeRTOS 队列创建任务间通信的基本应用程序 。 BSP 版本: M480系列 BSP CMSIS V3.04.000 硬件: NuMaker-PFM-M487
    发表于 08-30 07:56

    什么是消息队列?消息队列中间件重要吗?

    应用解耦:消息队列减少了服务之间的耦合性,不同的服务可以通过消息队列进行通信,而不用关心彼此的实现细节。
    的头像 发表于 11-07 14:55 1411次阅读

    如何使用消息队列进行通信

    我们在裸机开发中,每个函数之间进行数据通信往往采用全局变量。而在嵌入式开发中。我们在进行进程间通信的时候,往往采用消息队列。对于操作系统来说,消息
    的头像 发表于 01-20 11:42 1352次阅读
    如何使用消息<b class='flag-5'>队列</b><b class='flag-5'>进行</b><b class='flag-5'>通信</b>

    嵌入式环形队列和消息队列的实现

    嵌入式环形队列和消息队列是实现数据缓存和通信的常见数据结构,广泛应用于嵌入式系统中的通信协议和领域。
    的头像 发表于 04-14 11:52 1553次阅读

    嵌入式环形队列和消息队列是如何去实现的?

    嵌入式环形队列和消息队列是实现数据缓存和通信的常见数据结构,广泛应用于嵌入式系统中的通信协议和领域。
    发表于 05-20 14:55 1129次阅读

    FreeRTOS消息队列介绍

    队列是为了任务与任务、任务与中断之间的通信而准备的,可以在任务与任务、任务与中断之间传递消息,队列中可以存储有限的、大小固定的数据项目。任务与任务、任务与中断之间要交流的数据保存在队列
    的头像 发表于 07-06 16:58 803次阅读
    FreeRTOS消息<b class='flag-5'>队列</b>介绍

    进程间通信的消息队列介绍

    消息队列是一种非常常见的进程间通信方式。
    的头像 发表于 04-08 17:27 309次阅读

    JavaWeb消息队列使用指南

    用程序的通信方法,允许异步传输消息,并且具有存储和转发消息的能力。它主要解决以下问题: 异步处理 :允许系统组件异步处理任务,提高响应速度。 解耦系统 :不同系统组件之间通过消息队列通信,降低耦合度。 流量削峰 :在高流量情况下
    的头像 发表于 11-25 09:27 142次阅读