第三章 TinyOS编程语言nesC
第三节 接口
3.3 接口
接口用于描述组件之间在功能方面的相互关系。在这种相互关系中,组件扮演的角色依赖于它是提供接口还是使用接口。与组件类似,接口名字与其源文件名字之间也是一一映射的关系。例如,文件Boot.nc中描述的是接口Boot,接口Init包含在文件Init.nc中。接口名字位于全局范围。
3.3.1 一般接口
在语法上,接口与组件完全不同,它只有一个组成部分,其中包括一个或多个函数。接口的定义如下所示,关键字interface用来表明这是一个接口定义。接口中的函数可以分为2类:命令和事件。关键字command和event分别标识它后面的函数是命令和事件。由此看来,接口实际上是事件和(/或)命令的集合。根据具体设计情况,接口中的命令或事件可以是一个或多个,也可以只有命令或事件。
interface 接口名{
command 类型标识符函数名(形式参数列表);
…
event 类型标识符函数名(形式参数列表);
…
}
接口Init和接口Boot的定义如下所示。这两个接口很简单,接口Init中只有一个命令init,接口Boot只有一个事件Booted。
例3.7:接口Init和接口Boot
1): interface Init{
command error_t init();
}
2): interface Boot{
event void booted();
}
为了便于描述,将在规范中具有提供某个接口语句的组件称为该接口的提供者,具有使用某个接口语句的组件称为该接口的使用者。
接口的使用者调用接口中的命令,接口的提供者调用接口中的事件。相反的,由使用者实现或定义事件,由提供者实现或定义命令。在应用Powerup中,组件PowerupC是接口Boot的使用者,组件MainC是接口Boot的提供者。当系统启动起来后,由组件MainC通过接口Boot通知该系统已启动的事件。这里的通知事件实际上就是函数调用,即由组件MainC(实际上是由MainC封装的模块RealMainP)调用组件PowerupC所使用接口Boot中的Boot.booted()函数,实现通知事件的目的。实现事件的工作在PowerC中进行。相对的,对于命令的实现与调用,与事件正好相反。组件PowerupC使用Leds接口(定义如下所示),该接口由LedsC提供。PowerupC调用组件LedsC(实际是模块LedsP)中实现的命令Leds.Leds0on()。
读者读到这里,也许会有些模糊。不用着急,阅读后续对模块和配件实现的介绍后,就会更加清楚了。
Leds接口代码如下:
interface Leds{
async command void led0On();
async command void led0Off();
async command void led0Toggle();
…
async command unit8_t get();
async command void set(uint8_t val);
}
前面接触的几个接口,要么只有命令,要么只有事件。还有一些接口中既包含命令也包含事件。例如,下一节将要介绍的分阶段接口就同时包含命令和事件。