首页 理论教育 nesC编程语言简介

nesC编程语言简介

时间:2023-06-30 理论教育 版权反馈
【摘要】:TinyOS以及基于TinyOS的应用程序都是用nesC编写的。nesC是一个提供了包含组件机制、事件驱动机制和并发型等特征的编程模式,满足了面向传感网的操作系统和应用程序的设计要求,并降低了复杂度。用C语言实现的目标代码比较长,而使用nesC语言产生的代码相对较小。一个nesC程序由一个或多个组件组合或连接而成。6)nesC中模块的并发性主要是基于任务与中断句柄。

nesC编程语言简介

1.nesC语言介绍

TinyOS最初是用C语言和汇编语言编写的,但是科研人员的进一步研究发现,C语言不能有效、方便地支持面向传感器网络的应用和操作系统的开发,于是加州大学伯克利分校在C语言的基础上进行了一定的扩展,开发了支持组件化编程的nesC(C language for net-work embedded systems)语言。TinyOS以及基于TinyOS的应用程序都是用nesC编写的。

nesC是一个提供了包含组件机制、事件驱动机制和并发型等特征的编程模式,满足了面向传感网的操作系统和应用程序的设计要求,并降低了复杂度。应用程序由一组可重用的系统组件和专门的应用程序代码组成,不明确区分软硬件界线,随应用程序和硬件平台而变化。用C语言实现的目标代码比较长,而使用nesC语言产生的代码相对较小。一个nesC的应用程序只使用相关的组件,而不需要操作系统的整体运行。所以只要连接需要使用的组件就可以完成功能,生成的代码小且高效。

TinyOS以及基于TinyOS的应用程序是由许多功能独立且相互联系的组件(Component)组成的。一个nesC程序由一个或多个组件组合或连接而成。组件定义了两种——配件(Configuration)和模块(Module),配件定义了程序使用的组件以及组件间的连接关系,模块则是组件的具体实现。一个组件使用或者提供若干接口,组件的接口是实现组件间联系的通道,如果组件实现的函数没有在它的接口中说明,就不能被其他组件使用,这实际上也是组件化编程的一个重要特征。接口的使用者需要实现的一组功能函数,称为事件(Events),接口的提供者需要实现一组功能函数,称为命令(Commands)。可以说接口是一系列声明的有名函数集合,同时接口是连接不同组件的纽带。

2.nesC的基本特点

1)独立的组件(Component)结构:所有nesC的程序都是由不同组件构成的,这些组件按照规则相互连接,最终形成了能实现特定功能的应用程序。组件包含两部分不同的内容,一部分是组件本身的细化,主要包括其应用实例的接口(Interface)名称;另一部分则是组件的功能描述。各组件在内部都是以任务(Task)的形式进行调度,而控制线程可以将一个组件通过接口过渡到另一个组件。我们既可以在任务中创建线程,也可以通过硬件中断来实现对各组件的控制。

2)接口所对应组件功能明确:接口可以由组件提供,同时也可以被组件使用。组件所提供的接口包括该组件要提供给使用者的功能,被使用的接口代表着组件需要完成其任务的具体功能。

3)接口是双向的:这便明确了一系列函数既可以由组件接口的提供者——指令(Com-mand)实现,也可以通过接口的使用者以事件(Events)触发的方式实现调用。这就允许用一个信号接口,表示一个复杂组件之间的交互行为,例如当一个事件发生后,首先注册这个事件的特征信息,其次进行事件的回调。接口的双向性很关键,因为在TinyOS中所有的长指令(如发送数据包),都需要无阻塞的双向传输;我们可以通过信号触发事件的方式来完成数据包的发送。如果只是通过指定接口,一个组件是不能调用发送命令的,除非该组件提供了数据包发送事件的功能。

4)各组件通过其接口以统计的方式进行互联:这种特点会提高程序运行的效率,增强代码设计的健壮性,同时允许对程序进行更好的统计分析

5)nesC的设计完全依照于整体程序的编译器:这使得开发人员可以更好地分析代码,有利于生成更加高效的代码,其中nesC中的“编译时间数据竞争探测器”便是一个非常典型的例子。

6)nesC中模块的并发性主要是基于任务与中断句柄。nesC编译器中,各中断句柄的并发运行,这种处理方式的优点是:程序的运行效率很高,会大大缩短事件和任务的响应时间;缺点在于:如果事件和任务的数量在短时间内超过了堆栈所能处理的能力,会引起潜在数据竞争,也会影响系统的稳定运行,因此在设计软件时要综合考虑。

由此可以看出nesC是一种类C语言,基于模块化的设计思想更为突出,同时TinyOS提供了丰富的接口,只要开发人员具有C语言基础,便可以在很短时间内开发出高效、可靠、强健壮性的nesC应用程序。这对缩短产品的开发周期,提高开发效率是非常有好处的。

3.nesC语言的组成结构

(1)nesC接口(Interface)

nesC中的接口具有双向功能,它们是实现两个组件之间进行多函数交互的桥梁,这两个组件分别为接口的提供者与接口的使用者。接口所涉及的一系列函数的调用是通过接口提供者以Command方式实现的;而接口使用者通过事件触发的方式对函数进行调用。在此我们介绍接口是如何指定的。

nesC-file:

978-7-111-43089-6-Chapter04-25.jpg

以上是定义了接口类型的标识符。这个标识符具有全局的作用范围,独立分属于组件和接口类型这两个作用域。因此在所有组件中的接口类型名称彼此区分,但都不与标准C中的声明相冲突。

每个组件类型在声明列表中的声明都有一个独立的作用范围。声明列表必须包含所有函数的声明,必须注明存储类别:指令或是事件,否则在编译过程中会出现错误

最后可选择的关键字async表示指令或是事件是以中断句柄的方式执行的,同样一个接口可以通过inludes-list引用C文件。以下是一个简单的接口应用:

978-7-111-43089-6-Chapter04-26.jpg(www.xing528.com)

所提供的SendMsg接口类型必须实施send指令,而使用者必须触发sendDone事件。

(2)nesC组件(Component)

在nesC中有两种类型的组件,分别称为模块(Module)和配置(Configuration)。模块提供应用程序代码,实现一个或多个接口;配置则是用来将其他组件装配起来的组件,将各个组件所使用的接口与其他组件提供的接口连接在一起。这种行为称为导通(wiring)。每个nesC应用程序都由一个顶级配置所描述,其内容就是将该应用程序所用到的所有组件导通起来,形成一个有机整体。nesC的所有源文件,包括接口、模块和配置,其文件后缀(扩展名)都是“.nc”。既可以是一个模块也可以是一个配置,以下是nesC组件的定义形式。

978-7-111-43089-6-Chapter04-27.jpg

组件的名称由identifier(标识符)唯一确定,标识符的作用域属于组件与接口类型的作用域。组件可以通过includes-list(头文件列表)有选择性的包含C文件,specification列出了该组件提供或使用的元素,例如接口实例、指令以及事件。一个组件必须执行该组件所提供接口的指令,同时也必须执行其使用接口的事件。除此之外,组件必须实现其所提供的指令和事件。通常情况下,指令是按照硬件组成部分向下执行的,而事件是依照应用组件向上触发的。由此我们可以将nesC应用程序视为,将应用组件置于最顶层的组件图形结构。

(3)nesC模块(Module)

模块是通过C代码来实现一个组件的所有内容,定义方式如下:

978-7-111-43089-6-Chapter04-28.jpg

translation-unit是一个用C语言声明和定义的列表,nesC顶层对模块translation-unit声明的作用范围属于模块组件的作用域。translation-unit必须实现其提供的所有指令或事件,例如所有直接提供的指令和事件,所有接口提供的指令及事件以及所有接口使用的事件。一个模块可以调用自身所包括的任何指令,同时也可用信号触发其包括的任何事件。这些指令和事件是通过以下的C扩展语义描述实现的。

978-7-111-43089-6-Chapter04-29.jpg

(4)nesC配置(Configuration)

nesC中的配置文件主要是利用connecting(连接)、wiring(导通)以及包含其他组件来实现一个接口。

978-7-111-43089-6-Chapter04-30.jpg

图4-12 nesC模块调用关系

通过以上介绍,我们可以将nesC的应用程序概括为以下3种类型:

1)接口定义文件—app.ncc。

2)模块文件—app_P.nc或app_M.nc。

3)配置文件—appC.nc。

模块间的调用关系如图4-12所示,配置文件中“Module B.a→Module A.a”,即表示模块B中的接口a调用了模块A中的接口a,格式为“调用者→提供者”。接口定义文件中定义了接口的成员,但成员的具体实现还需在模块文件的implementation里完成,同时模块中设置了接口类型以便使用。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈