一个偶然的机会,我接触到了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;
};

从 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\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; }; }

对,是一个函数的定义,就是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 类型的指针,最后一个元素是空指针(这是一个标记,标记数组的末尾)

初识contiki(2.7版本)的更多相关文章

  1. webservice初识,SOAP1.1版本

    客户端与服务端模式,非web端发布 1.1      [Jax-ws第一个例子] 1.1.1     第一步:服务端开发 编写SEI(Service Endpoint Interface),SEI在w ...

  2. Contiki 源代码目录结构

    最近要在烧写contiki的CC2650上做一些简单的实验,需要对contiki的目录结构有一个简单的了解.本文使用的是contiki 3.0版本,并且参考了百度文库上的一篇文档:https://we ...

  3. Phython笔记初识

    Phython笔记初识   Python 1898 第一版本 1991 荷兰人 Guido  协议 Gpl                     动态语音类型  

  4. MAC Wireshark抓包IOS

    网络抓包是个基础技能,对于网络协议的掌握有一定的要求.iOS上实现网络抓包可以用Charles(针对http和https),tcpdump(快速分析网络包),和Wireshare.之前写过一篇介绍tc ...

  5. Docker工具的使用

    初识 Docker jdk的版本问题,环境造成的问题很常见,称为代码的水土不服 把环境和代码一起传过去 软件跨环境迁移的问题就解决了 Docker 是一个开源的应用容器引擎 诞生于 2013 年初,基 ...

  6. 初识git版本控制系统

    当下git分布式版本控制系统越来越火,掌握git也是必须的一个技能.因此,对git做了如下学习. Git初级指南 1. 先安装git.(ps:在select cmponents处要勾选Git Bash ...

  7. 《玩转D语言系列》一、通过四个版本的 Hello Word 初识D语言

    对于D语言,相信很多朋友还没听说过,因为它还不够流行,跟出自名门的一些语言比起来也没有名气,不过这并不影响我对它的偏爱,我就是这样的一种人,我喜欢的女孩子一定是知己型,而不会因为她外表,出身,学历,工 ...

  8. 分布式版本控制系统Git-----1.Git 初识

    开始工作咯,师傅让我开始学习Git.刚接触我是懵逼的,"分布式版本控制系统"啥玩意啊这是,大家可不能从字面意思上理解啊,刚开始,版本控制么,我以为是团队合作的时候把开发工具.JDK ...

  9. 01python初识—编辑器&版本&变量知识

    python2.0和3.0版本变化很大,要跟随脚步,学新的,用新的.3.0 python开发工具pycharm 5.0 python的交互器 python的程序一般放到Linux环境下运行. pyth ...

随机推荐

  1. SuperSocket1.6电子书离线版

    使用离线浏览器制作,格式为chm,本人不对电子书内容具有任何权利!简体中文,适用于.NET开发. 下载地址

  2. Django之博客系统邮件分享博客

    在上一章中,我们创建了一个基础的博客应用,我们能在http://127.0.0.1:8000/blog/显示我们的博客.在这一章我们将尝试给博客系统添加一些高级的特性,比如通过email来分享帖子,添 ...

  3. binder学习笔记(十)—— 穿越到驱动层

    Binder驱动层的代码在kernel/goldfish/drivers/staging/android下的binder.c和binder.h.Android源码是不带Linux内核的,驱动正是在这个 ...

  4. models说明

    class UserType(models.Model): caption = models.CharField(max_length=32) class User(models.Model): na ...

  5. console的使用

    一.显示信息的命令 console.log("normal"); // 用于输出普通信息 console.info("information"); // 用于输 ...

  6. slice()、substring()、substr()的区别用法

    在js中字符截取函数有常用的三个slice().substring().substr()了,下面我来给大家介绍slice().substring().substr()函数在字符截取时的一些用法与区别吧 ...

  7. asp web.config文件里compilation的assemblies add的元素来自哪里

    该程序集组合由版本.区域性和公钥标记组成. ASP.NET 首先在应用程序的专用 Bin 目录中搜索程序集 DLL,然后在系统程序集缓存中搜索程序集 DLL. add 元素添加要在动态资源编译期间使用 ...

  8. cheerio制作markDown索引目录

    原文地址:cheerio制作markDown索引目录 制作目录索引这种东西当然是放在前端方便.选择放在后端一是为了了解Node后端生态,掌握更多后端技术:二是因为公司实行前后端分离的方式开发,睾贵的J ...

  9. Jmeter-无法启动,'findstr'不是内部或外部命令,也不是可运行的程序

    今天有一个同事的jmeter无法安装,于是帮他看了看,报以下错误: JAVA的环境变量没有配置好,于是重新配置了下环境变量后,再启动,发现还是不好,于是网上查了下, 发现要在电脑的环境变量中增加 pa ...

  10. P1080 国王游戏

    题意: 让n 位大臣排成一排,国王站在队伍的最前面. 排好队后,所有的大臣都会获得国王奖赏的若干金币, 每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向 ...