声明:本专栏参考韦东山,野火,正点原子以及其他博主的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.创建三个任务
任务执行函数:
可以看到,在三个任务函数中,任务一和任务二通过队列发送信息(任务一发送正数,任务二发送负数)
任务三通过队列集----监测两个队列中的信息,这里尤其要注意在任务三中的队列集是如何接收消息的
git仓库源码地址:https://gitee.com/he-dejiang/free-rtos.git