上一篇文章使用了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)
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
}
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){}
}
}
需要注意一下,这是判断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;默默的打开串口助手进行查看