参考教程来源
//* 实验平台:启明欣欣 STM32F407应用开发板(高配版)
参考正点原子
#include "freertos_demo.h"
#include "./SYSTEM/usart/usart.h"
#include "led.h"
#include "lcd.h"
#include "key.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); /* 任务函数 */
/******************************************************************************************************/
QueueHandle_t key_queue; /* 小数据句柄 */
QueueHandle_t big_date_queue; /* 大数据句柄 */
char buff[100] = {"我是一个大数组,大大的数组 124214 uhsidhaksjhdklsadhsaklj"};
/**
* @brief FreeRTOS例程入口函数
* @param 无
* @retval 无
*/
void freertos_demo(void)
{
BRUSH_COLOR=RED; //设置画笔颜色为红色
LCD_DisplayString(10,10,24,"Illuminati STM32");
/* key_queue队列的动态创建 */
key_queue = xQueueCreate( 2, sizeof(uint8_t) );
if(key_queue != NULL)
{
printf("key_queue队列创建成功!!\r\n");
}else printf("key_queue队列创建失败!!\r\n");
/* big_date_queue队列的动态创建 */
big_date_queue = xQueueCreate( 1, sizeof(char *) );
if(big_date_queue != NULL)
{
printf("big_date_queue队列创建成功!!\r\n");
}else printf("big_date_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); /* 任务句柄 */
printf("开始任务ok\r\n");
vTaskDelete(StartTask_Handler); /* 删除开始任务 */
taskEXIT_CRITICAL(); /* 退出临界区 */
}
/* 任务一,实现入队 */
void task1(void *pvParameters)
{
char * buf;
BaseType_t err = 0;
buf = buff; /* 等同于buf = &buff[0] */
while(1)
{
key_scan(0);
if(keyup_data == KEY0_DATA || keyup_data == KEY1_DATA)
{
err = xQueueSend( key_queue, &keyup_data, portMAX_DELAY );//参数1:创建队列返回的句柄,2:待写入的消息(这里是键值)
if(err != pdTRUE) //3:阻塞超时时间(这里最大值即一直等)
{
printf("key_queue队列发送失败\r\n");
}
}else if(keyup_data == KEY2_DATA) //和上面入队实际值(&keyup_data)不同,此处入队的是指针&buf(应用于大数据)
{
err = xQueueSend( big_date_queue, &buf, portMAX_DELAY );
if(err != pdTRUE)
{
printf("key_queue队列发送失败\r\n");
}
}
vTaskDelay(10);
}
}
/* 任务二,小数据出队 */
void task2(void *pvParameters)
{
uint8_t key = 0;
BaseType_t err = 0;
while(1)
{
err = xQueueReceive( key_queue,&key,portMAX_DELAY);
if(err != pdTRUE)
{
printf("key_queue队列读取失败\r\n");
}else
{
printf("key_queue读取队列成功,数据:%d\r\n",key);
}
}
}
/* 任务三,大数据出队 */
void task3(void *pvParameters)
{
char * buf;
BaseType_t err = 0;
while(1)
{//AI:通常在使用 xQueueReceive(或类似的队列接收函数)时,您应该传递指针的地址,
//以便函数能够更新该指针以指向接收到的数据。这意味着您应该传递 buf 的地址(即 &buf),而不是 buf 本身
err = xQueueReceive( big_date_queue,&buf,portMAX_DELAY);//对应入队,此处出队也是指针所以是&buf
if(err != pdTRUE)
{
printf("big_date_queue队列读取失败\r\n");
}else
{
printf("数据:%s\r\n",buf);
}
}
}
上电后,按key0----key1----key2 :
下面是队列结构体ppt: