xt-sdk 文档 v1.0.3
xt-sdk 嵌入式 SDK API 参考
载入中...
搜索中...
未找到
xt_task(协程式任务调度)

基于 LC(Local Continuation)+ timer2 + event 的轻量级协程任务调度 更多...

专题

 xt_event(事件管理)
 事件发布订阅模块接口(去重匹配、dispatch 上下文栈、临界区保护)
 xt_timer(软件定时器)
 XTINY 软件定时器接口(数组池、ID 索引方式)
 xt_timer2(硬件定时器)
 新版软件定时器接口(对象化、单链表、new/delete 生命周期)

结构体

struct  xt_task
 任务控制块结构体 更多...

宏定义

#define XT_TASK_INLIVAD_ID   0xff
 无效父任务 ID(0xff),表示无父任务的独立根任务
#define XT_TASK_WAIT_FOREVER   0xffffffff
 永不超时标记(0xffffffff),用于纯事件等待(不启动定时器,无超时限制)
#define XT_TASK_LC_INIT_VALUE   0
 LC(Local Continuation)机制的初始值,表示协程从起始位置重新执行
#define xt_task_lc_init(s)
 初始化 lc 变量
#define xt_task_lc_resume(s)
 恢复协程执行点
#define _xt_task_lc_set(s)
 设置协程恢复点(内部宏)
#define xt_task_lc_end(s)
 结束 lc switch 块
#define XT_TASK_BEGIN()
 协程任务函数开头
#define XT_TASK_END()
 协程任务函数结尾
#define xt_task_delay(ms)
 延时等待若干毫秒后继续执行
#define xt_task_wait_event(event_id, event_param)
 等待指定事件(永不超时)
#define xt_task_wait_until(event_id, timeout)
 等待指定事件或超时
#define xt_task_call_subtask(entry, user_data)
 调用子任务并等待其完成

类型定义

typedef void(* xt_task_entry_t) (void *user_data)
 协程任务入口函数类型
typedef struct xt_task xt_task_t
 协程任务句柄

函数

void xt_task_timer_start (uint32_t timeout_ms)
 启动当前 task 的定时器
void xt_task_event_subscribe (xt_event_id_t event_id, uint32_t timeout_ms)
 为当前 task 订阅事件
void xt_task_event_handler (xt_event_id_t event_id)
 事件到达分发入口

任务生命周期与控制

xt_err_t xt_task_setup (void)
 初始化 task 子系统
xt_task_t * xt_task_start (xt_task_entry_t entry, void *user_data)
 启动一个协程任务
xt_task_t * xt_task_running (void)
 获取当前正在运行的 task
bool xt_task_is_running (xt_task_t *task)
 检查 task 是否在运行
void xt_task_sys_reset (void)
 重置 task 子系统(仅测试用)

详细描述

基于 LC(Local Continuation)+ timer2 + event 的轻量级协程任务调度

宏定义说明

◆ _xt_task_lc_set

#define _xt_task_lc_set ( s)
值:
s = __LINE__; case __LINE__:

设置协程恢复点(内部宏)

将 lc 记录为当前行号 __LINE__,并生成 case __LINE__: 标签。 当协程下次 resume(即函数被重新调用)时,xt_task_lc_resume 的 switch 会跳转到此 case 继续执行。 隐式 fallthrough 警告由 XT_TASK_BEGIN/END 中的 _Pragma 抑制。

注解
内部宏,用户不应直接使用。

在文件 xt_task.h 第 73 行定义.

◆ XT_TASK_BEGIN

#define XT_TASK_BEGIN ( )
值:
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"") \
{ char XT_TASK_YIELD_FLAG = 1; (void)XT_TASK_YIELD_FLAG; xt_task_lc_resume(xt_task_running()->lc)
xt_task_t * xt_task_running(void)
获取当前正在运行的 task
#define xt_task_lc_resume(s)
恢复协程执行点

协程任务函数开头

必须在每个 task 入口函数的最顶部使用,与 XT_TASK_END() 配对。 声明局部 yield 标志变量 XT_TASK_YIELD_FLAG,并通过 xt_task_lc_resume 恢复协程执行点。 首次进入时 lc == 0,从 case 0 进入;yield 后 lc 记录行号,resume 时跳转到对应位置。 通过 _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"") 抑制 lc case fallthrough 警告。 _Pragma 是 C99 标准预处理运算符,在 -std=gnu99 下可用。

在文件 xt_task.h 第 208 行定义.

◆ xt_task_call_subtask

#define xt_task_call_subtask ( entry,
user_data )
值:
do { \
xt_task_t *__sub = xt_task_start(entry, user_data); \
if (__sub == NULL) { \
break; \
} \
XT_TASK_YIELD_FLAG = 0; \
_xt_task_lc_set((xt_task_running()->lc)); \
if (XT_TASK_YIELD_FLAG == 0) { \
return; \
} \
} while(0)
xt_task_t * xt_task_start(xt_task_entry_t entry, void *user_data)
启动一个协程任务
struct xt_task xt_task_t
协程任务句柄

调用子任务并等待其完成

启动子任务 entry,当前父任务 yield 挂起直到子任务完成。 子任务在 _xt_task_call 中完成时,父任务被恢复执行。 子任务通过 parent_id 字段关联父任务(记录父任务在 xt_task_array 中的索引)。

参数
entry子任务入口函数
user_data子任务透传数据
注解
不支持孙任务——子任务中不能再 call_subtask(触发 XT_GRANDCHILD_NOT_SUPPORT assert)。
子任务必须至少 yield 一次(例如 xt_task_delay(1)),否则立即完成会导致递归重入父任务。
子任务启动失败(task 数组满)时 break 跳出 do-while,父任务继续执行。

在文件 xt_task.h 第 305 行定义.

◆ xt_task_delay

#define xt_task_delay ( ms)
值:
do { \
xt_task_timer_start(ms); \
XT_TASK_YIELD_FLAG = 0; \
_xt_task_lc_set(xt_task_running()->lc); \
if (XT_TASK_YIELD_FLAG == 0) { \
return; \
} \
} while(0)

延时等待若干毫秒后继续执行

启动当前 task 的内嵌定时器,设置延迟 ms 毫秒后恢复执行。 内部调用 xt_task_timer_start + lc 设置 + return 使协程挂起。 超时后 timer2 回调触发 _xt_task_call 重新调用 task entry 函数, lc resume 跳转到 _xt_task_lc_set 记录的 case 行号处继续执行。

参数
ms延迟毫秒数,不能超过 XT_TIMER2_TIMEOUT_MAX

在文件 xt_task.h 第 234 行定义.

◆ XT_TASK_END

#define XT_TASK_END ( )
值:
_Pragma("GCC diagnostic pop")
#define xt_task_lc_end(s)
结束 lc switch 块
#define xt_task_lc_init(s)
初始化 lc 变量

协程任务函数结尾

必须在每个 task 入口函数的最底部使用,与 XT_TASK_BEGIN() 配对。 调用 xt_task_lc_end 闭合 switch 块,并重置 lc 为 XT_TASK_LC_INIT_VALUE。 作用域结束时 XT_TASK_BEGIN 的 { 与 XT_TASK_END 的 } 配对闭合。

在文件 xt_task.h 第 220 行定义.

◆ XT_TASK_INLIVAD_ID

#define XT_TASK_INLIVAD_ID   0xff

无效父任务 ID(0xff),表示无父任务的独立根任务

在文件 xt_task.h 第 39 行定义.

◆ xt_task_lc_end

#define xt_task_lc_end ( s)
值:
default:; break; }

结束 lc switch 块

生成 default 分支和 break,闭合 xt_task_lc_resume 打开的 switch 语句。

注解
内部宏,用户不应直接使用。

在文件 xt_task.h 第 82 行定义.

◆ xt_task_lc_init

#define xt_task_lc_init ( s)
值:
#define XT_TASK_LC_INIT_VALUE
LC(Local Continuation)机制的初始值,表示协程从起始位置重新执行

初始化 lc 变量

将 lc 重置为 XT_TASK_LC_INIT_VALUE。 XT_TASK_END() 中调用,确保任务结束后下次重新进入时从开头执行。

在文件 xt_task.h 第 53 行定义.

◆ XT_TASK_LC_INIT_VALUE

#define XT_TASK_LC_INIT_VALUE   0

LC(Local Continuation)机制的初始值,表示协程从起始位置重新执行

在文件 xt_task.h 第 45 行定义.

◆ xt_task_lc_resume

#define xt_task_lc_resume ( s)
值:
switch(s) { case XT_TASK_LC_INIT_VALUE:

恢复协程执行点

生成 switch(s) 块,case XT_TASK_LC_INIT_VALUE 作为首次进入点。 若 lc 已被 _xt_task_lc_set 修改为某个行号 __LINE__,则直接跳转到对应 case 标签处继续执行。 隐式 fallthrough 警告由 XT_TASK_BEGIN/END 中的 _Pragma 抑制。

在文件 xt_task.h 第 62 行定义.

◆ xt_task_wait_event

#define xt_task_wait_event ( event_id,
event_param )
值:
do { \
xt_task_event_subscribe(event_id, XT_TASK_WAIT_FOREVER); \
XT_TASK_YIELD_FLAG = 0; \
_xt_task_lc_set(xt_task_running()->lc); \
if (XT_TASK_YIELD_FLAG == 0) { \
return; \
} \
} while(0)
void * xt_event_get_current_event_param(void)
获取当前事件参数
#define XT_TASK_WAIT_FOREVER
永不超时标记(0xffffffff),用于纯事件等待(不启动定时器,无超时限制)

等待指定事件(永不超时)

订阅 event_id 事件后通过 lc yield 挂起当前协程。 事件到达后 xt_task_event_handler 唤醒 task,lc resume 后 event_param 接收事件参数。 通过 XT_TASK_WAIT_FOREVER 标记不启动定时器,纯事件等待。

参数
event_id等待的事件 ID
event_param输出参数,接收 xt_event_get_current_event_param() 返回的事件参数
注解
若事件永远不到达,task 将永远挂起。

在文件 xt_task.h 第 256 行定义.

◆ XT_TASK_WAIT_FOREVER

#define XT_TASK_WAIT_FOREVER   0xffffffff

永不超时标记(0xffffffff),用于纯事件等待(不启动定时器,无超时限制)

在文件 xt_task.h 第 42 行定义.

◆ xt_task_wait_until

#define xt_task_wait_until ( event_id,
timeout )
值:
do { \
xt_task_event_subscribe(event_id, timeout); \
XT_TASK_YIELD_FLAG = 0; \
_xt_task_lc_set((xt_task_running()->lc)); \
if (XT_TASK_YIELD_FLAG == 0) { \
return; \
} \
} while(0)

等待指定事件或超时

同时订阅事件并启动定时器。两种唤醒路径互斥:

  • 事件先到达:xt_task_event_handler 停止定时器并唤醒 task
  • 超时先到达:timer2 回调清除 wait_event 并唤醒 task

唤醒后调用者需通过 xt_event_get_current_event_id() 判断唤醒原因:

  • 非 XT_EVENT_INVALID_ID → 事件唤醒
  • == XT_EVENT_INVALID_ID → 超时唤醒
参数
event_id等待的事件 ID
timeout超时毫秒数,不能超过 XT_TIMER2_TIMEOUT_MAX

在文件 xt_task.h 第 281 行定义.

类型定义说明

◆ xt_task_entry_t

typedef void(* xt_task_entry_t) (void *user_data)

协程任务入口函数类型

参数
user_data用户透传数据,由 xt_task_start 传入

在文件 xt_task.h 第 90 行定义.

◆ xt_task_t

typedef struct xt_task xt_task_t

协程任务句柄

在文件 xt_task.h 第 93 行定义.

函数说明

◆ xt_task_event_handler()

void xt_task_event_handler ( xt_event_id_t event_id)

事件到达分发入口

遍历任务数组,唤醒等待 event_id 的任务。由 xt_event_handler 调用。

参数
event_id触发的事件 ID
注解
内部 API,用户不应直接调用。

◆ xt_task_event_subscribe()

void xt_task_event_subscribe ( xt_event_id_t event_id,
uint32_t timeout_ms )

为当前 task 订阅事件

参数
event_id事件 ID
timeout_ms超时毫秒数,XT_TASK_WAIT_FOREVER 表示永不超时
注解
内部 API,由 xt_task_wait_event / xt_task_wait_until 宏间接调用。

◆ xt_task_is_running()

bool xt_task_is_running ( xt_task_t * task)

检查 task 是否在运行

entry 非 NULL 表示 task 仍在运行(含 yield 等待中)。

参数
tasktask 句柄
返回
true task 在运行
false task 不在运行或 task==NULL

◆ xt_task_running()

xt_task_t * xt_task_running ( void )

获取当前正在运行的 task

返回
当前 task 句柄
返回值
NULL无 task 在运行

◆ xt_task_setup()

xt_err_t xt_task_setup ( void )

初始化 task 子系统

幂等:多次调用只执行一次。清零 task 数组,初始化 event 和 timer2 子系统。

返回
XT_EOK 成功

◆ xt_task_start()

xt_task_t * xt_task_start ( xt_task_entry_t entry,
void * user_data )

启动一个协程任务

从 task 数组分配一个空闲槽位,设置入口函数和用户数据,然后立即第一次调用。

参数
entry任务入口函数
user_data用户透传数据
返回
分配的 task 句柄
返回值
NULL分配失败(task 数组满)

◆ xt_task_sys_reset()

void xt_task_sys_reset ( void )

重置 task 子系统(仅测试用)

清零 task 数组,复位当前 task 指针。 不触碰 timer2 和 event 子系统(由各自 reset 函数管理)。

◆ xt_task_timer_start()

void xt_task_timer_start ( uint32_t timeout_ms)

启动当前 task 的定时器

参数
timeout_ms超时毫秒数,不能超过 XT_TIMER2_TIMEOUT_MAX
注解
内部 API,由 xt_task_delay / xt_task_wait_until 宏间接调用。