STM32移植FreeRTOS系列十九:队列集

目录

1、队列集简介

 2、队列集相关API函数介绍

2.1、 xQueueCreateSet(

                                const  UBaseType_t  uxEventQueueLength

                                        );

2.2、此函数用于往队列集中添加队列

BaseType_t xQueueAddToSet(

QueueSetMemberHandle_t     xQueueOrSemaphore ,

        QueueSetHandle_t     xQueueSet    );

扫描二维码关注公众号,回复: 15814745 查看本文章

2.3、函数用于从队列集中移除队列

BaseType_t   xQueueRemoveFromSet( QueueSetMemberHandle_t    xQueueOrSemaphore ,            QueueSetHandle_t     xQueueSet );

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

QueueSetMemberHandle_t     xQueueSelectFromSet(                                                         QueueSetHandle_t   xQueueSet,

                                                        TickType_t const   xTicksToWait )

3,队列集操作实验(掌握)


1、队列集简介

configUSE_QUEUE_SETS 为 1 时启用队列集功能。

一个队列只允许任务间传递的消息为同一种数据类型,如果需要在任务间传递不同数据类型的消息时,那么就可以使用队列集!
作用:用于对多个队列或信号量进行“监听”,其中不管哪一个消息到来,都可让任务退出阻塞状态
假设:有个接收任务,使用到队列接收和信号量的获取,如下:

 使用队列集可以使该任务流程变成

 2、队列集相关API函数介绍

函数

描述

xQueueCreateSet()

创建队列集

xQueueAddToSet()

队列添加到队列集中

xQueueRemoveFromSet()

从队列集中移除队列

xQueueSelectFromSet()

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

xQueueSelectFromSetFromISR()

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

2.1、 xQueueCreateSet(

                                const  UBaseType_t  uxEventQueueLength

                                        );

QueueSetHandle_t     xQueueCreateSet( const  UBaseType_t   uxEventQueueLength );

此函数用于创建队列集。

形参

描述

uxEventQueueLength

队列集可容纳的队列数量

返回值

描述

NULL

队列集创建失败

其他值

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

2.2、此函数用于往队列集中添加队列

BaseType_t xQueueAddToSet(

QueueSetMemberHandle_t     xQueueOrSemaphore ,

        QueueSetHandle_t     xQueueSet    );

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

形参

描述

xQueueOrSemaphore

待添加的队列句柄

xQueueSet

队列集

返回值

描述

pdPASS

队列集添加队列成功

pdFAIL

队列集添加队列失败

2.3、函数用于从队列集中移除队列

BaseType_t   xQueueRemoveFromSet( QueueSetMemberHandle_t    xQueueOrSemaphore ,
           
QueueSetHandle_t     xQueueSet );

形参

描述

xQueueOrSemaphore

待移除的队列句柄

xQueueSet

队列集

返回值

描述

pdPASS

队列集移除队列成功

pdFAIL

队列集移除队列失败

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

QueueSetMemberHandle_t     xQueueSelectFromSet(                                                         QueueSetHandle_t   xQueueSet,

                                                        TickType_t const   xTicksToWait )

形参

描述

xQueueSet

队列集

xTicksToWait

阻塞超时时间

返回值

描述

NULL

获取消息失败

其他值

获取到消息的队列句柄

3,队列集操作实验(掌握)

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

2、实验设计:将设计三个任务:start_tasktask1task2

三个任务的功能如下:

        队列集使用流程

1、启用队列集功能需要将宏configUSE_QUEUE_SETS 配置为 1

2、创建队列集

3、创建队列或信号量

4、往队列集中添加队列或信号量

5、往队列发送信息或释放信号量

6、获取队列集的消息

main.c

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "lcd.h"
#include "key.h"
#include "beep.h"
#include "malloc.h"
#include "string.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
/******************************************************************************************************/
/*FreeRTOS配置*/
#define  configSTACK_DEPTH_TYPE  uint16_t
/* 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)
{    

}

int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4	 
	delay_init();	    				//延时函数初始化	 
	uart_init(115200);					//初始化串口
	LED_Init();		  					//初始化LED
	KEY_Init();							//初始化按键
	//BEEP_Init();						//初始化蜂鸣器
	LCD_Init();							//初始化LCD
	//TIM2_Int_Init(5000,7200-1);			//初始化定时器2,周期500ms
	my_mem_init(SRAMIN);            	//初始化内部内存池
            	//加载主UI
	
    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);
        if(key == KEY1_PRES)
        {
            err = xQueueSend( queue_handle, &key, portMAX_DELAY );
            if(err == pdPASS)
            {
                printf("往队列queue_handle写入数据成功!!\r\n");
            }
        }else if(key == KEY2_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");
        }
    }
}

链接:https://pan.baidu.com/s/118WiJj3UGRrGsObLBYtOow?pwd=scg1 
提取码:scg1

猜你喜欢

转载自blog.csdn.net/qq_51519091/article/details/131858588