Queue的介绍
队列是任务间通信的主要形式。它们可以用于在任务之间、中断和任务之间发送消息。在大多数情况下,它们被用作线程安全的FIFO (First In First Out)缓冲区,新数据被发送到队列的后面,尽管数据也可以发送到队列的前面。
一个sendTask向队列发送数据,一个recTask从队列中接收数据。
integer
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "freertos/queue.h"
void sendTask(void *pvParam)
{
QueueHandle_t QHandle;
QHandle = (QueueHandle_t)pvParam;
BaseType_t xStatus;
int i = 0;
while (1)
{
/* code */
xStatus = xQueueSend(QHandle, &i, 0);
i++;
if (xStatus != pdPASS)
{
printf("send fail\n");
}
else
{
printf("send done\n");
}
if(i == 8){
i = 0;
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void recTask(void *pvParam)
{
QueueHandle_t QHandle;
QHandle = (QueueHandle_t)pvParam;
BaseType_t xStatus;
int j = 0;
while (1)
{
/* code */
if (uxQueueMessagesWaiting(QHandle) != 0)
{
/* code */
xStatus = xQueueReceive(QHandle, &j, 0);
if (xStatus != pdPASS)
{
printf("rec fail\n");
}
else
{
printf("rec j=%d\n", j);
}
}
else
{
printf("no data\n");
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void app_main(void)
{
QueueHandle_t QHandle;
QHandle = xQueueCreate(5, sizeof(int));
if (QHandle != NULL)
{
printf("create queue successfully\n");
xTaskCreate(sendTask, "sendTask", 1024 * 5, (void *)QHandle, 1, NULL);
xTaskCreate(recTask, "recTask", 1024 * 5, (void *)QHandle, 1, NULL);
}
else
{
printf("can not create queue\n");
}
}
首先包含#include "freertos/queue.h"头文件
使用xQueueCreate()函数创建一个QueueHandle_t类型的队列缓冲区句柄。
如果QHandle不为空,则调用xTaskCreate()语句创建两个任务,一个作为向队列缓冲区中发送数据 ,一个作为从队列缓冲区中接收数据
xTaskCreate(sendTask, "sendTask", 1024 * 5, (void *)QHandle, 1, NULL);
xTaskCreate(recTask, "recTask", 1024 * 5, (void *)QHandle, 1, NULL);
接下来分别看发送数据的任务函数sendTask():
同样是使用QueueHandle_t声明变量QHandle,通过指定的方式将形参pvParam转换为QueueHandle_t类型。
然后创建一个while(1)死循环,死循环的目的是为了不断的向队列缓冲区中发送数据,发送数据的过程就需要调用xQueueSend()函数。
这个xQueueSend()函数会返回一个BaseType_t类型的值,如果返回的值等于pdPASS,说明发送数据成功;如果返回的值不等于pdPASS,说明发送数据失败。
接着,看接收数据的任务函数recTask():
同样,创建一个while(1)死循环,为了不断的从队列缓冲区中获取数据,获取数据后就要进行循环输出。
那么为了保证接收数据的任务函数recTask()函数从队列缓冲区取值,而不是接收数据后输出莫名其妙的语句,调用uxQueueMessagesWaiting()函数来查看队列缓冲区中有无数据。
那好,如果有数据,接收数据的函数取出数据;如果没有数据,则进行输出。
那么当确认了队列缓冲区中有数据了,此时就应该调用xQueueReceive()函数取出。
xQueueReceive()的返回值同样是BaseType_t类型,返回的值等于pdPASS,说明从队列中接收数据成功,进行打印输出;
如果返回的值不等于pdPASS,说明从队列中接收数据失败。
struct
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "freertos/queue.h"
typedef struct A_STRUCT
{
/* data */
char id;
char data;
} xStruct;
void sendTask(void *pvParam)
{
QueueHandle_t QHandle;
QHandle = (QueueHandle_t)pvParam;
BaseType_t xStatus;
xStruct xUSB = {1, 55};
while (1)
{
xStatus = xQueueSend(QHandle, &xUSB, 0);
if (xStatus != pdPASS)
{
printf("send fail\n");
}
else
{
printf("send done\n");
}
xUSB.id++;
if (xUSB.id == 8)
{
xUSB.id = 0;
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void recTask(void *pvParam)
{
QueueHandle_t QHandle;
QHandle = (QueueHandle_t)pvParam;
BaseType_t xStatus;
xStruct xUSB = {0, 0};
while (1)
{
/* code */
if (uxQueueMessagesWaiting(QHandle) != 0)
{
xStatus = xQueueReceive(QHandle, &xUSB, 0);
if (xStatus != pdPASS)
{
printf("rec fail\n");
}
else
{
printf("rec id=%d, data=%d!\n", xUSB.id, xUSB.data);
}
}
else
{
printf("no data\n");
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void app_main(void)
{
QueueHandle_t QHandle;
QHandle = xQueueCreate(5, sizeof(xStruct));
if (QHandle != NULL)
{
printf("create queue successfully\n");
xTaskCreate(sendTask, "sendTask", 1024 * 5, (void *)QHandle, 1, NULL);
xTaskCreate(recTask, "recTask", 1024 * 5, (void *)QHandle, 1, NULL);
}
else
{
printf("can not create queue\n");
}
}
pointer
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "freertos/queue.h"
void sendTask(void *pvParam)
{
QueueHandle_t QHandle;
QHandle = (QueueHandle_t)pvParam;
BaseType_t xStatus;
char *pStrToSend;
int i = 0;
while (1)
{
pStrToSend = (char *)malloc(50);
snprintf(pStrToSend, 50, "Today is a good day %d\r\n", i);
i++;
xStatus = xQueueSend(QHandle, &pStrToSend, 0);
if (xStatus != pdPASS)
{
printf("send fail\n");
}
else
{
printf("send done\n");
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void recTask(void *pvParam)
{
QueueHandle_t QHandle;
QHandle = (QueueHandle_t)pvParam;
BaseType_t xStatus;
char *pStrToRec;
while (1)
{
/* code */
if (uxQueueMessagesWaiting(QHandle) != 0)
{
xStatus = xQueueReceive(QHandle, &pStrToRec, 0);
if (xStatus != pdPASS)
{
printf("rec fail\n");
}
else
{
printf("rec %s\n", pStrToRec);
}
free(pStrToRec);
}
else
{
printf("no data\n");
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void app_main(void)
{
QueueHandle_t QHandle;
QHandle = xQueueCreate(5, sizeof(char *));
if (QHandle != NULL)
{
printf("create queue successfully\n");
xTaskCreate(sendTask, "sendTask", 1024 * 5, (void *)QHandle, 1, NULL);
xTaskCreate(recTask, "recTask", 1024 * 5, (void *)QHandle, 1, NULL);
}
else
{
printf("can not create queue\n");
}
}