FreeRTOS实时操作系统(十一)队列集

系列文章

FreeRTOS实时操作系统(一)RTOS的基本概念

FreeRTOS实时操作系统(二)任务创建与任务删除(HAL库)

FreeRTOS实时操作系统(三)任务挂起与恢复

FreeRTOS实时操作系统(四)中断任务管理

FreeRTOS实时操作系统(五)进入临界区、任务调度器挂起与恢复

FreeRTOS实时操作系统(六)列表与列表项

FreeRTOS实时操作系统(七)时间片调度及RTOS的滴答定时器

FreeRTOS实时操作系统(八)任务状态查询及时间统计函数

FreeRTOS实时操作系统(九)时间延时函数及消息队列

FreeRTOS实时操作系统(十)信号量

FreeRTOS实时操作系统(十一)队列集

FreeRTOS实时操作系统(十二)事件标志组

FreeRTOS实时操作系统(十三)任务通知

FreeRTOS实时操作系统(十四)软件定时器

FreeRTOS实时操作系统(十五)Tickless低功耗模式

FreeRTOS实时操作系统(十六)内存管理



队列集简介

队列只允许传递一种数据类型,队列集可以传递多种消息。

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

相关API函数

函数描述
xQueueCreateSet()创建队列集
xQueueAddToSet()队列添加到队列集中
xQueueRemoveFromSet()从队列集中移除队列
xQueueSelectFromSet()获取队列集中有有效消息的队列
xQueueSelectFromSetFromISR()在中断中获取队列集中有有效消息的队列

队列集创建函数

BaseType_t xQueueAddToSet( QueueSetMemberHandle_t  xQueueOrSemaphore , QueueSetHandle_t  xQueueSet); 

往队列集中添加队列,在被添加到队列集之前,队列中不能有有效的消息。

形参:
xQueueOrSemaphore:待添加的队列句柄
xQueueSet :队列集

返回值:
pdPASS :队列集添加队列成功
pdFAIL :队列集添加队列失败

队列集中移除函数

BaseType_t   xQueueRemoveFromSet( QueueSetMemberHandle_t  xQueueOrSemaphore ,QueueSetHandle_t  xQueueSet ); 

从队列集中移除队列,在从队列集移除之前,必须没有有效的消息

形参:
xQueueOrSemaphore:待移除的队列句柄
xQueueSet :队列集

返回值:
pdPASS :队列集移除队列成功
pdFAIL :队列集移除队列失败

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

QueueSetMemberHandle_t     xQueueSelectFromSet( QueueSetHandle_t xQueueSet,TickType_t const xTicksToWait )

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

形参:
xQueueSet:队列集
xTicksToWait:阻塞超时时间

返回值:
NULL:获取消息失败
其他值 :获取到消息的队列句柄

实验测试:

将宏configUSE_QUEUE_SETS置1
在这里插入图片描述

#include "semphr.h"
int fputc(int ch,FILE *f)
{
	HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,0xffff);
	return ch;
}

TaskHandle_t    task1_handler;

#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;


void vTaskCode( void * pvParameters )
 {	 
    taskENTER_CRITICAL();               /* 进入临界区 */
    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();                /* 退出临界区 */
 }
 
QueueHandle_t mutex_semphore_handle;

 // Function that creates a task.
 void vOtherFunction( void )
 {
	 
	 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( vTaskCode, "tak1", 128, NULL, 1, &task1_handler );
	vTaskStartScheduler();
 }
 
 //实现队列发送和信号量释放
void task1( void * pvParameters )
{
    BaseType_t err = 0;
	BaseType_t err1 = 0;
	uint8_t key=1;
	err = xQueueSend( queue_handle, &key, portMAX_DELAY );
	if(err == pdPASS)
	{
		printf("往队列queue_handle写入数据成功!!\r\n");
	}
	 err1 = xSemaphoreGive(semphr_handle);
	if(err1 == pdPASS)
	{
		printf("释放信号量成功!!\r\n");
	}
	
	
    while(1) 
    {
        vTaskDelay(100);
    }
}

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

在这里插入图片描述
实验说明:由于task1的优先级比task2低,所以先执行task2,获取任务列中有消息的队列,此时没有,进入等待消息阻塞,之后task1执行,先写入队列1,之后回到task2进行了数据获取,之后才回到task1去printf(“往队列queue_handle写入数据成功!!\r\n”);,之后信号量是因为task2进入vTaskDelay阻塞,所以task1才能全部运行完

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值