分享

ncc编译nesC程序的作用域

 幸福的乐土 2012-04-16
nesC程序可以通过make命令直接编译、连接,并下载到mote上,编译连接规则和使用的硬件平台定义在makefile文件中。下面讲解ncc是如何把Blink.nc和BlinkM.nc有效地连接起来的。
编译和连接命令如下:
ncc -o build/mica2/main.exe -Os -board=micasb -target=mica2 –Wall -Wshadow
-DDEF_TOS_AM_GROUP=0x7d   -WnesC-all    -finline-limit=100000
-fnesC-cfile=build/mica2/app.c  Blink.nc –lm
对其中命令选项的含义可以查阅ncc帮助信息。
从以上编译选项中可以看出,ncc编译的输入文件只有Blink.nc 配件文件,并没有BlinkM.nc模块文件。那么,究竟是如何把它们连接成一个可执行文件的呢?
首先需要理解:ncc是对C的扩展和修改,使其更好地适合嵌人式系统,特别是适合系统资源相当少的传感器网络系统。ncc是nesC的编译器,也是对gcc的修改和扩充。ncc先把nesC预编译成C文件,再通过交叉编译器把C文件编译成可执行文件。
典型的nesC应用程序代码由三部分组成:一套C声明和定义,一套接口集合;一套组件集合。它们与C文件的对应关系问题(如变量作用域,命令及事件与C语言中函数的对应关系等)将在下面逐一分析。
1、作用域问题
在作用域的最顶层包含三个名字空间的全局作用域,分别为C变量和标签名字空间(针对C声明和定义)。组件名字空间和接口名字空间。C声明和定义可能又有自己的作用域,比如C函数中的局部变量。注意,C本身是处于全局作用域中的,这点可以从Blink编译生成的C文件得到证实。
每个接口类型处于全局作用域中,但是接口中的命令和事件却处于该接口的作用域内。也就是说接口中的命令或者事件必须要指定接口名称才能访问,如在BlinkM中要用到接口Timer,根据第一条可知BlinkM和Timer处于同一作用范围内,所以在BlinkM中可以引用Timer。但是使用Time中的命令 start()时,就必须指明为Timer.start(),而不能直接写为start()。显然在任何组件中都可以使用C的变量和函数,这是因为C的变量和函数是处于全局域中的。这就是为什么上面提到的在模块BlinkM中使用result_t, uint32_t,char类型并没有出错。从ncc编译生成的C文件中可明显地看出这一点。下面是app.c(ncc编译产生的C文件)开头的一段代码,它们的定义是全局的。
    typedef int int16_t;
    typedef unsigned int uint16_t;
    typedef long int32_t;
    typedef unsigned longuint32_t;
    typedef long long long uint64_t;
    typedef unsigned long long uint64_t;
    typedef int16_t intptr_t;
    typedef unsigned long uint32_t;
    typedef uint8_t result_t;
每个组件引入了两个作用域:一个是规范域(specification),它处于全局域中;另外一个是实现域(implementation),它处于规范域内。
2、cc整合C文件、接口和组件的过程
从上面的编译信息可以看出,ncc编译的输入是一个配件文件Blink.nc(一个顶层配件文件)。ncc首先装人tos.h文件,该文件包含了基本数据类型定义和一些基本函数。然后ncc把需要的c文件、接口或者组件装人到ncc编译器中进行编译。最后装人顶层配件文件(此处为Blink. nc)。具体步骤如下:
(1)      装入C文件:首先定位C文件,再作一些预处理,展开宏定义与其中定义的头文件。由于组件的接口函数的声明和定义映射到C语言的全局范围,所以对于其他组件而言,其接口函数是全局可见的。
(2)      装入接口:装入接口首先要定位该接口,然后装入该接口包含的文件。
(3)      装入组件:首先定位组件,再递归装入该组件使用的其他组件和相关文件。
3、nesC语言命名到C语言命名的映射
所谓nesC语言命名到C语

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多