5.2 任务创建
1 任务创建入口
在这份代码中,任务创建的入口函数是:
void MX_FREERTOS_Init(void)这个函数的作用就是:
- 创建 FreeRTOS 任务
- 为任务分配或指定资源
- 完成任务初始化
也就是说,这不是任务执行的地方,而是任务创建的地方。:contentReference[oaicite:0]
2 本程序中创建了哪些任务
这份代码中一共创建了 4 个任务:
defaultTaskSoundTaskLightTaskColorTask:contentReference[oaicite:1]{index=1} :contentReference[oaicite:2]
3 defaultTask 的创建
defaultTask 是 STM32CubeMX 默认创建的任务,代码如下:
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);它的特点是:
- 使用
osThreadNew()创建 - 任务函数是
StartDefaultTask - 任务名是
defaultTask - 栈大小是
128 * 4 - 优先级是
osPriorityNormal:contentReference[oaicite:3]{index=3} :contentReference[oaicite:4]
说明这个任务是通过 CMSIS-RTOS 接口 创建的,而不是直接使用 FreeRTOS 原生接口。
4 SoundTask 的创建
SoundTask 的创建代码如下:
ret = xTaskCreate(PlayMusic, "SoundTask", 128, NULL, osPriorityNormal, &xSoundTaskHandle);它的特点是:
- 使用
xTaskCreate()创建 - 任务函数是
PlayMusic - 任务名是
SoundTask - 栈大小是
128 - 参数传入为
NULL - 优先级是
osPriorityNormal - 任务句柄保存在
xSoundTaskHandle中 :contentReference[oaicite:5]{index=5} :contentReference[oaicite:6]
这里使用的是 FreeRTOS 原生动态创建任务方式。
所谓动态创建,是指任务的栈空间和任务控制块由 FreeRTOS 在运行时动态申请内存。
5 LightTask 的创建
LightTask 的创建代码如下:
xLightTaskHandle = xTaskCreateStatic(Led_Test, "LightTask", 128, NULL, osPriorityNormal, g_pucStackOfLightTask, &g_TCBofLightTask);它的特点是:
- 使用
xTaskCreateStatic()创建 - 任务函数是
Led_Test - 任务名是
LightTask - 栈大小是
128 - 参数传入为
NULL - 优先级是
osPriorityNormal - 使用用户自己定义的栈空间
g_pucStackOfLightTask - 使用用户自己定义的任务控制块
g_TCBofLightTask - 任务句柄保存在
xLightTaskHandle中 :contentReference[oaicite:7]{index=7} :contentReference[oaicite:8]
这里使用的是 FreeRTOS 原生静态创建任务方式。
所谓静态创建,是指任务运行所需的栈和任务控制块,不由系统动态分配,而是由程序员提前定义好。
6 ColorTask 的创建
ColorTask 的创建代码如下:
xColorTaskHandle = xTaskCreateStatic(ColorLED_Test, "ColorTask", 128, NULL, osPriorityNormal, g_pucStackOfColorTask, &g_TCBofColorTask);它的特点与 LightTask 类似:
- 使用
xTaskCreateStatic()创建 - 任务函数是
ColorLED_Test - 任务名是
ColorTask - 栈大小是
128 - 参数传入为
NULL - 优先级是
osPriorityNormal - 使用用户自己提供的栈和任务控制块
- 任务句柄保存在
xColorTaskHandle中 :contentReference[oaicite:9]{index=9} :contentReference[oaicite:10]
7 本程序中体现出的三种任务创建方式
从这份代码可以看出,程序中一共使用了三种任务创建方式:
7.1 CMSIS-RTOS 方式
osThreadNew(...)用于创建 defaultTask。:contentReference[oaicite:11]
7.2 FreeRTOS 动态创建方式
xTaskCreate(...)用于创建 SoundTask。:contentReference[oaicite:12]
7.3 FreeRTOS 静态创建方式
xTaskCreateStatic(...)用于创建 LightTask 和 ColorTask。:contentReference[oaicite:13]
因此,这份代码非常适合用来学习 任务的不同创建方式。
8 静态任务创建前为什么要先定义变量
在创建 LightTask 和 ColorTask 之前,代码先定义了这些变量:
static StackType_t g_pucStackOfLightTask[128];
static StaticTask_t g_TCBofLightTask;
static TaskHandle_t xLightTaskHandle;
static StackType_t g_pucStackOfColorTask[128];
static StaticTask_t g_TCBofColorTask;
static TaskHandle_t xColorTaskHandle;它们的作用分别是:
g_pucStackOfLightTask[128]:LightTask 的任务栈g_TCBofLightTask:LightTask 的任务控制块xLightTaskHandle:LightTask 的任务句柄g_pucStackOfColorTask[128]:ColorTask 的任务栈g_TCBofColorTask:ColorTask 的任务控制块xColorTaskHandle:ColorTask 的任务句柄 :contentReference[oaicite:14]
这说明:
静态创建任务时,必须由用户提前准备好任务栈和任务控制块。
9 任务创建代码中各参数的基本含义
以这句代码为例:
ret = xTaskCreate(PlayMusic, "SoundTask", 128, NULL, osPriorityNormal, &xSoundTaskHandle);各参数含义如下:
PlayMusic:任务函数"SoundTask":任务名字128:任务栈大小NULL:传递给任务函数的参数osPriorityNormal:任务优先级&xSoundTaskHandle:保存任务句柄的地址 :contentReference[oaicite:15]
所以,一个任务在创建时,至少要明确这些内容:
- 执行什么函数
- 叫什么名字
- 给多大栈空间
- 优先级是多少
- 是否需要传参
- 是否保存句柄
10 本程序中任务优先级的特点
从代码可以看出,这几个任务的优先级都设置成了:
osPriorityNormal也就是说,目前这几个任务是 同一优先级。:contentReference[oaicite:16]{index=16} :contentReference[oaicite:17]
这说明当前代码更主要是在演示“如何创建多个任务”,而不是通过不同优先级体现复杂调度关系。
11 本程序中任务创建部分的学习重点
从学习任务管理的角度看,这段代码最值得掌握的内容有 3 个:
11.1 任务创建入口是 MX_FREERTOS_Init()
所有任务都是在这里创建的。:contentReference[oaicite:18]
11.2 任务可以有不同的创建方式
本程序同时展示了:
- CMSIS-RTOS 创建方式
- FreeRTOS 动态创建方式
- FreeRTOS 静态创建方式 :contentReference[oaicite:19]
11.3 静态创建和动态创建的区别
- 动态创建:系统自动分配栈和 TCB
- 静态创建:用户自己提供栈和 TCB
这是学习 FreeRTOS 任务管理时非常重要的一个知识点。:contentReference[oaicite:20]{index=20} :contentReference[oaicite:21]
12 小结
这份代码的任务创建部分,主要展示了 FreeRTOS 中任务的创建方法。程序在 MX_FREERTOS_Init() 中一共创建了 4 个任务,其中 defaultTask 使用 CMSIS-RTOS 接口创建,SoundTask 使用 FreeRTOS 动态方式创建,LightTask 和 ColorTask 使用 FreeRTOS 静态方式创建。通过这段代码,可以初步理解任务函数、任务句柄、任务栈、任务控制块以及动态创建和静态创建之间的区别。
