FreeRTOS 队列集

目录

简介

队列集使用流程 

队列集相关API函数

xQueueCreateSet()

 xQueueAddToSet()

 xQueueRemoveFromSet

xQueueSelectFromSet

队列集操作实验

实验代码

实验结果 


简介

         一个队列只允许任务间传递的消息为同一种数据类型,如果需要在任务间传递不同数据类型的消息时,那么就可以使用队列集 !

        作用:用于对多个队列或信号量进行 “监听”,其中不管哪一个消息到来,都可让任务退出阻塞状态

         假设:有个接收任务,使用到队列接收和信号量的获取,如下:

   

队列集使用流程 

  1. 启用队列集功能需要将 宏 configUSE_QUEUE_SETS 配置为 1
  2. 创建队列集
  3. 创建队列或信号量
  4. 往队列集中添加队列或信号量
  5. 往队列发送信息或释放信号量
  6. 获取队列集的消息

队列集相关API函数

函数

描述

xQueueCreateSet()

创建队列集

xQueueAddToSet()

队列添加到队列集中

xQueueRemoveFromSet()

从队列集中移除队列

xQueueSelectFromSet()

获取队列集中有有效消息的队列

xQueueSelectFromSetFromISR()

在中断中获取队列集中有有效消息的队列

xQueueCreateSet()

 此函数用于创建队列集。

QueueSetHandle_t  xQueueCreateSet(const UBaseType_t uxEventQueueLength); 

形参

描述

uxEventQueueLength

队列集可容纳的队列数量

返回值

描述

NULL

队列集创建失败

其他值

队列集创建成功,返回队列集句柄

 xQueueAddToSet()

        此函数用于往队列集中添加队列,要注意的时,队列在被添加到队列集之前,队列中不能有有效的消息

BaseType_t xQueueAddToSet (QueueSetMemberHandle_t  xQueueOrSemaphore ,
					       QueueSetHandle_t        xQueueSet ); 

形参

描述

xQueueOrSemaphore

待添加的队列句柄

xQueueSet

队列集

返回值

描述

pdPASS

队列集添加队列成功

pdFAIL

队列集添加队列失败

 xQueueRemoveFromSet

         此函数用于从队列集中移除队列, 要注意的是,队列在从队列集移除之前,必须没有有效的消息

BaseType_t  xQueueRemoveFromSet (QueueSetMemberHandle_t  xQueueOrSemaphore ,        
                                 QueueSetHandle_t   	 xQueueSet ); 

形参

描述

xQueueOrSemaphore

待移除的队列句柄

xQueueSet

队列集

返回值

描述

pdPASS

队列集移除队列成功

pdFAIL

队列集移除队列失败

xQueueSelectFromSet

         此函数用于在任务中获取队列集中有有效消息的队列

QueueSetMemberHandle_t  xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
                                             TickType_t const xTicksToWait )

形参

描述

xQueueSet

队列集

xTicksToWait

阻塞超时时间

返回值

描述

NULL

获取消息失败

其他值

获取到消息的队列句柄

队列集操作实验

实验目的:学习 FreeRTOS 的队列集相关API的使用。

实验设计:将设计三个任务:start_task、task1、task2

三个任务的功能如下:

  • start_task:用来创建其他的2个任务,并创建队列集,队列/信号量,将队列/信号量添加到队列集中
  • task1:用于扫描按键,当KEY0按下,往队列写入数据,当KEY1按下,释放二值信号量
  • task2:读取队列集中的消息,并打印

有不懂地方可以回顾一下消息队列 

 FreeRTOS 消息队列_freertos消息队列-CSDN博客

实验代码

QueueSetHandle_t queueset_handle;
QueueHandle_t    queue_handle;
QueueHandle_t    semphr_handle;

void freertos_demo(void)
{    
    xTaskCreate((TaskFunction_t         )   start_task,
                (char *                 )   "start_task",
                (configSTACK_DEPTH_TYPE )   START_STK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   START_TASK_PRIO,
                (TaskHandle_t *         )   &StartTask_Handler );
    vTaskStartScheduler();
}


void start_task( void * pvParameters )
{
    taskENTER_CRITICAL();                           /* 进入临界区 */
    queueset_handle = xQueueCreateSet( 2 );         /* 创建队列集,可以存放2个队列 */
    if(queueset_handle != NULL)
    {
        printf("队列集创建成功!!\r\n");
    }
    
    queue_handle = xQueueCreate( 1, sizeof(uint8_t) );  /* 创建队列 */ 
    semphr_handle = xSemaphoreCreateBinary();           /* 创建二值信号量 */
    
    xQueueAddToSet( queue_handle,queueset_handle);
    xQueueAddToSet( semphr_handle,queueset_handle);
    
    xTaskCreate((TaskFunction_t         )   task1,
                (char *                 )   "task1",
                (configSTACK_DEPTH_TYPE )   TASK1_STK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK1_PRIO,
                (TaskHandle_t *         )   &Task1Task_Handler );
                
    xTaskCreate((TaskFunction_t         )   task2,
                (char *                 )   "task2",
                (configSTACK_DEPTH_TYPE )   TASK2_STK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK2_PRIO,
                (TaskHandle_t *         )   &Task2Task_Handler );
                             
    vTaskDelete(NULL);
    taskEXIT_CRITICAL();                /* 退出临界区 */
}

/* 任务一,实现队列发送以及信号量释放 */
void task1( void * pvParameters )
{
    uint8_t key = 0;
    BaseType_t err = 0;
    while(1) 
    {
        key = key_scan(0);
        if(key == KEY0_PRES)
        {
            err = xQueueSend( queue_handle, &key, portMAX_DELAY );
            if(err == pdPASS)
            {
                printf("往队列queue_handle写入数据成功!!\r\n");
            }
        }else if(key == KEY1_PRES)
        {
            err = xSemaphoreGive(semphr_handle);
            if(err == pdPASS)
            {
                printf("释放信号量成功!!\r\n");
            }
        }
        vTaskDelay(10);
    }
}

/* 任务二,获取队列集的消息 */
void task2( void * pvParameters )
{
    QueueSetMemberHandle_t member_handle;
    uint8_t key;
    while(1)
    {
        member_handle = xQueueSelectFromSet( queueset_handle,portMAX_DELAY);
        if(member_handle == queue_handle)
        {
            xQueueReceive( member_handle,&key,portMAX_DELAY);
            printf("获取到的队列数据为:%d\r\n",key);
        }else if(member_handle == semphr_handle)
        {
            xSemaphoreTake( member_handle, portMAX_DELAY );
            printf("获取信号量成功!!\r\n");
        }
    }
}

实验结果 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值