ESP32-IDF的Freertos消息队列的创建与基础应用

本文深入介绍了FreeRTOS中消息队列的概念、作用及API调用,强调了其在任务间通信和中断处理中的重要性。通过 ESP32-IDF 实验展示了如何创建、发送和接收消息,以及中断服务程序中的消息传递。同时,文章提供了API函数如xQueueCreate、xQueueSend、xQueueReceive等的使用示例,并分析了返回值的意义。

实战派 ESP32-S3,双模无线开发板

ESP32-S3 原生支持 ESP-IDF,WiFi + 蓝牙一次搞定


前言

写博客是为了总结知识,提炼知识不做知识的搬运者
文章不一定全是原创但是所写内容都有经过自身研读与提炼
喜欢我博客的朋友可以跟我交流与点赞,


一、消息队列是什么?

队列是任务间通信的主要形式。它们可用于在任务之间以及中断和任务之间发送消息。在大多数情况下,它们用作线程安全的 FIFO(先进先出)缓冲区,将新数据发送到队列的后面,尽管数据也可以发送到前面。

在这里插入图片描述

  • 是一种常用于任务间通信的数据结构队列可以在任务与任务间、中断和任务间传递信息,实现了任务接收来自其他任务或中断的不固定长度的消息,任务能够从队列里面读取消息。
  • 当队列中的消息是空时,读取消息的任务将被阻塞,用户还可以指定阻塞的任务时间 xTicksToWait,在这段时间中,如果队列为空,该任务将保持阻塞状态以等待队列数据有效。当队列中有新消息时,被阻塞的任务会被唤醒并处理新消息;当等待的时间超过了指定的阻塞时间,即使队列中尚无有效数据,任务也会自动从阻塞态转为就绪态。
  • 通过消息队列服务,任务或中断服务例程可以将一条或多条消息放入消息队列中。同
    样,一个或多个任务可以从消息队列中获得消息。当有多个消息发送到消息队列时,通常
    是将先进入消息队列的消息先传给任务,也就是说,任务先得到的是最先进入消息队列的
    消息,即先进先出原则(FIFO),但是也支持后进先出原则(LIFO)。

总结:队列是单片机数据结构,用于任务间的通信,任务可以在一个队列(这个队列是自己定义的大小)中发送和收取多个消息,可以设置阻塞状态,超过阻塞状态会自动就绪处于发送或者接收信息

二、消息队列的作用

  • 使用消息队列可以让 RTOS 内核有效地管理任务,而全局数组是无法做到的,任务的超时等机制需要用户自己去实现
  • 使用了全局数组就要防止多任务的访问冲突,而使用消息队列则处理好了这个问题,用户无需担心。
  • 使用消息队列可以有效地解决中断服务程序与任务之间消息传递的问题。
  • FIFO 机制更有利于数据的处理。
  • 消息队列可以应用于发送不定长消息的场合,包括任务与任务间的消息交换,队列是
    FreeRTOS 主要的任务间通讯方式,可以在任务与任务间、中断和任务间传送信息,发送到
    队列的消息是通过拷贝方式实现的,这意味着队列存储的数据是原数据,而不是原数据的
    引用。
    这部分内容由于实践项目应用不够无法多于总结

三、FreeRtos中消息队列API的调用

使用丰富的API23个函数可以实现 FreeRTOS 的消息队列官网链接:API链接

重要函数理解:

函数 xQueueCreate

函数返回类型为指针QueueHandle_t所以需要提前定义一个指针QueueHandle_t queuex;用于函数的返回,即
queue =QueueHandle_t xQueueCreate(x,x)


QueueHandle_t xQueueCreate
	( UBaseType_t uxQueueLength, /* 消息个数 */
        UBaseType_t uxItemSize ); /* 每个消息大小,单位字节 */

函数 xQueueSend


BaseType_t xQueueSend(
       QueueHandle_t xQueue, /* 消息队列句柄 */
       const void * pvItemToQueue, /* 要传递数据地址 */
       TickType_t xTicksToWait /* 等待消息队列有空间的最大等待时间 */
 );

重点:

  • 接收到消息以后可以自动删除当前已经接收的消息接收下一个队列里面的消息,
  • 区分一下中断里面的xQueueSendFromISR,
  • 了解调用API的返回值

在这里插入图片描述

在这里插入图片描述

函数 xQueueReceive


BaseType_t xQueueReceive(
        QueueHandle_t xQueue, /* 消息队列句柄 */
        void *pvBuffer, /* 接收消息队列数据的缓冲地址 */
 	TickType_t xTicksToWait /* 等待消息队列有数据的最大等待时间 */
 );

函数 xQueueSendFromISR


BaseType_t xQueueSendFromISR
	 (
	 QueueHandle_t xQueue, /* 消息队列句柄 */
	 const void *pvItemToQueue, /* 要传递数据地址 */
	 BaseType_t *pxHigherPriorityTaskWoken /* 高优先级任务是否被唤醒的状态保存 */
 );

中断函数里面调用发送队列的信息

函数 uxQueueMessagesWaiting

UBaseType_t uxQueueMessagesWaiting(QueueHandle_t xQueue);

函数 uxQueueSpacesAvailable

UBaseType_t uxQueueSpacesAvailable(QueueHandle_t xQueue);

函数 xQueuePeek


 BaseType_t xQueuePeek(
                          QueueHandle_t xQueue,
                          无效 *pvBuffer,
                          TickType_t xTicksToWait
                       );

函数 xQueueOverwrite

 BaseType_t xQueueOverwrite(
                             QueueHandle_t xQueue,
                           const void * pvItemToQueue
                              );
 

接收到消息以后不会自动删除当前已经接收的消息不会接收下一个队列里面的消息,一直卡在了队头

四、基于esp32-idf实验

这个实验不拘泥于任何单片机,可以在任何单片机上运行

#include <stdio.h>

实战派 ESP32-S3,双模无线开发板

ESP32-S3 原生支持 ESP-IDF,WiFi + 蓝牙一次搞定

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值