k_work_schedule函数功能
本主要介绍k_work_schedule函数功能和Zephyr RTOS 的工作队列(Workqueue),Zephyr RTOS 的工作队列(Workqueue)是其异步任务处理的核心机制,专为资源受限的嵌入式系统设计。它提供了一种高效、线程安全的方式执行延迟任务、中断下半部处理以及周期性操作。
目录
概述
本主要介绍k_work_schedule函数功能和Zephyr RTOS 的工作队列(Workqueue),Zephyr RTOS 的工作队列(Workqueue)是其异步任务处理的核心机制,专为资源受限的嵌入式系统设计。它提供了一种高效、线程安全的方式执行延迟任务、中断下半部处理以及周期性操作。
1 k_work_schedule函数
k_work_schedule 是实时操作系统(特别是 Zephyr RTOS)中用于延迟执行工作项(work item) 的核心函数。它属于工作队列(workqueue)子系统,用于实现异步、延迟的任务执行。以下是详细解析:
1.1 函数介绍
1)函数原型
int k_work_schedule(struct k_work_delayable *dwork, k_timeout_t delay);
2)参数介绍
| 参数 | 类型 | 说明 |
|---|---|---|
dwork |
struct k_work_delayable* |
指向可延迟工作项的指针(需先初始化) |
delay |
k_timeout_t |
延迟时间: - K_NO_WAIT: 立即提交- K_FOREVER: 取消调度- 正整数值: 具体延迟 |
3)功能介绍
延迟任务调度
将工作项
dwork安排在指定的delay时间后执行时间单位:毫秒(如
K_MSEC(100))或绝对时间点(如K_TIMEOUT_ABS_T(ms))取消与重置
若该工作项已处于调度状态,自动取消原计划并重新计时
支持动态调整延迟时间(用于实现看门狗、超时重试等场景)
线程安全
可在中断上下文调用(如 ISR 中调度延迟任务)
内部使用锁保护工作队列状态
1.2 工作流程

具体步骤如下:
1) 初始化工作项
struct k_work_delayable my_work;
k_work_init_delayable(&my_work, my_handler); // 绑定处理函数
2) 调度延迟执行
// 在中断中调度:200ms后执行
k_work_schedule(&my_work, K_MSEC(200));
3)到期自动执行
系统定时器到期后,工作项被提交到绑定的工作队列
工作队列线程调用预定义的
my_handler()函数
1.3 关键特性
| 特性 | 说明 |
|---|---|
| 异步执行 | 工作项处理函数在工作队列线程中运行,与调用者隔离 |
| 动态调度 | 支持运行时修改延迟时间 |
| 取消机制 | 通过 k_work_cancel_delayable() 可手动取消未执行的任务 |
| 资源高效 | 共享工作队列线程,避免为每个任务创建独立线程 |
| ISR 安全 | 唯一可在中断上下文中安全使用的延迟执行机制 |
1.4 与相关函数对比
| 函数 | 特点 | 执行上下文限制 |
|---|---|---|
k_work_schedule() |
延迟执行(可取消/重置) | 允许在 ISR 中调用 |
k_work_submit() |
立即提交到工作队列(非延迟) | 允许在 ISR 中调用 |
k_timer_start() |
纯定时器(无工作队列集成) | 允许在 ISR 中调用 |
k_thread_create() |
创建独立线程(开销大) | 不能在 ISR 中调用 |
2 工作队列的其他API
2.1 . 初始化与提交
| API | 功能说明 | ISR 安全 |
|---|---|---|
k_work_init() |
初始化标准工作项 | ✓ |
k_work_submit() |
立即提交到系统队列 | ✓ |
k_work_submit_to_queue() |
提交到指定队列 | ✓ |
k_work_init_delayable() |
初始化可延迟工作项 | ✓ |
k_work_schedule() |
调度延迟执行(核心调度函数) | ✓ |
k_work_reschedule() |
强制重新调度延迟工作项 | ✓ |
2.2 队列管理
| API | 功能说明 |
|---|---|
k_work_queue_start() |
启动自定义队列线程 |
k_work_queue_drain() |
排空队列并阻止新任务 |
k_work_flush() |
等待特定工作项完成 |
2.3 控制与状态
| API | 功能说明 |
|---|---|
k_work_cancel() |
取消未执行的标准工作项 |
k_work_cancel_delayable() |
取消延迟工作项 |
k_work_busy_get() |
获取工作项状态(0=空闲, 1=提交, 2=运行) |
2.4 系统工作队列 vs 自定义工作队列
| 特性 | 系统工作队列 (k_sys_work_q) |
自定义工作队列 |
|---|---|---|
| 线程优先级 | 内核级负优先级 (-1) | 用户可配置 (默认 0) |
| 栈大小 | 固定 (CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE) | 用户定义 |
| 使用场景 | 轻量级通用任务 | 耗时/专用任务 |
| 资源开销 | 共享资源,零新增开销 | 每队列额外占用 1 线程 + 栈空间 |
| 典型应用 | 传感器数据采集、网络回调 | 文件系统操作、加密计算 |
3 典型应用
3.1 延时触发功能
1) 定义k_work_delayable
static struct k_work_delayable adv_work;
static struct k_work_delayable sleep_work;
2) 初始化k_work_init_delayable
void app_work_start( void )
{
// initial work queue
k_work_init_delayable(&adv_work, start_adv_work);
k_work_init_delayable(&sleep_work, stop_adv_work);
k_work_schedule(&adv_work, K_NO_WAIT);
}
3) 定义执行函数
static void stop_adv_work(struct k_work *work)
{
k_work_schedule(&adv_work, K_MINUTES(30));
printk("stop to beacon, and system will sleep \n");
}
static void start_adv_work(struct k_work *work)
{
k_work_schedule(&sleep_work, K_SECONDS(30));
printk("start to beacon, interval = %d s \n", interval );
}
3.2 精确周期任务
void periodic_handler(struct k_work *work) {
do_task();
// 每 100ms 重新调度自身
k_work_schedule(
container_of(work, struct k_work_delayable, work),
K_MSEC(100)
);
}
// 初始化延迟工作项
k_work_init_delayable(&periodic_work, periodic_handler);
k_work_schedule(&periodic_work, K_NO_WAIT); // 立即启动
4 高级特性与优化技巧
1) 工作项池 (Work Pool)
预初始化静态工作项数组
避免运行时内存分配碎片
K_WORK_DEFINE(work_pool[10], handler);
2) 链式工作项 (Chained Work)
在工作处理函数中提交新工作项
实现任务流水线
void stage1(struct k_work *w) { process_stage1(); k_work_submit(&stage2_work); // 触发下一阶段 }
3) 动态延迟调整
根据系统状态修改调度时间
void adaptive_handler(struct k_work *work) { int new_delay = calculate_optimal_delay(); k_work_reschedule(dwork, K_MSEC(new_delay)); }
4) 工作项标记
使用
work->flags传递状态#define WORK_FLAG_URGENT BIT(0) work.flags |= WORK_FLAG_URGENT;
5 性能关键设计
5.1 主要特性
-
零拷贝提交
-
工作项提交仅复制指针(约 10 个 CPU 周期)
-
-
无锁队列操作
-
使用原子操作管理任务队列
-
中断提交无需关中断
-
-
内存占用优化
对象 内存占用 (bytes) struct k_work20 struct k_work_q56 线程栈 (典型) 256-2048 -
实时性保障
-
工作项处理最坏延迟 = 当前项执行时间 + 线程切换时间
-
5.2 最佳实践
避免在工作处理函数中阻塞
ISR 提交的工作项延迟应 < 5ms
耗时任务 (>1ms) 使用自定义队列
使用
k_work_flush()在关机前确保任务完成
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐

所有评论(0)