FreeRTOS学习--46讲 队列集

发布时间:2023年12月28日

队列集作用:

????????一个队列只允许任务之间传递的消息为同一种数据类型,队列集允许传递多种消息,且队列集能监听多个队列,不管哪个消息到来,都可以让任务退出阻塞状态

使用队列集的条件:在FreeRTOSConfig.h中把configUSE_QUEUE_SETS置1

创建队列集 ??????????????????????????????????????????????xQueueCreateSet()
QueueSetHandle_t xQueueCreateSet(const UBaseType_t uxEventQueueLength)
参数:可容纳队列最大数量?? ??? ??? ?????????????????????????返回值:失败 NULL,成功 队列集

往队列集添加队列????????????????????????????????????? xQueueAddToSet()
BaseType_t xQueueAddToSet(QueueSetMemberHandle_t xQueueOrSemaphore,QueueSetHandle_t xQueueSet)

参数:待添加的队列,队列集? ? ? ? ? ? ? ? ? ????????????????? ? 返回值:成功 pdPASS,失败 pdFAIL

移除队列? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? xQueueRemoveFromSet()
BaseType_t xQueueRemoveFromSet(QueueSetMemberHandle_t xQueueOrSemaphore,QueueSetHandle_t xQueueSet)
参数:待移除的队列,队列集 ? ? ????????????????????????????????返回值:成功 pdPASS,失败 pdFAIL

获取队列集中有有效消息的队列???????????????xQueueSelectFromSet()
QueueSetMemberHandle_t xQueueSelectFromSet(QueueSetHandle_t xQueueSet,TickType_t const xTicksToWait)
参数:队列集,阻塞超时时间(未获取成功便阻塞)?? ??? ?返回值:成功 目标队列,失败 NULL

队列集实验代码

//freertos_demo.c

#include "freertos_demo.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"
#include "./MALLOC/malloc.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
/******************************************************************************************************/
/*FreeRTOS配置*/

/* START_TASK 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );

/* TASK1 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );


/* TASK2 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );

/******************************************************************************************************/
QueueSetHandle_t queueset_handle;           //定义队列集变量
QueueHandle_t    queue_handle;              //定义队列
QueueHandle_t    semphr_handle;             //定义二值信号量队列
/**
 * @brief       FreeRTOS例程入口函数
 * @param       无
 * @retval      无
 */
void freertos_demo(void)
{    
    xTaskCreate((TaskFunction_t         )   start_task,
                (char *                 )   "start_task",
                (configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   START_TASK_PRIO,
                (TaskHandle_t *         )   &start_task_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_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK1_PRIO,
                (TaskHandle_t *         )   &task1_handler );
                
    xTaskCreate((TaskFunction_t         )   task2,
                (char *                 )   "task2",
                (configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK2_PRIO,
                (TaskHandle_t *         )   &task2_handler );
                             
    vTaskDelete(NULL);
    taskEXIT_CRITICAL();                /* 退出临界区 */
}

/* 任务一,实现队列发送以及信号量释放 */
void task1( void * pvParameters )
{
    uint8_t key = 0;
    BaseType_t err = 0;
    while(1) 
    {
        key = key_scan(0);      //把按键扫描的值赋给key
        if(key == KEY0_PRES)
        {
            err = xQueueSend( queue_handle, &key, portMAX_DELAY );  //写入队列,队列值是key地址的值
            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");
        }
    }
}

//freertos_demo.h

#ifndef __FREERTOS_DEMO_H
#define __FREERTOS_DEMO_H

void freertos_demo(void); 

#endif

文章来源:https://blog.csdn.net/weixin_60444711/article/details/135236686
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。