【FreeRTOS(六)】队列

队列

创建队列 xQueueCreate

创建一个新的队列。为新的队列分配所需的存储内存,并返回一个队列句柄。

xQueueHandle xQueueCreate(unsigned portBASE_TYPE uxQueueLength, 
                          unsigned portBASE_TYPE uxItemSize);
Parametersdistribution
uxQueueLength队列中包含最大项目数量
uxItemSize队列中每个项目所需的字节数。项目通过复制而不是引用排队,因为,所需的字节数,将复制给每个项目。队列中每个项目必须分配同样大小
return成功与否

发送消息至队列 xQueueSend

发送消息至队列

portBASE_TYPE xQueueSend(xQueueHandle xQueue, 
						const void * pvItemToQueue, 
						portTickType xTicksToWait);
parametersdistribution
xQueue队列句柄
pvItemToQueue指向队列中放置的项目的指针。项目的大小,由队列创建时定义,因为许多字节可以从 pvItemToQueue复制到队列的储存区域
xTicksToWait最大时间量(任务应该锁住,等待队列中的可用空间)应该已经满了。如果设置为0,调用将立即返回。时间使用滴答周期来定义,因此如果需要,常量portTICK_RATE_MS应该用来转换实时时间
returnpdTRUE:成功
pdFALSE:失败

接受队列消息 xQueueReceive

接受队列消息

portBASE_TYPE xQueueReceive( xQueueHandle xQueue, 
                             void *pvBuffer, 
                             portTickType xTicksToWait);
parametersdistribution
pxQueue队列句柄
pvBuffer指向将要复制接收项目的缓冲器的指针。
xTicksToWait等待市场
returnpdTRUE:成功
pdFALSE:失败

获取队列信息数目 uxQueueMessagesWaiting

返回队列中存储的信息数目

UBaseType_t uxQueueMessagesWaiting( QueueHandle_t xQueue );
parametersdistribution
xQueue队列句柄
return队列中存储的信息数目

代码示例

#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 task1(void *pvParam)
{
    int *my_queue = (int *)pvParam;

    int i = 0;

    while (1)
    {
        xQueueSend(my_queue, &i, 0);

        vTaskDelay(3000 / portTICK_PERIOD_MS);
        i++;
    }
}

void task2(void *pvParam)
{
    int *my_queue = (int *)pvParam;

    int i = 0;

    while (1)
    {

        if (xQueueReceive(my_queue, &i, 0))
        {
            printf("received successful i= %d\n", i);
        }

        vTaskDelay(3000 / portTICK_PERIOD_MS);
    }
}

void app_main(void)
{
    xQueueHandle my_queue;
    my_queue = xQueueCreate(10, sizeof(int));

    xTaskCreate(task1, "task1", 4096, (void *)my_queue, 1, NULL);
    xTaskCreate(task2, "task2", 4096, (void *)my_queue, 1, NULL);
}


创建队列集 xQueueCreateSet

队列集提供了一种机制,允许RTOS任务同时来自多个RTOS队列或信号量的读取操作。

QueueSetHandle_t xQueueCreateSet(const UBaseType_t uxEventQueueLength);
parametersdistribution
uxEventQueueLength设置长度
return如果成功创建了队列集,则返回创建的队列集的句柄。否则返回NULL。

将队列加入队列集 xQueueAddToSet

将队列加入队列集

BaseType_t xQueueAddToSet(QueueSetMemberHandle_t xQueueOrSemaphore,QueueSetHandle_t xQueueSet);
parametersdistribution
xQueueOrSemaphore要添加到队列集的队列或信号量的句柄(强制转换为QueueSetMemberHandle_t类型)。
xQueueSet要添加队列或信号量的队列集的句柄。
return如果队列或信号量已成功添加到队列集,则返回pdPASS。如果队列无法成功添加到队列集,因为它已经是不同队列集的成员,则返回pdFAIL。

将队列从队列集中移除

从队列集中删除RTOS队列或信号量。

BaseType_t xQueueRemoveFromSet(QueueSetMemberHandle_t xQueueOrSemaphore,QueueSetHandle_t xQueueSet);
parametersdistribution
xQueueOrSemaphore从队列集中删除的队列或信号量的句柄(强制转换为QueueSetMemberHandle_t类型)。
xQueueSet包含队列或信号量的队列集的句柄。
return如果从队列集中成功删除了队列或信号量,则返回pdPASS。 如果队列不在队列集中,或者队列(或信号量)不为空,则返回pdFAIL。

从队列集里获取一个队列

从队列成员中选择一个队列或信号量,该队列或信号量包含数据(在队列的情况下)或可用于(在信号量的情况下)。 xQueueSelectFromSet()有效地允许任务同时阻塞(挂起)队列集中所有队列和信号量的读操作。

QueueSetMemberHandle_t xQueueSelectFromSet(QueueSetHandle_t xQueueSet,const TickType_t xTicksToWait);
parametersdistribution
xQueueSet队列集。
xTicksToWait调用任务将保持在阻塞状态(其他任务正在执行)的最长时间(以时钟周期为单位),以等待队列集的成员为成功的队列读取或信号量执行操作做好准备。
return将返回包含在包含数据的队列集中的队列句柄(强制转换为QueueSetMemberHandle_t类型),或者返回包含在可用队列集中的信号量句柄(强制转换为QueueSetMemberHandle_t类型),或者为NULL如果在指定的块时间到期之前没有这样的队列或信号量。

代码示例

#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 sendTask1(void *pvParam)
{
    QueueHandle_t QHandle;
    QHandle = (QueueHandle_t)pvParam;

    BaseType_t xStatus;
    int i = 111;

    while (1)
    {
        xStatus = xQueueSend(QHandle, &i, 0);
        if(xStatus != pdPASS)
            printf("send fail!\n");
        else
            printf("send done!\n");

        vTaskDelay(3000 / portTICK_PERIOD_MS);
    }
}

void sendTask2(void *pvParam)
{
    QueueHandle_t QHandle;
    QHandle = (QueueHandle_t)pvParam;

    BaseType_t xStatus;
    int i = 222;

    while (1)
    {
        xStatus = xQueueSend(QHandle, &i, 0);
        if(xStatus != pdPASS)
            printf("send fail!\n");
        else
            printf("send done!\n");

        vTaskDelay(3000 / portTICK_PERIOD_MS);
    }
}

void recTask(void *pvParam)
{
    QueueHandle_t QueueSet;
    QueueSet = (QueueHandle_t)pvParam;

    QueueSetMemberHandle_t QueueData;

    BaseType_t xStatus;
    int i;
    

    while (1)
    {
        QueueData = xQueueSelectFromSet(QueueSet, portMAX_DELAY);
        xStatus = xQueueReceive(QueueData, &i, portMAX_DELAY);
        if(xStatus != pdPASS)
            printf("rec fail!\n");
        else
            printf("rec: %d!\n",i);

        vTaskDelay(3000 / portTICK_PERIOD_MS);
    }
}

void app_main(void)
{
    QueueHandle_t QHandle1;
    QHandle1 = xQueueCreate(5, sizeof(int));

    QueueHandle_t QHandle2;
    QHandle2 = xQueueCreate(5, sizeof(int));

    QueueSetHandle_t QueueSet;
    QueueSet = xQueueCreateSet(10);

    xQueueAddToSet(QHandle1, QueueSet);
    xQueueAddToSet(QHandle2, QueueSet);

    if((QHandle1 != NULL) && (QHandle2 != NULL) && (QueueSet != NULL))
    {
        printf("Create queue successfully!\n");

        xTaskCreate(sendTask1, "sendTask1", 4096, (void *)QHandle1, 1, NULL);
        xTaskCreate(sendTask2, "sendTask2", 4096, (void *)QHandle2, 1, NULL);
        xTaskCreate(recTask, "recTask", 4096, (void *)QueueSet, 2, NULL);
    }
    else
    {
        printf("Can't crate queue!\n");
    }  
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Eiker_3169

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值