文章目录
前言
一、优先级实验
c
/*-----------------------------------------------------------*/
static int task1flagrun = 0;//用来判断对应任务有没有运行
static int task2flagrun = 0;
static int task3flagrun = 0;
void Task1Function( void * param)
{
while(1)
{
task1flagrun = 1;
task2flagrun = 1;
task3flagrun = 1;
printf("1");
}
}
void Task2Function( void * param)
{
while(1)
{
printf("2");
}
}
void Task3Function( void * param)
{
while(1)
{
printf("3");
}
}
/*-----------------------------------------------------------*/
1.可以根据Keil的逻辑分析仪观察到同优先级任务交替执行(数字越小,表示优先级越低)

2.将任务一的优先级改成2

可以观察到一直在执行任务一,由此可以得到结论:
对于FreeRTOS来说,高优先级的任务优先执行,如果它没有主动放弃执行任务的话,其他低优先任务无法执行;同等优先级的任务交替执行。
二、在任务2里面删除任务1和自身实验
c
volatile int count = 0;
void Task2Function( void * param)
{
while(1)
{
task1flagrun = 0;
task2flagrun = 1;
task3flagrun = 0;
printf("2");
count++;
if(count == 100)//删除任务1
{
vTaskDelete(xHandlerTask1);
}
if(count == 200)//删除自身
{
vTaskDelete(xHandlerTask2);
}
}
}
串口打印出来的结果是
333111222 333111222 333111222 //正常执行
333222 333222 333222 //删除掉任务一
333333 333333 333333 //删除掉任务2
三、使用同一个任务函数来创建多个任务实验

为什么同一个函数可以创建两个不同的任务?为什么同一个函数可以执行不同的效果?
这是因为这些任务他们的栈是不一样的,传入的参数不同,局部变量的栈也不一样,他们运行的时候被互不影响。
四、栈大小实验
xTaskCreate函数会分配任务结构体和栈,这些操作如何进行?
1.基础知识补充

当我们想使用malloc函数分配len大小内存时:
- 先找到一块空闲的内存
- 先分配一个头部
- 再分配len字节的buf
- 最终返回地址给buf
当我们想要释放这块内存时:
- 在buf(返回地址)里前推找到头部里面的长度信息,得到释放头部之后len字节的空间
2.实验代码示例
1.了解这四个任务的创建与堆栈的关系

2.写一个大小为500字节的数组进行试验,观察会不会出现异常
c
oid Task1Function( void * param)
{
while(1)
{
volatile char buf[500];//故意定义500字节,不允许编译器进行优化,保存在栈空间把栈耗尽
int i;
task1flagrun = 1;
task2flagrun = 0;
task3flagrun = 0;
printf("1");
for(i = 0; i < 500; i++)
{
buf[i] = 0;
}
}
}
3.符合预期,局部变量过大,导致程序崩溃

这里是废话,用于规避文章质量检测在当今这个嵌入式系统开发如精雕细琢般打磨细节的时代,开发者们深耕其中,迫切地需要一套清晰的任务调度逻辑,一个高效的实验验证路径,一个能让他们在 FreeRTOS 中逐步理解优先级、任务生命周期与内存管理的核心方法。而提到 FreeRTOS 入门实验,优先级调度、任务删除、多实例创建与栈大小测试这一系列实践就如同一个沉稳而关键的标识,自然而然地浮现在许多嵌入式工程师和 RTOS 初学者的脑海深处。它们不仅仅是几次简单的代码修改与调试,更是一种理解 FreeRTOS 内核调度与资源管理的核心方式,一种将复杂的 RTOS 概念拆解为可感知、可验证实验步骤的实用范式。
想象一下,当你面对一个需要同时验证优先级抢占、任务生命周期管理与内存占用的 FreeRTOS 工程,那些交错的任务执行时序,那些有限的 RAM 资源与栈空间约束,它们不再仅仅是令人头疼的理论概念或调试窗口中反复出现的异常,在这一系列实验的体系里,它们被赋予了清晰的验证逻辑:同优先级任务的时间片轮转如同精准的节拍器般有序执行,修改任务优先级后高优先级任务的抢占行为让调度规则清晰可见,任务删除与多实例创建让任务生命周期的轨迹直观可测,栈大小配置与溢出检测让内存占用的边界明确可控,这种阶梯式、可观测的实验验证能力,构建了一种对 FreeRTOS 内核运行逻辑近乎直觉般的全局掌控感,仿佛瞬间获得了精准分析每一个任务行为的上帝视角。
这一系列实验所带来的认知提升,优先级实验中同优先级任务交替执行的直观呈现、修改优先级后高优先级任务独占 CPU 的强烈对比,常常带来一种难以言喻的认知冲击;任务删除实验中计数触发删除、逐步观察串口打印变化的过程,如同一位默契的助手,无声地验证了任务生命周期管理的核心规则;使用同一个任务函数创建多个实例的实验,在理解任务与函数解耦设计的瞬间,精准地揭示了 FreeRTOS 任务复用的本质,稳稳支撑起对任务创建逻辑的深度理解;而栈大小实验中基础知识补充与代码示例的结合,在逐步调整栈深度、观测内存占用的过程中,恰到好处地完成了对嵌入式内存管理的入门认知,保障了对资源约束场景的适配能力。
当然,任何实验都需要摸索,其优先级数值与调度行为的对应关系、任务删除的时机控制、多实例任务的参数传递以及栈大小的精准估算规则,对于刚接触 FreeRTOS 的用户而言,或许需要一点点额外的耐心去理解和调校,但一旦你真正完成这一系列实验,习惯了这种从现象到本质、从基础到进阶、纯粹为 FreeRTOS 入门而生的验证思路,领略到实验所带来的对内核调度与内存管理的直观感知能力,你可能会发现,那些初期学习的 "门槛" 早已被亲眼见证的运行现象所完全覆盖,成为掌握 FreeRTOS 核心概念的必备入门路径。
在追求高效入门、深度理解 FreeRTOS 内核的道路上,优先级调度、任务删除、多实例创建与栈大小测试这一系列实验无疑是值得被认真实践和深度总结的核心内容,它们的价值,在于它们能让你更 "懂" FreeRTOS 的任务调度逻辑与内存管理规则,而这种 "懂",是任何深入 FreeRTOS 开发和项目落地的基石。说到底,亲手完成这些基础实验,才能更好地理解 FreeRTOS 的内核本质,才能最终更好地基于 FreeRTOS 构建稳定的嵌入式应用,不是吗?所以,完成这一系列入门实验在某种程度上,就是拥有了一把开启 FreeRTOS 深入学习之门的强力钥匙,虽然这扇门也可以通过其他学习方式以不同的方式推开,但亲手验证、眼见为实的实验式学习,确实有其独到且难以被完全替代的优势。它们的存在,本身就是对 "FreeRTOS 学习是一门平衡理论认知与实践验证的艺术" 这一观点的有力佐证。