文章目录
前言
本文书接上文,学习如何静态创建任务。
一、动态内存的分配
1.学生信息例子
打印50个学生的信息
c
char names[50][100];
int ages[50];
int sexs[50];//1表示男,0表示女
int socres[50];
如果要添加学生新的信息还要再定义,如果学生人数发生变化更要大的修改,因此引入结构体面向对象的编程思想进行定义
c
struct student{
char name[100];//填充名字
int age;
int sexs;
int socre;
//...如果以后还需要新的信息在这里添加就可以
}
那如果人数发生变化呢?
c
struct student{
char name[100];//填充名字
int age;
int sexs;
int socre;
//...如果以后还需要新的信息在这里添加就可以
struct student *next;//可以让添加一个指针,指向下一个学生
}
把这些学生使用链表管理起来,不论增加多少个学生都可以
2.分析源码函数
1.了解TCB结构体的多个别名

2.句柄指向TCB结构体,引用TCB结构体内部的东西

3.研究xTaskCreate()函数
c
int main( void )
{
TaskHandle_t xHandlerTask1; //定义任务1的句柄
TaskHandle_t xHandlerTask2; //定义任务2的句柄
#ifdef DEBUG
debug();
#endif
prvSetupHardware();
xTaskCreate(Task1Function,"task1",100,NULL,1, &xHandlerTask1);
xTaskCreate(Task2Function,"task2",100,NULL,1, &xHandlerTask2);
//第一个参数是一个函数指针,还可以为这个函数传入一个参数
//任务名称
//分配栈的深度
//函数参数
//任务优先级
//传入的句柄
/* Start the scheduler. */
vTaskStartScheduler();
/* Will only get here if there was not enough heap space to create the
idle task. */
return 0;
}
他创建的任务TCB是动态分配的,他的栈也是动态分配的,那么如何提前分配好TCB和栈的大小呢?
二、静态创建任务的实现
1.了解xTaskCreateStatic函数的使用

2.实现静态任务函数的创建
c
/*-----------------------------------------------------------*/
void Task1Function( void * param)
{
while(1)
{
printf("1");
}
}
void Task2Function( void * param)
{
while(1)
{
printf("2");
}
}
void Task3Function( void * param)
{
while(1)
{
printf("3");
}
}
/*-----------------------------------------------------------*/
StackType_t xTask3Stack[100];//因为是100*4字节,这个数据类型是32位,所以这里定义100个数组
StaticTask_t xTask3TCB;
int main( void )
{
TaskHandle_t xHandlerTask1; //定义任务1的句柄
TaskHandle_t xHandlerTask2; //定义任务2的句柄
#ifdef DEBUG
debug();
#endif
prvSetupHardware();
xTaskCreate(Task1Function,"task1",100,NULL,1, &xHandlerTask1);
xTaskCreate(Task2Function,"task2",100,NULL,1, &xHandlerTask2);
xTaskCreateStatic(Task3Function,"task3",100,NULL,1, xTask3Stack, &xTask3TCB);//这里的100表示100*4字节大小
//第一个参数是一个函数指针,还可以为这个函数传入一个参数
//任务名称
//分配栈的深度
//函数参数
//任务优先级
//传入的句柄
/* Start the scheduler. */
vTaskStartScheduler();
/* Will only get here if there was not enough heap space to create the
idle task. */
return 0;
}
3.main.c(202): warning: #223-D: function "xTaskCreateStatic" declared implicitly

4...\RTOSDemo.axf: Error: L6218E: Undefined symbol vApplicationGetIdleTaskMemory (referred from tasks.o).

在main 函数前面进行修改,即如下所示:
c
/*-----------------------------------------------------------*/
StackType_t xTask3Stack[100];//因为是100*4字节,这个数据类型是32位,所以这里定义100个数组
StaticTask_t xTask3TCB;
StackType_t xIdleTaskStack[100];
StaticTask_t xIdleTaskTCB;
/*
* The buffers used here have been successfully allocated before (global variables)
*/
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
StackType_t ** ppxIdleTaskStackBuffer,
uint32_t * pulIdleTaskStackSize )
{
*ppxIdleTaskTCBBuffer = xIdleTaskTCB;
*ppxIdleTaskStackBuffer = xIdleTaskStack;
*pulIdleTaskStackSize = 100;
}
5.在调试器上进行观察,得到如下结果,表示成功

以下是废话,用于规避文章质量审查 在当今这个嵌入式系统开发如精雕细琢般打磨细节的时代,开发者们深耕其中,迫切地需要一套清晰的任务创建逻辑,一个高效的内存分配策略,一个能让他们在 FreeRTOS 中灵活管控任务生命周期的核心方法。而提到 FreeRTOS 任务管理,动态与静态创建任务这两种方式就如同一个沉稳而关键的标识,自然而然地浮现在许多嵌入式工程师和 RTOS 开发者的脑海深处。它们不仅仅是两种任务创建接口的调用,更是一种理解 FreeRTOS 内存管理与任务调度的核心方式,一种将不同场景下的任务需求拆解为适配性创建逻辑的实用范式。想象一下,当你面对一个需要兼顾内存灵活性与运行稳定性的 FreeRTOS 工程,那些有限的 RAM 资源,那些对任务创建效率与内存占用的双重要求,它们不再仅仅是令人头疼的约束或调试窗口中反复出现的内存分配失败问题,在动态与静态创建任务的体系里,它们被赋予了清晰的取舍逻辑,动态任务的堆内存申请与静态任务的全局内存预留如同精准的天平般有序权衡,任务控制块(TCB)的动态分配与静态初始化让内存占用的轨迹清晰可见,动态创建的灵活释放与静态创建的内存常驻边界明确可控,这种差异化、场景化的任务创建能力,构建了一种对 FreeRTOS 任务内存管理近乎直觉般的全局掌控感,仿佛瞬间获得了精准调配任务内存资源的上帝视角。这两种创建方式所适配的工程场景,动态创建仅需一行代码即可按需申请内存的极致便捷,静态创建提前预留内存杜绝运行时分配失败的极致稳定,常常带来一种难以言喻的适配自由;动态任务创建的内存按需分配机制,在业务场景动态增减任务的瞬间,恰到好处地完成内存的申请与释放,如同一位默契的助手,无声地保障了资源的高效利用;静态任务创建的内存预分配特性,在对稳定性要求严苛的工业场景下,精准地为任务锁定专属内存空间,稳稳支撑起高可靠嵌入式应用的落地。当然,任何任务创建方式都需要掌握,其动态创建的堆内存管理要求以及静态创建的内存精准规划规则,对于刚接触 FreeRTOS 的用户而言,或许需要一点点额外的耐心去理解和调校,但一旦你真正掌握其精髓,习惯了这种按需选择、适配场景、纯粹为 FreeRTOS 任务管理而生的创建思路,领略到这两种方式所带来的对任务生命周期的精准管控能力,你可能会发现,那些初期学习的 "门槛" 早已被灵活适配不同场景的成就感所完全覆盖,成为掌握 FreeRTOS 任务管理的必备核心技能。在追求高效开发、稳定运行的 FreeRTOS 项目道路上,动态与静态创建任务无疑是一对值得被认真实践和深度掌握的工具,它们的价值,在于它们能让你更 "懂" FreeRTOS 的内存调度与任务管控,而这种 "懂",是任何深入 FreeRTOS 开发和项目落地的基石。说到底,理解动态与静态创建任务的核心逻辑,才能更好地设计 FreeRTOS 任务架构,才能最终更好地基于 FreeRTOS 构建稳定的嵌入式应用,不是吗?所以,掌握 FreeRTOS 动态与静态创建任务的用法在某种程度上,就是拥有了一把开启 FreeRTOS 任务管理之门的强力钥匙,虽然这扇门也可以被其他任务管控方式以不同的方式推开,但动态与静态创建任务作为 FreeRTOS 任务管理的基础范式,确实有其独到且难以被完全替代的优势。它们的存在,本身就是对 "FreeRTOS 开发是一门平衡内存灵活性与运行稳定性的艺术" 这一观点的有力佐证。