一个偶然的机会,我接触到了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\n"); 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; };
第四个成员也很重要:
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\n"); 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\n"); }; PT_YIELD_FLAG = 0; (process_pt)->lc = 0;; return 3; }; }
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 类型的指针,最后一个元素是空指针(这是一个标记,标记数组的末尾)