八,FreeRTOS之——队列集

声明:本专栏参考韦东山,野火,正点原子以及其他博主的FreeRTOS教程,如若侵权请告知,马上删帖致歉,个人总结,如有不对,欢迎指正。

    • 队列集
      • 实验一:队列集---传送数据
      • 实验描述:
      • 圈重点
      • 仿真效果

队列集

转:队列集概述

队列知道是什么,那么队列集呢,没错就是套娃,队列集里面是队列。

看看代码就懂了,

实验一:队列集—传送数据

/**
   FreeRTOS v9.0.0 + STM32 动态创建任务
   实验平台:韦东山 STM32F103ZE开发板 
**/ 
 
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
/* 开发板硬件bsp头文件 */
#include "bsp_led.h"
#include "bsp_usart.h"

/* 任务句柄 */
static TaskHandle_t AppTaskCreate_Handle = NULL;  /* 起始任务  句柄 */
static TaskHandle_t Task1_Handle = NULL;  /* Task1 句柄*/
static TaskHandle_t Task2_Handle = NULL;  /* Task2 句柄*/
static TaskHandle_t Task3_Handle = NULL;  /* Task3 句柄*/
																				  
static QueueHandle_t xQueueHandle1 = NULL;  /*队列1句柄*/
static QueueHandle_t xQueueHandle2 = NULL;  /*队列2句柄*/
static QueueSetHandle_t xQueueSet  = NULL;  /*队列集句柄*/
																					  


/* 函数声明 */
static void AppTaskCreate(void);/* 用于创建起始任务 */
static void Flag1_Task(void* pvParameters);/* Flag1_Task任务函数 */
static void Flag2_Task(void* pvParameters);/* Flag2_Task任务函数 */
static void Flag3_Task(void* pvParameters);/* Flag3_Task任务函数 */

static void BSP_Init(void);/* 用于初始化板载相关资源 */

/*****************************************************************
  * @brief  主函数
  * @param  无
  * @retval 无
  * @note   第一步:开发板硬件初始化 
            第二步:创建APP应用任务
            第三步:启动FreeRTOS,开始多任务调度
  ****************************************************************/
	
	
	/*实验说明:
	 *将两个队列添加到队列集中,任务一二使用队列发送信息
	 *任务三使用队列集进行监测信息*/
	
	/*队列集实验流程*/
	
	/* 1. 创建两个队列 */
	/* 2. 创建一个个队列集 */
	/* 3. 把队列添加到队列集中 */
	/* 4. 创建三个任务 */
	
	
	/*创建队列以及队列集合*/
	void creat_queue(void)
	{
		
		/*创建第一个队列*/
    xQueueHandle1=xQueueCreate(2,sizeof(int));/* 创建队列1 */
    (xQueueHandle1 == NULL)?  
     printf("error create queue1\r\n"):/*创建失败*/
     printf(" create queue1 ok! \r\n");/*创建成功*/
    
    /*创建第二个队列*/
    xQueueHandle2=xQueueCreate(2,sizeof(int));/* 创建队列2 */
    (xQueueHandle2 == NULL)?
     printf("error create queue2\r\n"):/*创建失败*/
     printf(" create queue2 ok! \r\n");/*创建成功*/
     
    /*创建队列集*/
     xQueueSet= xQueueCreateSet(4);            /* 创建队列集   参数:队列总长度   当前为:2+2 */
    (xQueueSet == NULL)?/*创建失败*/
     printf("error create queue set \r\n"):
     printf(" create queue set ok! \r\n");
		
		
		/* 3. 把2个queue添加进queue set */
	  xQueueAddToSet(xQueueHandle1, xQueueSet);
	  xQueueAddToSet(xQueueHandle2, xQueueSet);
    	
}
	
	
	
	
int main(void)
{	
  BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */

  /* 开发板硬件初始化 */
  BSP_Init();
  printf("这是一个STM32F103ZE开发板-FreeRTOS-队列集实验!\r\n");
	
	
	creat_queue();/* 创建队列以及队列集合 */
	
   /* 创建AppTaskCreate任务 */
  xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate,  /* 任务入口函数 */
                        (const char*    )"AppTaskCreate",/* 任务名字 */
                        (uint16_t       )512,  /* 任务栈大小 */
                        (void*          )NULL,/* 任务入口函数参数 */
                        (UBaseType_t    )1, /* 任务的优先级 */
                        (TaskHandle_t*  )&AppTaskCreate_Handle);/* 任务控制块指针 */ 
  /* 启动任务调度 */           
  if(pdPASS == xReturn)
    vTaskStartScheduler();   /* 启动任务,开启调度 */
  else
    return -1;  
  
  while(1);   /* 正常不会执行到这里 */    
}


/***********************************************************************
  * @ 函数名  : AppTaskCreate
  * @ 功能说明: 为了方便管理,所有的任务创建函数都放在这个函数里面
  * @ 参数    : 无  
  * @ 返回值  : 无
  **********************************************************************/
static void AppTaskCreate(void)
{
  BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */
  
  taskENTER_CRITICAL();           //进入临界区
  
  /* 创建Flag1_Task任务 */
  xReturn = xTaskCreate((TaskFunction_t )Flag1_Task, /* 任务入口函数 */
                        (const char*    )"Flag1_Task",/* 任务名字 */
                        (uint16_t       )512,   /* 任务栈大小 */
                        (void*          )NULL,	/* 任务入口函数参数 */
                        (UBaseType_t    )2,	    /* 任务的优先级 */
                        (TaskHandle_t*  )&Task1_Handle);/* 任务控制块指针 */
  if(pdPASS == xReturn)
    printf("创建Flag1_Task任务成功!\r\n");
	
	 /* 创建Flag2_Task任务 */
  xReturn = xTaskCreate((TaskFunction_t )Flag2_Task, /* 任务入口函数 */
                        (const char*    )"Flag2_Task",/* 任务名字 */
                        (uint16_t       )512,   /* 任务栈大小 */
                        (void*          )NULL,	/* 任务入口函数参数 */
                        (UBaseType_t    )2,	    /* 任务的优先级 */
                        (TaskHandle_t*  )&Task2_Handle);/* 任务控制块指针 */
  if(pdPASS == xReturn)
    printf("创建Flag2_Task任务成功!\r\n");
	
	
	 /* 创建Flag3_Task任务 */
  xReturn = xTaskCreate((TaskFunction_t )Flag3_Task, /* 任务入口函数 */
                        (const char*    )"Flag3_Task",/* 任务名字 */
                        (uint16_t       )512,   /* 任务栈大小 */
                        (void*          )NULL,	/* 任务入口函数参数 */
                        (UBaseType_t    )1,	    /* 任务的优先级 */
                        (TaskHandle_t*  )&Task3_Handle);/* 任务控制块指针 */
  if(pdPASS == xReturn)
    printf("创建Flag3_Task任务成功!\r\n");
  
  vTaskDelete(AppTaskCreate_Handle); //删除AppTaskCreate任务
  
  taskEXIT_CRITICAL();            //退出临界区
}

/**********************************************************************
  * @ 函数名  : LED_Task
  * @ 功能说明: LED_Task任务主体
  ********************************************************************/
uint8_t flag1;
uint8_t flag2;
uint8_t flag3;

/*任务1   优先级2*/
static void Flag1_Task(void* parameter)
{
	static int value1= 1;
	 while (1)
    {
			xQueueSend( xQueueHandle1, ( void* )&value1, queueSEND_TO_BACK);  /*发送队列消息*/
			value1++;
			vTaskDelay(10);   /* 延时10个tick */
    }
}


/*任务2   优先级2*/
static void Flag2_Task(void* parameter)
{
	static int value2= -1;
  	while (1)
    {
			  xQueueSend( xQueueHandle2, ( void* )&value2, queueSEND_TO_BACK);  /*发送队列消息*/
			  value2--;
			  vTaskDelay(10);   /* 延时10个tick */
			
    }
}


/*任务3   优先级2*/
static void Flag3_Task(void* parameter)
{
	static int value3;
	QueueSetMemberHandle_t handle;
  	while (1)
    {
			/*  读取队列集 选择 队列数据 */
				handle = xQueueSelectFromSet(xQueueSet, portMAX_DELAY);/*死等*/
			/* 读取队列*/ 
			  xQueueReceive(handle, &value3, 0);
			/* 将读取到的数据打印出来*/
			  printf("get data : %d\r\n", value3); 
		  
	// vTaskDelay(10);   /* 延时1个tick */		 		
     
    }
}

/***********************************************************************
  * @ 函数名  : BSP_Init
  * @ 功能说明: 板级外设初始化,所有板子上的初始化均可放在这个函数里面
  * @ 参数    :   
  * @ 返回值  : 无
  *********************************************************************/
static void BSP_Init(void)
{
	/*
	 * STM32中断优先级分组为4,即4bit都用来表示抢占优先级,范围为:0~15
	 * 优先级分组只需要分组一次即可,以后如果有其他的任务需要用到中断,
	 * 都统一用这个优先级分组,千万不要再分组,切忌。
	 */
	NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
	
	/* LED 初始化 */
	LED_GPIO_Config();

	/* 串口初始化	*/
	USART_Config();
  
}

/********************************END OF FILE****************************/

实验描述:

该实验创建了三个任务,两个队列,一个队列集,
将两个队列加入到队列集中,任务一二使用队列发送信息,
任务三队列集监测两个队列任务

队列集监测基本流程(以本次实验为例)
1.创建两个队列
2.创建一个队列集
3.把队列添加到队列集中
4.创建三个任务

圈重点

队列以及队列集任务句柄
在这里插入图片描述

创建两个队列,一个队列集,并把两个队列添加到队列集中
八,FreeRTOS之——队列集_第1张图片

任务执行函数:
可以看到,在三个任务函数中,任务一和任务二通过队列发送信息(任务一发送正数,任务二发送负数)
任务三通过队列集----监测两个队列中的信息,这里尤其要注意在任务三中的队列集是如何接收消息的
八,FreeRTOS之——队列集_第2张图片
八,FreeRTOS之——队列集_第3张图片

仿真效果

八,FreeRTOS之——队列集_第4张图片
可以看到打印出了正数和负数,证明接收到了两个队列中的数据。

git仓库源码地址:https://gitee.com/he-dejiang/free-rtos.git

你可能感兴趣的:(FreeRTOS,stm32,freertos)