当前位置: 首页 > news >正文

B站Michale_ee——ESP32_IDF SDK——FreeRTOS_2 队列

一、通过队列传递三种类型数据(整型、结构体、指针)

1.队列简介

  • FreeRTOS中的队列本质就是一个先入先出的缓冲区(FIFO,First Input First Output)
    在这里插入图片描述

2.API简介

(1)创建队列的API

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(2)发送数据到队列的API

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(3)从队列中接收数据的API

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(4)查询当前队列中项的数量

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.示例代码及运行结果

(1)通过队列传递整型数据

#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"
#include "freertos/queue.h"       // add by lxlTaskHandle_t SendTask_Handle = NULL;
TaskHandle_t RecvTask_Handle = NULL;void SendTask(void *pvParam)
{QueueHandle_t QHandle = (QueueHandle_t)pvParam;BaseType_t xStatus;int i = 0;while(1){xStatus = xQueueSend(QHandle, &i, 0);if(xStatus == pdPASS){printf("Send Successfully!\n");}else{printf("Send Fail!\n");}i++;i%=8;vTaskDelay(1000 / portTICK_PERIOD_MS);}
}void RecvTask(void *pvParam)
{QueueHandle_t QHandle = (QueueHandle_t)pvParam;BaseType_t xStatus;int i = 0;while(1){if(uxQueueMessagesWaiting(QHandle) != 0){xStatus = xQueueReceive(QHandle, &i, 0);if(xStatus == pdPASS){printf("recv:%d\n", i);}else{printf("recv fail\n");}}else{printf("No data in queue.\n");}vTaskDelay(1000 / portTICK_PERIOD_MS);}
}void app_main(void)
{QueueHandle_t QHandle = NULL;QHandle = xQueueCreate(5, sizeof(int));if(QHandle != NULL){printf("Create Queue Successfully!\n");xTaskCreate(SendTask, "SendTask", 1024 *5, (void *)QHandle, 1, &SendTask_Handle);    //! FreeRTOS的任务优先级值越大,优先级越高;xTaskCreate(RecvTask, "RecvTask", 1024 *5, (void *)QHandle, 1, &RecvTask_Handle);}else{printf("Create Queue Fail\n");}
}

在这里插入图片描述
在这里插入图片描述

(2)通过队列传递结构体类型数据

#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"
#include "freertos/queue.h"       // add by lxlTaskHandle_t SendTask_Handle = NULL;
TaskHandle_t RecvTask_Handle = NULL;typedef struct A_Struct{char MessageID;char Data;
} xStruct;void SendTask(void *pvParam)
{QueueHandle_t QHandle = (QueueHandle_t)pvParam;BaseType_t xStatus;xStruct xSendData = {0, 1};while(1){xStatus = xQueueSend(QHandle, &xSendData, 0);if(xStatus == pdPASS){printf("Send Successfully!\n");}else{printf("Send Fail!\n");}xSendData.MessageID++;xSendData.MessageID %= 8;vTaskDelay(1000 / portTICK_PERIOD_MS);}
}void RecvTask(void *pvParam)
{QueueHandle_t QHandle = (QueueHandle_t)pvParam;BaseType_t xStatus;xStruct RecvData={0,0};while(1){if(uxQueueMessagesWaiting(QHandle) != 0){xStatus = xQueueReceive(QHandle, &RecvData, 0);if(xStatus == pdPASS){printf("recv:ID->%d;Data->%d\n", RecvData.MessageID, RecvData.Data);}else{printf("recv fail\n");}}else{printf("No data in queue.\n");}vTaskDelay(1000 / portTICK_PERIOD_MS);}
}void app_main(void)
{QueueHandle_t QHandle = NULL;QHandle = xQueueCreate(5, sizeof(xStruct));if(QHandle != NULL){printf("Create Queue Successfully!\n");xTaskCreate(SendTask, "SendTask", 1024 *5, (void *)QHandle, 1, &SendTask_Handle);    //! FreeRTOS的任务优先级值越大,优先级越高;xTaskCreate(RecvTask, "RecvTask", 1024 *5, (void *)QHandle, 1, &RecvTask_Handle);}else{printf("Create Queue Fail\n");}
}

在这里插入图片描述

在这里插入图片描述

(3)通过队列传递指针类型的数据

#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"
#include "freertos/queue.h"       // add by lxlTaskHandle_t SendTask_Handle = NULL;
TaskHandle_t RecvTask_Handle = NULL;#define DATA_NUM    5
#define DATA_SIZE   50void SendTask(void *pvParam)
{QueueHandle_t QHandle = (QueueHandle_t)pvParam;BaseType_t xStatus;char * pStrToSend = NULL;int i = 0;while(1){pStrToSend = malloc(DATA_SIZE);snprintf(pStrToSend, DATA_SIZE, "Today is a good day! ->%d\r\n", i);xStatus = xQueueSend(QHandle, &pStrToSend, 0);      //! 注意此处传递的是指针的地址,即指针的指针;if(xStatus == pdPASS){printf("Send Successfully!\n");}else{printf("Send Fail!\n");}i++;i%=8;vTaskDelay(1000 / portTICK_PERIOD_MS);}
}void RecvTask(void *pvParam)
{QueueHandle_t QHandle = (QueueHandle_t)pvParam;BaseType_t xStatus;char * pStrToRecv = NULL;while(1){if(uxQueueMessagesWaiting(QHandle) != 0){xStatus = xQueueReceive(QHandle, &pStrToRecv, 0);if(xStatus == pdPASS){printf("recv:%s\n", pStrToRecv);}else{printf("recv fail\n");}}else{printf("No data in queue.\n");}vTaskDelay(1000 / portTICK_PERIOD_MS);}
}void app_main(void)
{QueueHandle_t QHandle = NULL;QHandle = xQueueCreate(DATA_NUM, DATA_SIZE);if(QHandle != NULL){printf("Create Queue Successfully!\n");xTaskCreate(SendTask, "SendTask", 1024 *5, (void *)QHandle, 1, &SendTask_Handle);    //! FreeRTOS的任务优先级值越大,优先级越高;xTaskCreate(RecvTask, "RecvTask", 1024 *5, (void *)QHandle, 1, &RecvTask_Handle);}else{printf("Create Queue Fail\n");}
}

在这里插入图片描述

在这里插入图片描述

二、队列多进单出传递数据

1.简介

在这里插入图片描述

  • 在队列多进单出的情况下,通常从队列接收数据的任务设置为较高的优先级,并且接收队列的API等待时间设置为portMAX_DELAY。这样当队列中没有数据时,从队列接收数据的任务就会阻塞等待;一旦队列中有数据,从队列接收数据的任务就会读取数据。向队列发送数据的任务可根据数据重要性分配优先级;

2.示例代码及运行结果

#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"
#include "freertos/queue.h"       // add by lxlTaskHandle_t SendTask_Handle = NULL;
TaskHandle_t RecvTask_Handle = NULL;typedef struct 
{char DataID;int Data;
} Data_t;void SendTask1(void *pvParam)
{QueueHandle_t QHandle = (QueueHandle_t)pvParam;BaseType_t xStatus;Data_t SendData = {1, 11};while(1){xStatus = xQueueSend(QHandle, &SendData, 0);      //! 注意此处传递的是指针的地址,即指针的指针;if(xStatus == pdPASS){printf("Send Task 1 Successfully!\n");}else{printf("Send Task 1 Fail!\n");}vTaskDelay(1000 / portTICK_PERIOD_MS);}
}void SendTask2(void *pvParam)
{QueueHandle_t QHandle = (QueueHandle_t)pvParam;BaseType_t xStatus;Data_t SendData = {2, 22};while(1){xStatus = xQueueSend(QHandle, &SendData, 0);      //! 注意此处传递的是指针的地址,即指针的指针;if(xStatus == pdPASS){printf("Send Task 2 Successfully!\n");}else{printf("Send Task 2 Fail!\n");}vTaskDelay(1000 / portTICK_PERIOD_MS);}
}void RecvTask(void *pvParam)
{QueueHandle_t QHandle = (QueueHandle_t)pvParam;BaseType_t xStatus;Data_t RecvData = {0, 0};while(1){xStatus = xQueueReceive(QHandle, &RecvData, portMAX_DELAY);if(xStatus == pdPASS){printf("recv-> ID:%d, Data:%d\n", RecvData.DataID, RecvData.Data);}else{printf("recv fail\n");}}
}void app_main(void)
{QueueHandle_t QHandle = NULL;QHandle = xQueueCreate(5, sizeof(Data_t));if(QHandle != NULL){printf("Create Queue Successfully!\n");xTaskCreate(SendTask1, "SendTask1", 1024 *5, (void *)QHandle, 1, NULL);    //! FreeRTOS的任务优先级值越大,优先级越高;xTaskCreate(SendTask2, "SendTask2", 1024 *5, (void *)QHandle, 1, NULL);xTaskCreate(RecvTask, "RecvTask", 1024 *5, (void *)QHandle, 2, &RecvTask_Handle);}else{printf("Create Queue Fail\n");}
}

在这里插入图片描述

三、队列集合

1.简介

在这里插入图片描述

2.API简介

(1)创建队列集合

在这里插入图片描述

(2)将队列添加到队列集合

在这里插入图片描述

(3)从队列集合中选择有数据的队列

在这里插入图片描述
在这里插入图片描述

(4)官方示例

在这里插入图片描述

3.示例代码及运行结果

#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"
#include "freertos/queue.h"       // add by lxlTaskHandle_t SendTask_Handle = NULL;
TaskHandle_t RecvTask_Handle = NULL;typedef struct 
{char DataID;int Data;
} Data_t;void SendTask1(void *pvParam)
{QueueHandle_t QHandle = (QueueHandle_t)pvParam;BaseType_t xStatus;Data_t SendData = {1, 11};while(1){xStatus = xQueueSend(QHandle, &SendData, 0);      //! 注意此处传递的是指针的地址,即指针的指针;if(xStatus == pdPASS){printf("Send Task 1 Successfully!\n");}else{printf("Send Task 1 Fail!\n");}vTaskDelay(1000 / portTICK_PERIOD_MS);}
}void SendTask2(void *pvParam)
{QueueHandle_t QHandle = (QueueHandle_t)pvParam;BaseType_t xStatus;Data_t SendData = {2, 22};while(1){xStatus = xQueueSend(QHandle, &SendData, 0);      //! 注意此处传递的是指针的地址,即指针的指针;if(xStatus == pdPASS){printf("Send Task 2 Successfully!\n");}else{printf("Send Task 2 Fail!\n");}vTaskDelay(1000 / portTICK_PERIOD_MS);}
}void RecvTask(void *pvParam)
{QueueSetHandle_t QueueSet = (QueueSetHandle_t)pvParam;QueueSetMemberHandle_t QueueData;BaseType_t xStatus;Data_t RecvData = {0, 0};while(1){QueueData = xQueueSelectFromSet(QueueSet, portMAX_DELAY);xStatus = xQueueReceive(QueueData, &RecvData, portMAX_DELAY);if(xStatus == pdPASS){printf("recv-> ID:%d, Data:%d\n", RecvData.DataID, RecvData.Data);}else{printf("recv fail\n");}}
}void app_main(void)
{QueueHandle_t QHandle1 = NULL;QHandle1 = xQueueCreate(5, sizeof(Data_t));QueueHandle_t QHandle2 = NULL;QHandle2 = xQueueCreate(5, sizeof(Data_t));QueueSetHandle_t QueueSet;QueueSet = xQueueCreateSet(10);     // 5+5xQueueAddToSet(QHandle1, QueueSet);xQueueAddToSet(QHandle2, QueueSet);if((QHandle1 != NULL) && (QHandle2 != NULL) && (QueueSet != NULL)){printf("Create Queue Successfully!\n");xTaskCreate(SendTask1, "SendTask1", 1024 *5, (void *)QHandle1, 1, NULL);    //! FreeRTOS的任务优先级值越大,优先级越高;xTaskCreate(SendTask2, "SendTask2", 1024 *5, (void *)QHandle2, 1, NULL);xTaskCreate(RecvTask, "RecvTask", 1024 *5, (void *)QueueSet, 2, &RecvTask_Handle);}else{printf("Create Queue Fail\n");}
}

在这里插入图片描述

四、队列邮箱

1.简介

在这里插入图片描述
在这里插入图片描述

2.API简介

(1)创建队列邮箱(使用创建队列的API,把项目数设为1即可)

在这里插入图片描述

(2)向邮箱写数据

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(3)从邮箱中读数据(读取后数据依然保存在队列中)

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

3.示例代码及运行结果

#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"
#include "freertos/queue.h"       // add by lxlTaskHandle_t SendTask_Handle = NULL;
TaskHandle_t RecvTask_Handle = NULL;typedef struct 
{char DataID;int Data;
} Data_t;void WriteTask(void *pvParam)
{QueueHandle_t Mailbox = (QueueHandle_t)pvParam;BaseType_t xStatus;Data_t SendData = {1, 1};while(1){xStatus = xQueueOverwrite(Mailbox, &SendData);  if(xStatus == pdPASS){printf("Overwrite Mail Successfully!\n");}else{printf("Overwrite Mail Fail!\n");}SendData.Data ++;SendData.Data %= 8;vTaskDelay(6000 / portTICK_PERIOD_MS);}
}void ReadTask1(void *pvParam)
{QueueHandle_t Mailbox = (QueueHandle_t)pvParam;BaseType_t xStatus;Data_t SendData = {0, 0};while(1){xStatus = xQueuePeek(Mailbox, &SendData, portMAX_DELAY);      if(xStatus == pdPASS){printf("Read Mail_1 Successfully!->ID:%d, Data:%d\n", SendData.DataID, SendData.Data);}else{printf("Read Mail_1 Fail!\n");}vTaskDelay(1000 / portTICK_PERIOD_MS);}
}void ReadTask2(void *pvParam)
{QueueHandle_t Mailbox = (QueueHandle_t)pvParam;BaseType_t xStatus;Data_t SendData = {0, 0};while(1){xStatus = xQueuePeek(Mailbox, &SendData, portMAX_DELAY);      if(xStatus == pdPASS){printf("Read Mail_2 Successfully!->ID:%d, Data:%d\n", SendData.DataID, SendData.Data);}else{printf("Read Mail_2 Fail!\n");}vTaskDelay(1000 / portTICK_PERIOD_MS);}
}void ReadTask3(void *pvParam)
{QueueHandle_t Mailbox = (QueueHandle_t)pvParam;BaseType_t xStatus;Data_t SendData = {0, 0};while(1){xStatus = xQueuePeek(Mailbox, &SendData, portMAX_DELAY);      if(xStatus == pdPASS){printf("Read Mail_3 Successfully!->ID:%d, Data:%d\n", SendData.DataID, SendData.Data);}else{printf("Read Mail_3 Fail!\n");}vTaskDelay(1000 / portTICK_PERIOD_MS);}
}void app_main(void)
{QueueHandle_t Mailbox = NULL;Mailbox = xQueueCreate(1, sizeof(Data_t));      // 队列邮箱项目个数为1if(Mailbox != NULL){printf("Create Queue Successfully!\n");xTaskCreate(WriteTask, "WriteTask", 1024 *5, (void *)Mailbox, 1, NULL);    //! FreeRTOS的任务优先级值越大,优先级越高;xTaskCreate(ReadTask1, "ReadTask1", 1024 *5, (void *)Mailbox, 2, NULL);xTaskCreate(ReadTask2, "ReadTask1", 1024 *5, (void *)Mailbox, 2, NULL);xTaskCreate(ReadTask3, "ReadTask1", 1024 *5, (void *)Mailbox, 2, NULL);}else{printf("Create Queue Fail\n");}
}

在这里插入图片描述

相关文章:

  • 2025大模型微调视频课程全套(附下载)
  • 2025年渗透测试面试题总结-拷打题库30(题目+回答)
  • Curl 全面使用指南
  • node.js模块化步骤(各标准区别)CommonJS规范、AMD规范、UMD规范、ES Modules (ESM)
  • 小刚说C语言刷题—1602总分和平均分
  • 基于若依RuoYi-Vue3-FastAPI 的 Docker 部署记录
  • 驱动开发系列55 - Linux Graphics QXL显卡驱动代码分析(二)显存管理
  • 《Android 应用开发基础教程》——第十章:使用 Gson 实现网络 JSON 数据解析与对象映射
  • RAGFlow报错:ESConnection.sql got exception
  • 纯html实现的json数据转csv文件
  • 题解:洛谷 CF2091E Interesting Ratio
  • 猫,为什么是猫?
  • Y1代码AC集
  • Python协程入门指北
  • 数据结构与算法学习笔记(Acwing提高课)----动态规划·背包模型(一)
  • 奥地利学派方法论的三个基础
  • Python TensorFlow库【深度学习框架】全面讲解与案例
  • 从MCP基础到FastMCP实战应用
  • 安全学习基础入门5集
  • 9. 深入Spring AI:刨析 ChatMemory
  • 今年4月上海一二手房成交面积同比增21%,二手房成交2.07万套
  • 美国务院宣布新一轮与伊朗相关的制裁
  • 力箭二号火箭成功进行满载起竖试验,计划今年首飞发射轻舟飞船
  • 现场聆听总书记讲话,“00后”博士和大模型CEO都“热血沸腾”
  • 哈莉·贝瑞、洪常秀等出任戛纳主竞赛单元评委
  • 上海乐高乐园建设进入最后冲刺,开园限量纪念年卡将于5月开售