全部文档
OneOS简介 硬件支持 编译构造工具 API参考文档 高级语言 用户编程手册 应用笔记 FAQ

任务管理及调度


简介

任务是 OneOS 操作系统中最小的调度单位,任务调度算法是基于优先级的抢占式调度算法,即在系统中除了中断处理函数、调度器上锁部分的代码和禁止中断的代码是不可抢占的之外,系统的其他部分都是可以抢占的。可支持 256 个任务优先级(可通过配置文件更改为32个或8个优先级),0 优先级代表最高优先级,最低优先级留给空闲任务使用;同时它也支持创建多个具有相同优先级的任务,相同优先级的任务间采用时间片轮转进行调度。系统不限制任务数量的多少。

OneOS 任务管理的主要功能是对任务进行管理和调度,当任务创建时,会从内核对象容器中分配任务对象,当任务被删除时,会从对象容器中删除,如图所示,每个任务都有重要的属性,如任务控制块、任务栈、入口函数等。


重要定义及数据结构

任务控制块

任务控制块包含了任务的一些重要信息,如任务优先级、状态、栈信息以及与其他任务或数据结构之间的关系等。其定义如下:

struct os_task
{
    os_object_t parent;                                 /* os object */        
    os_list_node_t   task_list;                         /* the task list */

    /* stack point and entry */
    void       *sp;                                     /* stack point */
    void       *entry;                                  /* entry */
    void       *parameter;                              /* parameter */
    void       *stack_addr;                             /* stack address */
    os_uint32_t stack_size;                             /* stack size */

    os_err_t    error;                                  /* error code */
    os_uint8_t  stat;                                   /* task status */
    /* priority */
    os_uint8_t  current_priority;                       /* current priority */
    os_uint8_t  init_priority;                          /* initialized priority */
#if OS_TASK_PRIORITY_MAX > 32
    os_uint8_t  number;
    os_uint8_t  high_mask;
#endif
    os_uint32_t number_mask;

#if defined(OS_USING_EVENT)
    /* task event */
    os_uint32_t event_set;
    os_uint8_t  event_info;
#endif

    os_ubase_t  init_tick;                              /* task's initialized tick */
    os_ubase_t  remaining_tick;                         /* remaining tick */
    os_timer_t  task_timer;                             /* built-in task timer */

    void (*cleanup)(struct os_task *task);              /* cleanup function when task exit */

    os_uint32_t user_data;                              /* private user data beyond this task */
};
任务控制块重要参数 说明
task_list 任务链表,用于维护与其他任务及数据结构的关系
sp 任务栈指针
entry 任务入口函数
parameter 任务入口函数参数
stack_addr 任务栈起始地址
stack_size 任务栈大小
stat 任务状态
current_priority 任务当前优先级,某些情况下会动态调整任务的优先级
init_priority 任务初始优先级,用于优先级调度算法
init_tick 任务的初始tick,用于在相同优先级任务间的时间片轮转调度算法
remaining_tick 任务的剩余tick,用于在相同优先级任务间的时间片轮转调度算法

API列表

接口 说明
os_task_init 任务静态方式初始化,即任务对象由使用者提供
os_task_deinit 任务反初始化,与os_task_init()匹配使用
os_task_create 任务动态创建,要求系统支持内存动态申请,与os_task_init()达到的效果一样,区别在于内存是动态申请的
os_task_destroy 任务动态销毁,与os_task_create()匹配使用
os_task_startup 开启任务执行
os_task_self 获取当前任务的句柄
os_task_name 根据任务句柄获取任务的名字
os_task_find 根据任务名字获取任务句柄
os_task_yield 任务主动放弃CPU的执行权
os_task_control 控制或更改任务的行为属性
os_task_sleep 让当前任务进入睡眠状态,以节拍为单位,不可以在中断上下文使用
os_task_msleep 让当前任务进入睡眠状态,以ms为单位,不可以在中断上下文使用
os_task_delay 与os_task_sleep()一致
os_task_mdelay 与os_task_msleep()一致
os_enter_critical 获得调度锁,进入关键代码区域,停止任务调度
os_exit_critical 释放调度锁,离开关键代码区域,恢复任务调度
os_critical_level 获得调度锁嵌套层次,若为0则代表调度锁已经被释放

os_task_init

该函数用于以静态方式初始化任务,其任务句柄(任务控制块指针)、任务栈所对应的空间由使用者提供。任务控制块、任务运行栈一般都设置为全局变量,在编译时就被确定、被分配处理,内核不负责分配其内存空间。其函数原型如下:

os_err_t os_task_init(os_task_t     *task,
                      const char    *name, 
                      void          (*entry)(void *parameter),
                      void          *parameter,
                      void          *stack_start,
                      os_uint32_t   stack_size,
                      os_uint8_t    priority,
                      os_uint32_t   tick);
参数 说明
task 任务句柄,由用户提供,并指向对应的任务控制块内存地址
name 任务名称,其最大长度由 oneos_config.h 中定义的OS_NAME_MAX 宏指定,多余部分会被自动截掉
entry 任务入口函数
parameter 任务入口函数参数
stack_start 任务栈起始地址
stack_size 任务栈大小,单位是字节。在大多数系统中需要做栈空间地址对齐
priority 任务的优先级。优先级范围根据系统配置情况(oneos_config.h 中的 OS_TASK_PRIORITY_MAX宏定义)确定,如果支持的是256级优先级,那么范围是从0 ~ 255,数值越小优先级越高,0为最高优先级
tick 任务的时间片大小。时间片(tick)的单位是操作系统的时钟节拍,当系统中存在相同优先级任务时,这个参数指定任务一次调度能够运行的最大时间长度
返回 说明
OS_EOK 任务创建成功
OS_ERROR 任务创建失败
OS_EINVAL 无效参数

os_task_deinit

该函数用于对静态任务反初始化,与os_task_init()匹配使用,函数原型如下:

os_err_t os_task_deinit(os_task_t *task);
参数 说明
task 任务句柄,是由 os_task_init() 初始化的任务句柄。
返回 说明
OS_EOK 成功
OS_ERROR 失败

os_task_create

该函数用于以动态方式创建并初始化任务,系统会从内存堆中分配一个任务控制块,按照参数中指定的栈大小从内存堆中分配相应的栈空间,然后初始化参数。函数原型如下:

os_task_t *os_task_create(const char    *name, 
                          void          (*entry)(void *parameter),
                          void          *parameter,
                          os_uint32_t   stack_size,
                          os_uint8_t    priority,
                          os_uint32_t   tick);
参数 说明
name 任务名称,最大长度由 oneos_config.h 中的宏 OS_NAME_MAX 指定
entry 任务入口函数
parameter 任务入口函数参数
stack_size 任务栈大小,单位是字节
priority 任务优先级。优先级范围根据系统配置情况(oneos_config.h 中的 OS_TASK_PRIORITY_MAX 宏定义)确定,如果支持的是256 级优先级,那么范围是从0~255,数值越小优先级越高,0为最高优先级
tick 任务时间片大小。时间片(tick)的单位是操作系统的时钟节拍,当系统中存在相同优先级任务时,这个参数指定任务一次调度能够运行的最大时间长度
返回 说明
非OS_NULL 任务创建成功,返回任务句柄
OS_NULL 任务创建失败

os_task_destroy

该函数用于销毁动态任务,与os_task_create()匹配使用,其函数原型如下:

os_err_t os_task_destroy(os_task_t *task);
参数 说明
task 要销毁的任务句柄,是由os_task_create()初始化的任务句柄
返回 说明
OS_EOK 销毁任务成功
OS_ERROR 销毁任务失败

os_task_startup

该函数可以在任务初始化或者创建成功后,让该任务进入就绪态,如果该任务优先级比当前运行的任务优先级高,会立即切换到该任务运行,其函数原型如下:

os_err_t os_task_startup(os_task_t *task);
参数 说明
task 任务句柄
返回 说明
OS_EOK 任务启动成功
OS_ERROR 任务启动失败

os_task_self

在系统运行时,该函数用于获取当前任务的句柄,其函数原型如下:

os_task_t *os_task_self(void);
参数 说明
返回 说明
os_task_t * 任务句柄

os_task_name

该函数用于根据任务句柄获取任务的名字,其函数原型如下:

char *os_task_name(os_task_t *task);
参数 说明
task 任务句柄
返回 说明
char * 任务名字

os_task_find

该函数用于根据任务名字获取任务句柄,该函数原型如下:

os_task_t *os_task_find(char *name);
参数 说明
name 任务名字
返回 说明
非OS_NULL 任务句柄
OS_NULL 未找到该任务

os_task_yield

使用该函数时,当前任务首先把自己从当前所在的就绪优先级任务队列中删除,然后把自己挂到这个优先级队列链表的尾部,然后激活调度器进行任务上下文切换,其函数原型如下:

os_err_t os_task_yield(void);
参数 说明
返回 说明
OS_EOK 成功

os_task_control

该函数用于控制或更改任务的行为属性,arg参数含义随着cmd的变化而变化,其函数原型如下:

os_err_t os_task_control(os_task_t *task, enum os_task_ctrl_cmd cmd, void *arg);
参数 说明
task 任务句柄
cmd 控制命令,包括以下几种:OS_TASK_CTRL_CHANGE_PRIORITY / OS_TASK_CTRL_STARTUP / OS_TASK_CTRL_CLOSE
arg 当命令为OS_TASK_CTRL_CHANGE_PRIORITY,此参数表示任务的新优先级
返回 说明
OS_EOK 更改成功
OS_ERROR 更改失败

os_task_sleep

让当前任务进入睡眠状态,以节拍为单位,不可以在中断上下文使用,其函数原型如下:

os_err_t os_task_sleep(os_tick_t tick);
参数 说明
tick 任务睡眠的时间,以tick为单位
返回 说明
OS_EOK 执行成功

os_task_msleep

让当前任务进入睡眠状态,以ms为单位,不可以在中断上下文使用,其函数原型如下:

os_err_t os_task_msleep(os_uint32_t ms);
参数 说明
ms 任务睡眠的时间,以ms为单位
返回 说明
OS_EOK 执行成功

os_task_delay

让当前任务进入睡眠状态,以节拍为单位,不可以在中断上下文使用,其函数原型如下:

os_err_t os_task_delay(os_tick_t tick);
参数 说明
tick 任务睡眠的时间,以tick为单位
返回 说明
OS_EOK 执行成功

os_task_mdelay

让当前任务进入睡眠状态,以ms为单位,不可以在中断上下文使用,其函数原型如下:

os_err_t os_task_mdelay(os_uint32_t ms);
参数 说明
ms 任务睡眠的时间,以ms为单位
返回 说明
OS_EOK 执行成功

os_enter_critical

获得调度锁,进入关键代码区域,停止任务调度,其函数原型如下:

void os_enter_critical(void);

os_exit_critical

释放调度锁,离开关键代码区域,调度锁嵌套层次为0时恢复任务调度,其函数原型如下:

void os_exit_critical(void);

os_critical_level

获得调度锁嵌套层次,若为0则代表调度锁已经被释放,其函数原型如下:

os_uint16_t os_critical_level(void);
参数 说明
返回 说明
os_uint16_t 当前调度嵌套的深度

使用示例

静态任务使用示例

本例会初始化静态任务并运行,之后再反初始化该任务

#include <oneos_config.h>
#include <os_dbg.h>
#include <os_errno.h>
#include <os_task.h>
#include <shell.h>

#define TEST_TASK_TAG           "TEST_TASK"
#define TEST_TASK_STACK_SIZE    1024

static os_uint8_t task_static_stack[TEST_TASK_STACK_SIZE];
static os_task_t task_static;

void static_task_entry(void *para)
{    
    os_uint8_t count = 0;

    while (1)
    {
        LOG_W(TEST_TASK_TAG, "static_task_entry is running, count:%d", count++);
        os_task_sleep(100);
    }
}

void staic_task_sample(void)
{
    os_err_t ret;

    ret = os_task_init(&task_static,
                       "task_static", 
                       static_task_entry, 
                       OS_NULL, 
                       &task_static_stack[0], 
                       TEST_TASK_STACK_SIZE, 
                       15, 
                       10);
    if (OS_EOK != ret)
    {
        LOG_E(TEST_TASK_TAG, "os_task_init fail");
        return;
    }

    LOG_W(TEST_TASK_TAG, "staic_task_sample startup");
    os_task_startup(&task_static);
    os_task_sleep(500);

    LOG_W(TEST_TASK_TAG, "staic_task_sample deinit");
    os_task_deinit(&task_static);
}

SH_CMD_EXPORT(static_task, staic_task_sample, "test task init and deinit");

运行结果如下:

sh />static_task
W/TEST_TASK: staic_task_sample startup
W/TEST_TASK: static_task_entry is running, count:0
W/TEST_TASK: static_task_entry is running, count:1
W/TEST_TASK: static_task_entry is running, count:2
W/TEST_TASK: static_task_entry is running, count:3
W/TEST_TASK: static_task_entry is running, count:4
W/TEST_TASK: staic_task_sample deinit

动态任务使用示例

本例会动态创建任务并运行,之后再销毁该任务

#include <oneos_config.h>
#include <os_dbg.h>
#include <os_errno.h>
#include <os_task.h>
#include <shell.h>

#define TEST_TASK_TAG           "TEST_TASK"
#define TEST_TASK_STACK_SIZE    1024

static os_task_t *task_dynamic = OS_NULL;

void dynamic_task_entry(void *para)
{
    os_uint8_t count = 0;

    while (1)
    {
        LOG_W(TEST_TASK_TAG, "dynamic_task_entry is running, count:%d", count++);
        os_task_sleep(100);
    }
}

void dynamic_task_sample(void)
{        
    task_dynamic = os_task_create("task_dynamic", 
                                  dynamic_task_entry, 
                                  OS_NULL, 
                                  TEST_TASK_STACK_SIZE, 
                                  15, 
                                  10);
    if (!task_dynamic)
    {
        LOG_E(TEST_TASK_TAG, "os_task_init fail");
        return;
    }

    LOG_W(TEST_TASK_TAG, "dynamic_task_sample startup");
    os_task_startup(task_dynamic);

    os_task_sleep(500);

    LOG_W(TEST_TASK_TAG, "dynamic_task_sample destroy");
    os_task_destroy(task_dynamic);
}

SH_CMD_EXPORT(dynamic_task, dynamic_task_sample, "test task create and destroy");

其运行结果如下:

sh />dynamic_task
W/TEST_TASK: dynamic_task_sample startup
W/TEST_TASK: dynamic_task_entry is running, count:0
W/TEST_TASK: dynamic_task_entry is running, count:1
W/TEST_TASK: dynamic_task_entry is running, count:2
W/TEST_TASK: dynamic_task_entry is running, count:3
W/TEST_TASK: dynamic_task_entry is running, count:4
W/TEST_TASK: dynamic_task_sample destroy

任务控制命令使用示例

本例利用命令来启动任务、关闭任务、调整优先级等

#include <oneos_config.h>
#include <os_dbg.h>
#include <os_errno.h>
#include <os_task.h>
#include <shell.h>

#define TEST_TASK_TAG           "TEST_TASK"
#define TEST_TASK_STACK_SIZE    1024

static os_uint8_t task_control_stack[TEST_TASK_STACK_SIZE];
static os_task_t task_control;

void task_control_entry(void *para)
{
    os_task_t *task;
    char *name;
    os_uint8_t count = 0;

    while (1)
    {
        task = os_task_self();
        if (task)
        {
            name = os_task_name(task);
            LOG_W(TEST_TASK_TAG, "task %s is running, count:%d", name, count++);
        }
        os_task_sleep(100);
    }
}

void control_task_sample(void)
{
    os_err_t ret;
    os_uint8_t priority;

    priority = 15;
    ret = os_task_init(&task_control, 
                       "task_control", 
                       task_control_entry, 
                       OS_NULL, 
                       task_control_stack, 
                       TEST_TASK_STACK_SIZE, 
                       priority, 
                       10);
    if (OS_EOK != ret)
    {
        LOG_E(TEST_TASK_TAG, "os_task_init fail");
        return;
    }

    LOG_W(TEST_TASK_TAG, "control_task_sample startup");
    ret = os_task_control(&task_control,OS_TASK_CTRL_STARTUP,OS_NULL);
    if (OS_EOK != ret)
    {
        LOG_E(TEST_TASK_TAG, "start up task fail:%d",ret);
    }

    os_task_sleep(500);

    LOG_W(TEST_TASK_TAG, "control_task_sample change priority");
    priority = 19;
    ret = os_task_control(&task_control,OS_TASK_CTRL_CHANGE_PRIORITY,&priority);
    if (OS_EOK != ret)
    {
        LOG_E(TEST_TASK_TAG, "change task priority fail:%d",ret);
    }

    os_task_sleep(500);

    LOG_W(TEST_TASK_TAG, "control_task_sample close");
    ret = os_task_control(&task_control,OS_TASK_CTRL_CLOSE,OS_NULL);
    if (OS_EOK != ret)
    {
        LOG_E(TEST_TASK_TAG, "close task fail:%d",ret);
    }
}

SH_CMD_EXPORT(control_task, control_task_sample, "test task control");

其运行结果如下:

sh />control_task
W/TEST_TASK: control_task_sample startup
W/TEST_TASK: task task_control is running, count:0
W/TEST_TASK: task task_control is running, count:1
W/TEST_TASK: task task_control is running, count:2
W/TEST_TASK: task task_control is running, count:3
W/TEST_TASK: task task_control is running, count:4
W/TEST_TASK: control_task_sample change priority
W/TEST_TASK: task task_control is running, count:5
W/TEST_TASK: task task_control is running, count:6
W/TEST_TASK: task task_control is running, count:7
W/TEST_TASK: task task_control is running, count:8
W/TEST_TASK: task task_control is running, count:9
W/TEST_TASK: control_task_sample close

results matching ""

    No results matching ""

    返回顶部