CC2538之TinyOS例程实验:8-RPL(roll)路由实验

上一篇文章使用了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 as MilliTimer;
    interface Timer 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;默默的打开串口助手进行查看




你可能感兴趣的:(cc2538,tinyos,TinyOS例程实验)