操作系统---FreeRTOS(队列集)

一、队列集简介

队列只能传输同一种数据,不同的任务之间需要传输不同的数据类型的消息时那么就需要使用队列集。

作用:用于对多个队列或者信号量进行监听,其中不管任何一个到来,都可以使任务退出阻塞状态。

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

二、相关API函数

队列集使用流程:

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

2、创建队列集;

3、创建队列或信号量;

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

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

6、获取队列集的消息;

创建队列集函数:QueueSetHandle_t     xQueueCreateSet( const  UBaseType_t   uxEventQueueLength );

往队列集中添加队列,需要注意的时,队列再被添加到队列集之前,队列中不能有有效的消息:

BaseType_t    xQueueAddToSet( QueueSetMemberHandle_t       xQueueOrSemaphore ,                           QueueSetHandle_t           xQueueSet );

往队列集中移除队列,需要注意的时,队列在从队列集移除之前,队列中不能有有效的消息:

BaseType_t     xQueueRemoveFromSet( QueueSetMemberHandle_t      xQueueOrSemaphore ,                                   QueueSetHandle_t           xQueueSet );

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

QueueSetMemberHandle_t     xQueueSelectFromSet( QueueSetHandle_t         xQueueSet,                                                                           TickType_t const         xTicksToWait );

三、队列集操作实验

工程代码:

main.c

#include "stm32f10x.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include <stdio.h>


//任务优先级
#define			START_TASK_PRIO	        1
//任务堆栈大小
#define			START_TASK_STACK_SIZE	128
//任务句柄
TaskHandle_t	start_task_handler;
//开始任务
void start_task(void *pvParameters);

//任务优先级
#define			TASK1_PRIO	        	2
//任务堆栈大小
#define			TASK1_STACK_SIZE		128
//任务句柄
TaskHandle_t	task1_handler;
//LED0任务
void task1(void *pvParameters);

//任务优先级
#define			TASK2_PRIO	        	3
//任务堆栈大小
#define			TASK2_STACK_SIZE		128
//任务句柄
TaskHandle_t	task2_handler;
//LED1任务
void task2(void *pvParameters);


QueueSetHandle_t queueset_handle;

QueueHandle_t    queue_handle;

QueueHandle_t    semaphore_handle;


 int main(void)
 {	

	 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组 4 
	 GPIO_INIT();
	 KEY_INIT();
	 uart_init(9600);
	 
//创建开始任务
	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)
{
	
	queueset_handle = xQueueCreateSet(2);							//创建队列集,可以存放2个队列
	if(queueset_handle != NULL)
	{
		printf("队列集创建成功\r\n");
	
	}
	queue_handle = xQueueCreate(1,sizeof(uint8_t));					//创建队列
	semaphore_handle = xSemaphoreCreateBinary();					//创建二值信号量
	
	xQueueAddToSet(queue_handle,queueset_handle);
	xQueueAddToSet(semaphore_handle,queueset_handle);
	
	//创建LED0任务
	xTaskCreate( (TaskFunction_t         )  task1,
				 (char *                 )  "task1", 
				 (configSTACK_DEPTH_TYPE )  TASK1_STACK_SIZE,
				 (void *                 )  NULL,
				 (UBaseType_t            )  TASK1_PRIO,
				 (TaskHandle_t *         )  &task1_handler );
	
	//创建LED1任务
	xTaskCreate( (TaskFunction_t         )  task2,
				 (char *                 )  "task2", 
				 (configSTACK_DEPTH_TYPE )  TASK2_STACK_SIZE,
				 (void *                 )  NULL,
				 (UBaseType_t            )  TASK2_PRIO,
				 (TaskHandle_t *         )  &task2_handler );
				 

				 				 
	//删除自己
	vTaskDelete(NULL);
	
}

//任务一释放二值信号量
void task1(void *pvParameters)
{
	u8 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(semaphore_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 == semaphore_handle)
        {
            xSemaphoreTake( member_handle, portMAX_DELAY );
            printf("获取信号量成功!!\r\n");
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值