数据分发实验
一、实验目的
通过本实验的课程教学,主要是让用户了解以下内容:
1.理解数据分发协议的功能及意义,并建立对无线网络多跳分发的时序控制、pipeline、干扰控制的认识。
2.了解数据分发协议的工作原理。
3.掌握Drip、Deluge分发协议的使用。
二、知识介绍
分发协议主要用于维护网络共享配置的一致性,这里的共享配置可以是节点传感器采样的周期、节点LPL醒睡的周期或者节点运行程序的映像等。每个节点都会维护一份这样的配置,分发协议负责通知每个节点这些配置的改变,并通过数据包的交换保证最终的网络配置一致性。即使考虑到网络丢包和链路动态性的影响,网络的一致性也必须得到保障。因此分发协议需要保证网络在不出现孤岛的情况下会尽可能迅速的收敛一致。
根据分发数据的大小,分发十几Kbytes的程序映像与分发2bytes的常量参数,分发协议的设计有很大的区别。但是对于大数据分发和小数据分发,我们都可以将分发协议分为两部分:控制流和数据流。数据流很大程度上取决于分发数据大小,但是控制流对于不同数据大小则是相同的。程序影响分发协议Deluge会在控制流中附加当前影响的版本号信息,当节点发现分发的版本号信息与本地的程序版本号不同时,它会进入数据接收阶段去更新程序映像。
Drip和Deluge分发协议都使用了Trickle来维护网络的版本一致性。在Trickle的工作模式下,节点周期性的广播自己拥有的数据版本号。当收到一个更新的版本号时,节点就获知自己的数据已经过时,需要从拥有新数据的节点索取数据。通过这样的方式,网络的一致性得到了保证。为了避免过多的版本号声明消息拥塞网络,Trickle使用的是指数的后退周期。即当广播完版本号后,在一段时间没有收到更新请求,则下次广播的间隔时间调长一倍。
Drip分发协议是一种针对小数据量的数据分发协议,主要用于系统参数的配置和更新。对于每一个变量,Drip都维护了一个版本号。因此,Drip可以细粒度地控制变量的更新时间和频率。
三、实验步骤
1.上传编译代码
选择上传EasyDissemination代码,编译实验代码。
图4-1 实验代码上传
图4-2 上传编译界面
2.烧录代码
选择0号、1号、2号三个节点同时烧录EasyDissemination代码,烧录提示信息如下:
图4-3 烧录提示信息
3.结果观察
节点0 2会随着节点1同步亮灯,如果节点1撤走或烧录空程序 0 、2节点停止亮灯
四、实验分析
1.TinyOS编程模式分析
本实验的组件关系图如下图所示:
图4-4 组件关系图
首先我们需要在应用程序中使用一个接口StdControl(在例程中被重命名为DisseminationControl)来控制Dissemination模块的工作,该接口连接到DisseminationC模块上。定义好DisseminatorC后,需要把应用程序中使用到的两个接口DisseminationValue和DisseminationUpdate连接到相应的DisseminatorC,
Dissemination提供了两个接口:DisseminationValue和DisseminationUpdate,分别如下图所示。
源码
interface DisseminationValue< t> {
command const t* get();
command void set( const t* );
event void changed();
}
当节点收到一个更新的数据版本号时,会触发changed事件。在changed时间的处理中,会调用get()和set()命令来更新相应的数据。
源码
interface DisseminationUpdate< t> {
command void change(t* ONE newVal);
}
当节点更新了一个数据时,change(t* ONE newVal)都会被调用,以触发一次新的Dissemination来把更新的数据发送到全网络。
//EasyDisseminationAppC.nc
configuration EasyDisseminationAppC {}
implementation {
components EasyDisseminationC;
components MainC;
EasyDisseminationC.Boot -> MainC;
components ActiveMessageC;
EasyDisseminationC.RadioControl -> ActiveMessageC;
components DisseminationC;
EasyDisseminationC.DisseminationControl -> DisseminationC;
components new DisseminatorC(uint16_t, 0x1234) as Diss16C;
EasyDisseminationC.Value -> Diss16C;
EasyDisseminationC.Update -> Diss16C;
components LedsC;
EasyDisseminationC.Leds -> LedsC;
components new TimerMilliC();
EasyDisseminationC.Timer -> TimerMilliC;
}
EasyDisseminationC.nc
//EasyDisseminationC.nc
#include <Timer.h>
module EasyDisseminationC {
uses interface Boot;
uses interface SplitControl as RadioControl;
uses interface StdControl as DisseminationControl;
uses interface DisseminationValue<uint16_t> as Value;
uses interface DisseminationUpdate<uint16_t> as Update;
uses interface Leds;
uses interface Timer<TMilli>;
}
implementation {
uint16_t counter;
task void ShowCounter() {
if (counter & 0x1)
call Leds.led0On();
else
call Leds.led0Off();
if (counter & 0x2)
call Leds.led1On();
else
call Leds.led1Off();
if (counter & 0x4)
call Leds.led2On();
else
call Leds.led2Off();
}
event void Boot.booted() {
call RadioControl.start();
}
event void RadioControl.startDone(error_t err) {
if (err != SUCCESS)
call RadioControl.start();
else {
call DisseminationControl.start();
counter = 0;
if ( TOS_NODE_ID == 1 )
call Timer.startPeriodic(2000);
}
}
event void RadioControl.stopDone(error_t err) {}
event void Timer.fired() {
counter = counter + 1;
// show counter in leds
post ShowCounter();
// disseminate counter value
call Update.change(&counter);
}
event void Value.changed() {
const uint16_t* newVal = call Value.get();
// show new counter in leds
counter = *newVal;
post ShowCounter();
}
}
//Makefile
COMPONENT=EasyDisseminationAppC
CFLAGS += -I$(TOSDIR)/lib/net \
-I$(TOSDIR)/lib/net/drip
include $(MAKERULES)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)