TinyOS操做系统由nesc语言写成,从程序员角度看,它的基本做用就是提供了一组API接口以及一些编程规则。程序员
具体来讲,基于nesc语言的TinyOS编程行为具备如下特色:算法
a.兼容C语言:使用nesc进行TinyOS编程时可使用C语言中几乎全部的结构体、函数语法。事实上,nesc仅仅是在较高的层次上增长了一些新的数据结构(即接口和组件)和并发执行模型。编程
b.组件式编程:组件相似于面向对象语言的类对象,能够提供或使用接口,而且有本身的内部实现,程序员使用代码肯定组件之间的链接关系。与C++或JAVA不一样的是,组件对象的实例化是在编译时运行的。数据结构
c.任务式编程:TinyOS提供一个简单的延期任务机制,即用task关键字修饰的任务函数使用post关键字投递后,能够被TinyOS的任务调度程序调度执行。任务可使组件在“后台”运行,而不是当即运行。并发
d.分阶段做业编程:当编写一个须要长时间运行的做业代码时,将其分为两个阶段,即调用和完成调用。例如一个读传感器工做,能够写成两个函数,read和readDone函数,当read函数读完时,在函数内部经过任务给调用者激发一个readDone事件。异步
e.事件驱动编程:事件机制致使代码的执行路径是不可预知的,不一样的事件执行不一样的代码片断。TinyOS有两种事件:硬件中断事件和程序事件(由程序自己使用signal关键字来激发的事件)ide
f.并发执行模型:nesC将代码区分为同步代码和异步代码。其中同步代码仅由任务来执行;异步代码可被任务和中断处理程序执行,nesC编译器检查并确保这个规则被执行。函数
TinyOS的源码目录post
TinyOS开发流程:spa
(1)肯定硬件资源
(2)应用需求分析
(3)应用程序组件和接口设计
(4)按组件编写程序代码以及makefile文件
(5)编译、下载、调试程序
一个简单的Blink程序:
在咱们C语言入门的时候,第一个拿出来说的例子是HELLOWORLD,单片机,FPGA编程的时候,第一个拿出来说的例子是流水灯。
这里基于nesc的TinyOS的编程咱们来说最简单的Blink程序,也就是点灯程序。
首先咱们来看Blink程序目录下的文件:
目录下一共有三个文件:BlinkAppC.nc:这是配件组件,BlinkC.nc:这是模块组件,Makefile:这是编译规则
根据TinyOS组件编程规则,一个应用程序有且只有一个顶层配置组件,用于配置程序中的组件之间的接口链接关系,模块组件能够有多个。
接下来咱们分别看一看三个文件的源码:
配件的源码咱们能够看到分为两个部分,一个是configuration的声明区,一个是配件的implementation的实现区。配件通常用configuration来声明。
声明区声明要使用的接口和提供的接口。实现区咱们也能够分为两部分:一部分是组件的声明,另一部分是组件的链接关系。
模块的源码也是分为两个部分,一部分是声明区,一部分是实现区。声明区声明使用的接口和提供的接口。实现区是业务实现代码。Boot接口的booted函数是入口函数,至关于C语言的main函数。
上述代码是一种固定写法,每个TinyOS的应用程序的Makefile文件至少包含这两行代码,其中:COMPONENT变量用于指定顶层配置组件的名字。include语句用于包含环境白能量MAKERULES,它指向TinyOS的默认Makefiles文件。
nesC程序结构
程序文件组成主要是一下几个部分:
一个完整的nesC程序是由多个组件组成的,组件是nesC程序的可运行模块。
接口:(相似C语言的.h文件 只有声明没有实现)
接口提供给组件来使用,而且必须由某个组件来实现才有意义。nesC接口的规定:
a.接口由一个或多个命令函数(command)和事件函数(event)组成,能够只有命令函数或事件函数。
b.接口能够被多个组件来实现(由配件来指定具体使用哪一个实现)
c.实现接口的组件,必须实现接口中全部的命令函数。
d.使用接口的组件,必须实现接口中的所用事件函数。
接口定义语法:
1 interface 接口名 2 { 3 command 函数声明 4 event 函数声明 5 }
组件:
共分为两类,模块和配件。
模块module是nesC程序的逻辑功能实体,经过提供接口或使用接口以实现某个确切的业务算法。通常以应用名称+C命名
配件configuration负责把其余组件给装配起来,把组件“使用的接口”绑定到“提供该接口”的组件上去。通常以应用名称+AppC命名
一般说,模块是包含可执行代码的组件,配件是包含组件关系的组件。
配件
配件定义的语法:
1 configuration 配件名 2 { 3 //接口声明 4 use interface X; 5 provide interface A; 6 } 7 implementation 8 { 9 //组件声明语句 10 components 组件A; 11 //组件链接语句 12 组件A.接口->组件B.接口//组件A的接口由组件B提供 13 }
模块:
模块定义的语法:
1 module 模块名 2 { 3 //接口声明 4 } 5 implementation 6 { 7 //变量定义 8 普通函数 9 { 10 } 11 task 任务函数 12 { 13 } 14 command 命令函数 15 { 16 } 17 event 事件函数 18 { 19 } 20 }
接口的声明语法
1 use interface X;//使用什么接口 2 provide interface A;//提供什么接口
模块的实现implementation包括两部分代码:变量定义,入口函数和其它函数。
变量定义:
本模块功能算法所用的变量,变量只在模块内有效,模块变量是静态变量。
入口函数:
nesC程序的入口须要在模块中使用系统提供的Boot接口,而后在程序中实现该接口的booted函数,此函数就是nesC程序的入口。
语法:
1 event void Boot.booted() 2 { 3 }
其余函数:
任务函数:由操做系统调度执行的函数。加关键字task。
命令函数:模块“提供的接口”所规定的全部命令函数 加关键字command,call命令触发。
事件函数:模块“使用的接口”所规定的全部事件函数 加关键字event,signal触发。