原创 Contiki:初探

2013-2-20 20:13 1051 9 9 分类: 消费电子

 

Contiki是为了Wireless Sensor Network设计的一个嵌入式系统,侧重于网络。虽然它也可以单独运行,但是这并不是它设计的初衷。
从它的core代码的多少就可以看出,在一共2.4M的代码中,net一个文件夹就占用了1.47M的内容。
在Contiki中包含的协议或机制:
Application:                CoAp
Transport:                   UDP
NetWork:                    IpV6/RPL
Adaptation:                   6LoWPAN
MAC:                            CSMA/link-layer bursts
Radio Duty Cycling:        ContikiMAC
Physical:                        802.15.4
 
Communication Architecture:Chameleon(consists of Rime Stack and a set of packet transformation modules)
 
其中Contiki是一个事件驱动型操作系统,有一个事件驱动的核心。
主要的进程模式是protothread,这个进程模式,使得contiki这个操作系统只使用一个堆栈,节约了本不富裕的嵌入式设备上的内存。
但是这也造成了,在进行进程切换时,系统不会去保存当前进程的堆栈,及寄存器信息,所以contiki也警告说,在protothread模式中编程时,local variable要小心使用。所以一般都是定义 static 和global variable。防止切换时,变量信息丢失。
 
(使用vim+cscope+needtree+ctag+taglist+taghighlight或者Source Insight等工具查看代码,比较方便)
1、contiki加载protothread进程的方式,通过autostart_processes,这个全局变量,定义了涉及到的进程名及其进程体的函数指针,在运行时,将其加到进程的process_list中。
 
首先通过AUTOSTART_PROCESSES(&hello_world_process),
定义autostart_processes这个全局变量,
之后再运行时调用autostart_start(autostart_processes)函数,
在autostart_start(autostart_processes)这个函数中调用 process_start(processes, NULL)函数,
将autostart_processes中的一个进程添加到process_list的首部,并改变其中的运行状态,将其设置为PROCESS_STATE_RUNNING,即运行状态在执行时。
 
在  process_start(processes, NULL)函数中调用process_post_synch(p, PROCESS_EVENT_INIT, (process_data_t)arg)设置事件初始化标志PROCESS_EVENT_INIT
在process_post_synch(p, PROCESS_EVENT_INIT, (process_data_t)arg)中,
调用call_process(p, ev, data);实现设置。
在call_process(p, ev, data)函数中 ret = p->thread(&p->pt, ev, data);
通过函数指针调用进程的进程体函数,执行。
至此将所有的进程添加到进程链表中,在执行时遍历链表。
 
2、在main函数执行的过程中,
 while(1) {
   
    int r;   
   
    do {
      /* Reset watchdog. */
      watchdog_periodic();
      r = process_run();
    } while(r > 0);
   
   
   
    ENERGEST_OFF(ENERGEST_TYPE_CPU);
    /* watchdog_stop(); */
    ENERGEST_ON(ENERGEST_TYPE_LPM);
    /* Go to idle mode. */
    halSleepWithOptions(SLEEPMODE_IDLE,0);
    /* We are awake. */
    /* watchdog_start(); */
    ENERGEST_OFF(ENERGEST_TYPE_LPM);
    ENERGEST_ON(ENERGEST_TYPE_CPU); 
   
  }
通过,do{}while();语句实现进程切换,如果r,满足条件则继续执行,不满足,则切换。
 
3、浅探protothread进程控制模型
通过__LINE__,保存退出前的位置信息,在再次被调用时,通过switch语句跳转到这里执行。
故此,这里还有一点要特别注意的就是,在进程主体函数总不能使用switch语句,因为protothread使用switch进行进程切换,如果使用会出现问题。

文章评论0条评论)

登录后参与讨论
我要评论
0
9
关闭 站长推荐上一条 /2 下一条