add the TSCH application-level timesync example

This commit is contained in:
Atis Elsts 2018-12-18 16:22:37 +00:00
parent 08cbbe224b
commit 99a68e84f1
4 changed files with 264 additions and 0 deletions

View File

@ -0,0 +1,24 @@
CONTIKI_PROJECT = node
all: $(CONTIKI_PROJECT)
CONTIKI=../../..
PLATFORMS_EXCLUDE = sky nrf52dk native
# force Orchestra from command line
MAKE_WITH_ORCHESTRA ?= 0
# force Security from command line
MAKE_WITH_SECURITY ?= 0
MAKE_MAC = MAKE_MAC_TSCH
MODULES += os/services/shell
ifeq ($(MAKE_WITH_ORCHESTRA),1)
MODULES += os/services/orchestra
endif
ifeq ($(MAKE_WITH_SECURITY),1)
CFLAGS += -DWITH_SECURITY=1
endif
include $(CONTIKI)/Makefile.include

View File

@ -0,0 +1,18 @@
This is a demonstration of application-level time synchronization using TSCH.
In a TSCH network, all nodes are synchronized to a global time counter maintained
by the coordinator. This fact can be exploited to measure properties such as latency.
The modes periodically send their detected network uptime to the coordinator.
The coordinator receives these packets, prints its local network uptime
and the time difference. This time difference is equal to the end-to-end latency,
which includes both the time to prepare the packet, the time until an appropriate
slot in the TSCH schedule, the over-the-air time (negligible). If the packet
does not arrive with the first attempt, it also includes the retransmission time.
The nodes in this example do not have any notion of the wall-clock time.
That would need additional synchronization between the TSCH network and an external clock source.
For example, one can periodically distribute UNIX timestamps over the UART interface
on the border router to implement this feature. Alternatively, the data collected from
the TSCH network can be timestamped with just TSCH timestamps, and them on the external gateway
these timestamps could be converted to wall-clock time.

View File

@ -0,0 +1,139 @@
/*
* Copyright (c) 2015, SICS Swedish ICT.
* Copyright (c) 2018, University of Bristol - http://www.bristol.ac.uk
* 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.
*
*/
/**
* \file
* A RPL+TSCH node demonstrating application-level time syncrhonization.
*
* \author Atis Elsts <atis.elsts@bristol.ac.uk>
* Simon Duquennoy <simonduq@sics.se>
*/
#include "contiki.h"
#include "net/routing/routing.h"
#include "net/netstack.h"
#include "net/ipv6/simple-udp.h"
#include "net/mac/tsch/tsch.h"
#include "lib/random.h"
#include "sys/node-id.h"
#include "sys/log.h"
#define LOG_MODULE "App"
#define LOG_LEVEL LOG_LEVEL_INFO
#define UDP_CLIENT_PORT 8765
#define UDP_SERVER_PORT 5678
#define SEND_INTERVAL (60 * CLOCK_SECOND)
/*---------------------------------------------------------------------------*/
static struct simple_udp_connection client_conn, server_conn;
PROCESS(node_process, "RPL Node");
AUTOSTART_PROCESSES(&node_process);
/*---------------------------------------------------------------------------*/
static void
udp_rx_callback(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)
{
uint64_t local_time_clock_ticks = tsch_get_network_uptime_ticks();
uint64_t remote_time_clock_ticks;
if(datalen >= sizeof(remote_time_clock_ticks)) {
memcpy(&remote_time_clock_ticks, data, sizeof(remote_time_clock_ticks));
LOG_INFO("Received from ");
LOG_INFO_6ADDR(sender_addr);
LOG_INFO_(", created at %lu, now %lu, latency %lu clock ticks\n",
(unsigned long)remote_time_clock_ticks,
(unsigned long)local_time_clock_ticks,
(unsigned long)(local_time_clock_ticks - remote_time_clock_ticks));
}
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(node_process, ev, data)
{
static struct etimer periodic_timer;
int is_coordinator;
uip_ipaddr_t dest_ipaddr;
PROCESS_BEGIN();
is_coordinator = 0;
#if CONTIKI_TARGET_COOJA
is_coordinator = (node_id == 1);
#endif
if(is_coordinator) {
NETSTACK_ROUTING.root_start();
}
/* Initialize UDP connections */
simple_udp_register(&server_conn, UDP_SERVER_PORT, NULL,
UDP_CLIENT_PORT, udp_rx_callback);
simple_udp_register(&client_conn, UDP_CLIENT_PORT, NULL,
UDP_SERVER_PORT, NULL);
NETSTACK_MAC.on();
etimer_set(&periodic_timer, random_rand() % SEND_INTERVAL);
while(1) {
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&periodic_timer));
if(tsch_is_coordinator) {
break;
}
if(NETSTACK_ROUTING.node_is_reachable() && NETSTACK_ROUTING.get_root_ipaddr(&dest_ipaddr)) {
/* Send network uptime timestamp to the DAG root */
uint64_t network_uptime;
network_uptime = tsch_get_network_uptime_ticks();
simple_udp_sendto(&client_conn, &network_uptime, sizeof(network_uptime), &dest_ipaddr);
LOG_INFO("Sent network uptime timestamp %lu to ", (unsigned long)network_uptime);
LOG_INFO_6ADDR(&dest_ipaddr);
LOG_INFO_("\n");
} else {
LOG_INFO("Not reachable yet\n");
}
/* Add some jitter */
etimer_set(&periodic_timer, SEND_INTERVAL
- CLOCK_SECOND + (random_rand() % (2 * CLOCK_SECOND)));
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View File

@ -0,0 +1,83 @@
/*
* Copyright (c) 2015, SICS Swedish ICT.
* Copyright (c) 2018, University of Bristol - http://www.bristol.ac.uk
* 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.
*
*/
/**
* \author Simon Duquennoy <simonduq@sics.se>
* Atis Elsts <atis.elsts@bristol.ac.uk>
*/
#ifndef __PROJECT_CONF_H__
#define __PROJECT_CONF_H__
/* Set to enable TSCH security */
#ifndef WITH_SECURITY
#define WITH_SECURITY 0
#endif /* WITH_SECURITY */
/* USB serial takes space, free more space elsewhere */
#define SICSLOWPAN_CONF_FRAG 0
#define UIP_CONF_BUFFER_SIZE 160
/*******************************************************/
/******************* Configure TSCH ********************/
/*******************************************************/
/* IEEE802.15.4 PANID */
#define IEEE802154_CONF_PANID 0x81a5
/* Do not start TSCH at init, wait for NETSTACK_MAC.on() */
#define TSCH_CONF_AUTOSTART 0
/* 6TiSCH minimal schedule length.
* Larger values result in less frequent active slots: reduces capacity and saves energy. */
#define TSCH_SCHEDULE_CONF_DEFAULT_LENGTH 3
#if WITH_SECURITY
/* Enable security */
#define LLSEC802154_CONF_ENABLED 1
#endif /* WITH_SECURITY */
/*******************************************************/
/************* Other system configuration **************/
/*******************************************************/
/* Logging */
#define LOG_CONF_LEVEL_RPL LOG_LEVEL_WARN
#define LOG_CONF_LEVEL_TCPIP LOG_LEVEL_WARN
#define LOG_CONF_LEVEL_IPV6 LOG_LEVEL_WARN
#define LOG_CONF_LEVEL_6LOWPAN LOG_LEVEL_WARN
#define LOG_CONF_LEVEL_MAC LOG_LEVEL_WARN
#define LOG_CONF_LEVEL_FRAMER LOG_LEVEL_WARN
#define TSCH_LOG_CONF_PER_SLOT 0
#endif /* __PROJECT_CONF_H__ */