zoukankan      html  css  js  c++  java
  • 初识contiki(2.7版本)

    一个偶然的机会,我接触到了contiki这个家伙。

    Contiki 是一个开源的、高度可移植的、采用 C 语言开发的非常小型的嵌入式操作系统,针对小内存微控制器设计,适用于联网嵌入式系统和无线传感器网络,由瑞典计算机科学学院(Swedish Institute of Computer Science)的Adam Dunkels和他的团队开发。 Contiki支持IPv4/IPv6通信,支持TCP/UDP,还提供了线程、定时器、文件系统等功能。它的官方网站是http://www.contiki-os.org/

    contiki 的特点有很多,其中最吸引我的是Protothreads,非常精致小巧。


    接下来,我们就扒拉出contiki的源码,看看这个小家伙的真面目吧。

    先看看一个特别简单的例子(从源码中的例子改编)

    PROCESS(blink_process, "LED blink process");
    
    AUTOSTART_PROCESSES(&blink_process);

    PROCESS_THREAD(blink_process, ev, data)
    {
     
      PROCESS_BEGIN();
      printf("hello
    ");
      PROCESS_END();
    }


    1.PROCESS宏

    我们宏展开,得到:

    static char process_thread_blink_process(struct pt *process_pt, process_event_t ev, process_data_t data);
    struct process blink_process = { ((void*)0), "LED blink process", process_thread_blink_process };

    也就是说,这一个宏有两个作用:

    1)声明一个函数

    函数名字:process_thread_xxxxxx

    函数返回值: char

    函数参数:有三个,分别是 struct pt 类型,process_event_t 类型, process_data_t 类型

    2)定义一个struct process 类型的结构体,这个结构体原型是什么呢?

    struct process {
      struct process *next;
      const char *name;
      char (* thread)(struct pt *, process_event_t, process_data_t);
      struct pt pt;
      unsigned char state, needspoll;
    };

    从 next成员可以看出,这个是链表的一个节点, name是这个进程的名字,可以随便起,第三个成员非常重要,是一个函数指针,刚好指向process_thread_xxxxxx这个函数。由此可以推测,对于用户的每一个进程(其实我认为是线程),都有这么一个结构体与其对应,调度任务的时候,实际上是通过函数指针调用了相关的函数。

    第四个成员也很重要:

    typedef unsigned short lc_t;
    
    struct pt {
      lc_t lc;
    };

    就是短整形的一个变量,用来保存行号(不明白?后面就知道了。)

    最后两个成员是状态变量,以后再说。

    struct process blink_process = { ((void*)0), "LED blink process", process_thread_blink_process };
    这句话,前三个成员已经赋值,后面三个成员默认是0(根据C99标准)

    2.PROCESS_THREAD宏

    PROCESS_THREAD(blink_process, ev, data)
    {
     
      PROCESS_BEGIN();
      printf("hello
    ");
      PROCESS_END();
    }

    这个宏展开是什么呢?

    static char process_thread_blink_process(struct pt *process_pt, process_event_t ev, process_data_t data)
    {
    
    	{ char PT_YIELD_FLAG = 1; if (PT_YIELD_FLAG) {;} switch((process_pt)->lc) { case 0:;
    		printf("hello
    ");
    	}; PT_YIELD_FLAG = 0; (process_pt)->lc = 0;; return 3; };
     
     
    }

    对,是一个函数的定义,就是thread 指针指向的函数。也就是说:
    PROCESS_BEGIN();
    就等于
    { char PT_YIELD_FLAG = 1; if (PT_YIELD_FLAG) {;} switch((process_pt)->lc) { case 0:;

    PT_YIELD_FLAG,这个标志,我的理解是=1表示即将占有CPU,=0表示即将放弃CPU
    switch((process_pt)->lc) 这个就是保存断点的秘诀,通过switch直接跳转到某一行


    PROCESS_END();就等于
    }; PT_YIELD_FLAG = 0; (process_pt)->lc = 0;; return 3; };


    3.AUTOSTART_PROCESSES宏

    AUTOSTART_PROCESSES(&blink_process);
    展开得
    struct process * const autostart_processes[] = {&blink_process, ((void*)0)};
    定义了一个数组,元素是struct process 类型的指针,最后一个元素是空指针(这是一个标记,标记数组的末尾)


  • 相关阅读:
    Uva 10719 Quotient Polynomial
    UVa 11044 Searching for Nessy
    Uva 10790 How Many Points of Intersection?
    Uva 550 Multiplying by Rotation
    Uva 10916 Factstone Benchmark
    Uva 10177 (2/3/4)D Sqr/Rects/Cubes/Boxes?
    Uva 591 Box of Bricks
    Uva 621 Secret Research
    Uva 10499 The Land of Justice
    Uva 10014 Simple calculations
  • 原文地址:https://www.cnblogs.com/longintchar/p/5224442.html
Copyright © 2011-2022 走看看