Added bursts support in CSMA/ContikiMAC, and CFS-swapping in

queuebuf. Exemplified in examples/udp-stream.
This commit is contained in:
simonduq 2011-09-27 16:05:30 +02:00
parent 5b1d9617c4
commit dd8576830e
19 changed files with 1197 additions and 285 deletions

View file

@ -0,0 +1,14 @@
all: udp-stream
APPS = servreg-hack
CONTIKI = ../..
ifndef TARGET
TARGET = sky
endif
WITH_UIP6 = 1
UIP_CONF_IPV6 = 1
CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\"
SMALL = 1
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1,21 @@
This is an example of bursts support in CSMA/ContikiMAC,
together with storage of long packet queue in CFS. This
is useful to support large fragmented UDP datagrams or
continuous data streaming. The current implementation
is a simplified version of the techniques presented in
"Lossy Links, Low Power, High Throughput", published in
the proceeding of ACM SenSys 2011.
In this example, node with ID==5 sends bursts of UDP
datagrams to node with ID==1, the root of the RPL dodag.
Testing in cooja:
$make TARGET=cooja udp-stream.csc
Testing on Tmote sky:
1) set node IDs to different motes so node 5 sends to
node 1 (using examples/sky-shell)
2) compile and program:
$make TARGET=sky udp-stream.upload
3) monitor motes with:
$make login MOTE=xxx

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: project-conf.h,v 1.1 2010/10/28 13:11:08 simonduq Exp $
*/
#ifndef __PROJECT_H__
#define __PROJECT_H__
/* Free some code and RAM space */
#define UIP_CONF_TCP 0
#undef UIP_CONF_DS6_NBR_NBU
#define UIP_CONF_DS6_NBR_NBU 12
#undef UIP_CONF_DS6_ROUTE_NBU
#define UIP_CONF_DS6_ROUTE_NBU 12
/* The total number of queuebuf */
#undef QUEUEBUF_CONF_NUM
#define QUEUEBUF_CONF_NUM 140
/* The number of queuebuf actually stored in RAM. If
not set or equal to the total number of queuebuf,
swapping is disabled, and CFS not linked. */
#define QUEUEBUFRAM_CONF_NUM 2
/* Set a large (1 sector) default size for coffee files. */
#define COFFEE_CONF_DYN_SIZE (COFFEE_SECTOR_SIZE - COFFEE_PAGE_SIZE + 1)
#endif /* __PROJECT_H__ */

View file

@ -0,0 +1,204 @@
/*
* Copyright (c) 2006, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: hello-world.c,v 1.1 2006/10/02 21:46:46 simonduq Exp $
*/
/**
* \file
* An example sending a UDP stream
* \author
* Simon Duquennoy <simonduq@sics.se>
*/
#include "contiki.h"
#include "contiki-net.h"
#include "uip.h"
#include "net/rpl/rpl.h"
#include "node-id.h"
#include "servreg-hack.h"
#include "cfs/cfs.h"
#include "cfs/cfs-coffee.h"
#define SINK_ID 1
#define SENDER_ID 5
#define DATASIZE 73
#define STREAMLEN QUEUEBUF_CONF_NUM
#define UDP_PORT 9876
#define SERVICE_ID 190
struct msg {
uint8_t streamno;
uint8_t seqno;
uint8_t buf[DATASIZE];
};
static struct simple_udp_connection unicast_connection;
/*---------------------------------------------------------------------------*/
PROCESS(udpstream_process, "UDP Stream Process");
AUTOSTART_PROCESSES(&udpstream_process);
/*---------------------------------------------------------------------------*/
static uip_ipaddr_t *
set_global_address(void)
{
static uip_ipaddr_t ipaddr;
int i;
uint8_t state;
uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF);
printf("IPv6 addresses: ");
for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
state = uip_ds6_if.addr_list[i].state;
if(uip_ds6_if.addr_list[i].isused &&
(state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) {
uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr);
printf("\n");
}
}
return &ipaddr;
}
/*---------------------------------------------------------------------------*/
static void
create_rpl_dag(uip_ipaddr_t *ipaddr)
{
struct uip_ds6_addr *root_if;
root_if = uip_ds6_addr_lookup(ipaddr);
if(root_if != NULL) {
rpl_dag_t *dag;
uip_ipaddr_t prefix;
rpl_set_root(ipaddr);
dag = rpl_get_dag(RPL_ANY_INSTANCE);
uip_ip6addr(&prefix, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
rpl_set_prefix(dag, &prefix, 64);
printf("created a new RPL dag\n");
} else {
printf("failed to create a new RPL DAG\n");
}
}
/*---------------------------------------------------------------------------*/
static void
receiver(struct simple_udp_connection *c,
const uip_ipaddr_t *sender_addr,
uint16_t sender_port,
const uip_ipaddr_t *receiver_addr,
uint16_t receiver_port,
const uint8_t *data,
uint16_t datalen)
{
static int cpt;
cpt++;
if(cpt%128==0) {
printf("Received %d datagrams\n", cpt);
}
}
/*---------------------------------------------------------------------------*/
static void
send_stream(uip_ipaddr_t *addr, uint16_t streamno)
{
int i;
int seqno = 0;
struct msg msg;
memset(&msg, 0xaa, sizeof(msg));
msg.streamno = streamno;
for(i=0; i<STREAMLEN; i++) {
msg.seqno = ++seqno;
simple_udp_sendto(&unicast_connection, (char*)&msg, sizeof(msg), addr);
}
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(udpstream_process, ev, data)
{
static uint16_t streamno;
static struct etimer et;
static uip_ipaddr_t *ipaddr;
PROCESS_BEGIN();
PROCESS_PAUSE();
printf("Formatting Coffee FS...\n");
cfs_coffee_format();
printf("done.\n");
/* We need re-initialize queuebuf after formatting */
queuebuf_init();
/* Start service registration */
servreg_hack_init();
ipaddr = set_global_address();
if(node_id == SINK_ID) {
/* The sink creates a dag and waits for UDP datagrams */
create_rpl_dag(ipaddr);
servreg_hack_register(SERVICE_ID, ipaddr);
simple_udp_register(&unicast_connection, UDP_PORT,
NULL, UDP_PORT, receiver);
while(1) {
PROCESS_WAIT_EVENT();
}
} else if(node_id == SENDER_ID) {
/* The sender looks for the sink and sends UDP streams */
ipaddr = NULL;
simple_udp_register(&unicast_connection, UDP_PORT,
NULL, UDP_PORT, receiver);
etimer_set(&et, 10*CLOCK_SECOND);
etimer_restart(&et);
while(1) {
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
if(ipaddr != NULL) {
streamno++;
send_stream(ipaddr, streamno);
} else {
ipaddr = servreg_hack_lookup(SERVICE_ID);
if(ipaddr != NULL) {
etimer_set(&et, 2*CLOCK_SECOND);
printf("Streaming to ");
uip_debug_ipaddr_print(ipaddr);
printf("\n");
} else {
printf("Service %d not found\n", SERVICE_ID);
}
}
etimer_restart(&et);
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,182 @@
<?xml version="1.0" encoding="UTF-8"?>
<simconf>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/mspsim</project>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/serial_socket</project>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/mrm</project>
<simulation>
<title>UDP Stream Example</title>
<delaytime>0</delaytime>
<randomseed>123456</randomseed>
<motedelay_us>1000000</motedelay_us>
<radiomedium>
se.sics.cooja.radiomediums.UDGM
<transmitting_range>50.0</transmitting_range>
<interference_range>100.0</interference_range>
<success_ratio_tx>1.0</success_ratio_tx>
<success_ratio_rx>1.0</success_ratio_rx>
</radiomedium>
<events>
<logoutput>40000</logoutput>
</events>
<motetype>
se.sics.cooja.mspmote.SkyMoteType
<identifier>mote</identifier>
<description>mote</description>
<source EXPORT="discard">[CONTIKI_DIR]/examples/udp-stream/udp-stream.c</source>
<commands EXPORT="discard">make udp-stream.sky TARGET=sky</commands>
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/udp-stream/udp-stream.sky</firmware>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.interfaces.IPAddress</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspClock</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspMoteID</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyButton</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyFlash</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyByteRadio</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspSerial</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyLED</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
</motetype>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>33.260163187353555</x>
<y>30.643217359962595</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>1</id>
</interface_config>
<motetype_identifier>mote</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>70.87477363740156</x>
<y>31.656474063135494</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>2</id>
</interface_config>
<motetype_identifier>mote</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>112.33402646502834</x>
<y>47.18506616257089</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>3</id>
</interface_config>
<motetype_identifier>mote</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>132.53950850661624</x>
<y>78.99637996219282</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>4</id>
</interface_config>
<motetype_identifier>mote</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>136.72844990548202</x>
<y>114.94735349716447</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>5</id>
</interface_config>
<motetype_identifier>mote</motetype_identifier>
</mote>
</simulation>
<plugin>
se.sics.cooja.plugins.SimControl
<width>259</width>
<z>4</z>
<height>178</height>
<location_x>0</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.Visualizer
<plugin_config>
<skin>se.sics.cooja.plugins.skins.IDVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.UDGMVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.AttributeVisualizerSkin</skin>
<viewport>1.2465387687077096 0.0 0.0 1.2465387687077096 22.99764760264848 12.704392736072247</viewport>
</plugin_config>
<width>257</width>
<z>3</z>
<height>297</height>
<location_x>0</location_x>
<location_y>180</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.LogListener
<plugin_config>
<filter />
<coloring />
</plugin_config>
<width>568</width>
<z>2</z>
<height>663</height>
<location_x>257</location_x>
<location_y>-2</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.RadioLogger
<plugin_config>
<split>449</split>
<analyzers name="6lowpan" />
</plugin_config>
<width>605</width>
<z>1</z>
<height>661</height>
<location_x>824</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.TimeLine
<plugin_config>
<mote>0</mote>
<mote>1</mote>
<mote>2</mote>
<mote>3</mote>
<mote>4</mote>
<showRadioRXTX />
<showRadioHW />
<split>125</split>
<zoomfactor>100000.0</zoomfactor>
</plugin_config>
<width>1429</width>
<z>0</z>
<height>141</height>
<location_x>1</location_x>
<location_y>661</location_y>
</plugin>
</simconf>