工作队列(Work Queue)是 Zephyr 中用于延迟执行和异步处理的重要机制。它将工作项(work item)排队,由专用线程稍后执行。
// 系统工作队列是内核预定义的
// 通过 k_work_submit() 使用
// 定义工作项
struct k_work my_work;
// 工作处理函数
void work_handler(struct k_work *work)
{
// 在这里执行工作
printk("Work executed!\n");
}
// 初始化并提交到系统工作队列
k_work_init(&my_work, work_handler);
k_work_submit(&my_work);
// 定义工作队列
struct k_work_q my_work_q;
// 工作队列线程栈
K_THREAD_STACK_DEFINE(work_q_stack, 2048);
// 初始化并启动工作队列
void init_my_work_q(void)
{
k_work_queue_init(&my_work_q);
k_work_queue_start(&my_work_q, work_q_stack,
K_THREAD_STACK_SIZEOF(work_q_stack),
K_PRIO_PREEMPT(5), NULL);
}
// 提交工作到自定义队列
void submit_to_my_q(void)
{
struct k_work my_work;
k_work_init(&my_work, work_handler);
k_work_submit_to_queue(&my_work_q, &my_work);
}
struct k_work work;
// 初始化
k_work_init(&work, handler);
// 提交(如果已在队列中,不会重复添加)
k_work_submit(&work);
// 检查是否正在等待执行
if (k_work_is_pending(&work)) {
// 工作项已在队列中
}
// 取消(如果尚未执行)
int ret = k_work_cancel(&work);
struct k_work_delayable dwork;
// 初始化
k_work_init_delayable(&dwork, handler);
// 延迟提交(100ms后执行)
k_work_reschedule(&dwork, K_MSEC(100));
// 延迟提交到指定队列
k_work_reschedule_for_queue(&my_work_q, &dwork, K_MSEC(100));
// 取消延迟工作
int ret = k_work_cancel_delayable(&dwork);
// 检查是否到期
if (k_work_is_pending(&dwork.work)) {
// 工作项已提交或正在执行
}
// 获取剩余时间
k_timeout_t remaining = k_work_delayable_remaining_get(&dwork);
struct k_work_sync sync;
// 同步取消 - 等待工作完成或从队列移除
bool pending = k_work_cancel_delayable_sync(&dwork, &sync);
// 或
bool pending = k_work_cancel_sync(&work, &sync);
struct k_work_delayable periodic_work;
void periodic_handler(struct k_work *work)
{
// 执行周期性任务
do_periodic_task();
// 重新调度,实现周期性
k_work_reschedule(&periodic_work, K_MSEC(1000));
}
void init_periodic(void)
{
k_work_init_delayable(&periodic_work, periodic_handler);
// 启动第一次执行
k_work_reschedule(&periodic_work, K_MSEC(1000));
}
// GPIO 中断回调
void gpio_callback(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
// 中断上下文:快速提交工作到队列
k_work_submit(&irq_work);
}
// 工作处理函数(线程上下文)
void irq_work_handler(struct k_work *work)
{
// 可以安全地执行阻塞操作
process_gpio_event();
k_msleep(10); // 允许!
}
// 工作1:数据采集
struct k_work data_collection_work;
void collect_data(struct k_work *work)
{
// 采集传感器数据
// 然后提交处理工作
k_work_submit(&data_processing_work);
}
// 工作2:数据处理
struct k_work data_processing_work;
void process_data(struct k_work *work)
{
// 处理数据
// 然后提交发送工作
k_work_submit(&data_send_work);
}
// 工作3:数据发送
struct k_work data_send_work;
void send_data(struct k_work *work)
{
// 通过网络发送
}
# 系统工作队列
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
CONFIG_SYSTEM_WORKQUEUE_PRIORITY=-1
# 工作队列统计
CONFIG_WORK_QUEUE_STATS=y
void good_handler(struct k_work *work)
{
// ✅ 快速执行,避免阻塞
// ✅ 处理完后立即返回
// ✅ 可以重新提交自己实现周期性
}
void bad_handler(struct k_work *work)
{
// ❌ 不要在工作函数中长时间阻塞
while (1) { }
// ❌ 不要在工作函数中使用无限循环
for (;;) { }
}
struct work_context {
struct k_work work;
uint8_t *buffer;
size_t len;
};
void handler_with_context(struct k_work *work)
{
struct work_context *ctx = CONTAINER_OF(work, struct work_context, work);
// 使用 ctx->buffer 和 ctx->len
}
// 如果需要在取消时知道是否成功
struct k_work_sync sync;
bool was_pending = k_work_cancel_delayable_sync(&dwork, &sync);
if (was_pending) {
// 工作项被取消
} else {
// 工作项已经完成或从未提交
}
| 特性 | 系统队列 | 自定义队列 |
|---|---|---|
| 启动开销 | 无(已启动) | 需要初始化 |
| 内存占用 | 共享栈 | 独立栈 |
| 优先级 | 固定(-1) | 可配置 |
| 适用场景 | 简单异步任务 | 复杂或实时任务 |
// 启用工作队列调试
CONFIG_WORK_QUEUE_LOG_LEVEL_DBG=y
// 检查系统队列状态
extern struct k_work_q k_sys_work_q;
printk("System work queue pending: %d\n",
k_work_busy_get(&k_sys_work_q));
| 函数 | 用途 |
|---|---|
k_work_init() | 初始化普通工作项 |
k_work_submit() | 提交到系统队列 |
k_work_submit_to_queue() | 提交到指定队列 |
k_work_init_delayable() | 初始化延迟工作项 |
k_work_reschedule() | 延迟调度工作 |
k_work_cancel() | 取消工作 |
k_work_cancel_delayable() | 取消延迟工作 |
k_work_cancel_sync() | 同步取消 |
*学习笔记创建时间: 2026-03-19*