第三章 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);

    }

    前面接触的几个接口,要么只有命令,要么只有事件。还有一些接口中既包含命令也包含事件。例如,下一节将要介绍的分阶段接口就同时包含命令和事件。