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

引言我们在裸机开发中,每个函数之间进行数据通信往往采用全局变量。而在嵌入式开发中。我们在进行进程间通信的时候,往往采用消息队列。对于操作系统来说,消息队列是非常重要的一个数据结构。本文将介绍一下,如何使用消息队列进行通信。
介绍消息队列概念队列又称消息队列,是一种常用于任务间通信的数据结构,队列可以在任务与任务间、中断和任务间传递信息,实现了任务接收来自其他任务或中断的不固定长度的消息,任务能够从队列里面读取消息,当队列中的消息是空时,读取消息的任务将被阻塞,用户还可以指定阻塞的任务时间 xtickstowait,在这段时间中,如果队列为空,该任务将保持阻塞状态以等待队列数据有效。当队列中有新消息时,被阻塞的任务会被唤醒并处理新消息;当等待的时间超过了指定的阻塞时间,即使队列中尚无有效数据,任务也会自动从阻塞态转为就绪态。消息队列是一种异步的通信方式。
在freertos中的消息队列函数设定消息队列的格式:osmessageqdef(myqueue, len, size);myqueue是消息队列的名称。len是消息队列的长度(有几个消息)size是每个消息的大小,也就是每个元素的格式创建消息:osmessagecreate(osmessageq(myqueue01), null);
创建消息的函数,实际上是调用了freertos的osmessagecreate()函数,只不过hal库进行了封装。
向消息队列发送消息
我们这里来介绍在中断中发送消息。使用函数xqueuesendfromisr(queuehandle,&res,time);
其中:
queuehandle:消息队列的句柄&res:要发送的数据的地址time:阻塞时间,就是如果消息队列满的时候,任务应该阻塞多久接收消息队列中的消息
xqueuereceive(queuehandle,&queue_buffer,time);
queuehandle:消息队列的句柄&queue_buffer:接收的消息要存放在的地址time:阻塞时间,就是如果消息队列空的时候,任务应该阻塞多久查询消息队列中消息的数量
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

华为P10闪存门最新消息!细扒华为P10“闪存门”事件,三星和苹果积极的推波助澜
FP5207与FP5208两款升压芯片的功能特性与参数对比
基于比特币交易隐私性的协议Zcash介绍
三输出同步降压控制器MAX15048/MAX15049
NVIDIA自动驾驶汽车正式路测
如何使用消息队列进行通信
笔记本用什么内存较好?
耐能KL720芯片的三大优势和在安防领域的应用
处理跨时钟域(CDC)信号同步的最常见方法
直线马达在电动窗帘中的应用,其原理是怎样的
量子计算的下一步是什么
ST展示完整的DOCSIS及C-DOCSIS 3.0系列方案
关于x86架构工控主板解决方案的详细介绍
光电耦合器的几个实用技巧
人工智能目前发展的怎么样了
28v的电压可以接24v电器吗?
因为美国政府禁令,AT&T不能将华为的设备用于高速网络
围绕计算机视觉领域的八大任务,进行了较为详细的综述
投影灯泡维护全攻略
小米发布新电动助力自行车 称技术媲美钢铁侠