无线传感器网络技术及其应用第六章无线传感器网络操作系统6.16.2无线传感器网络操作系统概述TinyOS操作系统MantisOS操作系统6.36.46.5SOS操作系统无线传感器网络操作系统的主要技术挑战16.1无线传感器网络操作系统概述第六章无线传感器网络操作系统6.16.2无线传感器网络操作系统概述TinyOS操作系统MantisOS操作系统6.36.46.5SOS操作系统无线传感器网络操作系统的主要技术挑战16.2TinyOS操作系统26.2TinyOS操作系统6.2.1nesC语言基础6.2.2TinyOS的组件模型6.2.3TinyOS的通信模型6.2TinyOS操作系统6.2.4TinyOS1.0的安装与调试6.2.5TinyOS2.0的安装与调试6.2.6TinyOS的典型应用与分析6.2.1nesC语言基础1.简介2.接口(interface)3.组件(component)4.模块(module)5.配置(configuration)1.简介nesC是对C的扩展,它基于体现TinyOS的结构化概念和执行模型而设计。nesC在设计时强调组件化的编程思想,基本特性如下:①结构和内容的分离。②根据接口的设置说明组件功能。③组件通过接口彼此静态地相连。一个nesC程序的基本组成是组件,一个组件是一个*.nc文件。一个应用程序(app)一般有一个称为Main的组件(类似于C的main函数),它调用其他的组件以实现程序的功能。1.简介6.2.1nesC语言基础1.简介2.接口(interface)3.组件(component)4.模块(module)5.配置(configuration)nesC的接口有双向性:它们描述多功能的两个组件(供给者和使用者)之间的交互渠道。接口声明了两组函数,命令(command)和事件(event)。接口的提供者实现命令,而接口的使用者实现事件。一个组件可以使用或提供多个接口。2.接口(interface)接口由interface类型定义,interface语法定义如下:nesC-file:includes-listoptinterface……interface:interfaceidentifier{declaration-list}storage-class-specifier:alsooneofcommandeventasync2.接口(interface)可选的async关键字指出命令或事件能在一个中断处理程序(interfacehandler)中执行。声明列表必须由有command或event存储类(storageclass)的功能描述组成,通过包含列表,一个接口可选择的文件包括C文件。下面给出一个简单的接口定义例子:interfaceSendMsg{commandresult_tsend(uint16_taddress,uint8_tlength,TOS_MsgPtrmsg);eventresult_tsendDone(TOS_MsgPtrmsg,result_tsuccess);}2.接口(interface)一个事件sendDone接口SendMsg包括了一个命令send6.2.1nesC语言基础1.简介2.接口(interface)3.组件(component)4.模块(module)5.配置(configuration)任何一个nesC应用程序都是有一个或多个组件连接起来的。在nesC中有两种类型的组件,分别称为模块和配置。每个nesC应用程序都由一个顶级配置所描述,其内容就是将该应用程序所用到的所有组件连接起来,形成一个有机整体。3.组件(component)组件的语法定义如下:nesC-file:includes-listoptmoduleincludes-listoptconfiguration...module:moduleidentifierspecificationmodule-implementationconfiguration:configurationidentifierspecificationconfiguration-implementation3.组件(component)一个组件可以有两种作用域:一个规范(specification)作用域,属于C的全局作用域;一个实现(implementation)作用域,属于规范作用域。通过包含列表(includes-list),一个组件能可选择地包括C文件。组件名由标识符(identifier)定义。该标识符是全局性的,且属于组件和接口类型命名空间。规范(specification)列出了该组件所提供或使用的规范元素(接口实例、命令或事件)。specification:{uses-provides-list}uses-provides-list:uses-providesuses-provides-listuses-providesuses-provides:usesspecification-element-listprovidesspecification-element-listspecification-element-list:specification-element{specification-elements}specification-elements:specification-elementspecification-elementsspecification-element3.组件(component)一个组件规范可以有多个uses和provides指令。多个uses和provides指令的规范元素可以通过使用“{”和“}”符号在一个uses或provides命令中指定。组件规范也可以描述一个接口实例:specification-element:interfacerenamed-identifierparameters...renamed-identifier:identifieridentifierasidentifierinterface-parameters:[parameter-type-list]3.组件(component)接口实例声明的完整语法是interfaceXasY,明确地定义Y作为接口的名字。如果接口参数(interface-parameters)被省略,那么就声明了一个简单的接口实例。如果给出了接口参数,那么这就是一个参数化的接口实例。通过包含一个标准的C函数声明,命令或事件可以直接作为规范元素被包含:specification-element:declaration...storage-class-specifier:alsooneofcommandeventasync3.组件(component)如果declaration不是使用command或event存储类说明的函数声明就会产生编译时错误。如果没有指定接口参数,命令或事件就只能是简单的命令或简单的事件;如果指定了接口参数,则表示参数化命令或参数化事件。例如:commandvoidsend[uint8_tid](intx):direct-declarator:alsodirect-declaratorinterface-parameters(parameter-type-list)...3.组件(component)接口参数放在普通函数参数列表之前。注意,只在组件定义中的命令或事件才允许接口参数,而在接口类型里面不允许接口参数。下面是一个完整规范的示例:configurationGenericComm{provides{interfaceStdControlasControl;interfaceSendVarLenPacket;//该接口以当前消息序号作参数interfaceSendMsg[uint8_tid];interfaceReceiveMsg[uint8_tid];}uses{eventresult_tsendDone();//发送完成之后为组件作标记}}3.组件(component)配置GenericComm提供StdControl类型的简单的接口实例Control;提供SendVarLenPacket类型的简单接口实例SendVarLenPacket;提供了SendMsg和ReceiveMsg类型的参数化接口实例,参数实例分别称为SendMsg和ReceiveMsg。使用了sendDone事件。组件K的规范中提供的命令(或事件)F称为K所提供命令(或事件)F;组件K的规范中使用的命令(或事件)称为K所使用命令(或事件)F。3.组件(component)组件K提供的接口实例X中的命令F称为K所提供命令X.F;组件K使用的接口实例X中的命令F称为K所使用命令X.F;组件K提供的接口实例X中的事件F称为K所使用事件X.F;组件K使用的接口实例X中的事件F称为K所提供事件X.F(注意,由于接口的双向性引起的提供事件和使用事件的双向性)。6.2.1nesC语言基础1.简介2.接口(interface)3.组件(component)4.模块(module)5.配置(configuration)模块(module)使用C语言实现组件规范,模块定义如下:module-implementation:implementation{translation-unit}4.模块(module)这里translation-unit是一连串的C语言声明和定义。模块中的translation-unit的顶层声明属于模块的组件实现作用域。这些声明的范围可以是:任意的标准C语言的声明或定义,任务声明或定义,命令或事件的实现。(1)模块实现translation-unit必须实现模块的所有命令a或事件a。下面的C语言语法定义了这些命令和事件的实现:storage-class-specifier:alsooneofcommandeventasyncdeclaration-specifiers:alsodefaultdeclaration-specifiersdirect-declarator:alsoidentifier.identifierdirect-declaratorinterface-parameters(parameter-type-list)简单命令a或事件a的实现需要满足具有command或event存储类的C语言函数定义的语法。4.模块(module)如果在命令a或事件a的声明中包含了async关键字,那么在实现中必须包含async。下面是在模块中接口Send的Send命令实现SendMsg类型的示例:commandresult_tSend.send(uint16_taddress,uint8_tlength,TOS_MsgPtrmsg){...returnSUCCESS;}4.模块(module)具有接口参数P的参数命令a或事件a,需要满足具有command或event存储类的C语言函数定义的语法,这时函数的普通参数列表要以P作为前缀,并带上方括号。例如,下面是一个Send接口的Send[uint8_tid]命令实现SendMsg类型的示例:commandresult_tSend.send[uint8_tid](uint16_taddress,uint8_tlength,TOS_MsgPtrmsg){...returnSUCCESS;}4.模块(module)具有n个T1,...,Tn类型的接口参数的参数化命令a(或事件a)可以使用calla[e1,...,en](...)来调用。接口参数表达式ei必须匹配类型Ti;实际的接口参数值是映射到Ti。4.模块(module)调用命令和触发事件后,它们的执行是立即完成的,即call和signal与函数调用是相似的。4.模块(module)例如,在模块中使用Send接口的SendMsg类型的命令Send[uint8tid]:intx=...;call