• 简单的玩玩etimer <contiki学习笔记之九>


      好吧,我承认etimer有点小复杂,主要是它似乎和contiki的process搅在一起,到处都在call_process。那就先搜搜contiki下的etimer的example看看,然后再试着写一个demo玩玩。

         在写demo之前,先说说自己是怎么找到etimer 的example的文件的。

         在core/sys/etimer.h 文件中,在描述etimer的数据结构的时候,作者显示的指出,如果要使用etimer,就必须先使用 etimer_set()这个函数进行一些工作,如图:

    是的,数据结构的定义之前,注释已经说的非常清楚了---etimer_set()是必须使用的。当然了,我也是根据这个信息找到了那些使用etimer的example。具体的,就是在contiki/目录下一条linux命令了:

    1 find -name "*.c" | xargs grep "etimer_set"

    ---------------------------------------------------------------

    好吧,按照contiki中那些提供的example,在native 环境下编写自己的etimer demo.

    在  contiki/examples/hello-world/  编写自己想要的hello-world.c文件:

     1 #include "contiki.h"
     2 
     3 #include <stdio.h> /* For printf() */
     4 /*---------------------------------------------------------------------------*/
     5 
     6 struct etimer timeout;
     7 
     8 PROCESS(hello_world_process, "Hello world process");
     9 AUTOSTART_PROCESSES(&hello_world_process /*,&led_process*/);
    10 /*---------------------------------------------------------------------------*/
    11 PROCESS_THREAD(hello_world_process, ev, data)
    12 {
    13     PROCESS_BEGIN();
    14     printf("-----------
    ");
    15     etimer_set(&timeout, 3*CLOCK_SECOND);
    16     while(1) {
    17         PROCESS_WAIT_EVENT();
    18 //    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&timeout));
    19         if(ev == PROCESS_EVENT_TIMER) {
    20             printf("LED on or off
    ");
    21         }
    22         etimer_reset(&timeout);
    23     }
    24 
    25     printf("Hello, world
    ");
    26     PROCESS_END();
    27 }

    简单的注释下代码:

    第6行: 整一个 sturct etimer{} 类型的变量吧  <就这么说吧,也许不准确>,属于全局的。按照很多example的显示,这个也可以拿进下面的函数体内,只不过是多加了个static的关键字---这样做,当然可以拿入。

    第15行:就按照实现etimer的作者的注释来写吧,使用etimer_set()。etime_set()的第二个参数 3 * CLOK_SECOND的意思表示 3 x 1 s 的时间,也就是3秒吧。这行代码的大概意思就是,设一个 3s 的超时的东西---到底是个什么东西,这里暂且不追究了。

    第16行到23行:我自己写了一个 死循环---永远不会打印"Hello world"了。

    第17行:PROCESS_WAIT_EVENT() 宏,其实它的内心是一个 PROCESS_YIELD()宏,而这个宏,我前面已经学习过,写在了 <contiki 学习笔记之七>

    PROCESS_YIELD()宏和C语言的switch语句< contiki学习笔记之七>

    第18行:PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&timeout));  它的功效类似于 PROCESS_WAIT_EVENT()。 是否等同还不知道。

    它定义在了 ./core/sys/process.h 文件中,而最终会被 ./core/sys/pt.h 文件中的 PT_YIELD_UNTIL(pt, cond)

    PT_YIELD_UNTIL(pt, cond)宏定义如下:

    1 #define PT_YIELD_UNTIL(pt, cond)        
    2   do {                        
    3     PT_YIELD_FLAG = 0;                
    4     LC_SET((pt)->lc);                
    5     if((PT_YIELD_FLAG == 0) || !(cond)) {    
    6       return PT_YIELDED;            
    7     }                        
    8   } while(0)

    殊途同归,这和PROCESS_YIELD()宏最后的实现,差不多。

    第19行:判断一个etimer事件是否发生,如果发生,则执行第20行代码,打印。

    -------------------------------

    下面写写自己的contiki-main.c 中的main()

    在目录 contiki/platform/native/  下 修改contiki-main.c 如下:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include "contiki.h"
     4 
     5 int
     6 main(int argc, char **argv)
     7 {
     8 
     9   process_init();
    10 
    11   process_start(&etimer_process, NULL);  
    12   autostart_start(autostart_processes);
    13   
    14   while(1) {
    15     process_run();
    16     etimer_request_poll();
    17   }
    18   return 0;
    19 }

    当然啦,要使用process的话,第9行必须有。

    第11行:启动etimer_process 。  注意,启动一个process,并不代表你就必须要使用这个process。

    第12行:启动自己编写的process。

    第14行到第17行,一个死循环。

    经过测试,最简单,最简单的,在这个while(1){}里面要留下这两个函数<目前不知道是否有可替代的函数>,否则,etimer的测试就完成不了---也就是自己修改的hello-world.c文件中的代码,或许并不会按照自己的意思执行。而这两行代码的先后顺序,经过测试,随便一个顺序都可以。

    然后在./examples/hello-world/ 目录下make

    ./hello-world.native

    现象是,每隔3s,就打印一次 "LED on or off" 。类似在上一次与下一次打印之间,sleep()了3秒。

    然后,再做了一个测试:将刚才自己编写的contiki-main.c 中的while(1)循环 注释掉,像下面这样:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include "contiki.h"
     4 
     5 int
     6 main(int argc, char **argv)
     7 {
     8 
     9   process_init();
    10 
    11   process_start(&etimer_process, NULL);  
    12   autostart_start(autostart_processes);
    13   
    14 //  while(1) {
    15     etimer_request_poll();
    16     process_run();
    17 //  }
    18   return 0;
    19 }

    然后再次make 并执行hello-world.native,其结果并不打印 "LED on or off" ,而且,也不会打印下面的 "Hello world!"。  嗯,这是个有趣的现象,具体原因,下次分享。

     

  • 相关阅读:
    BZOJ1877: [SDOI2009]晨跑
    SPFA的两个优化:SLF与LLL
    BZOJ1858: [Scoi2010]序列操作
    java线程基础巩固---如何捕获线程运行期间的异常
    java线程基础巩固---如何给你的应用程序注入钩子程序
    类的命名空间与卸载详解及jvisualvm使用
    okhttp拦截器之RetryAndFollowUpInterceptor&BridgeInterceptor分析
    okhttp初识拦截器
    类加载器双亲委托机制实例深度剖析
    类加载器重要方法详解
  • 原文地址:https://www.cnblogs.com/chineseboy/p/3887358.html
Copyright © 2020-2023  润新知