现代操作系统都建立在任务的基础上,任务是AliOS Things的一个基本执行环境,有的操作系统也称之为线程(thread)。多任务的运行环境提供了一个基本机制,从宏观上可以看作单个CPU执行单元上同时执行多个任务,从微观上看,CPU快速地切换任务来并发运行多个任务。AliOS Things实时操作系统支持多任务机制。
每个任务都具有上下文(context),上下文context是指当任务被调度执行的时候此任务能看见的CPU资源和系统资源,当发生任务切换的时候,任务的上下文被保存在任务控制块(ktask_t)中,这些上下文包括当前任务的CPU指令地址(PC指针),当前任务的栈空间,当前任务的CPU寄存器状态等。
任务管理功能的相关源码位于:/core/osal/aos/rhino.c 文件中(AliOS Things v3.1);osal/aos/rhino.c(AliOS Things v3.0及以前)。
API列表
aos_task_new() | 动态创建一个任务,任务句柄不返回,创建完后自动运行 |
aos_task_new_ext() | 动态创建一个任务,传入任务句柄,并指定优先级,创建完后自动运行 |
aos_task_exit() | 任务自动退出 |
aos_task_delete() | 任务删除 |
aos_task_name() | 返回当前任务名 |
aos_task_key_create() | 申请一个任务私有数据区域 |
aos_task_key_delete() | 释放一个任务私有数据区域 |
aos_task_setspecific() | 设置指定任务私有数据区域的内容 |
aos_task_getspecific() | 获取指定任务私有数据区域的内容 |
使用
添加该组件
任务管理是AliOS Things 默认添加的组件,开发者无需再手动添加。
包含头文件
#include <aos/kernel.h>
使用示例
示例说明:创建一个任务,在任务内创建任务私有数据区域,设置私有区域内容、获取私有区域内容,删除私有数据区域,最后任务退出。
/* 创建任务test_task,任务栈大小为1024字节 */
aos_task_new("test_task", test_task, NULL, 1024);
static void test_task(void *paras)
{
int ret = -1;
int var = 0;
aos_task_key_t task_key;
void *task_value = NULL;
/* 创建任务私有数据区域*/
ret = aos_task_key_create(&task_key);
/* 打印任务名和任务私有数据区域索引值*/
printf("%s task key %d: \r\n", aos_task_name(), task_key);
var = 0x5a5a;
/* 设置当前任务私有数据区域的某索引空闲块内容 */
ret = aos_task_setspecific(task_key, &var);
/* 获取当前任务私有数据区域的某索引数据块内容 */
task_value = aos_task_getspecific(task_key);
printf("%s task key 0x%x: \r\n", aos_task_name(), *(int*)task_value);
/* 删除任务私有数据区域的空闲块索引 */
aos_task_key_delete(task_key);
/* 任务退出 */
aos_task_exit(0);
}
API 详情
任务管理的应用层API说明请参考include/aos/kernel.h
aos_task_new()
动态创建一个任务,任务句柄不返回,创建完后自动运行。采用默认优先级AOS_DEFAULT_APP_PRI(32)。受宏RHINO_CONFIG_KOBJ_DYN_ALLOC开关控制。
函数原型
int aos_task_new(const char *name, void (*fn)(void *), void *arg, int stack_size);
输入参数
name |
任务名 | '"test_task"' |
fn |
任务处理函数 | |
arg |
任务处理函数的参数 | |
stack_size |
任务栈大小(单位:字节) |
返回参数
0表示成功,其他值表示失败。具体的返回值见本文档返回参数定义小节。
调用示例
static void test_task(void *paras)
{
……
}
aos_task_new("test_task", test_task, NULL, 1024);
aos_task_new_ext()
动态创建一个任务,传入任务句柄,并指定优先级,创建完后自动运行。
函数原型
int aos_task_new_ext(aos_task_t *task, const char *name, void (*fn)(void *), void *arg, int stack_size, int prio);
输入参数
task |
任务句柄 | |
name |
任务名 | '"test_task"' |
fn |
任务处理函数 | |
arg |
任务处理函数的参数 | |
stack_size |
任务栈大小(单位:字节) | |
prio |
任务运行优先级(范围:0~ RHINO_CONFIG_PRI_MAX-2; RHINO_CONFIG_PRI_MAX-1为idle任务优先级) | 10 |
返回参数
0表示成功,其他值表示失败。具体的返回值见本文档返回参数定义小节。
调用示例
static void test_task(void *paras)
{
……
}
aos_task_t task_handle;
aos_task_new_ext(&task_handle, "test_task", test_task, NULL, 1024, 10);
aos_task_exit()
任务自动退出。
函数原型
void aos_task_exit(int code);
输入参数
code |
任务退出码,暂时无用 |
返回参数
无
调用示例
/* 任务处理函数 */
void task_entry(void *arg)
{
……
aos_task_exit(0); /* 任务自动退出 */
}
aos_task_delete()
删除任务。
函数原型
int aos_task_delete(char *name);
输入参数
name |
待删除的任务名 | '"test_task"' |
返回参数
0表示成功,其他值表示失败。具体的返回值见本文档返回参数定义小节。
调用示例
static void test_task(void *paras)
{
……
}
aos_task_new("test_task", test_task, NULL, 1024);
……
aos_task_delete("test_task");
aos_task_name()
获得当前任务名字。
函数原型
const char *aos_task_name(void);
输入参数
无
返回参数
任务名字符串。
调用示例
char *task_name;
task_name = aos_task_name();
printf("task name: %s\r\n", task_name);
aos_task_key_create()
申请一个任务私有数据区域。
函数原型
int aos_task_key_create(aos_task_key_t *key);
输入参数
key |
任务私有数据区域的索引,新分配的索引保存在该参数中 |
返回参数
0表示成功,失败返回-EINVAL。
调用示例
int ret = -1;
aos_task_key_t task_key;
ret = aos_task_key_create(&task_key);
aos_task_key_delete()
释放一个任务私有数据区域。
函数原型
void aos_task_key_delete(aos_task_key_t key);
输入参数
key |
任务私有数据区域的索引,删除该索引指向的任务私有数据区域 |
返回参数
无
调用示例
int ret = -1;
aos_task_key_t task_key;
ret = aos_task_key_create(&task_key);
……
aos_task_key_delete(task_key);
aos_task_setspecific()
设置指定任务私有数据区域的内容。
函数原型
int aos_task_setspecific(aos_task_key_t key, void *vp);
输入参数
key |
任务私有数据区域的索引,设置该索引指向的任务私有数据区域 | |
vp |
设置到任务私有数据区域的值 |
返回参数
0表示成功,其他值表示失败。具体的返回值见本文档返回参数定义小节。
调用示例
int ret = -1;
int var = 0;
aos_task_key_t task_key;
ret = aos_task_key_create(&task_key);
var = 0x5a5a;
ret = aos_task_setspecific(task_key, &var);
aos_task_getspecific()
获取指定任务私有数据区域的内容。
函数原型
void *aos_task_getspecific(aos_task_key_t key);
输入参数
key |
任务私有数据区域的索引,获取该索引指向的任务私有数据区域的内容 |
返回参数
指定任务私有数据区域的内容。
调用示例
int ret = -1;
int var = 0;
aos_task_key_t task_key;
void *task_value = NULL;
ret = aos_task_key_create(&task_key);
var = 0x5a5a;
ret = aos_task_setspecific(task_key, &var);
……
task_value = aos_task_getspecific(task_key);
其他
返回参数定义
返回值定义在core/rhino/include/k_err.h文件中。该文件为内部文件,出错时可根据返回值查阅该文件确认出错原因。
typedef enum
{
RHINO_SUCCESS = 0u,
RHINO_SYS_FATAL_ERR,
RHINO_SYS_SP_ERR,
RHINO_RUNNING,
RHINO_STOPPED,
RHINO_INV_PARAM,
RHINO_NULL_PTR,
RHINO_INV_ALIGN,
RHINO_KOBJ_TYPE_ERR,
RHINO_KOBJ_DEL_ERR,
RHINO_KOBJ_DOCKER_EXIST,
RHINO_KOBJ_BLK,
RHINO_KOBJ_SET_FULL,
RHINO_NOTIFY_FUNC_EXIST,
RHINO_MM_POOL_SIZE_ERR = 100u,
RHINO_MM_ALLOC_SIZE_ERR,
RHINO_MM_FREE_ADDR_ERR,
RHINO_MM_CORRUPT_ERR,
RHINO_DYN_MEM_PROC_ERR,
RHINO_NO_MEM,
RHINO_RINGBUF_FULL,
RHINO_RINGBUF_EMPTY,
RHINO_SCHED_DISABLE = 200u,
RHINO_SCHED_ALREADY_ENABLED,
RHINO_SCHED_LOCK_COUNT_OVF,
RHINO_INV_SCHED_WAY,
RHINO_TASK_INV_STACK_SIZE = 300u,
RHINO_TASK_NOT_SUSPENDED,
RHINO_TASK_DEL_NOT_ALLOWED,
RHINO_TASK_SUSPEND_NOT_ALLOWED,
RHINO_TASK_CANCELED,
RHINO_SUSPENDED_COUNT_OVF,
RHINO_BEYOND_MAX_PRI,
RHINO_PRI_CHG_NOT_ALLOWED,
RHINO_INV_TASK_STATE,
RHINO_IDLE_TASK_EXIST,
RHINO_NO_PEND_WAIT = 400u,
RHINO_BLK_ABORT,
RHINO_BLK_TIMEOUT,
RHINO_BLK_DEL,
RHINO_BLK_INV_STATE,
RHINO_BLK_POOL_SIZE_ERR,
RHINO_TIMER_STATE_INV = 500u,
RHINO_NO_THIS_EVENT_OPT = 600u,
RHINO_BUF_QUEUE_INV_SIZE = 700u,
RHINO_BUF_QUEUE_SIZE_ZERO,
RHINO_BUF_QUEUE_FULL,
RHINO_BUF_QUEUE_MSG_SIZE_OVERFLOW,
RHINO_QUEUE_FULL,
RHINO_QUEUE_NOT_FULL,
RHINO_SEM_OVF = 800u,
RHINO_SEM_TASK_WAITING,
RHINO_MUTEX_NOT_RELEASED_BY_OWNER = 900u,
RHINO_MUTEX_OWNER_NESTED,
RHINO_MUTEX_NESTED_OVF,
RHINO_NOT_CALLED_BY_INTRPT = 1000u,
RHINO_TRY_AGAIN,
RHINO_WORKQUEUE_EXIST = 1100u,
RHINO_WORKQUEUE_NOT_EXIST,
RHINO_WORKQUEUE_WORK_EXIST,
RHINO_WORKQUEUE_BUSY,
RHINO_WORKQUEUE_WORK_RUNNING,
RHINO_TASK_STACK_OVF = 1200u,
RHINO_INTRPT_STACK_OVF,
RHINO_STATE_ALIGN = INT_MAX /* keep enum 4 bytes at 32bit machine */
} kstat_t;
在文档使用中是否遇到以下问题
更多建议
匿名提交