TSCH port for Zolertia ReMote/Zoul.
This commit is contained in:
parent
10cd17b626
commit
373fda46f7
|
@ -37,6 +37,7 @@ It has been tested on the following platforms:
|
||||||
* Tmote Sky (`sky`, tested on hardware and in cooja)
|
* Tmote Sky (`sky`, tested on hardware and in cooja)
|
||||||
* Zolertia Z1 (`z1`, tested in cooja only)
|
* Zolertia Z1 (`z1`, tested in cooja only)
|
||||||
* CC2538DK (`cc2538dk`, tested on hardware)
|
* CC2538DK (`cc2538dk`, tested on hardware)
|
||||||
|
* Zolertia Zoul (`zoul`, tested on hardware)
|
||||||
|
|
||||||
This implementation was present at the ETSI Plugtest
|
This implementation was present at the ETSI Plugtest
|
||||||
event in Prague in July 2015, and did successfully inter-operate with all
|
event in Prague in July 2015, and did successfully inter-operate with all
|
||||||
|
@ -77,7 +78,7 @@ Orchestra is implemented in:
|
||||||
|
|
||||||
A simple TSCH+RPL example is included under `examples/ipv6/rpl-tsch`.
|
A simple TSCH+RPL example is included under `examples/ipv6/rpl-tsch`.
|
||||||
To use TSCH, first make sure your platform supports it.
|
To use TSCH, first make sure your platform supports it.
|
||||||
Currently, `jn516x`, `sky`, `z1` and `cc2538dk` are the supported platforms.
|
Currently, `jn516x`, `sky`, `z1`, `cc2538dk` and `zoul` are the supported platforms.
|
||||||
To add your own, we refer the reader to the next section.
|
To add your own, we refer the reader to the next section.
|
||||||
|
|
||||||
To add TSCH to your application, first include the TSCH module from your makefile with:
|
To add TSCH to your application, first include the TSCH module from your makefile with:
|
||||||
|
@ -163,7 +164,7 @@ Finally, one can also implement his own scheduler, centralized or distributed, b
|
||||||
## Porting TSCH to a new platform
|
## Porting TSCH to a new platform
|
||||||
|
|
||||||
Porting TSCH to a new platform requires a few new features in the radio driver, a number of timing-related configuration paramters.
|
Porting TSCH to a new platform requires a few new features in the radio driver, a number of timing-related configuration paramters.
|
||||||
The easiest is probably to start from one of the existing port: `jn516x`, `sky`, `z1`, `cc2538dk`.
|
The easiest is probably to start from one of the existing port: `jn516x`, `sky`, `z1`, `cc2538dk`, `zoul`.
|
||||||
|
|
||||||
### Radio features required for TSCH
|
### Radio features required for TSCH
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ print_network_status(void)
|
||||||
uip_ds6_route_t *route;
|
uip_ds6_route_t *route;
|
||||||
|
|
||||||
PRINTA("--- Network status ---\n");
|
PRINTA("--- Network status ---\n");
|
||||||
|
|
||||||
/* Our IPv6 addresses */
|
/* Our IPv6 addresses */
|
||||||
PRINTA("- Server IPv6 addresses:\n");
|
PRINTA("- Server IPv6 addresses:\n");
|
||||||
for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
|
for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
|
||||||
|
@ -83,13 +83,13 @@ print_network_status(void)
|
||||||
PRINTA("\n");
|
PRINTA("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Our default route */
|
/* Our default route */
|
||||||
PRINTA("- Default route:\n");
|
PRINTA("- Default route:\n");
|
||||||
default_route = uip_ds6_defrt_lookup(uip_ds6_defrt_choose());
|
default_route = uip_ds6_defrt_lookup(uip_ds6_defrt_choose());
|
||||||
if(default_route != NULL) {
|
if(default_route != NULL) {
|
||||||
PRINTA("-- ");
|
PRINTA("-- ");
|
||||||
uip_debug_ipaddr_print(&default_route->ipaddr);;
|
uip_debug_ipaddr_print(&default_route->ipaddr);
|
||||||
PRINTA(" (lifetime: %lu seconds)\n", (unsigned long)default_route->lifetime.interval);
|
PRINTA(" (lifetime: %lu seconds)\n", (unsigned long)default_route->lifetime.interval);
|
||||||
} else {
|
} else {
|
||||||
PRINTA("-- None\n");
|
PRINTA("-- None\n");
|
||||||
|
@ -104,9 +104,9 @@ print_network_status(void)
|
||||||
PRINTA(" via ");
|
PRINTA(" via ");
|
||||||
uip_debug_ipaddr_print(uip_ds6_route_nexthop(route));
|
uip_debug_ipaddr_print(uip_ds6_route_nexthop(route));
|
||||||
PRINTA(" (lifetime: %lu seconds)\n", (unsigned long)route->state.lifetime);
|
PRINTA(" (lifetime: %lu seconds)\n", (unsigned long)route->state.lifetime);
|
||||||
route = uip_ds6_route_next(route);
|
route = uip_ds6_route_next(route);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRINTA("----------------------\n");
|
PRINTA("----------------------\n");
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -134,16 +134,23 @@ PROCESS_THREAD(node_process, ev, data)
|
||||||
PROCESS_BEGIN();
|
PROCESS_BEGIN();
|
||||||
|
|
||||||
/* 3 possible roles:
|
/* 3 possible roles:
|
||||||
* - role_6ln: simple node, will join any network, secured or not
|
* - role_6ln: simple node, will join any network, secured or not
|
||||||
* - role_6dr: DAG root, will advertise (unsecured) beacons
|
* - role_6dr: DAG root, will advertise (unsecured) beacons
|
||||||
* - role_6dr_sec: DAG root, will advertise secured beacons
|
* - role_6dr_sec: DAG root, will advertise secured beacons
|
||||||
* */
|
* */
|
||||||
static int is_coordinator = 0;
|
static int is_coordinator = 0;
|
||||||
static enum { role_6ln, role_6dr, role_6dr_sec } node_role;
|
static enum { role_6ln, role_6dr, role_6dr_sec } node_role;
|
||||||
node_role = role_6ln;
|
node_role = role_6ln;
|
||||||
|
|
||||||
/* Set node with ID == 1 as coordinator, convenient in Cooja. */
|
/* Set node with MAC address c1:0c:00:00:00:00:01 as coordinator,
|
||||||
if(node_id == 1) {
|
* convenient in cooja for regression tests using z1 nodes
|
||||||
|
* */
|
||||||
|
|
||||||
|
#ifdef CONTIKI_TARGET_Z1
|
||||||
|
extern unsigned char node_mac[8];
|
||||||
|
unsigned char coordinator_mac[8] = { 0xc1, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
|
||||||
|
|
||||||
|
if(memcmp(node_mac, coordinator_mac, 8) == 0) {
|
||||||
if(LLSEC802154_ENABLED) {
|
if(LLSEC802154_ENABLED) {
|
||||||
node_role = role_6dr_sec;
|
node_role = role_6dr_sec;
|
||||||
} else {
|
} else {
|
||||||
|
@ -152,6 +159,7 @@ PROCESS_THREAD(node_process, ev, data)
|
||||||
} else {
|
} else {
|
||||||
node_role = role_6ln;
|
node_role = role_6ln;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CONFIG_VIA_BUTTON
|
#if CONFIG_VIA_BUTTON
|
||||||
{
|
{
|
||||||
|
@ -162,8 +170,8 @@ PROCESS_THREAD(node_process, ev, data)
|
||||||
|
|
||||||
while(!etimer_expired(&et)) {
|
while(!etimer_expired(&et)) {
|
||||||
printf("Init: current role: %s. Will start in %u seconds. Press user button to toggle mode.\n",
|
printf("Init: current role: %s. Will start in %u seconds. Press user button to toggle mode.\n",
|
||||||
node_role == role_6ln ? "6ln" : (node_role == role_6dr) ? "6dr" : "6dr-sec",
|
node_role == role_6ln ? "6ln" : (node_role == role_6dr) ? "6dr" : "6dr-sec",
|
||||||
CONFIG_WAIT_TIME);
|
CONFIG_WAIT_TIME);
|
||||||
PROCESS_WAIT_EVENT_UNTIL(((ev == sensors_event) &&
|
PROCESS_WAIT_EVENT_UNTIL(((ev == sensors_event) &&
|
||||||
(data == &button_sensor) && button_sensor.value(0) > 0)
|
(data == &button_sensor) && button_sensor.value(0) > 0)
|
||||||
|| etimer_expired(&et));
|
|| etimer_expired(&et));
|
||||||
|
@ -180,7 +188,7 @@ PROCESS_THREAD(node_process, ev, data)
|
||||||
#endif /* CONFIG_VIA_BUTTON */
|
#endif /* CONFIG_VIA_BUTTON */
|
||||||
|
|
||||||
printf("Init: node starting with role %s\n",
|
printf("Init: node starting with role %s\n",
|
||||||
node_role == role_6ln ? "6ln" : (node_role == role_6dr) ? "6dr" : "6dr-sec");
|
node_role == role_6ln ? "6ln" : (node_role == role_6dr) ? "6dr" : "6dr-sec");
|
||||||
|
|
||||||
tsch_set_pan_secured(LLSEC802154_ENABLED && (node_role == role_6dr_sec));
|
tsch_set_pan_secured(LLSEC802154_ENABLED && (node_role == role_6dr_sec));
|
||||||
is_coordinator = node_role > role_6ln;
|
is_coordinator = node_role > role_6ln;
|
||||||
|
@ -192,19 +200,19 @@ PROCESS_THREAD(node_process, ev, data)
|
||||||
} else {
|
} else {
|
||||||
net_init(NULL);
|
net_init(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WITH_ORCHESTRA
|
#if WITH_ORCHESTRA
|
||||||
orchestra_init();
|
orchestra_init();
|
||||||
#endif /* WITH_ORCHESTRA */
|
#endif /* WITH_ORCHESTRA */
|
||||||
|
|
||||||
/* Print out routing tables every minute */
|
/* Print out routing tables every minute */
|
||||||
etimer_set(&et, CLOCK_SECOND * 60);
|
etimer_set(&et, CLOCK_SECOND * 60);
|
||||||
while(1) {
|
while(1) {
|
||||||
print_network_status();
|
print_network_status();
|
||||||
PROCESS_YIELD_UNTIL(etimer_expired(&et));
|
PROCESS_YIELD_UNTIL(etimer_expired(&et));
|
||||||
etimer_reset(&et);
|
etimer_reset(&et);
|
||||||
}
|
}
|
||||||
|
|
||||||
PROCESS_END();
|
PROCESS_END();
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -77,6 +77,14 @@ typedef uint32_t rtimer_clock_t;
|
||||||
#define RTIMER_CLOCK_DIFF(a, b) ((int32_t)((a) - (b)))
|
#define RTIMER_CLOCK_DIFF(a, b) ((int32_t)((a) - (b)))
|
||||||
/** @} */
|
/** @} */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#define TSCH_CONF_HW_FRAME_FILTERING 0
|
||||||
|
|
||||||
|
/* 352us from calling transmit() until the SFD byte has been sent */
|
||||||
|
#define RADIO_DELAY_BEFORE_TX ((unsigned)US_TO_RTIMERTICKS(352))
|
||||||
|
/* 192us as in datasheet but ACKs are not always received, so adjusted to 250us */
|
||||||
|
#define RADIO_DELAY_BEFORE_RX ((unsigned)US_TO_RTIMERTICKS(250))
|
||||||
|
#define RADIO_DELAY_BEFORE_DETECT 0
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
* \name Serial Boot Loader Backdoor configuration
|
* \name Serial Boot Loader Backdoor configuration
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue