TinyOS学习笔记讲解 下载本文

内容发布更新时间 : 2024/9/20 1:26:09星期一 下面是文章的全部内容请认真阅读。

第一篇 基础知识

TinyOS调度 MainC组件 应用程序接口 (应用程序提供的接口,仅供本程序使用) 应用程序模块 *C.nc 应用层配件 *App.nc 库组件 在/tos/lib目录下 TinyOS 接口 存放在/tos/interface目录下 TinyOS系统组件 在/tos/system目录下,为系统抽象出的最高层组件 硬件适配层/抽象层 该层一般位于/tos/chips或相应的平台/platforms下 具体硬件 TinyOS体系结构

Sleep Task1 Task2 提交task3 提交task1 COMP1 提交task2 事件2 Task3 Task3 Task1运行 事件1 COMP2 Task2 Task3 中断服务向量 TinyOS任务调度 硬件中断 (1) 组件模型module & configuration

TinyOS是基于构件的微操作系统,采用事件驱动模型,有效的提高了系统的运行效率以及能源合理利用。TinyOS采用nesC语言编写,其应用程序由一个或多个组件连接而成,而组件可以提供和使用接口,组件必须实现其所提供的command接口,并且必须实现其连接组件中申明的事件event接口。接口是程序的实体,实现程序的各功能模块,分为command和event,command接口由组件本身实现,而event接口则由调用者实现,值得注意的是,接口是双向的,调用command接口时必须实现其event接口。

组件又可以细分为模块module和配件。模块亦可分为2个部分,其一,首先申明提供以及使用的接口,如 <>表示可变类型argument type

只用做配线时类型匹配检测 申明使用的接口。As 表明生成这个接口的一个实例。这是标准写法,其实下面这条语句的全写就是 uses module BlinkC {

uses interface Timer as Timer0; uses interface Leds; users interface Boot; }

interface Leds as Leds; 其二,在implementation中模块包含各接口所提供的行为(方法),也包含仅供本模块内部使用的函数,以及申明本模块所具有的事件signal,以及实现其连接或使用的event。

implementation {

uint8_t counter = 0; void ledctl() 实现Boot接口中的事件 { call Leds.set(counter); }

event void Boot.booted() 使用接口提供的方法 {

call Timer0.startPeriodic( 250 ); } 实现调用Timer0的事件 event void Timer0.fired() {

counter++; 调用模块内部函数 ledctl(); } }

配件configuration也可以分为两个部分,和module一样,第一部分是申明可以提供以及使用的接口。第二部分implementation 中首先列出与其相连接模块的名称,使用components标注连接的模块,然后对本配件提供的以及与其相对应模块使用以及提供的接口进行配线,如下例:

configuration BlinkAppC { BlinkC模块中使用的Boot接口连接到MainC模块上 BlinkC作为该配件对应的模块 }

implementation

与其连接的模块申明 {

components MainC, BlinkC, LedsC,TimerMilliC; BlinkC -> MainC.Boot; /////或者写作BlinkC.Boot -> MainC.Boot; BlinkC.Timer ->TimerMilliC; BlinkC.Leds -> LedsC; }

在TinyOS中存在很多中间配件,这些配件的特点是没有与之相对应的模块,其作用就是根据不同的条件将上层的连接转接到不同的模块上,如下例所示

generic configuration AMSenderC(am_id_t AMId) { provides {

interface AMSend; 配件提供接口供其他组件连 interface Packet; interface AMPacket;

interface PacketAcknowledgements as Acks; } }

implementation {

根据不同条件申明连接的模块

#if defined(LOW_POWER_LISTENING)

components new LplAMSenderC(AMId) as SenderC; #else ()带参数的模块 components new DirectAMSenderC(AMId) as SenderC; #endif 为该配件提供的接口配线 AMSend = SenderC; Packet = SenderC; AMPacket = SenderC; Acks = SenderC; }

接口文件相当于C程序中头文件对函数的声明,接口文件一般放置于提供该接口的模块的同一目录下的interface文件夹中,也可以放在TinyOS根目录下的interface目录中,其命名必须与模块中所提供接口名字相同,注意不是接口的实例化名称或nickname。如下例

interface CC2420Register { 当在中断中调用时必须加此声明

async command cc2420_status_t read( uint8_t* data ,uint8_t len);

async command cc2420_status_t write( uint8_t *data ,uint8_t len); 作为模块命令,使用call访问 }

注意:带有参数的接口在interface中申明时不需要写出其接口参数,比如,上例中CC2420Registe接口是带有参数的,而在模块中实现是则写成CC2420Registe [uint8_t addr]。