freeRTOS队列集
队列集简介
队列集操作实验
1、实验目的:学习 FreeRTOS 的队列集相关API的使用
2、实验设计:将设计三个任务:start_task、task1、task2
start_task:用来创建其它任务,并创建队列集,队列/信号量,将队列/信号量添加到队列集中
task1:用于扫描按键,当KEY0按下,释放二值信号量,当KEY1按下,写入队列2,当wk_up按下,写入队列2
task2:读取队列集中的消息,并打印
freertos_demo.c
#include "freertos_demo.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
/******************************************************************************************************/
/*FreeRTOS配置*/
/* START_TASK 任务 配置
* 包括: 任务句柄 任务优先级 堆栈大小 创建任务
*/
#define START_TASK_PRIO 1 /* 任务优先级 */
#define START_STK_SIZE 128 /* 任务堆栈大小 */
TaskHandle_t StartTask_Handler; /* 任务句柄 */
void start_task(void *pvParameters); /* 任务函数 */
/* TASK1 任务 配置
* 包括: 任务句柄 任务优先级 堆栈大小 创建任务
*/
#define TASK1_PRIO 2 /* 任务优先级 */
#define TASK1_STK_SIZE 128 /* 任务堆栈大小 */
TaskHandle_t Task1Task_Handler; /* 任务句柄 */
void task1(void *pvParameters); /* 任务函数 */
/* TASK2 任务 配置
* 包括: 任务句柄 任务优先级 堆栈大小 创建任务
*/
#define TASK2_PRIO 3 /* 任务优先级 */
#define TASK2_STK_SIZE 128 /* 任务堆栈大小 */
TaskHandle_t Task2Task_Handler; /* 任务句柄 */
void task2(void *pvParameters); /* 任务函数 */
static QueueSetHandle_t xQueueSet; /* 定义队列集 */
QueueHandle_t xQueue1; /* 定义队列1 */
QueueHandle_t xQueue2; /* 定义队列2 */
SemaphoreHandle_t xSemaphore; /* 定义二值信号量 */
#define QUEUE_LENGTH 1 /* 队列支持的消息个数 */
#define QUEUE_ITEM_SIZE sizeof(uint32_t) /* 队列中每条消息的大小 */
#define SEMAPHORE_BINARY_LENGTH 1 /* 二值信号量的有效长度 */
#define QUEUESET_LENGTH ((2 * QUEUE_LENGTH) + SEMAPHORE_BINARY_LENGTH) /* 队列集支持的消息个数 */
/******************************************************************************************************/
/**
* @brief FreeRTOS例程入口函数
* @param 无
* @retval 无
*/
void freertos_demo(void)
{
xTaskCreate((TaskFunction_t )start_task, /* 任务函数 */
(const char* )"start_task", /* 任务名称 */
(uint16_t )START_STK_SIZE, /* 任务堆栈大小 */
(void* )NULL, /* 传入给任务函数的参数 */
(UBaseType_t )START_TASK_PRIO, /* 任务优先级 */
(TaskHandle_t* )&StartTask_Handler); /* 任务句柄 */
vTaskStartScheduler();
}
/**
* @brief start_task
* @param pvParameters : 传入参数(未用到)
* @retval 无
*/
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); /* 进入临界区 */
/* 创建队列集 */
xQueueSet = xQueueCreateSet(QUEUESET_LENGTH);
/* 创建队列 */
xQueue1 = xQueueCreate(QUEUE_LENGTH, QUEUE_ITEM_SIZE);
xQueue2 = xQueueCreate(QUEUE_LENGTH, QUEUE_ITEM_SIZE);
/* 创建二值信号量 */
xSemaphore = xSemaphoreCreateBinary();
/* 将队列和二值信号量添加到队列集 */
xQueueAddToSet(xQueue1, xQueueSet);
xQueueAddToSet(xQueue2, xQueueSet);
xQueueAddToSet(xSemaphore, xQueueSet);
/* 创建任务1 */
xTaskCreate((TaskFunction_t )task1,
(const char* )"task1",
(uint16_t )TASK1_STK_SIZE,
(void* )NULL,
(UBaseType_t )TASK1_PRIO,
(TaskHandle_t* )&Task1Task_Handler);
/* 创建任务2 */
xTaskCreate((TaskFunction_t )task2,
(const char* )"task2",
(uint16_t )TASK2_STK_SIZE,
(void* )NULL,
(UBaseType_t )TASK2_PRIO,
(TaskHandle_t* )&Task2Task_Handler);
vTaskDelete(StartTask_Handler); /* 删除开始任务 */
taskEXIT_CRITICAL(); /* 退出临界区 */
}
/**
* @brief task1
* @param pvParameters : 传入参数(未用到)
* @retval 无
*/
void task1(void *pvParameters)
{
uint8_t key = 0;
while (1)
{
key = key_scan(0);
switch (key)
{
case WKUP_PRES: /* 队列1发送消息 */
{
xQueueSend(xQueue1, &key, portMAX_DELAY);
break;
}
case KEY1_PRES: /* 队列2发送消息 */
{
xQueueSend(xQueue2, &key, portMAX_DELAY);
break;
}
case KEY0_PRES: /* 释放二值信号量 */
{
xSemaphoreGive(xSemaphore);
break;
}
default:
{
break;
}
}
vTaskDelay(10);
}
}
/**
* @brief task2
* @param pvParameters : 传入参数(未用到)
* @retval 无
*/
void task2(void *pvParameters)
{
QueueSetMemberHandle_t activate_member = NULL;
uint32_t queue_recv = 0;
while (1)
{
activate_member = xQueueSelectFromSet(xQueueSet, portMAX_DELAY);/* 等待队列集中的队列接收到消息 */
if (activate_member == xQueue1)
{
xQueueReceive(activate_member, &queue_recv, portMAX_DELAY);
printf("接收到来自xQueue1的消息: %d\r\n", queue_recv);
}
else if (activate_member == xQueue2)
{
xQueueReceive(activate_member, &queue_recv, portMAX_DELAY);
printf("接收到来自xQueue2的消息: %d\r\n", queue_recv);
}
else if (activate_member == xSemaphore)
{
xSemaphoreTake(activate_member, portMAX_DELAY);
printf("获取到二值信号量: xSemaphore\r\n");
}
}
}