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

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");}
}

在这里插入图片描述

http://www.xdnf.cn/news/3433.html

相关文章:

  • NU1680低成本、无固件、高集成度无线充电电源接收器
  • 速通Ollama本地部署DeepSeek-r1
  • 【Redis】String详细介绍及其应用场景
  • Angular教程前言:历史、安装与用途
  • Git---GitHub Actions
  • 大模型 Function Call
  • 力扣面试150题--旋转链表
  • 编写教育网站后端页面笔记
  • 本地部署 n8n 中文版
  • 日期有关的算法题(ctime库的使用)
  • LLM与AI Agent交互范式的演进:从工具依赖到智能协同(深度解析)
  • Google NotebookLM正式支持中文!AI笔记助手开启中文创作新纪元
  • 常见电源的解释说明
  • 设计模式简述(十四)组合模式
  • 2.4流程控制语句
  • 笔试专题(十三)
  • 上位机知识篇---二进制操作
  • 【C到Java的深度跃迁:从指针到对象,从过程到生态】第五模块·生态征服篇 —— 第十九章 Spring生态:从main函数到企业级开发
  • 数字智慧方案5968丨智慧农业产销一体化云平台建设方案(72页PPT)(文末有下载方式)
  • 深入理解C语言中的整形提升与算术转换
  • 《Android 应用开发基础教程》——第十章:使用 Gson 实现网络 JSON 数据解析与对象映射
  • STM32移植U8G2
  • 【Java面试笔记:安全】31.你了解Java应用开发中的注入攻击吗?
  • 21.2Linux中的LCD驱动实验(驱动)_csdn
  • 【大模型】图像生成:ESRGAN:增强型超分辨率生成对抗网络的革命性突破
  • 二叉树删除结点详细代码
  • 计算机视觉(CV)技术的优势和挑战(本片为InsCode)
  • OpenGL-ES 学习(9) ---- OpenGL-ES 简介和基本 Pipeline
  • 如何通过日志在本地调试LangChain编写的程序?
  • 《跨越边界:探索跨端框架中通用状态管理方案设计》