数据汇聚实验

 

 

一、实验目的

通过本实验的课程教学,主要是让用户了解以下内容:

1.为学习CTP组网提供基础

2.了解Collection接口的使用

3.理解汇聚的含义

二、知识介绍

1.Collection接口

一个节点在汇聚中可以扮演4种角色:生产者,消费者,侦听者和转发者。根据节点角色的不同,在Collection组件中使用不同的接口。

消费者即树的根节点,根节点以及到根节点的路径组成了汇聚网络路由的基础。在实现了汇聚协议并互相连接的节点集中,只有一个汇聚基础。在该集合中同时激活的根节点是相同基础的一部分。

节点可以通过RootControl接口成为根节点,RootControl.setRoot()必定使当前节点成为汇聚基础的根节点,RootControl.unsetRoot()必定使当前节点不再是一个根节点,两个调用必须是同样地强力。RootControl.setRoot()可以在当前节点己经是根节点的时候调用,同样RootControl.unsetRoot()也可以在当前节点不是根节点的时候调用。

 
源码
   
interface RootControl {  
    command error_t setRoot();  
    command error_t unsetRoot();  
    command bool isRoot();  
}  
   

通过汇聚标识,汇聚基础可以在独立的程序间复用。数据流是可以复用的,但控制流不能复用。

产生要发送到根节点数据的节点是生产者,它使用Send接口发送数据到根。汇聚标识就是在实例化Send时指定的参数。

从网络中接收数据的根节点是消费者。消费者通过Receive接口接收汇聚上来的信息。汇聚标识即实例化Receive时指定的参数。

无意中收到传输中的消息的节点称侦听者。它使用Receive接口接收侦听到的消息。其汇聚标识即实例化Receive时指定的参数。

能处理转发正在传输中的包的节点称网络处理者。它使用Intercept接口接收并更新数据包。其汇聚标识是实例化Intercept时指定的参数。

三、实验步骤

1.上传编译代码

选择上传EasyCollection代码,编译实验代码。


图5-1实验代码上传


图5-2上传编译界面

2.烧录代码

选择0号、1号、2号三个节点烧录EasyCollection代码,烧录提示信息如下:


5-3 烧录提示信息

3.监听数据包

选中0号节点,点击收数按钮,收数成功会在右方提示信息里显示。


图5-4 收数操作

4.实验结果显示

点击下一步查看实验结果。如果想停止收数,回到Step2选中节点点击停止按钮即可。


图5-5 实验结果展示

四、实验分析

1.TinyOS编程模式分析

本实验的组件关系图如下图所示:

图5-6 组件关系图

00 02 列代表的是发送节点的节点号,可看出1号和2号节点的数据包都汇聚到0号节点了。

汇聚服务必须提供组件CollectionC,它的形式如下:

 
源码
   
configuration CollectionC {  
    provides {  
        interface StdControl;  
        interface Send[uint8_t client];  
        interface Receive[collection_id_t id];  
        interface Receive as Snoop[collection_id_t];  
        interface Intercept[collection_id_t id];  
        interface RootControl;  
        interface Packet;  
        interface CollectionPacket;  
    }  
    uses {  
        interface CollectionId[uint8_t client];  
    }  
}  
   

CollectionC可能有更多的接口,但它们必须实现外部调用(命令,事件)的默认函数,从而使接口在没有被连接的情况下也能正常工作。

组件不可以连接到CollectionC.Send,通用组件CollectionSenderC提供了虚拟化的发送接口。

Receive、Snoop、Intercept 都使用collection id t作为参数。每个collection id t对应一个在汇聚协议之上的协议来操作,这与活跃消息中使用不同的am id t值来对应不同的上层协议是类似的。用特定的collection id t发送的包有相同的格式,从而侦听者、处理者、接收者都可以恰当地处理它。

在非根节点上不能触发Receive.receive信号。CollectionC只在根节点成功地收到包时触发该信号。如果根节点调用Send,则必须把它作为一个已接收到的包来处理。注意Receive.receive的缓冲区交换问题,当出现上述情况时,要求CollectionC在发出Receive. receive信号时复制一份缓冲区。

如果CollectionC接收到一份需要转发的包并且当前节点并不是根节点,则它发出一个Intercept.forward信号。

如果CollectionC接收到的数据包应当是由其它节点转发的,则发出Snoop.receive信号。

RootControl可以使节点成为汇聚树的根节点,CollectionC不能将一个节点默认配置为根节点。

Packet和CollectionPacket接口用于让组件访问汇聚数据包的各个字段。

CollectionSenderC

Collection有一个虚拟化的抽象,通用组件CollectionSenderC:

 
源码
   
generic configuration CollectionSenderC(collection_id_t collectid) {  
    provides {  
        interface Send;  
        interface Packet;  
    }  
}  
   

这种抽象类似于AMSenderC的虚拟化方法,只不过用collection id t代替了am id t。与am id t类似,每个collection id t需要有一种包格式,从而接收者可以根据collection ID分析它的内容。

实现在tinyos-2.x/tos/lib/net/ctp与tinyos-2.x/tos/lib/net/le中,属于CTP协议。这里只列出主要的组件。这只是一种参考实现,并不是唯一的。它包含3个主要的组件,相互连接起来构成CollectionC:LinkEstimatorP、CtpRoutingEngineP和CtpForwardingEngineP。这种分解试图支持构件演化,并通过模块化的方法使其更易使用。邻居管理和链路估计与路由协议分开;转发策略如转发队列和定时同步与路由选择和路由协议分开。

LinkEstimatorP

LinkEstimatorP为每个邻居节点估计从本节点到邻居节点的双向链路质量。链路估计可以用多种方法实现,在这儿我们不指定是哪种,它与路由的建立分离开。LinkEstimator是链路估计器和路由引擎的窄接口,唯一的要求是它的返回值应该是标准化的。对LinkEstimator.getQuality()、LinkEstimator.getForwardQuality()、LinkEstimator.getReverseQuality()的返回值有以下要求:越小的值表示链路质量越好。这个值应当在[0,255]之间,在该范围内值的变化应当是线性的。链路质量估计的实现方法可以是使用无线模块提供的LQI或RSI值,或者是通过信息帧计算ETX值,或者是两者的结合。

LinkEstimator可以有自己的控制信息来计算双向链路质量。它提供调用txAck()、txNoAck()、clearDLQ(),根据到邻居节点的数据传输成功与否来更新链路估计。LinkEstimatorP的使用者可以调用insertNeighbor()来手工地在邻居节点表中插入一项,pinNeighbor()可以阻止邻居被剔除,unpinNeighbor()可以恢复剔除策略。

 
源码
typedef uint16_t neighbor_table_entry_t  
  
LinkEstimatorP {  
    provides {  
        interface StdControl;  
        interface AMSend as Send;  
        interface Receive;  
        interface LinkEstimator;  
        interface Init;  
        interface Packet;  
        interface LinkSrcPacket;  
    }  
}  
          
interface LinkEstimator {  
    command uint8_t getLinkQuality(uint16_t neighbor);  
    command uint8_t getReverseQuality(uint16_t neighbor);  
    command uint8_t getForwardQuality(uint16_t neighbor);  
    command error_t insertNeighbor(am_addr_t neighbor);  
    command error_t pinNeighbor(am_addr_t neighbor);  
    command error_t unpinNeighbor(am_addr_t neighbor);  
    command error_t txAck(am_addr_t neighbor);  
    command error_t txNoAck(am_addr_t neighbor);  
    command error_t clearDLQ(am_addr_t neighbor);  
    event void evicted(am_addr_t neighbor);  
}  
      

CtpRoutingEngineP

CtpRoutingEngineP负责计算到根的路由。在传统的网络术语中,这属于网络控制层面的部分,它并不直接转发数据包,那是CtpForwardingEngineP的职责。两者间的接口是UnicastNameFreeRouting。

CtpRoutingEngineP通过使用LinkEstimator接口来取得LinkEstimatorP维护的邻居节点表信息和与邻居节点的双向链路质量。汇聚协议中实现的路由协议必须是基于树的并且至少有一个树根。CtpRoutingEngineP允许节点被动态地配置为根或非根节点。

CtpRoutingEngineP维护了多个候选的下一跳。

 
源码
generic module CtpRoutingEngineP(uint8_t routingTableSize,uint16_t minInterval,  
    uint16_t maxInterval) {  
    provides {  
        interface UnicastNameFreeRouting as Routing;  
        interface RootControl;  
        interface CtpInfo;  
        interface StdControl;  
        interface CtpRoutingPacket;  
        interface Init;  
    }  
    
    uses {  
        interface AMSend as BeaconSend;  
        interface Receive as BeaconReceive;  
        interface LinkEstimator;  
        interface AMPacket;  
        interface SplitControl as RadioControl;  
        interface Timer< TMilli> as BeaconTimer;  
        interface Timer< TMilli> as RouteTimer;  
        interface Random;  
        interface CollectionDebug;  
        interface CtpCongestion;  
        interface Comparebit;  
    }  
}  
  
  
interface UnicastNameFreeRouting {  
        command am_addr_t nextHop();  
        command bool hasRoute();  
        event void routeFound();  
        event void noRoute();  
}  
   

CtpForwardingEngineP

CtpForwardingEngineP提供了所有的顶层接口(除了RootControl)供CollectionC和应用程序使用。它处理重传、重复抑制、包同步、路由循环检测,并将传输是否成功的结果反馈给LinkEstimator使用。

 
源码
generic module CtpForwardingEngineP() {  
    provides {  
        interface Init;  
        interface StdControl;  
        interface Send[uint8_t client];  
        interface Receive[collection_id_t id];  
        interface Receive as Snoop[collection_id_t id];  
        interface Intercept[collection_id_t id];  
        interface Packet;  
        interface CollectionPacket;  
        interface CtpPacket;  
        interface CtpCongestion;  
    }  
    
    uses {  
        interface SplitControl as RadioControl;  
        interface AMSend as SubSend;  
        interface Receive as SubReceive;  
        interface Receive as SubSnoop;  
        interface Packet as SubPacket;  
        interface UnicastNameFreeRouting;  
        interface Queue< fe_queue_entry_t*> as SendQueue;  
        interface Pool< fe_queue_entry_t> as QEntryPool;  
        interface Pool< message_t> as MessagePool;  
        interface Timer< TMilli> as RetxmitTimer;  
        interface LinkEstimator;  
        interface Timer< TMilli> as CongestionTimer;  
        interface Cache< message_t*> as SentCache;  
        interface CtpInfo;  
        interface PacketAcknowledgements;  
        interface Random;  
        interface RootControl;  
        interface CollectionId[uint8_t client];  
        interface AMPacket;  
        interface CollectionDebug;  
    }  
}  
   

CtpForwardingEngineP使用了大量的接口,可以根据功能分为几组:

• 单跳通信:SubSend,SubReceive,SubSnoop,SubPacket,PacketAcknowledgements,AMPacket

• 路由:UnicastNameFreeRouting,RootControl,CtpInfo,CollectionId,SentCache

• 队列和缓冲区管理:SendQueue,MessagePool,QEntryPool

• 包定时同步:Random,RetxmitTimer

posted @   枫让  阅读(184)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示