4.2 任务管理
4.2 任务管理
📚 本节导读
学习时长: 约 90 分钟(含所有子节)
难度级别: ⭐⭐⭐⭐☆
前置知识: 实时操作系统基本概念、C 语言指针与内存管理
🎯 学习目标
- 理解 OneOS 中任务的概念和任务控制块(TCB)的结构
- 掌握静态创建与动态创建任务的区别
- 熟悉任务管理的 API 分类和功能
- 了解各子节的导航关系
一、任务管理概述
任务管理是 OneOS-Lite 内核最核心的模块,负责管理系统中所有任务的整个生命周期。任务管理模块提供了任务创建、启动、调度、状态管理、优先级控制、时间片控制、挂起恢复、延时以及销毁等全部功能。所有任务管理相关的 API 均在 kernel/include/os_task.h 中声明,核心实现在 kernel/source/os_task.c 中。
二、任务基本概念
2.1 任务控制块(TCB)
任务控制块(Task Control Block,TCB)是内核描述和管理一个任务的核心数据结构。每个任务都有唯一的 TCB,其中包含了任务运行所需的所有上下文信息。
在 OneOS 中,TCB 的内部结构体 os_task_t 包含以下关键字段:
| 字段 | 类型 | 说明 |
|---|---|---|
stack_top | void * | 当前栈顶指针(SP) |
stack_begin | void * | 任务栈起始地址 |
stack_end | void * | 任务栈结束地址 |
state | uint16_t | 任务当前状态(位掩码) |
current_priority | uint8_t | 当前优先级 |
backup_priority | uint8_t | 备用优先级(用于优先级继承) |
err_code | os_err_t | 任务错误码 |
time_slice | os_tick_t | 任务时间片大小(单位:tick) |
remaining_time_slice | os_tick_t | 剩余时间片(单位:tick) |
block_list_head | os_list_node_t * | 阻塞所在的 IPC 队列 |
cleanup | void (*)(void *) | 清理回调函数 |
user_data | void * | 用户私有数据 |
name | char[OS_NAME_MAX+1] | 任务名称 |
object_inited | uint8_t | 内核对象初始化状态 |
object_alloc_type | uint8_t | 分配类型(静态/动态) |
注意:用户代码中不应直接访问 TCB 的内部字段,而应通过
os_task.h中提供的 API 函数进行操作。TCB 的内部结构仅通过os_dummy.h以dummy_task_t的形式暴露给用户,用于静态定义任务控制块。
2.2 任务栈
每个任务都有自己独立的栈空间,用于保存函数调用上下文、局部变量、CPU 寄存器等。任务栈是任务运行的基础:
- 栈大小:由创建任务时指定,取决于任务的功能需求(局部变量大小、函数调用深度等)
- 栈对齐:栈必须按架构要求的对齐方式对齐(
OS_ARCH_STACK_ALIGN_SIZE) - 栈生长方向:由 CPU 架构决定,可以是向下生长(满递减栈)或向上生长
2.3 任务入口函数
任务入口函数是任务开始执行时调用的函数,其签名为:
void task_entry(void *arg);arg:创建任务时传入的参数,可以为OS_NULL- 任务函数通常是一个无限循环(
while(1)),也可以正常返回(返回后任务自动退出)
三、静态创建与动态创建
OneOS 支持两种任务创建方式:
| 方式 | 说明 | 适用场景 |
|---|---|---|
| 静态创建 | 用户预先定义 TCB 和栈空间,创建时传入已分配内存的指针 | 资源受限、不允许动态内存分配的系统 |
| 动态创建 | 创建时传入 NULL,内核自动从堆中分配 TCB 和栈空间 | 内存充足、方便灵活的场景 |
静态创建
/* 定义任务控制块 */
OS_TASK_DEFINE(my_task_cb);
/* 定义任务栈 */
OS_TASK_STACK_DEFINE(my_task_stack, 1024);
/* 创建任务 */
os_task_id tid = os_task_create(
&my_task_cb, /* 静态 TCB */
OS_TASK_STACK_BEGIN_ADDR(my_task_stack), /* 栈起始地址 */
OS_TASK_STACK_SIZE(my_task_stack), /* 栈大小 */
"my_task", /* 任务名称 */
task_entry, /* 入口函数 */
OS_NULL, /* 入口参数 */
5 /* 优先级 */
);动态创建
/* 创建任务(TCB 和栈都由内核自动分配) */
os_task_id tid = os_task_create(
OS_NULL, /* TCB 为 NULL,内核自动分配 */
OS_NULL, /* 栈为 NULL,内核自动分配 */
1024, /* 栈大小 */
"my_task", /* 任务名称 */
task_entry, /* 入口函数 */
OS_NULL, /* 入口参数 */
5 /* 优先级 */
);注意:动态创建需要启用
OS_USING_HEAP配置宏,否则无法使用。
四、API 快速参考表
4.1 任务生命周期管理
| API 函数 | 功能 | 说明 |
|---|---|---|
os_task_create() | 创建任务 | 静态或动态创建,返回任务 ID |
os_task_startup() | 启动任务 | 将任务从 INIT 状态转为 READY 状态 |
os_task_destroy() | 销毁任务 | 销毁指定的任务并回收资源 |
os_task_set_cleanup_callback() | 设置清理回调 | 任务销毁前执行的回调函数 |
os_task_set_user_data() | 设置用户数据 | 为任务关联私有数据 |
os_task_get_user_data() | 获取用户数据 | 获取已关联的私有数据 |
4.2 任务调度与控制
| API 函数 | 功能 | 说明 |
|---|---|---|
os_task_yield() | 主动让出 CPU | 让同优先级的下一个任务运行 |
os_task_suspend() | 挂起任务 | 暂停任务执行 |
os_task_resume() | 恢复任务 | 恢复被挂起的任务 |
os_task_tsleep() | 节拍延时 | 基于系统时钟节拍的延时 |
os_task_msleep() | 毫秒延时 | 基于毫秒的延时 |
os_schedule_lock() | 锁定调度器 | 禁止任务切换 |
os_schedule_unlock() | 解锁调度器 | 恢复任务切换 |
os_is_schedule_locked() | 检查调度器状态 | 返回调度器是否锁定 |
4.3 任务属性管理
| API 函数 | 功能 | 说明 |
|---|---|---|
os_task_set_priority() | 设置优先级 | 动态修改任务优先级 |
os_task_get_priority() | 获取优先级 | 获取任务当前优先级 |
os_task_set_time_slice() | 设置时间片 | 修改任务时间片大小 |
os_task_get_time_slice() | 获取时间片 | 获取任务时间片大小 |
os_task_get_remaining_time_slice() | 获取剩余时间片 | 获取任务当前剩余时间片 |
4.4 任务信息查询
| API 函数 | 功能 | 说明 |
|---|---|---|
os_get_current_task() | 获取当前任务 | 获取当前正在运行的任务 ID |
os_task_get_id() | 按名称查找任务 | 通过任务名称获取任务 ID |
os_task_check_exist() | 检查任务是否存在 | 判断指定任务是否有效 |
os_task_get_name() | 获取任务名称 | 获取指定任务的名称字符串 |
os_task_get_state() | 获取任务状态 | 获取指定任务的当前状态 |
os_task_get_stack_top() | 获取栈顶 | 获取任务当前栈顶指针 |
os_task_get_stack_begin() | 获取栈起始地址 | 获取任务栈起始地址 |
os_task_get_stack_end() | 获取栈结束地址 | 获取任务栈结束地址 |
os_task_get_total_count() | 获取任务总数 | 获取系统中当前的任务总数 |
4.5 调度器钩子
| API 函数 | 功能 | 说明 |
|---|---|---|
os_task_switch_hook_add() | 添加任务切换钩子 | 注册任务切换时的回调函数 |
os_task_switch_hook_delete() | 删除任务切换钩子 | 注销已注册的任务切换回调 |
4.6 错误码操作
| 宏/函数 | 功能 | 说明 |
|---|---|---|
os_errno() | 获取错误码指针 | 返回当前任务的错误码指针 |
OS_SET_ERRNO(code) | 设置错误码 | 设置当前任务错误码 |
OS_GET_ERRNO() | 获取错误码 | 获取当前任务错误码 |
五、子节导航
任务管理模块的详细内容按以下子节展开,建议按顺序阅读:
| 子节 | 说明 | 页内链接 |
|---|---|---|
| 4.2.1 | 任务状态机 —— 7 种状态的完整状态转换图 | 4.2.1 任务状态机 |
| 4.2.2 | 任务创建与销毁 —— 静态/动态创建、启动、销毁 | 4.2.2 任务创建与销毁 |
| 4.2.3 | 任务调度 —— 优先级抢占、时间片轮转、主动让出 | 4.2.3 任务调度 |
| 4.2.4 | 任务优先级 —— 优先级范围、动态修改、优先级继承 | 4.2.4 任务优先级 |
| 4.2.5 | 任务时间片 —— 时间片概念、配置、API 使用 | 4.2.5 任务时间片 |
| 4.2.6 | 任务挂起与恢复 —— SUSPEND 状态、挂起恢复操作 | 4.2.6 任务挂起与恢复 |
| 4.2.7 | 任务延时 —— tick 延时、ms 延时、SLEEP 状态 | 4.2.7 任务延时 |
| 4.2.8 | 调度器锁定 —— 锁定/解锁调度器、临界区保护 | 4.2.8 调度器锁定 |
| 4.2.9 | 任务钩子 —— 任务切换钩子的注册与使用 | 4.2.9 任务钩子 |
📝 本节小结
任务是 OneOS-Lite 中最基本的执行单元。每个任务拥有独立的 TCB 和栈空间,通过任务入口函数执行业务逻辑。OneOS 支持静态和动态两种任务创建方式,提供了丰富的 API 用于任务生命周期管理、调度控制、属性管理和信息查询。后续子节将详细展开每个主题。