FreeRTOS 体验教程:6.如何用消息队列实现FreeRTOS多线程通信?

FreeRTOS 消息队列使用教程

在 FreeRTOS 中,消息队列(Queue)是实现任务间通信的重要机制之一。通过队列,任务可以在不同优先级上下文中安全地传递数据。本文将详细介绍如何创建和使用 FreeRTOS 消息队列。

1. 创建队列 API

首先,使用 xQueueCreate 函数创建一个队列。该函数的定义在 queue.h 中,受控于动态内存申请的宏 configSUPPORT_DYNAMIC_ALLOCATION(定义在 FreeRTOS.h 中),该宏默认是启用的。
image.png
image.png

2. 添加头文件

为了使用队列相关的 API 函数,您需要包含 queue.h 头文件:

#include "queue.h"

image.png

3. 声明并创建消息队列

确保包含正确的头文件,并在代码中声明和创建消息队列:

void createMyQueue(void)
{
	if (queueHandle == NULL)
	{
		queueHandle = xQueueCreate(10, 64);
	}
}

image.png

4. 发送函数

在 FreeRTOS 中,有多个函数可用于向队列发送消息。以下是一些常用的发送函数:

// 写入到队末,队列满后,超时不会插入
xQueueSend(xQueue, &item, portMAX_DELAY); 

// 写入到队末,队列满后,超时不会插入 
xQueueSendToBack(xQueue, &item, portMAX_DELAY); 

// 覆盖队末,队列满后,超时不会插入 
xQueueOverwrite(xQueue, &item); 

// 写入到队首,队列满后,超时不会插入 
xQueueSendToFront(xQueue, &item, portMAX_DELAY);

其中 xQueueSendxQueueSendToBack 命名不同但内部实现是相同的:
image.png
image.png

5. 接收函数

以下是接收队列消息的两个常用函数:

// 从队列中取出消息,并删除该消息 
xQueueReceive(xQueue, &item, portMAX_DELAY); 

// 从队列中取出消息,但不删除队列中的该消息 
xQueuePeek(xQueue, &item, portMAX_DELAY);

6. 队列满时的处理

6.1 使用 xQueueSend 发送消息,队列满了之后的处理

  1. 假设任务每 100 毫秒发送一次消息,我们可以使用以下方法验证效果:
    image.png

  2. 使用 xQueuePeek 读取小时,每 1S 读取一次:
    image.png
    效果:读队首,入队末,所以读出来的数据一直没变
    image.png

  3. 使用 xQueueReceive 读取小时,每 1S 读取一次:
    image.png
    效果:队列满后消息插入失败
    image.png
    xQueueSendToBack的实际实现跟xQueueSend完全一致,这里就不尝试了,队列满了,使用xQueueSendOverwrite会如何?

6.2 使用 xQueueSendOverwrite 发送消息,队列满了之后的处理

假设任务每 100 毫秒使用 xQueueSendOverwrite 发送一次消息:
image.png

在接收端,同样可以使用 xQueuePeekxQueueReceive

  1. 使用 xQueuePeek 读取小时,每 1S 读取一次,效果如下:队列满后重新覆盖
    image.png

  2. 使用 xQueueReceive 读取小时,每 1S 读取一次,效果如下:
    image.png

如果 xQueueSendToFront 发送时,队列满了,又会如何?

6.3 使用 xQueueSendToFront 发送消息,队列满了之后的处理

假设任务每 100 毫秒使用 xQueueSendToFront 发送一次消息:
image.png

在接收端,同样可以使用 xQueuePeekxQueueReceive

  1. 使用 xQueuePeek 读取小时,每 1S 读取一次,效果如下:队列满后插入消息失败
    image.png

  2. 使用 xQueueReceive 读取小时,每 1S 读取一次,效果如下:
    image.png

7. 实际使用中的注意事项

在实际项目中使用 FreeRTOS 消息队列时,还需要考虑以下几点:

  1. 队列长度和项目需求匹配:确保队列长度设置合理,能够容纳任务间传递的消息量。
  2. 优先级反转:在高优先级任务频繁获取队列时,可能导致低优先级任务饥饿。可以通过使用信号量等机制来缓解这一问题。
  3. 实时性要求:根据系统的实时性要求,选择适当的发送和接收函数及其超时时间。

通过本文的介绍,我们详细了解了 FreeRTOS 消息队列的创建、发送和接收的不同方式及其行为特性。掌握这些基本操作后,您可以根据项目的具体需求,灵活应用消息队列来实现任务间的高效通信。

也可扫码关注博主同名公众号"不解之榬" 更多相关文章
不解之榬

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值