本专栏将对FreeRTOS进行快速讲解,带你了解并使用FreeRTOS的各部分内容。适用于快速了解FreeRTOS并进行开发、突击面试、对新手小白非常友好。期待您的后续关注和订阅!
目录
任务创建和删除
1 任务创建方式
任务创建方式分为两种,一种为动态创建,另一种为静态创建方式。区别就是一个系统自行分配,另外一个由用户自己进行分配。
- 动态创建任务:任务的任务控制块和任务的栈空间所需的内存,均由 FreeRTOS 从 FreeRTOS 管理的堆中分配。
-
静态创建任务:任务的任务控制块以及任务的栈空间所需的内存,需用户分配提供。
任务创建和删除主要用到以下三个API函数:
API函数 | 描述 |
xTaskCreate() | 动态方式创建任务 |
xTaskCreateStatic() | 静态方式创建任务 |
vTaskDelete() | 删除任务 |
1.1 动态任务创建
(1)函数简介
动态任务创建函数详解如下所示,动态任务创建完成后会有一个返回值,当返回值为pdPASS的时候说明任务创建成功,若为其他值时说明任务创建失败!任务函数详解如下:
返回值 | 描述 |
pdPASS | 任务创建成功 |
errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY | 任务创建失败 |
(2)任务创建流程
静态任务创建需要以下三部进行:
- 将宏configSUPPORT_DYNAMIC_ALLOCATION 配置为 1
- 定义函数入口参数
- 编写任务函数
(3)程序举例
函数创建举例如下,在这个例子中,我们创建了一个简单的任务,并启动了调度器。注意,实际任务代码可能会更复杂,并且需要根据应用的具体需求进行调整。
#include "FreeRTOS.h"
#include "task.h"
// 任务函数声明
void vTaskFunction(void *pvParameters);
// 主函数
void main(void) {
// 任务句柄声明
TaskHandle_t xHandle = NULL;
// 任务名字声明
const char *pcTaskName = "TaskName";
// 堆栈大小声明
const configSTACK_DEPTH_TYPE usStackDepth = configMINIMAL_STACK_SIZE;
// 参数声明
void *pvParameters = NULL;
// 优先级声明
UBaseType_t uxPriority = tskIDLE_PRIORITY + 1;
// 创建任务
BaseType_t xReturned = xTaskCreate(
vTaskFunction, // 任务函数
pcTaskName, // 任务名字
usStackDepth, // 堆栈大小
pvParameters, // 传递给任务函数的参数
uxPriority, // 任务优先级
&xHandle // 任务句柄
);
// 检查任务创建是否成功
if (xReturned == pdPASS) {
// 任务创建成功
} else {
// 任务创建失败
}
// 启动调度器
vTaskStartScheduler();
// 程序不应到达这里
for (;;) {}
}
// 任务函数定义
void vTaskFunction(void *pvParameters) {
for (;;) {
// 任务代码
}
}
1.2 静态任务创建
静态任务创建函数很少使用,绝大部分都是动态任务创建函数。等大家技术精炼了之后,可以使用静态任务创建函数进行榨干内存试一试。
(1)函数简介
静态任务创建函数详解如下所示,动态任务创建完成后也会会有一个返回值,其返回值与动态任务创建函数不同,当返回值不等于NULL时任务创建成功,若为其他值时说明任务创建失败!任务函数详解如下:
返回值 | 描述 |
NULL | 用户没有提供相应的内存,任务创建失败 |
其他值 | 任务句柄,任务创建成功 |
(2)任务创建流程
静态任务创建需要以下5部进行:
- 将宏configSUPPORT_DYNAMIC_ALLOCATION 配置为 1
- 定义空闲任务&定时器任务的任务堆栈及TCB
- 实现两个接口函数
- 定义函数入口参数
- 编写任务函数
(3)程序举例
函数创建举例如下,在这个例子中,我们创建了一个简单的任务,也启动了调度器。注意,实际任务代码可能会更复杂,并且需要根据应用的具体需求进行调整。
#include "FreeRTOS.h"
#include "task.h"
// 任务函数声明
void vTaskFunction(void *pvParameters);
// 静态任务相关变量声明
#define TASK_STACK_SIZE 100 // 定义堆栈大小
#define TASK_PRIORITY tskIDLE_PRIORITY + 1 // 定义任务优先级
// 任务堆栈和任务控制块
static StackType_t xStack[TASK_STACK_SIZE];
static StaticTask_t xTaskBuffer;
void main(void) {
// 任务名字声明
const char *pcTaskName = "StaticTask";
// 参数声明
void *pvParameters = NULL;
// 创建静态任务
TaskHandle_t xHandle = xTaskCreateStatic(
vTaskFunction, // 任务函数
pcTaskName, // 任务名字
TASK_STACK_SIZE, // 堆栈大小
pvParameters, // 传递给任务函数的参数
TASK_PRIORITY, // 任务优先级
xStack, // 任务堆栈
&xTaskBuffer // 任务控制块
);
// 启动调度器
vTaskStartScheduler();
// 程序不应到达这里
for (;;) {}
}
// 任务函数定义
void vTaskFunction(void *pvParameters) {
for (;;) {
// 任务代码
}
}
2 任务删除函数
(1)函数简介
任务删除函数非常简单,用于删除已被创建的任务。被删除的任务将从就绪态任务列表、阻塞态任务列表、挂起态任务列表和事件列表中全部移除。
需要注意的是以下两点:
- 传入的参数为NULL,则代表删除任务自身(当前正在运行的任务)
- 空闲任务会负责释放被删除任务中由系统分配的内存,但由用户在任务删除前申请的内存, 则需要由用户在任务被删除前提前释放,否则将会导致内存泄露
形参 | 描述 |
xTaskToDelete | 待删除任务的任务句柄 |
(2)任务创建流程
静态任务创建需要以下2部进行:
- 使用删除任务函数,需将宏INCLUDE_vTaskDelete 配置为 1
- 入口参数输入需要删除的任务句柄(NULL代表删除本身)
(3)程序举例
任务删除函数非常简单,该函数我们在以下程序创建了一个任务,然后删除。
#include "FreeRTOS.h"
#include "task.h"
// 任务函数声明
void vTaskFunction(void *pvParameters);
void main(void) {
// 任务句柄声明
TaskHandle_t xHandle = NULL;
// 创建任务
BaseType_t xReturned = xTaskCreate(
vTaskFunction, // 任务函数
"TaskName", // 任务名字
configMINIMAL_STACK_SIZE, // 堆栈大小
NULL, // 传递给任务函数的参数
tskIDLE_PRIORITY + 1, // 任务优先级
&xHandle // 任务句柄
);
// 检查任务创建是否成功
if (xReturned == pdPASS) {
// 任务创建成功,启动调度器
vTaskStartScheduler();
} else {
// 任务创建失败,处理错误
for (;;) {}
}
}
// 任务函数定义
void vTaskFunction(void *pvParameters) {
for (int i = 0; i < 10; i++) {
// 模拟任务代码
vTaskDelay(pdMS_TO_TICKS(1000)); // 延时1秒
}
// 删除任务
vTaskDelete(NULL); // 删除自身任务
}
小结
- 在实际应用中,动态方式创建任务是最常用的,一般都会使用动态方式创建任务
- 动态创建非常简单,并且更为常用
- 静态创建:将任务堆栈放置在特定的内存位置,并且不需要关心对内存分配失败的处理
本专栏将对FreeRTOS进行快速讲解,带你了解并使用FreeRTOS的各部分内容。期待诸君的订阅和关注!
标签:操作系统,FreeRTOS,创建,void,通篇,任务,删除,函数 From: https://blog.csdn.net/weixin_49007164/article/details/140446492