上一篇文章使用了BLIP,本次的例程正是需要依赖BLIP栈,后面的网络实验也都需要BLIP
视频第十四部也做了RPL实验,关于RPL路由不做概念讲解,可以去百度网盘文档区或者IETF官网进行学习
例程目录:
tinyos-main-release_tinyos_2_1_2\apps\cc2538_Test\TestRPL\udp
源码还是官方的例程源码
Makefile文件:
- COMPONENT=TestRPLAppC
-
- CFLAGS += -DUSE_TIMER_HANDLER
- #CFLAGS += -DUSE_UART_HANDLER
- CFLAGS += -DUSE_RF_HANDLER
- CFLAGS += -DNOT_USE_PRINTFC_BUT_USE_PRINT
-
- # NB :
- # DEFAULT_LOCAL_GROUP=0xabcd
-
- # radio settings
- CFLAGS+=-DCC2420_DEF_CHANNEL=25
- CFLAGS+=-DCC2520_DEF_CHANNEL=25
-
- ################################################################################
- ### Set the addressing scheme
- ################################################################################
-
- # Use IN6_PREFIX with static addressing modes
- PFLAGS += -DIN6_PREFIX=\"aaaa::/64\"
- # Use BLIP Neighbor Discovery to autoconfigure an address
- PFLAGS += -DBLIP_ADDR_AUTOCONF=0
- # Use RPL and prefix information in DIO messages to autoconfigure an address
- PFLAGS += -DRPL_ADDR_AUTOCONF=0
-
- ################################################################################
- ### Configure BLIP
- ################################################################################
-
- # Configure the Neighbor Discovery mechanism
- PFLAGS += -DBLIP_SEND_ROUTER_SOLICITATIONS=0
- PFLAGS += -DBLIP_SEND_ROUTER_ADVERTISEMENTS=0
-
- # Configure the number of times BLIP tries to send a packet and how long it
- # waits between attempts
- PFLAGS += -DBLIP_L2_RETRIES=3
- PFLAGS += -DBLIP_L2_DELAY=103
-
- # Configure how many of the 6LoWPAN headers we support
- #PFLAGS += -DLIB6LOWPAN_FULL=1
-
- # Configure the header compression for 6LoWPAN
- PFLAGS += -DLIB6LOWPAN_HC_VERSION=6
-
- # Keep statistics about various BLIP/IPv6 parameters. See BlipStatistics.h
- #PFLAGS += -DBLIP_STATS
- #PFLAGS += -DBLIP_STATS_IP_MEM
-
- ################################################################################
- ### Configure RPL
- ################################################################################
-
- # Include the RPL layer if set to 1
- PFLAGS += -DRPL_ROUTING=1
-
- # If set keep routing information in each node. If not the root must keep all
- # routing information.
- PFLAGS += -DRPL_STORING_MODE=1
-
- # Choose the objective function RPL should use
- PFLAGS += -DRPL_OF_0=1
- PFLAGS += -DRPL_OF_MRHOF=0
-
- ################################################################################
- ### Configure LPL
- ################################################################################
-
- #PFLAGS += -DLOW_POWER_LISTENING
- #PFLAGS += -DLPL_SLEEP_INTERVAL=512
- #PFLAGS += -DLPL_DEF_LOCAL_WAKEUP=512
- #PFLAGS += -DLPL_DEF_REMOTE_WAKEUP=512
-
- ################################################################################
- ### Configure printf() output
- ################################################################################
-
- PFLAGS += -DNEW_PRINTF_SEMANTICS -DPRINTFUART_ENABLED -DPRINTF_BUFFER_SIZE=1024
-
- ################################################################################
- ### Configure this application
- ################################################################################
-
- # 5 second packet generation interval
- CFLAGS+=-DPACKET_INTERVAL=5120UL
-
- CFLAGS+=-DRPL_ROOT_ADDR=11
-
-
- # enable printf
- CFLAGS += -DNEW_PRINTF_SEMANTICS -DPRINTFUART_ENABLED -DPRINTF_BUFFER_SIZE=1024
-
- include $(MAKERULES)
突然发现Makefile内容多了不少,本质都是一些网络参数;需要注意的是
CFLAGS+=-DRPL_ROOT_ADDR=11 设定RPL路由的root节点地址是11;回忆上一部帖子介绍;至少我们需要编译这么一个节点了make cc2538cb blip id.11;
TestRPLAppC.nc文件:
- #include "TestRPL.h"
- #include "printf.h"
-
- /**
- * Configuration for the RadioCountToLeds application. RadioCountToLeds
- * maintains a 4Hz counter, broadcasting its value in an AM packet
- * every time it gets updated. A RadioCountToLeds node that hears a counter
- * displays the bottom three bits on its LEDs. This application is a useful
- * test to show that basic AM communication and timers work.
- *
- * @author Philip Levis
- * @date June 6 2005
- */
-
- configuration TestRPLAppC {
- }
- implementation {
- components MainC, TestRPLC as App, LedsC;
- components new TimerMilliC();
- components new TimerMilliC() as Timer;
- components RandomC;
- components RPLRankC;
- components RPLRoutingEngineC;
- components IPDispatchC;
- //components RPLForwardingEngineC;
- components RPLDAORoutingEngineC;
- components IPStackC;
- components IPProtocolsP;
-
- App.Boot -> MainC.Boot;
- App.SplitControl -> IPStackC;//IPDispatchC;
- App.Leds -> LedsC;
- App.MilliTimer -> TimerMilliC;
- App.RPLRoute -> RPLRoutingEngineC;
- App.RootControl -> RPLRoutingEngineC;
- App.RoutingControl -> RPLRoutingEngineC;
-
- components new UdpSocketC() as RPLUDP;
- App.RPLUDP -> RPLUDP;
-
- App.RPLDAO -> RPLDAORoutingEngineC;
- App.Timer -> Timer;
- App.Random -> RandomC;
-
- components StaticIPAddressC;
-
- #ifdef RPL_ROUTING
- components RPLRoutingC;
- #endif
-
- #ifdef PRINTFUART_ENABLED
-
- #endif
-
- }
哇,看着好复杂的样子,呵呵;咱们有神器YETI2;大家可以去图形化组件查看分析他
TestRPLC.nc文件:
- /*******************************************************************
- *实验6----zigbee roll路由实验
- *节点需求数 >= 2
- *编译命令make cc2538cb blip id.xx (xx为1~65533)
- ********************************************************************/
-
- #include "Timer.h"
- #include "TestRPL.h"
- #include "lib6lowpan/ip.h"
- #include "blip_printf.h"
- /**
- * Implementation of the RadioCountToLeds application. RadioCountToLeds
- * maintains a 4Hz counter, broadcasting its value in an AM packet
- * every time it gets updated. A RadioCountToLeds node that hears a counter
- * displays the bottom three bits on its LEDs. This application is a useful
- * test to show that basic AM communication and timers work.
- *
- * @author Philip Levis
- * @date June 6 2005
- */
-
- module TestRPLC @safe() {
- uses {
- interface Leds;
- interface Boot;
- interface Timer<TMilli> as MilliTimer;
- interface Timer<TMilli> as Timer;
- interface RPLRoutingEngine as RPLRoute;
- interface RootControl;
- interface StdControl as RoutingControl;
- interface SplitControl;
- //interface IP as RPL;
- interface UDP as RPLUDP;
- //interface RPLForwardingEngine;
- interface RPLDAORoutingEngine as RPLDAO;
- interface Random;
- }
- }
- implementation {
-
- #ifndef RPL_ROOT_ADDR
- #define RPL_ROOT_ADDR 1
- #endif
-
- #define UDP_PORT 5678
-
- //uint8_t payload[10];
- //struct in6_addr dest;
- struct in6_addr MULTICAST_ADDR;
-
- bool locked;
- uint16_t counter = 0;
-
- event void Boot.booted() {
- memset(MULTICAST_ADDR.s6_addr, 0, 16);
- MULTICAST_ADDR.s6_addr[0] = 0xFF;
- MULTICAST_ADDR.s6_addr[1] = 0x2;
- MULTICAST_ADDR.s6_addr[15] = 0x1A;
-
-
- if(TOS_NODE_ID == RPL_ROOT_ADDR){
- call RootControl.setRoot();
- }
- call RoutingControl.start();
- call SplitControl.start();
-
- call RPLUDP.bind(UDP_PORT);
- }
-
-
- uint32_t countrx = 0;
- uint32_t counttx = 0;
-
- event void RPLUDP.recvfrom(struct sockaddr_in6 *from, void *payload, uint16_t len, struct ip6_metadata *meta){
-
- nx_uint16_t temp[10];
- memcpy(temp, (uint8_t*)payload, len);
- call Leds.led2Toggle();
-
- printf(">>>> RX %d %d %d %lu \n", TOS_NODE_ID, temp[0], temp[9], ++countrx);
- printfflush();
- }
-
- event void SplitControl.startDone(error_t err){
- while( call RPLDAO.startDAO() != SUCCESS );
-
- if(TOS_NODE_ID != RPL_ROOT_ADDR){
- call Timer.startOneShot((call Random.rand16()%2)*2048U);
- }
- }
-
- event void Timer.fired(){
- call MilliTimer.startOneShot(PACKET_INTERVAL + (call Random.rand16() % 100));
- }
-
- task void sendTask(){
- struct sockaddr_in6 dest;
-
- nx_uint16_t temp[10];
- uint8_t i;
-
- for(i=0;i<10;i++){
- temp[i] = 0xABCD;
- }
-
- temp[0] = TOS_NODE_ID;
- temp[9] = counttx;
-
- memcpy(dest.sin6_addr.s6_addr, call RPLRoute.getDodagId(), sizeof(struct in6_addr));
-
- if(dest.sin6_addr.s6_addr[15] != 0) // destination is set as root!
- ++counttx;
-
- //if(dest.sin6_addr.s6_addr[0] == 0xAA)
- call Leds.led0Toggle();
-
- dest.sin6_port = htons(UDP_PORT);
-
- printf("Generate Packet at %d \n", TOS_NODE_ID);
- /**可以自行修改负载测试,假设是你采集的传感器数据呢******************/
- call RPLUDP.sendto(&dest, temp, 20);
- }
-
- event void MilliTimer.fired(){
- //call Leds.led1Toggle();
- call MilliTimer.startOneShot(PACKET_INTERVAL + (call Random.rand16() % 100));
- post sendTask();
- }
-
- event void SplitControl.stopDone(error_t err){}
-
- }
if(TOS_NODE_ID != RPL_ROOT_ADDR){
call Timer.startOneShot((call Random.rand16()%2)*2048U);
}
需要注意一下,这是判断root节点,根据地址,大家也应该清楚如果我要改成别的id的方法了;
代码部分不多做介绍;注意
call RPLUDP.sendto(&dest, temp, 20);部分在前面取了地址,可以自己去看看如何取的;
这个例程因为是TinyOS的官方例程,大家实验一下就行了;在以后的例程RPL路由是基础;
但是我不推荐这种写法,一般来说的写法会有组网成功事件(event),也就是路由表添加事件
推荐那种写法;
调用发包的时候如果目的地址在路由表不存在将会怎么动作呢?交给聪明的你来分析;懒死我算了,呵呵!
现在大家可以自己参考这个例程编写RPL路由的应用,使用其实本质是很简单的,不要被这一堆代码吓到!
测试的时候两个节点,假设一个是11号(root),一个是12号
输入命令make cc2538cb blip id.11烧写
输入命令make cc2538cb blip id.12烧写
至于实验结果,大家可以插上cc2538cb到PC;默默的打开串口助手进行查看