外观
静态创建任务
我们已经了解到,任务的运行需要任务控制块、栈等资源的支持,这些资源可以使用rt_thread_create()请求RT-Thread进行分配。实际上,这些资源是从RT-Thread管理的堆空间(后续介绍)中分配的。
在某些时间,我们可能希望采用静态创建的方法来分配这些资源。
静态创建任务(需提前分配资源)
这种方法指的是任务控制块、栈使用全局变量进行分配,即在程序编译时确定好其存储空间。
例如,对于之前的代码,可以修改如下:
#include <rtthread.h>
#include "base.h"
/*---------------------------------------
* 静态任务资源定义
*--------------------------------------*/
// LED任务资源
static struct rt_thread led_thread;
static rt_uint8_t led_stack[4096];
// 按键任务资源
static struct rt_thread key_thread;
static rt_uint8_t key_stack[4096];
/*---------------------------------------
* 任务1:LED心跳
*--------------------------------------*/
void led_task_entry(void *param) {
RT_UNUSED(param);
while (1) {
led_toggle(LED0);
rt_thread_mdelay(2000);
}
}
/*---------------------------------------
* 任务2:按键检测
*--------------------------------------*/
void key_task_entry(void *param) {
RT_UNUSED(param);
while (1) {
if (key_pressed()) {
rt_kprintf("key pressed\n");
}
}
}
/*---------------------------------------
* 应用入口(main函数)
*--------------------------------------*/
int main(void) {
hardware_init();
// 静态初始化 LED 心跳任务
rt_thread_init(
&led_thread,
"led_heartbeat",
led_task_entry,
RT_NULL,
led_stack,
sizeof(led_stack),
10, // 优先级
5 // 时间片
);
rt_thread_startup(&led_thread);
// 静态初始化 按键监控任务
rt_thread_init(
&key_thread,
"key_monitor",
key_task_entry,
RT_NULL,
key_stack,
sizeof(key_stack),
10, // 优先级
5 // 时间片
);
rt_thread_startup(&key_thread);
return 0;
}
一旦分配好空间,即可以使用rt_thread_init()对任务控制块进行初始化,最后再使用rt_thread_startup()启动任务。
优缺点
这种方法相比动态创建任务,其不同之处及优缺点如下:
特点 | 静态创建 | 动态创建 |
---|---|---|
内存分配 | 编译时确定,使用全局变量 | 运行时动态分配,使用堆空间 |
可靠性 | 更高,避免堆碎片或创建失败 | 存在内存不足或分配失败的风险 |
灵活性 | 较低,任务结构和栈空间固定 | 高,可根据情况动态创建不同任务 |
适合场景 | 长期运行任务,系统初始化时创建 | 临时性任务或任务数量变化的场景 |
此外,如果所有任务都采用静态分配,且任务中不使用任何堆操作,则可以进一步裁剪RT-Thread,去掉其堆管理模块的使用,从而减少占用的存储空间。