Skip to content

静态创建任务

李述铜

591字约2分钟

2025-08-30

我们已经了解到,任务的运行需要任务控制块、栈等资源的支持,这些资源可以使用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,去掉其堆管理模块的使用,从而减少占用的存储空间