TinyOS 2.x 入门教程 - 图文 下载本文

TinyOS Programming

口的提供者。因为BlinkC模块使用了Boot、Leds和Timer接口,所以必须指明这些接口都是由其他哪些组件提供的。

先使用component关键字标明,这个程序当中,总共要用到哪几个组件。其中包括我们自己编写的BlinkC模块。还有负责提供Boot接口的MainC组件,负责提供Leds接口的LedsC组件。还有提供Timer接口的TimerMilliC,其属于泛型(generic)配置,支持被实例化。这里先不细说,因为我们需要用到三个计时器,所以需要使用new关键字创建三个计时器的实例,然后分别用as被重命名为Timer0、Timer1和Timer2。 components new TimerMilliC() as Timer0; components new TimerMilliC() as Timer1; components new TimerMilliC() as Timer2; 再往下就是组件之间的连接了。BlinkC使用了Boot接口,而MainC正好提供了BlinkC所需的Boot接口,所以我们将他们进行连接。nesC使用箭头来指示接口之间的关系。你可以把向右箭头(?)当作“绑定到”(binds to)。箭头左边的接口绑定一个接口到右边的(接口的)实现上。换句话说,组件使用的接口在左边,而右边组件提供的接口在右边。 BlinkC->MainC.Boot // 或者像下面这样也是可以的。 MainC.Boot<-BlinkC 因为BlinkC内部就使用了一个Boot接口,所以BlinkC后面的Boot被省略了。完整的书写格式为: // 意为:Blink组件内使用的Boot接口由MainC组件提供。 BlinkC.Boot->Mainc.Boot 接着是控制发光二极管的Leds接口,由LedsC组件提供。这里也进行了简写,完整的书写格式为: BlinkC.Leds->LedsC.Leds 计数器的连接同理。

2.3.2 BlinkC模块

BlinkC模块的代码如下:

#include \

module BlinkC {

uses interface Timer as Timer0; uses interface Timer as Timer1; uses interface Timer as Timer2; uses interface Leds; uses interface Boot; }

implementation {

event void Boot.booted() {

call Timer0.startPeriodic( 250 ); call Timer1.startPeriodic( 500 ); call Timer2.startPeriodic( 1000 ); }

Page 14 of 94

TinyOS Programming

event void Timer0.fired() {

dbg(\ call Leds.led0Toggle(); }

event void Timer1.fired() {

dbg(\ call Leds.led1Toggle(); }

event void Timer2.fired() {

dbg(\ call Leds.led2Toggle(); } }

在模块BlinkC的声明内(module BlinkC{?})表明了该程序需要用到的全部接口。因为

Blink程序主要是将telosb节点上的三个LED发光二极管以不同的频率闪烁。所以我们需要三个精度为毫秒(TMilli)的计时器接口(Timer),分别使用关键字as重命名为Timer0、Timer1和Timer2。既然需要点亮发光二极管,自然需要一个操控发光二极管的接口,也就是Leds,最后就是程序启动负责初始化的接口Boot。接着在实现部分(implementation{?})。在实现部分需要实现所有我们用到的接口的事件,以为在这个程序里面,我们只是使用了接口,而作为这些接口的用户,我们只需要负责去实现他们的事件。这些接口内的命令,则由接口的提供者负责实现。

这里主要是两个事件,一个是Boot接口的booted事件,另一个是计时器被触发的fired事件。在booted事件中,也就是程序启动以后,我们的主要任务就一个,启动三个计时器: event void Boot.booted() { call Timer0.startPeriodic( 250 ); call Timer1.startPeriodic( 500 ); call Timer2.startPeriodic( 1000 ); } Timer 0的频率为4Hz,Timer 1的频率为2Hz,Timer 2的频率为1Hz。这里startPeriodic是一个启动计时器的命令,呼叫命令需要使用call关键字。同样,因为是命令,所以它们由接口的提供者负责实现,我们只负责使用就可以了。另一个需要我们处理的事件就是计时器的触发,因为有三个计时器,所以需要书写三个触发事件: event void Timer0.fired() { dbg(\ call Leds.led0Toggle(); } event void Timer1.fired() { dbg(\ call Leds.led1Toggle(); } event void Timer2.fired()

Page 15 of 94

TinyOS Programming

{ dbg(\ call Leds.led2Toggle(); } 我们可以看到Timer0被触发的时候,我们切换0号发光二极管的状态(如果是亮的则熄灭,如果是灭的则点亮),同理Timer1被触发的时候切换1号发光二极管的状态,Timer2被触发的时候切换2号发光二极管的状态。Led0Toggle、led1Toggle和led2Toggle属于Leds接口的三个命令用call的方式调用即可。

2.3.3 事件evenst和命令commands

在Blink示例中用到的接口文件为:

? /opt/tinyos-2.x/tos/lib/timer/Timer.nc ? /opt/tinyos-2.x/tos/interfaces/Leds.nc ? /opt/tinyos-2.x/tos/interfaces/Boot.nc

以Leds接口为例,它定义了多个命令,如:redOn(),redOff()等等,其作用是将LED灯

(红、绿、黄)灯打开或关闭。由于BlinkC模块使用了Leds接口,因此它可以调用其中的任意一条命令。但请注意,Leds仅仅只是一个接口,其实现由使用它的组件对应的配置文件指定。在本例中,是在BlinkAppC.nc中指定为LedsC,即是要由LedsC来实现Leds接口。 简单的调用实现过程如下图所示:

Page 16 of 94

TinyOS Programming

2.3.4 编译Blink应用程序

TinyOS支持多种平台,每个平台在tos/platform目录下有自己的目录。在本教程中,我们将适用telosb平台作为例子。要为telosb节点编译Blink应用程序,只需在cygwin shell 中转到apps/Blink目录下,输入:

make telosb

即可。如果没有任何语法错误,您将看到以下图 2.1编译信息:

图 2.6 成功为Telosb节点编译程序

关于编译方面的更多信息不在本教程之内,目前也只需知道这些。有兴趣的读者可以自己翻阅相关资料。

2.3.5 安装Blink程序到Telosb节点并运行

要安装Blink程序到Telosb节点,先将telosb节点插入PC的USB接口中,在之前已编译的基础上,您只需要在apps/Blink目录下输入: make telosb reinstall

make install, bsl,

即可,如果成功的话可以看到以下图 2.2安装信息:

Page 17 of 94