TinyOS最初是用C语言实现,产生的目标代码比较长。后来研究设计基于组件化和并行模型的nesC语言开发,产生的目标代码相对较小。用nesC语言可开发TinyOS和其上运行的应用程序。
本系统中的接口一般指一系列声明的有名函数的集合,同时,接口也是连接不同组件的纽带。组件的接口通常是双向的,这种接口实际上是提供者组件和使用者组件之间的一个多功能交互通道。接口的提供者所实现的接口的一组功能函数称为命令;接口的使用者需要实现的一组功能函数称为事件。
示意图如图4-4所示。
在接口中声明命令和事件完成不同的功能,命令是接口具有的功能,事件是接口具有通告事件发生的能力。Asy可以让命令或事件在中断处理程序中调用。
接口体现事件驱动功能和模块化。通过事件通知让使用接口者对事件进行响应;任何满足接口功能的实现者都可被其他需要这个接口功能的组件调用。
图4-4 接口示意图
2.组件
组件是nesC程序的基本单元,组件可分为模块与配件两种。其中模块是组件的逻辑功能实体,主要包括命令、事件、任务的具体实现。在TinyOS中,命令都是非阻塞的,它们完成后会通知相关的事件调用。一般情况下,命令调用都是向下的,即应用组件调用那些与硬件紧密结合的组件,事件调用则正好相反。一些特殊的基本事件的调用必须绑定在硬件中断上。nesC语言中还有一类特殊的函数称为任务。在TinyOS中,任务是一个可以被调度的实体,类似于传统操作系统中的进程或线程概念。组件的定义格式如图4-5所示。
图4-5 组件的原型
一个组件提供(provides)和使用(uses)接口。接口是访问组件的唯一途径,并且接口是具有双向性的。一个接口声明了一系列称之为命令(command)的函数,及一系列称之为事件(event)的函数,接口的提供者必须实现该接口声明的所有的命令,而接口的使用者则必须实现该接口声明的所有的事件。一个组件可以提供或使用多个接口,并且可以提供或使用同一个接口的多个实例。
配件通常可通过一系列其他组件来实现一个组件规范,它主要实现组件间的相互访问方式。配件包括组件列表和连接说明,组件列表定义了实现配件的组件,连接通常可将定义的元素(接口、命令、事件等)联系在一起,以完成组件之间功能的调用。
组件是配线文件或模块文件,是逻辑功能的抽象,程序员完全可直接调用组件进行程序开发。
配线文件只是完成组成之间的接口连接情况,模块文件则具体实现接口中的命令和事件。在这两个文件中都可使用provides uses语句。Provides表明这个组件可以提供哪些接口,实现这些接口的命令和事件通知。Uses表明这个组件使用哪些接口,组件可以调用接口中提供的命令和实现对接口中事件进行响应。组件的装配图如图4-6所示。
基于组件的思想,一个组件可通过多个组件完成一定的逻辑功能,对外声明需要哪些接口和提供哪些接口。由组件A、B和C形成新的功能组件D。组件D的结构图如图4-7所示。
图4-6 组件装配图
图4-7 组件D结构图
3.并行模型
通过任务(Task)和中断处理事件(Interrupt hander event)来体现TinyOS并行处理能力。任务(Task)会加入一个FIFO队列中,在没有执行之前,任务之间没有竞争,但中断处理程序则可以打断任务执行。TinyOS采用二级调度机制来满足无线传感器网络运行特点,整个程序调度过程如图4-8所示,组件中完成任务提交,由操作系统完成调度。
基于以上分析,一个节点上应用程序的框图如图4-8所示,操作系统只是在后台提供队列服务。
图4-8 TinyOS任务调度过程
4.具体实现
现以节点收发计数器中的数值为例,更为详细说明网络协议如何通过消息传输来实现。程序要求节点启动以后,开始让计数器计数,每秒向外广播自己的计数值,同时接收别的节点上计数器的值。
(1)主组件
TinyOS的应用程序是从主组件开,完成主组件的StdControl接口的三个命令init()、start()和stop()的具体实现。这个接口中命令执行次序可用init∗(start|stop)∗,应用程序执行前执行init()完成必要初始化工作,start是这个程序要完成的工作,stop是系统关闭前所要执行的动作。这个接口是TinyOS应用程序标准接口,与硬件操作相关的其他组件必须用到这个接口,实现接口中的命令。(www.daowen.com)
(2)使用到接口
StdControl接口完成应用程序启动及相关硬件初始化。
Timer接口完成计数功能。
SendMsg接口发送消息。
(3)使用到组件
组件Main,test5M,TimerC,GenericComm完成逻辑功能:
Main是系统必需的。
test5M实现提供接口的命令和对调用接口事件的响应。
GenericComm完成消息的发送和对接收消息的通告。
其配线文件如下:
Main.StdControl->test5M.StdControl;
Main.StdControl->TimerC.StdControl;
test5M.Timer->TimerC.Timer[unique("Timer")];
test5M.SubControl->Comm;
test5M.Send->Comm.SendMsg;
test5M.Receive->Comm.ReceiveMsg;
(4)test5M模块文件
test5M模块接口如下:
provides是声明这个组件所实现接口中命令和通告相关事件的产生。需要实现StdControl接口中命令init()、start()和stop()。
uses是声明这个组件调用接口中命令和对接口中事件进行响应。所需要响应的事件为Timer接口的fired事件、SendMsg接口的sendDone事件和ReceiveMsg接口的receive事件。
(5)通信实现
组件test5M发送和接收消息是通过组件GenericComm来实现的,GenericComm通过调用其他组件完成从消息包到主动消息、字节级数据传送、位级数据传送到无线电收发模块的功能,在此不再深入分析其实现过程,采用随机后退的CSMA/AD的MAC协议,只要调用组件GenericComm可以完成消息的收发。
GenericComm提供了256个消息收发接口,也就是说系统可以使用256种消息,或者说256种状态进行转换。由于系统是非阻塞模式,一旦消息到达组件test5M中receive事件会立刻调用,因此在这个事件中实现不同消息的转换,从而实现通信双方的握手:
本节从分析无线传感器节点和其上运行的操作系统TinyOS出发,描述无线传感网络节点体系结构,通过应用程序开发说明其通信模型建立思路,为进一步研究TinyOS无线传感器网络打下扎实基础。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。