FreeRTOS——任务动态创建与删除
一、实验简介
本篇博客带大家完成 FreeRTOS 多任务创建 + 任务动态删除经典入门实验,非常适合新手理解 RTOS 多任务并发、任务优先级、任务生命周期、vTaskDelete 函数用法。
实验功能:
-
创建三个任务:开始任务、任务1、任务2
-
系统启动后,任务1、任务2同时并发运行,LED0、LED1 每秒翻转一次,串口打印运行信息
-
任务1计数运行5次后,动态删除任务2
-
任务2被删除后彻底停止运行,仅剩任务1独立运行
实验现象:
-
前5秒:两个LED同时闪烁,串口同时打印两个任务运行日志
-
5秒后:LED1停止闪烁,Task2不再打印,只有Task1持续运行
二、完整可运行代码
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"
//===================== 开始任务配置 =====================
#define START_TASK_SIZE 120
#define START_TASK_PRIO 1
TaskHandle_t StartTask_Hander;
void start_task( void * pvParameters );
//===================== 任务1配置 =====================
#define TASK1_TASK_SIZE 120
#define TASK1_TASK_PRIO 2
TaskHandle_t TASK1Task_Hander;
void task1_task( void * pvParameters );
//===================== 任务2配置 =====================
#define TASK2_TASK_SIZE 120
#define TASK2_TASK_PRIO 3
TaskHandle_t Task2Task_Hander;
void task2_task( void * pvParameters );
//主函数
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//中断分组4
delay_init();
uart_init(115200);
LED_Init();
//创建开始任务
xTaskCreate( (TaskFunction_t) start_task,
(char *) "start_task",
(uint16_t) START_TASK_SIZE,
(void *) NULL,
(UBaseType_t) START_TASK_PRIO,
(TaskHandle_t *) &StartTask_Hander );
vTaskStartScheduler(); //开启任务调度
}
//开始任务:负责创建所有业务任务,随后自删除
void start_task( void * pvParameters )
{
//创建任务1
xTaskCreate( (TaskFunction_t) task1_task,
(char *) "task1_task",
(uint16_t) TASK1_TASK_SIZE,
(void *) NULL,
(UBaseType_t) TASK1_TASK_PRIO,
(TaskHandle_t *) &TASK1Task_Hander );
//创建任务2
xTaskCreate( (TaskFunction_t) task2_task,
(char *) "task2_task",
(uint16_t) TASK2_TASK_SIZE,
(void *) NULL,
(UBaseType_t) TASK2_TASK_PRIO,
(TaskHandle_t *) &Task2Task_Hander );
//开始任务完成使命,自我删除
vTaskDelete(StartTask_Hander);
}
//任务1:计数5次后删除任务2
void task1_task( void * pvParameters )
{
char task1_num = 0;
while(1)
{
task1_num++;
//运行5次后删除任务2
if(task1_num == 5)
{
printf("Task2 is delete \r\n");
vTaskDelete(Task2Task_Hander);
}
LED0 = -LED0;
vTaskDelay(1000);
printf("Task1 is running %d\r\n",task1_num);
}
}
//任务2:持续闪烁打印,等待被删除
void task2_task( void * pvParameters )
{
char task2_num =0;
while(1)
{
task2_num++;
LED1 = -LED1;
vTaskDelay(1000);
printf("Task2 is running %d\r\n",task2_num);
}
}
三、代码分层详细解析
1. 任务通用配置规范
FreeRTOS 所有任务都遵循四件套配置规范,这是标准模板:
-
任务堆栈大小:规定任务占用的栈内存
-
任务优先级:数值越大,优先级越高
-
任务句柄:任务的唯一标识,用于操控任务(删除/挂起/恢复)
-
任务函数:任务具体执行的业务逻辑
本实验优先级:任务2(3) > 任务1(2) > 开始任务(1)
2. Main 函数逻辑
main 函数在 FreeRTOS 中只做初始化和创建起始任务,不写业务代码:
-
配置中断分组、延时、串口、LED硬件初始化
-
唯一创建 开始任务
-
调用
vTaskStartScheduler()启动RTOS调度,系统正式进入多任务运行
3. 开始任务(中转任务)
开始任务是 FreeRTOS 经典设计:只负责创建其他业务任务,随后自删。
优势:系统启动更稳定,避免在调度未完全就绪时创建任务,是工程通用写法。
执行流程:创建任务1 → 创建任务2 → 自我删除,彻底释放资源。
4. 任务1(主控任务)
核心功能:计数监测 + 动态删除其他任务
-
定义计数变量,每1秒自增一次
-
计数等于5时,调用
vTaskDelete(任务2句柄)杀死任务2 -
持续翻转LED0、打印运行日志,永久运行
5. 任务2(被控制任务)
普通业务任务,无特殊逻辑:每秒翻转LED1、打印运行信息,一旦被删除,永久停止执行。
四、整体运行时序流程
-
系统启动:硬件初始化完成,创建开始任务,开启调度器
-
任务初始化:开始任务创建任务1、任务2,随后自我销毁
-
并发运行阶段(0-5s):任务1、任务2同时抢占运行,双灯闪烁,双任务日志打印
-
任务删除时刻(第5s):任务1计数达到5,执行删除API,任务2彻底终止
-
单任务运行阶段(5s后):仅任务1持续运行,LED1定格、Task2日志不再输出
五、核心知识点总结
1. vTaskDelete 函数要点
-
作用:删除一个已经创建的任务,回收任务堆栈和TCB资源
-
传参:填写任务句柄可删除指定任务;填NULL删除自身
-
删除后任务彻底结束,无法自动恢复
2. FreeRTOS 多任务核心特性
-
带
vTaskDelay()的任务会主动让出CPU,实现伪并行并发 -
优先级决定抢占顺序,空闲延时状态下高低优先级任务均可正常轮转
-
所有业务任务必须包含
while(1)死循环,否则运行一次就退出
3. 工程标准开发模板
新手固定套此流程写FreeRTOS代码,零报错:
-
定义所有任务(堆栈、优先级、句柄、函数声明)
-
main函数仅做硬件初始化 + 创建开始任务
-
开始任务批量创建业务任务,随后自删
-
编写各任务while(1)业务逻辑
-
通过RTOS API动态管控任务(删除、挂起、恢复)
六、写 FreeRTOS 程序的【固定步骤】(万能模板)
以后写 FreeRTOS 代码,严格按这 6 步走,绝对不会错:
步骤 1:定义任务三要素
#define XXX_TASK_SIZE xx
#define XXX_TASK_PRIO x
TaskHandle_t XXXTask_Handler;
void xxx_task(void *pvParameters);
步骤 2:main 函数初始化硬件
NVIC配置、延时、串口、LED...
步骤 3:main 里只创建 “开始任务”
xTaskCreate(start_task,...);
vTaskStartScheduler();
步骤 4:开始任务里创建所有业务任务
xTaskCreate(任务1);
xTaskCreate(任务2);
...
vTaskDelete(NULL); // 删除自己
步骤 5:写业务任务逻辑
void task1_task(void *pvParameters)
{
while(1)
{
// 你的功能代码
vTaskDelay(xxx);
}
}
步骤 6:使用 FreeRTOS API 控制任务(延时、删除、挂起等)
- vTaskDelay()
- vTaskDelete()
- vTaskSuspend()
- ...

更多推荐



所有评论(0)