Contiki:初探

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进行进程切换,如果使用会出现问题。


转载于:https://my.oschina.net/u/859741/blog/279683

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值