Contiki:初探跟WinAVR

Contiki:初探和WinAVR

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[i], NULL)函数,
将autostart_processes中的一个进程添加到process_list的首部,并改变其中的运行状态,将其设置为PROCESS_STATE_RUNNING,即运行状态在执行时。

在  process_start(processes[i], 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进行进程切换,如果使用会出现问题。

附录:

Contiki:初探跟WinAVR
Figure 1.由此图可知,如果uIP通过无线传输,则需要Rime协议栈;
同样如果Rime要走以太网,Rime就需要uIP的帮忙(这种情况估计不会用)。

Contiki:初探跟WinAVR
Figure 2.Rime Map(Partial)

Contiki:初探跟WinAVR
Figure 3.Rime 组织结构

参考:
http://blog.chinaunix.net/uid/9112803/frmd/24079.html
http://www.smeshlink.com/contiki/forum.php?mod=viewthread&tid=275&extra=page%3D3


WinAVR

http://baike.baidu.com/link?url=5WoF5phtFV-wCr569_jS_4fqB-rYZcNxpF4hWotLnnXht78D6H7PPJ7zytTpVKcq86ZiYzp2VUp_dO20xMS6N_