2025最新超详细FreeRTOS入门教程:第二章 FreeRTOS任务创建
本文是FreeRTOS入门教程第二章,重点讲解任务创建与管理。从裸机系统与RTOS的对比切入,详细介绍了动态创建任务(xTaskCreate)和静态创建任务(xTaskCreateStatic)两种方式,包括参数说明和使用场景。通过示例代码展示了多任务并发实现,并讲解了任务优先级、调度策略以及任务生命周期管理。文章还提供了任务句柄的用法、常见问题解决方法及开发建议,帮助初学者掌握FreeRTOS多
2025最新超详细FreeRTOS入门教程:第二章 FreeRTOS任务创建
摘要
在完成第一章 FreeRTOS 移植到 STM32 后,我们已经能够运行一个最小任务。本章将带你深入理解 任务(Task) 的概念、创建方式、运行机制和调度策略。
任务是 FreeRTOS 的核心,掌握任务的创建和使用,意味着你已经正式踏入 RTOS 世界。
文章目录
一、任务的基本概念
📌 在 裸机系统 中,程序代码通常放在
while(1)
循环中顺序执行,而 FreeRTOS 将应用划分为 多个任务,每个任务都可以看作一个独立的线程,内核负责任务的调度和切换。
特点
- 每个任务都有自己的 堆栈空间
- 内核根据 优先级 和 调度算法 切换任务
- 每个任务都像一个无限循环,通常以
for(;;)
或while(1)
形式实现
二、任务创建 API
FreeRTOS 提供了 xTaskCreate()
和 xTaskCreateStatic()
两种方式。
1. 动态创建任务
BaseType_t xTaskCreate(
TaskFunction_t pvTaskCode, // 任务函数
const char * const pcName, // 任务名字
configSTACK_DEPTH_TYPE usStackDepth, // 栈深度
void *pvParameters, // 任务参数
UBaseType_t uxPriority, // 优先级
TaskHandle_t *pxCreatedTask // 任务句柄
);
参数说明:
参数 | 说明 |
---|---|
pvTaskCode |
任务入口函数 |
pcName |
任务名(调试用) |
usStackDepth |
栈大小,以 word 计 |
pvParameters |
传入参数 |
uxPriority |
优先级(数值越大,优先级越高) |
pxCreatedTask |
任务句柄(可为空) |
2. 静态创建任务
xTaskCreateStatic()
需要手动分配堆栈和任务控制块(TCB),常用于安全性要求高的系统:
TaskHandle_t xTaskCreateStatic(
TaskFunction_t pvTaskCode,
const char * const pcName,
uint32_t ulStackDepth,
void *pvParameters,
UBaseType_t uxPriority,
StackType_t *puxStackBuffer,
StaticTask_t *pxTaskBuffer
);
静态任务不会依赖 FreeRTOS 的堆管理,更稳定,但更复杂。
三、任务的优先级与调度
调度策略
- 基于优先级:高优先级任务优先运行
- 同优先级任务:采用时间片轮转
示例
四、任务创建实战
示例:两个任务并发
#include "FreeRTOS.h"
#include "task.h"
void vTaskLED(void *pvParameters)
{
while(1)
{
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
vTaskDelay(500); // 延时500ms
}
}
void vTaskUART(void *pvParameters)
{
while(1)
{
printf("Hello FreeRTOS!\n");
vTaskDelay(1000);
}
}
int main(void)
{
HAL_Init();
SystemClock_Config();
// 创建两个任务
xTaskCreate(vTaskLED, "LED", 128, NULL, 2, NULL);
xTaskCreate(vTaskUART, "UART", 128, NULL, 1, NULL);
// 启动调度器
vTaskStartScheduler();
while(1) {}
}
五、任务句柄的使用
获取任务信息
TaskHandle_t xHandleLED, xHandleUART;
xTaskCreate(vTaskLED, "LED", 128, NULL, 2, &xHandleLED);
xTaskCreate(vTaskUART, "UART", 128, NULL, 1, &xHandleUART);
任务句柄可用于:
- 删除任务
vTaskDelete(xHandle)
- 挂起/恢复任务
vTaskSuspend(xHandle)
/vTaskResume(xHandle)
- 动态修改优先级
vTaskPrioritySet(xHandle, newPriority)
六、任务生命周期
七、常见问题与解决方法
问题 | 可能原因 | 解决方法 |
---|---|---|
任务未运行 | 调度器未启动 | 确认 vTaskStartScheduler() |
栈溢出 | 栈设置过小 | 增大 usStackDepth |
多任务不切换 | SysTick 中断未配置 | 检查 SysTick_Handler |
打印乱码 | 串口任务未同步 | 使用信号量/队列管理输出 |
八、经验分享
📌 开发建议
- 任务数量不要太多,模块化设计 更重要
- 建议使用
configCHECK_FOR_STACK_OVERFLOW
开启栈检测- 调试时多用
uxTaskGetStackHighWaterMark()
观察剩余栈空间- 使用
vTaskDelay()
而不是阻塞式for
循环,保证调度公平
九、总结
通过本章学习,你应该掌握:
- 使用
xTaskCreate()
创建任务 - 理解任务的优先级和调度规则
- 管理任务的生命周期(创建、挂起、恢复、删除)
- 编写多任务并发程序
至此,你已经能够写出一个 多任务系统,并亲身感受到 RTOS 与裸机的差异。
🔗 FreeRTOS专栏👉 下一章:2025最新超详细FreeRTOS入门教程:第三章 FreeRTOS任务管理 —— 将深入讲解任务的挂起、删除、优先级动态调整等更高级操作。
更多推荐
所有评论(0)