导读
本文通过分析Contiki的源码,梳理Contiki的process-event模型中的process机制。
引入:
通过前文的阐述我们明白了Contiki的协程工作的逻辑层面。本文在上一篇的基础上,进一步分析协程在语法层面的实现,而这也正是Contiki设计中最精妙的部分。
还是以看门狗协程为例
PROCESS(dog,"dog");//看门狗任务
PROCESS_THREAD(dog, ev, dataa)
{
static struct etimer et;
PROCESS_BEGIN();
etimer_set(&et,CLOCK_SECOND*2);//初始化etimer,并设置延时为2s
while(1)
{
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));//等待etimer过期
spin_watchdog_clear();//喂狗
etimer_restart(&et);//重启etimer
}
PROCESS_END();
}
在之前我们说过上面这段代码中,所有的大写字符串都是宏定义,而这些宏定义正是Contiki的协程在语法层面的具体实现,现在我们就要展开它们,并分析它们是如何工作的。
宏PROCESS(dog,"dog")[1]
#define PROCESS(name, strname) \
PROCESS_THREAD(name, ev, dataa); \
struct process name = { NULL, \
process_thread_##name }
#define PROCESS_THREAD(name, ev, dataa) \
static PT_THREAD(process_thread_##name(struct pt *process_pt, \
process_event_t ev, \
process_data_t dataa))
#define PT_THREAD(name_args) char name_args
以上就是宏展开的全部结果,通过手动替换,我们可以写出宏PROCESS(dog,“dog”)替换的结果:
static char process_thread_dog(struct pt *process_pt,process_event_t ev,process_data_t dataa);<