nRF connect SDK提供zephyr支持的mesh协议栈的实现和应用程序,对比之前的老的SDK的实现,简单很多,对比起来,nRF SDK for mesh就显得很复杂,这里举个例子,就是状态变换处理,看看有内核支持的是如何实现的
如何基于内核服务实现状态的变换
kernel 服务提供workqueue,支持可延时的调度,也就是在一个延时后,将一个work item提交到
workqueue队列,然后一个专门的线程按先进先出的顺序去处理,调用我们的一个handler函数
我们仅仅是定义一个工作项 k_work_delayable ,然后聚焦于如何写好handler函数,不去考虑它是
如何被调用的,内核帮我们完成这些工作
1 执行调度后,kernel执行延时,当延时到期后,调用我们的工作项中记录的handler
我们再根据transition time 判断是否进行状态变换
2 不需要状态变换,则将模型在回调中的set参数,记录在led ->value中,去映射到硬件,然后
发布一个未经请求的消息,报告状态的改变
3 当需要进行状态变换,则调用led_transiton_start()完成状态变换
4 根据变换时间再次安排进行一次工作项调度,当时间到期,则变换结束
如何返回剩余时间?
当变换正在进行中的时候,我们可以从内核中获取从这个工作项开始启动到当前的已经流失的tick数
并转换成ms,然后,使用总定时时间减去流失的时间就是剩余时间
只需不到10行的语句即可完成
step1 定义一个延时工作项
struct k_work_delayable work;
step2 初始化
void k_work_init_delayable(struct k_work_delayable *dwork, k_work_handler_t handler);
step3 调度
当收到一个消息,变换参数delay不为0的时候,通知kernel在delay之后启动变换操作
extern int k_work_reschedule(struct k_work_delayable *dwork, k_timeout_t delay);
一个调度的例子: k_work_reschedule(&led->work, K_MSEC(set->transition->delay));
step4 等待我们的handler被调用