FreeRTOS动态任务和静态任务创建
一.动态任务创建
1.搭建任务框架
去task.c中将任务参数复制到main中
然后将const去掉,它会限制参数类型,任务大小、任务优先级、任务句柄需要去宏定义,任务句柄是指针类型要取地址
vTaskStartScheduler(); //开启任务调度,.c中1900多行
创建了任务函数就要去定义,在task.h定义,在.c中通过动态任务函数跳转到.h中,将vTaskCode复制过去
void vTaskCode( void * pvParameters )
{
for( ;; )
{
// Task code goes here.
}
}
然后把vTaskCode改成任务名,之后去声明,之后我在函数中写两个任务,这两个任务和之前任务的创建过程一样,这个任务需要删除任务
建立了两个task,就要去写两个task的函数
到此框架就写好了,去写具体任务的内容
2.写具体任务
二.静态任务创建
1.修改宏
ConfigSUPPORT_STATIC_ALLOCATION = 1
有两个函数未定义
1.vApplication Getidle TaskMemory
2.vApplication GetTimer TaskMemory
给空闲任务分配内存
给定时器任务分配内存
去task.c中将任务参数复制到main中
去到定义里面
然后修改,将0改为1,之后编译一下,会报错说有两个东西没有定义,要自己去定义
1.vApplication Getidle TaskMemory //空闲任务
2.vApplication GetTimer TaskMemory //定时器任务
Ctrl+f跳出查找窗然后在find in File查分别找vApplication Getidle vApplication GetTimer,在查找框中去找其声明函数复制到main中
三个空闲任务大小都要定义,推栈一般是一个数组,数组的大小goto到开启任务调度函数vTaskStartScheduler()的定义
来到定义的地方找到动态函数然后goto到动态中推栈大小的定义处,然后复制蓝色部分,这就是数组的大小
同样的方法定义定时器任务,只不过定时器任务的推栈大小的数组大小不一样
goto到开启任务调度函数vTaskStartScheduler()的定义 找到图中语句去到定义处然后往下找
找到下图中语句去到定义处,就行找到软件定时器推栈大小
2.编写测试代码
开始任务 框架
task1 task2 框架
测试
任务框架创建方法和动态任务一样
写好上没代码,我们要写一个返回值handle
定义一个TaskHandle_t StartTask_Handle;然后写一下代码,TaskHandle_t 规定的
void start_task( void * pvParameters ) 这个函数在task.h中300多行,start_task是我们上面给任务的名字,这个函数写完要在顶部声明图二
然后在开始任务中创建任务,过程与开始创建任务一样,到此就完成了静态任务的创建
三.两者的运用场景和区别
在 FreeRTOS 中,静态任务和动态任务有着不同的特点,适用于不同的应用场景,下面为你详细分析它们各自适合的情况。
静态任务适用情况
对内存使用可预测性要求高的场景 - **原因**:静态任务的任务控制块(TCB)和任务堆栈所需的内存是在编译时就分配好的,通常是全局变量或者静态变量,存放在静态存储区。这使得开发者在设计阶段就能准确知道系统的内存占用情况,不会在运行时出现内存使用量不可控的情况。 - **示例**:在一些航空航天、医疗设备等对安全性和稳定性要求极高的嵌入式系统中,需要精确地规划内存使用,以避免因内存分配失败或内存碎片问题导致系统故障。例如,一个心脏起搏器的嵌入式系统,它的任务数量和每个任务所需的内存是固定的,使用静态任务可以确保系统在长时间运行过程中内存使用的稳定性。
内存资源有限且固定的场景
静态任务不会产生内存碎片,因为它们的内存分配和释放模式是固定的。在内存资源有限的系统中,内存碎片可能会导致后续的内存分配失败,即使系统看起来还有足够的空闲内存。 - **示例**:一些低成本的微控制器,如 8 位或 16 位单片机,其内存资源非常有限。在这样的系统中开发程序时,使用静态任务可以更有效地利用有限的内存资源,避免因内存碎片问题而影响系统的正常运行。
对实时性要求极高的场景
由于静态任务的内存分配和调度行为在编译时就已经确定,系统的运行时间和行为具有较高的可预测性。这对于实时系统来说非常重要,因为实时系统需要在规定的时间内完成任务,任何不可预测的内存分配或调度延迟都可能导致系统错过任务截止时间。 - **示例**:工业自动化中的机器人控制系统,需要对机器人的运动进行精确控制,每个任务都有严格的时间要求。使用静态任务可以确保任务按照预定的时间顺序执行,提高系统的实时性能。
动态任务适用情况
任务数量或内存需求动态变化的场景 - **原因**:动态任务可以在程序运行过程中根据实际需求动态地创建和删除任务,并且系统会自动管理任务所需的内存分配和释放。这使得系统能够根据不同的运行情况灵活调整任务数量和内存使用。 - **示例**:在一个智能家居系统中,用户可能会随时添加或移除智能设备。每个智能设备可能对应一个或多个任务,系统需要根据设备的连接和断开情况动态地创建或删除相应的任务。使用动态任务可以方便地实现这种功能,而不需要在编译时预先分配大量的内存来应对可能出现的所有任务。
程序功能扩展性强的场景
当程序需要不断添加新功能或模块时,动态任务可以方便地集成这些新功能。开发者可以在不修改原有代码结构的情况下,动态创建新的任务来实现新的功能。 - **示例**:一个多功能的智能手表应用程序,可能会随着软件的更新不断添加新的功能,如运动监测、睡眠分析、消息提醒等。每个新功能都可以通过动态创建一个或多个任务来实现,而不需要对原有的任务进行大规模的修改。
开发和调试阶段
在开发和调试过程中,开发者可能需要频繁地修改任务的数量、优先级和功能。动态任务的创建和删除更加灵活,方便开发者进行实验和测试。 - **示例**:在一个新的嵌入式项目开发初期,开发者可能需要不断尝试不同的任务设计和调度策略。使用动态任务可以快速地创建和删除任务,观察系统的运行情况,从而更快地找到最优的设计方案。