Queue的介绍

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

一个sendTask向队列发送数据,一个recTask从队列中接收数据。

Queue的三种数据传递_#include

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,说明从队列中接收数据失败。

Queue的三种数据传递_c++_02

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

Queue的三种数据传递_死循环_03

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

Queue的三种数据传递_#include_04