Zephyr的work queue机制以及相关API

一、前言


    Zephyr的work队列机制跟Linux的相似,用于实现一些耗时操作,zephyr的work队列是基于线程的,原理类似于一个线程一直在等待work队列发来的工作项,这个工作项是初始化work项时候指定的函数,当有工作项被调度时线程就是执行这个函数,当有多个工作项提交队列执行时,队列按照FIFO(先进先出)形式调度。一个work项在使用前需要初始化,主要是关联处理函数,标记工作项为挂起状态,等着被线程调度。一个work项可以在ISR或者线程中被提交,提交后work项就会被添加到work queue队列中。

二、延时工作项–Delayed work


    如字面意思,就是按照指定时间延时后执行的工作项。当Delayed work被提交时并不会立马被添加到work queue中,而是在等待一个指定延时的时间后才被添加。一个延时工作项通过struct k_delayed_work去定义,并通过 k_delayed_work_init()去初始化,通过调用k_delayed_work_submit()把延时工作项提交给系统工作队列,通过k_delayed_work_submit_to_queue()把延时工作项提交给用户自己定义的工作队列。当想取消一个超时工作项,可以使用 k_delayed_work_cancel()函数,但是需注意,取消只能在工作项指定的超时没发生之前,否则不能被取消。

三、poll工作项


    该工作项是和POLL机制相关的工作项,他是在一个线程中等待多个内核对象有效比如信号量、FIFO等。使用k_work_poll_init初始化一个poll工作项,并绑定一个处理函数,使用k_work_poll_submit提交该工作项,当监视的资源或者轮询信号触发或者超时发生时,队列将会调度一开始关联的处理函数,当工作项提交以后,内核就开始观察轮询事件指定的对象。,一旦观察的对象有一个处于更改状态,工作项就会立刻把工作项加到队列中等待调度处理。在内核观察到观察对象变更之前的这段时间,工作项可以被随时取消。

四、系统工作队列System Workqueue


    work是被提交到work queue的一个元素,当内核使能了工作队列功能,内核就会自动创建一个system workqueuede 的工作队列,这个队列用户可以通过manuconfig去配置。当用户没有自定义队列时work默认提交到这个队列去调度执行。补充一点的是,虽然zephyr支持用户自定义工作队列,但是自定义队列需要消耗大量的资源,RAM、FLASH等,并且zephyr一般是运行在资源有限的系统上,所以并不推荐自定义工作队列。

五、用户定义一个工作队列


    #define MY_STACK_SIZE 512
    #define MY_PRIORITY 5

    K_THREAD_STACK_DEFINE(my_stack_area, MY_STACK_SIZE);   // 定义一个栈空间

    struct k_work_q my_work_q;    // 定义一个工作队列

    k_work_q_start(&my_work_q, my_stack_area, K_THREAD_STACK_SIZEOF(my_stack_area), MY_PRIORITY);  // 初始化工作队列并启动工作队列

六、用户使用工作项


1.普通工作项

    struct k_work state_change_work;  // 定义一个工作项

    /* 定义一个工作项执行函数  */

    void state_change_work_handler(struct k_work *work)
    {
         ........
    }

    k_work_init(&state_change_work, state_change_work_handler);  // 初始化工作项

    k_work_submit(&state_change_work);  // 提交一个工作项到队列

2.poll工作项

    static struct k_poll_event change_led_events[1] = {
        K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_MSGQ_DATA_AVAILABLE,
        K_POLL_MODE_NOTIFY_ONLY,
        &change_led_msgq, 0)
    };  // 定义轮询观察的对象事件

    struct k_work_poll change_led_work; // 定义poll工作项

    / * 定义poll工作项处理函数 * /

    void change_led_work_handler(struct k_work *work)
    {
        ........
    }

    k_work_poll_init(&change_led_work, change_led_work_handler); // 初始化poll工作项

    k_work_poll_submit(&change_led_work, change_led_events, ARRAY_SIZE(change_led_events), K_FOREVER);  // 提交poll工作项到队列等待调度

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值