基于contiki平台的路由协议仿真Word格式文档下载.docx
《基于contiki平台的路由协议仿真Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《基于contiki平台的路由协议仿真Word格式文档下载.docx(13页珍藏版)》请在冰豆网上搜索。
重庆邮电大学本科课程设计报告目录
重庆邮电大学本科课程设计报告第一章绪论
第一章绪论
1.1设计题目:
基于Contiki平台的传感网路由协议设计与仿真
1.2设计任务:
基于Contiki操作系统和Cooja仿真器,运用所学的无线传感网知识,选择一种典型的传感网路由协议进行组网设计和仿真。
路由协议可在AODV、RPL、RIME等协议中任选一种,也可选择其它典型的传感网路由协议。
1.3设计要求:
1.掌握Contiki物联网平台开发的基础知识。
2.组网规模不少于20个节点。
3.完成网络的运行场景分析、拓扑结构规划和路由协议设计。
4.在Contiki平台上独立编写符合需求的传感网程序。
5.采用Contiki自带的网络仿真器,对编写的程序和网络路由协议进行仿真,给出网络运行效果图。
6.调节路由协议的一些参数,对路由协议的性能变化进行分析。
1.4参考资料:
1.Contiki开发组.Contiki:
TheOpenSourceOSfortheInternetofThings.http:
//www.contiki-os.org/
2.桂劲松.《物联网系统设计》.北京:
电子工业出版社.2013.
3.谢希仁.《计算机网络》.北京:
电子工业出版社.2008.
4.李晓维.《无线传感器网络技术》.北京:
北京理工大学出版社.2007.
重庆邮电大学本科课程设计报告第二章总体设计方案(或系统建模)
第二章总体方案设计(或系统建模)
2.1RPL概述
RPL是为LLN而设计的距离矢量路由协议,通过使用目标函数和度量集合构建具有目的地的有向无环图(DODAG)。
目标函数利用度量和约束条件的集合计算出最优路径。
由于网络部署的目的性有异,同一网络可能需要不同的链路质量要求等等。
2.1.1DODAG的构建过程
DODAG的构造过程由根节点或LoWPAN边界路由器(LBR)发起。
为了实现DODAG的构造,RPL基于ICMPv6,新增加了如下三条控制消息:
DIS、DIO、DAO。
RPL支持三种基本的数据传输模式:
多点到点,Multipoint-to-Point(MP2P)、点到多点,Point-to-Multipoint(P2MP)、点到点,Point-to-Point(P2P).。
首先来说实现为MP2P构造上行到根节点的路径。
根节点利用DIO消息广播DODAG的信息;
根节点的邻居节点收到DIO后,根据一定的准则,决定是否加入这个DODAG,这些准则包括:
目标函数、DAG特性、各种自定义的本地策略等,当某个邻居节点加入所广播的DODAG后,它就建立了一条到达DODAG根节点的路径。
根节点被称为该节点的“父节点”。
如果新加入图的节点类型是路由器,它将向自己的邻居节点继续广播包含DODAG信息的DIO消息。
如果新加入图的节点是“叶子节点”,则只是完成入网动作,不广播DIO消息。
邻居节点不断重复上述广播和加入动作,直至到达网络的所有叶子节点。
每个节点都有一条路径由指向自己的父节点,通过将数据消息发给父节点,最终就能到达根节点。
然后来说实现为P2MP构造的从根节点出发的下行路径,下行路由的构造通过DAO消息来完成。
每个节点加入DODAG后,在网络发起上行路径构造指令后,将发送DAO消息到它的父节点。
DAO消息中含有前缀、前缀的有效时间等信息,用于表征节点所在前缀的可达性。
当一个节点收到DAO消息后,将对前缀信息进行处理,并在路由表中添加路由表项。
然后将该前缀信息进一步通过DAO上传给自己的父节点。
一个节点也可以将收到的前缀可达性信息进行汇集后,再发给自己的父节点。
前缀上传过程一直进行,直至前缀信息到达父节点。
每个节点都完成前缀上传后,整个网络将建立起一个从根节点到达所有叶子节点的下行路由图。
2.1.2环路避免的机制
RPL采用两种策略避免环的出现,这些方法都用到rank值。
策略1:
最大深度策略,一个节点在邻居中选择父节点时,不能选择rank值比它自己的rank
值大一定程度的节点,即rank值超过node-rank+max_depth的节点,不能选择
作为父节点。
至于超过多少深度才不能选择(max_depth的大小),由根节点确定。
这种策略主要是防止选比自己还深的节点作为父节点。
策略2:
一个节点不能过度贪婪(greedy),不能为了增加父节点数,而移动自己在图中的深度,使深度值加大。
2.1.3涓流机制
大多数路由协议,都需要设计周期性的keepalive帧,保证路由表的更新和维护。
在LLN中,需周期性的发送DIO等消息,而周期性的更新会导致过多的控制开销,浪费能量。
所以RPL采用了一种自适应的定时器机制,称为trickletimer。
这种机制用来控制DIO消息发送的频率。
trickletimer机制将图的更新视为一致性问题,使用trickletimer来决定何时组播DIO消息。
trickletimer有个初始值,当网络趋于稳定时,trickletimer的周期会逐渐变大,相应的,网络中DIO消息发送的频率会减少。
当网络发生一些“不一致”事件时,trickletimer的值又会恢复到初始值,DIO消息的发送就会比较频繁。
这些事件有:
节点检测到环路、节点新入网、节点发生了移动,采用了trickletimer机制后,当网络越来越稳定的时候,RPL控制报文会逐渐减少;
而当网络出现问题时,控制报文发送的频率又会显著增加,保障网络及时通过控制报文快速修复问题。
2.2基于Contiki平台的RPL路由协议仿真
我利用了Contiki平台上的cooja对RPL路由协议进行仿真,下面为仿真过程:
(1)打开cooja,新建一个模拟器。
图2.1新建模拟器
(2)加入根节点和叶子节点。
图2.2加入节点
(3)创建成功后,便能出现如下画面,其中ID1为根节点,其他为叶子节点,按下simulationcontrol的start键,便开始DODAG图的构造。
图2.3开始仿真
重庆邮电大学本科课程设计报告第三章个人设计工作(或系统仿真分析)
第三章个人设计工作(或系统仿真分析)
3.1DODAG图构建分析
我对icmp6.c中的打印函数进行修改,使得整个DODAG图的构建过程能够清楚地显示出来。
(1)上行路径的构建:
从打印信息可清楚地看出构建上行路径的过程,根节点利用DIO消息广播DODAG的信息;
图3.1上行路径构建
(2)下行路径的构建:
下行路由的构造通过DAO消息来完成。
图3.2下行路径构建
(3)最终DODAG图的建立
图3.3建立DODAG图
3.2能耗的分析
我对节点分布较分散的情况和节点较密集的情况进行了仿真,结果显示,节点较密集的时候在拓扑建立的过程中能耗较高且较为均衡。
另外,我发现在第一种情况的仿真过程中,连接多条路径的节点都会消耗更多的能量,结果如图所示。
图3.4不同节点分布情况的示意图
图3.5情况1的节点能耗示意图
图3.6情况2的节点能耗示意图
3.3涓流机制
下图为节点的DIO消息发送间隔统计图,横轴代表网络运行时间,纵轴代表DIO消息的发送间隔,从图中可以看出涓流机制的工作原理。
初始的DIO发送间隔是区间内的随机数,节点收到一致的DIO消息后,DIO发送间隔在原来的基础上翻倍,图中呈现出阶梯型增长的趋势。
随着网络的稳定,信道中的控制消息数据包数量大大减少。
如图所示就是节点10发生了位置的移动,导致其DIO消息的发送间隔时间又回到初始值。
图3.7涓流机制示意图
3.4其他参数修改:
(1)在collect-commmon.c中Line053:
#definePERIOD60改为30,修改过后使用collect-view工具进行数据收集的时间提前,可以在开始后30秒的时候看到收集到的个节点的信息。
方便我们对RPL的性能进行分析。
(2)在rpl-conf.hLine148:
#defineRPL_DIO_INTERVAL_MIN12改为10,使DIO消息发送间隔变为10秒,加快节点发送消息的速度。
重庆邮电大学本科课程设计报告第四章设计总结
第四章设计总结
这次课程设计我进行了对RPL路由协议的仿真,感觉获益良多,在这里总结一下这次课程设计的收获与感受。
前段时间我们在物联网系统设计的课堂上才刚刚学习了RPL路由协议的相关知识,而这次则对此进行了一次实践,进一步加深了对此的理解。
从仿真的过程中,可以直观地看到DODAG的构建过程,直观地看到上行路径到根节点和下行路径的构建。
在icmp6.c中有一段代码直观地描述了避免环路的机制。
通过实际操作了解到了涓流机制的实质。
另外,通过这次课程设计,也开拓了我的视野,使我有了第一次的机会对windows以外的操作系统进行操作,了解到了makefile的一些规则以及Linux的一些命令。
另外,这次设计对我C语言学习的帮助是巨大的,在啃代码,提高看代码的能力的同时,还能加深对RPL协议的理解,可谓是一举两得。
我也希望自己在后续学习中去补足自己在这次课程设计所发现的一些问题,继续提高自己读写代码的能力,为日后学习工作打下一个良好的基础。
重庆邮电大学本科课程设计报告参考文献
参考文献
[1]郭梯云,邬国扬,李建东.移动通信[M].西安:
西安电子科技大学出版社,2001.
[2]董晓芳,孙岩,陈仁贵等.自行研制仪器设备的规范化管理〔J〕.实验技术与管理,2007,24﹝5﹞:
163-165
[3]孙利民,李建中.无线传感器网络[M].北京:
清华大学出版社,2005.
[4]李振强.IPV6技术解密[M].北京.人民邮电出版社,2006.
重庆邮电大学本科课程设计报告附录
附录
Leaf.c:
PROCESS_THREAD(rpl_leaf_process,ev,data){
staticstructetimerperiodic;
/*定义etimer周期性定时器*/
staticstructctimerbackoff_timer;
/*定义ctimer补偿定时器*/
PROCESS_BEGIN();
PROCESS_PAUSE();
set_global_address();
printf("
UDPLEAFIPADDRESS:
"
);
print_local_addresses();
leaf_connection=udp_new(NULL,UIP_HTONS(UDP_LEAF_PORT),NULL);
if(leaf_connection==NULL){
PRINTF("
FailtomakeUDPconnection,exitingtheprocess!
\n"
PROCESS_EXIT();
}
udp_bind(leaf_connection,UIP_HTONS(UDP_LEAF_PORT));
Createdaconnectionwiththeroot"
PRINT6ADDR(&
leaf_connection->
ripaddr);
local/remoteport%u/%u\n"
UIP_HTONS(leaf_connection->
lport),UIP_HTONS(leaf_connection->
rport));
etimer_set(&
periodic,SEND_INTERVAL);
/*设置etimer定时器,定时时长为SEND_INTERVAL*/
/*
*etimer:
定时器期满,发送事件
*ctimer:
定时器期满,调用函数
*rtimer:
实时时钟,在一个精确的时间调用函数
*/
while
(1){
PROCESS_YIELD();
if(ev==tcpip_event){
tcpip_handler();
if(etimer_expired(&
periodic)){
etimer_reset(&
periodic);
ctimer_set(&
backoff_timer,SEND_TIME,send_packet,NULL);
PROCESS_END();
}
Root.c:
PROCESS_THREAD(udp_root_precess,ev,data){
uip_ipaddr_tipaddr;
structuip_ds6_addr*root_if;
SENSORS_ACTIVATE(button_sensor);
UDProotstarted\n"
#ifUIP_CONF_ROUTER
uip_ip6addr(&
ipaddr,0xaaaa,0,0,0,0,0,0,0xbbbb);
/*构造ipv6地址*/
/*uip_ds6_set_addr_iid(&
ipaddr,&
uip_lladdr);
uip_ds6_addr_add(&
ipaddr,0,ADDR_MANUAL);
root_if=uip_ds6_addr_lookup(&
ipaddr);
if(root_if!
=NULL){
rpl_dag_t*dag;
*rpl_set_root(uint8_tinstance_id,uip_ipaddr_t*dag_id)
*0x2a,42
*/
dag=rpl_set_root(0x2a,(uip_ip6addr_t*)&
NETSTACK_RDC.off
(1);
/*
*udp_new(constuip_ipaddr_t*ripaddr,uint16_tport,void*appstate)
*returnc
*structuip_udp_conn*c
root_connection=udp_new(NULL,UIP_HTONS(UDP_LEAF_PORT),NULL);
/*建立新的udp*/
udp_bind(root_connection,UIP_HTONS(UDP_ROOT_PORT));
/*绑定端口号*/
Createdarootconnectionwithremoteaddress"
root_connection->
/*打印远端地址*/
/*打印本地和远程的端口号*/
UIP_HTONS(root_connection->
lport),
UIP_HTONS(root_connection->
}elseif(ev==sensors_event&
&
data==&
button_sensor){
Initiaingglobalrepair\n"
*rpl_repair_root(uint8_tinstance_id)
*全局修复
*实例ID,0x2a
rpl_repair_root(0x2a);
}
PROCESS_END();