一、freertos队列特点:
1、数据入队出队方式:一般先进先出,也可以后进后出
2、数据传输方式:采用实际值进行传输
3、多任务访问:任何任务或中断都可以向队列发送或者读取消息
4、出队、入队阻塞:任务向队列发送消息时,设置阻塞时间,假设队列已满无法入队,
(1)阻塞时间为0:直接返回不等待
(2)阻塞时间为0-port_MAX_Delay:等待设定阻塞时间,如果等待时间之后仍然没有入队,超时后直接返回不再等待
(3)阻塞时间为port_MAX_Delay:死等,一直等到可以入队为止。
二、队列操作基本过程:
(1)创建队列
(2)往队列里面写第一个消息
(3)往队列里面写第二个消息
(4)往队列写n个消息
(5)从队列中读取第一个消息(系统会自动将第二个、第三个……第n个消息移动到第一个消息的地方)
三、实验设计:
#include "freertos_demo.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./MALLOC/malloc.h"
#include "./BSP/LED/led.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "queue.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); /* 任务函数 */
/* TASK3 任务 配置
* 包括: 任务句柄 任务优先级 堆栈大小 创建任务
*/
#define TASK3_PRIO 4 /* 任务优先级 */
#define TASK3_STK_SIZE 128 /* 任务堆栈大小 */
TaskHandle_t Task3Task_Handler; /* 任务句柄 */
void task3(void *pvParameters); /* 任务函数 */
/******************************************************************************************************/
List_t TestList; /* 定义测试列表 */
ListItem_t ListItem1; /* 定义测试列表项1 */
ListItem_t ListItem2; /* 定义测试列表项2 */
ListItem_t ListItem3; /* 定义测试列表项3 */
QueueHandle_t key_queue;
QueueHandle_t big_data_queue;
char buff[100]={"我是中国人,my number is 001"};
/**
* @brief FreeRTOS例程入口函数
* @param 无
* @retval 无
*/
void freertos_demo(void)
{
key_queue =xQueueCreate(2,sizeof(uint8_t));
if(key_queue != NULL)
{
printf("key_queue队列创建成功\r\n");
}
else
{
printf("key_queue队列创建失败\r\n");
}
big_data_queue = xQueueCreate(1,sizeof(char *));
if(big_data_queue != NULL)
{
printf("big_data_queue队列创建成功\r\n");
}
else
{
printf("big_data_queue队列创建失败\r\n");
}
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(); /* 进入临界区 */
/* 创建任务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);
/* 创建任务3 */
xTaskCreate((TaskFunction_t )task3,
(const char* )"task3",
(uint16_t )TASK3_STK_SIZE,
(void* )NULL,
(UBaseType_t )TASK3_PRIO,
(TaskHandle_t* )&Task3Task_Handler);
vTaskDelete(StartTask_Handler); /* 删除开始任务 */
taskEXIT_CRITICAL(); /* 退出临界区 */
}
/*task1
* @brief task1
* @param pvParameters : 传入参数(未用到)
* @retval 无
*/
void task1(void *pvParameters)
{
uint8_t key =0;
char* buf;
buf = buff;
BaseType_t errorflag = 0;
while (1)
{
key = key_scan(0);
if(key == KEY0_PRES ||key == KEY1_PRES)
{
errorflag =xQueueSend(key_queue,&key,portMAX_DELAY);
if(errorflag != pdTRUE)
{
printf("key_queue写入队列失败\r\n");
}
}
else if(key == WKUP_PRES)
{
errorflag =xQueueSend(big_data_queue,&buf,portMAX_DELAY);
if(errorflag != pdTRUE)
{
printf("big_data_queue写入队列失败\r\n");
}
}
vTaskDelay(10);
}
}
/*task2
* @brief task2
* @param pvParameters : 传入参数(未用到)
* @retval 无
*/
void task2(void *pvParameters)
{
uint8_t key = 0;
BaseType_t errorflag = 0;
while(1)
{
errorflag = xQueueReceive(key_queue,&key,portMAX_DELAY);
if(errorflag != pdTRUE)
{
printf("key_queue读取队列失败\r\n");
}
else
{
printf("key_queue读取队列成功,数据:%d\r\n",key);
}
}
}
/*task3
* @brief task3
* @param pvParameters : 传入参数(未用到)
* @retval 无
*/
void task3(void *pvParameters)
{
uint8_t key = 0;
char* buf;
BaseType_t errorflag = 0;
buf = buff;
while(1)
{
errorflag = xQueueReceive(big_data_queue,&buf,portMAX_DELAY);
if(errorflag != pdTRUE)
{
printf("big_data_queue读取队列失败\r\n");
}
else
{
printf("big_data_queue读取队列成功,数据:%s\r\n",buf);
}
}
}