From 9cd439d8c0058ba96db271d1a316e32fadbf1b21 Mon Sep 17 00:00:00 2001 From: Billy Kozak Date: Wed, 12 Aug 2015 09:51:26 -0600 Subject: [PATCH 001/374] changed tcpip static temporaries to stack vars A number of local variables in tcpip.c were declared with static storage for no good reason (they do not ever preserve state between function calls). This patch removes static declaration from these variables. --- core/net/ip/tcpip.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/core/net/ip/tcpip.c b/core/net/ip/tcpip.c index 1c75d1bc9..b827bc9ce 100644 --- a/core/net/ip/tcpip.c +++ b/core/net/ip/tcpip.c @@ -249,7 +249,7 @@ tcp_connect(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate) void tcp_unlisten(uint16_t port) { - static unsigned char i; + unsigned char i; struct listenport *l; l = s.listenports; @@ -267,7 +267,7 @@ tcp_unlisten(uint16_t port) void tcp_listen(uint16_t port) { - static unsigned char i; + unsigned char i; struct listenport *l; l = s.listenports; @@ -371,7 +371,7 @@ static void eventhandler(process_event_t ev, process_data_t data) { #if UIP_TCP - static unsigned char i; + unsigned char i; register struct listenport *l; #endif /*UIP_TCP*/ struct process *p; @@ -764,9 +764,9 @@ tcpip_uipcall(void) #if UIP_TCP { - static unsigned char i; + unsigned char i; struct listenport *l; - + /* If this is a connection request for a listening port, we must mark the connection with the right process ID. */ if(uip_connected()) { @@ -795,11 +795,11 @@ tcpip_uipcall(void) PROCESS_THREAD(tcpip_process, ev, data) { PROCESS_BEGIN(); - + #if UIP_TCP { - static unsigned char i; - + unsigned char i; + for(i = 0; i < UIP_LISTENPORTS; ++i) { s.listenports[i].port = 0; } From e544e4c5b07cceb607e4798d1234f11edc202f47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20=27Morty=27=20Str=C3=BCbe?= Date: Thu, 15 Oct 2015 10:17:07 +0200 Subject: [PATCH 002/374] Cooja: Make sure motes are always removed from the list of unintialized motes --- tools/cooja/java/org/contikios/cooja/Simulation.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/cooja/java/org/contikios/cooja/Simulation.java b/tools/cooja/java/org/contikios/cooja/Simulation.java index 18dfa7fe8..74f6ed902 100644 --- a/tools/cooja/java/org/contikios/cooja/Simulation.java +++ b/tools/cooja/java/org/contikios/cooja/Simulation.java @@ -847,6 +847,9 @@ public class Simulation extends Observable implements Runnable { } }; + //Add to list of uninitialized motes + motesUninit.add(mote); + if (!isRunning()) { /* Simulation is stopped, add mote immediately */ addMote.run(); @@ -854,8 +857,6 @@ public class Simulation extends Observable implements Runnable { /* Add mote from simulation thread */ invokeSimulationThread(addMote); } - //Add to list of uninitialized motes - motesUninit.add(mote); } From e5c7437e17a5d7b6ad78dc2cc757b86b8859c23e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Harter?= Date: Thu, 15 Oct 2015 17:11:09 +0200 Subject: [PATCH 003/374] Fix default tun/tap issue with multiple tunslip6 When running multiple tunslip6 instances, it collides with tun0 being already used (cannot open file). However, system default is already to use "tun0" and "tap0". By putting the default empty string as name, system automatically increment and selects a free interface, "tun0", "tun1". --- tools/tunslip6.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tools/tunslip6.c b/tools/tunslip6.c index 4f3ff7e3e..3dda01c66 100644 --- a/tools/tunslip6.c +++ b/tools/tunslip6.c @@ -852,14 +852,6 @@ exit(1); break; } - if(*tundev == '\0') { - /* Use default. */ - if(tap) { - strcpy(tundev, "tap0"); - } else { - strcpy(tundev, "tun0"); - } - } if(host != NULL) { struct addrinfo hints, *servinfo, *p; int rv; From fbc5b5300de430f1149606a7297acfc7e65c0cf6 Mon Sep 17 00:00:00 2001 From: Valentin Sawadski Date: Wed, 28 Oct 2015 14:58:52 +0100 Subject: [PATCH 004/374] trims resolv.c by removing unrequired static declarations Closes https://github.com/contiki-os/contiki/issues/1333 --- core/net/ip/resolv.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/core/net/ip/resolv.c b/core/net/ip/resolv.c index 0dd06104b..3cc179046 100644 --- a/core/net/ip/resolv.c +++ b/core/net/ip/resolv.c @@ -783,9 +783,9 @@ check_entries(void) static void newdata(void) { - static uint8_t nquestions, nanswers; + uint8_t nquestions, nanswers; - static int8_t i; + int8_t i; register struct namemap *namemapptr = NULL; @@ -872,7 +872,7 @@ newdata(void) } return; } else { - static uint8_t nauthrr; + uint8_t nauthrr; PRINTF("resolver: But we are still probing. Waiting...\n"); /* We are still probing. We need to do the mDNS * probe race condition check here and make sure @@ -960,7 +960,7 @@ newdata(void) #endif /* !ARCH_DOESNT_NEED_ALIGNED_STRUCTS */ #if VERBOSE_DEBUG - static char debug_name[40]; + char debug_name[40]; decode_name(queryptr, debug_name, uip_appdata); DEBUG_PRINTF("resolver: Answer %d: \"%s\", type %d, class %d, ttl %d, length %d\n", ++i, debug_name, uip_ntohs(ans->type), @@ -1266,9 +1266,9 @@ remove_trailing_dots(const char *name) { void resolv_query(const char *name) { - static uint8_t i; + uint8_t i; - static uint8_t lseq, lseqi; + uint8_t lseq, lseqi; register struct namemap *nameptr = 0; @@ -1315,7 +1315,7 @@ resolv_query(const char *name) { size_t name_len = strlen(name); - static const char local_suffix[] = "local"; + const char local_suffix[] = "local"; if((name_len > (sizeof(local_suffix) - 1)) && (0 == strcasecmp(name + name_len - (sizeof(local_suffix) - 1), local_suffix))) { @@ -1347,7 +1347,7 @@ resolv_lookup(const char *name, uip_ipaddr_t ** ipaddr) { resolv_status_t ret = RESOLV_STATUS_UNCACHED; - static uint8_t i; + uint8_t i; struct namemap *nameptr; From 0e0bf33d311528adf4e293fc73044e5af0fbcf05 Mon Sep 17 00:00:00 2001 From: Tommy Sparber Date: Tue, 3 Nov 2015 14:19:47 +1100 Subject: [PATCH 005/374] uIP Stats: Count sent ICMP6 packets The sent ICMP6 packets (for example from RPL) are currently not counted towards the sum of sent ip and icmp packets. Is there any reason behind this or is it just a bug? Looking at the code I found no side effects of adding these two lines. Debug output: ``` uip_stat.ip .recv 10 .sent 23 .forwared 0 .drop 0 uip_stat.icmp .recv 10 .sent 11 .drop 0 uip_stat.udp .recv 0 .sent 12 .drop 0 ``` (Sum of ip.sent matches icmp.sent and udp.sent) --- core/net/ipv6/uip-icmp6.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/net/ipv6/uip-icmp6.c b/core/net/ipv6/uip-icmp6.c index a9dc9e352..8f5772833 100644 --- a/core/net/ipv6/uip-icmp6.c +++ b/core/net/ipv6/uip-icmp6.c @@ -38,7 +38,7 @@ /** * \file * ICMPv6 (RFC 4443) implementation, with message and error handling - * \author Julien Abeille + * \author Julien Abeille * \author Mathilde Durvy */ @@ -313,6 +313,10 @@ uip_icmp6_send(const uip_ipaddr_t *dest, int type, int code, int payload_len) UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + payload_len; + + UIP_STAT(++uip_stat.icmp.sent); + UIP_STAT(++uip_stat.ip.sent); + tcpip_ipv6_output(); } /*---------------------------------------------------------------------------*/ From 5a440dd00319851138cbdf9f4e1c27aad2f19d8b Mon Sep 17 00:00:00 2001 From: myrfy001 Date: Tue, 17 Nov 2015 14:30:04 +0800 Subject: [PATCH 006/374] off_t changed to signed to stay the same as POSIX On many other tool chains, like TI's new MSG430-GCC, the typedef will be conflict. --- platform/sky/platform-conf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/sky/platform-conf.h b/platform/sky/platform-conf.h index f5530f3aa..a4a7300b6 100644 --- a/platform/sky/platform-conf.h +++ b/platform/sky/platform-conf.h @@ -71,7 +71,7 @@ /* Types for clocks and uip_stats */ typedef unsigned short uip_stats_t; typedef unsigned long clock_time_t; -typedef unsigned long off_t; +typedef long off_t; /* the low-level radio driver */ #define NETSTACK_CONF_RADIO cc2420_driver From 92840e7adc927ecccdf3902a66bb325702e48130 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 20 Nov 2015 19:07:20 +0100 Subject: [PATCH 007/374] Simplify uip-ds6-nbr module further when NDP is disabled. Avoids known issue https://github.com/contiki-os/contiki/issues/1380 of neighbors in non-REACHABLE state. --- core/net/ipv6/uip-ds6-nbr.c | 14 +++++++++----- core/net/ipv6/uip-ds6-nbr.h | 8 +++++--- core/net/ipv6/uip-ds6.c | 2 ++ core/net/rpl/rpl-icmp6.c | 4 ++++ core/net/rpl/rpl.c | 4 ++++ 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/core/net/ipv6/uip-ds6-nbr.c b/core/net/ipv6/uip-ds6-nbr.c index db14f8647..75e949c1b 100644 --- a/core/net/ipv6/uip-ds6-nbr.c +++ b/core/net/ipv6/uip-ds6-nbr.c @@ -84,15 +84,19 @@ uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr, uip_ds6_nbr_t *nbr = nbr_table_add_lladdr(ds6_neighbors, (linkaddr_t*)lladdr); if(nbr) { uip_ipaddr_copy(&nbr->ipaddr, ipaddr); +#if UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER nbr->isrouter = isrouter; +#endif /* UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER */ nbr->state = state; - #if UIP_CONF_IPV6_QUEUE_PKT +#if UIP_CONF_IPV6_QUEUE_PKT uip_packetqueue_new(&nbr->packethandle); - #endif /* UIP_CONF_IPV6_QUEUE_PKT */ +#endif /* UIP_CONF_IPV6_QUEUE_PKT */ +#if UIP_ND6_SEND_NA /* timers are set separately, for now we put them in expired state */ stimer_set(&nbr->reachable, 0); stimer_set(&nbr->sendns, 0); nbr->nscount = 0; +#endif /* UIP_ND6_SEND_NA */ PRINTF("Adding neighbor with ip addr "); PRINT6ADDR(ipaddr); PRINTF(" link addr "); @@ -230,6 +234,7 @@ uip_ds6_link_neighbor_callback(int status, int numtx) #endif /* UIP_DS6_LL_NUD */ } +#if UIP_ND6_SEND_NA /*---------------------------------------------------------------------------*/ void uip_ds6_neighbor_periodic(void) @@ -241,7 +246,7 @@ uip_ds6_neighbor_periodic(void) case NBR_REACHABLE: if(stimer_expired(&nbr->reachable)) { #if UIP_CONF_IPV6_RPL - /* when a neighbor leave it's REACHABLE state and is a default router, + /* when a neighbor leave its REACHABLE state and is a default router, instead of going to STALE state it enters DELAY state in order to force a NUD on it. Otherwise, if there is no upward traffic, the node never knows if the default router is still reachable. This @@ -268,7 +273,6 @@ uip_ds6_neighbor_periodic(void) #endif /* UIP_CONF_IPV6_RPL */ } break; -#if UIP_ND6_SEND_NA case NBR_INCOMPLETE: if(nbr->nscount >= UIP_ND6_MAX_MULTICAST_SOLICIT) { uip_ds6_nbr_rm(nbr); @@ -304,7 +308,6 @@ uip_ds6_neighbor_periodic(void) stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000); } break; -#endif /* UIP_ND6_SEND_NA */ default: break; } @@ -330,5 +333,6 @@ uip_ds6_get_least_lifetime_neighbor(void) } return nbr_expiring; } +#endif /* UIP_ND6_SEND_NA */ /*---------------------------------------------------------------------------*/ /** @} */ diff --git a/core/net/ipv6/uip-ds6-nbr.h b/core/net/ipv6/uip-ds6-nbr.h index 36a202e86..24e3f7aaf 100644 --- a/core/net/ipv6/uip-ds6-nbr.h +++ b/core/net/ipv6/uip-ds6-nbr.h @@ -69,12 +69,14 @@ NBR_TABLE_DECLARE(ds6_neighbors); /** \brief An entry in the nbr cache */ typedef struct uip_ds6_nbr { uip_ipaddr_t ipaddr; - struct stimer reachable; - struct stimer sendns; - uint8_t nscount; uint8_t isrouter; uint8_t state; uint16_t link_metric; +#if UIP_ND6_SEND_NA || UIP_ND6_SEND_RA + struct stimer reachable; + struct stimer sendns; + uint8_t nscount; +#endif /* UIP_ND6_SEND_NA || UIP_ND6_SEND_RA */ #if UIP_CONF_IPV6_QUEUE_PKT struct uip_packetqueue_handle packethandle; #define UIP_DS6_NBR_PACKET_LIFETIME CLOCK_SECOND * 4 diff --git a/core/net/ipv6/uip-ds6.c b/core/net/ipv6/uip-ds6.c index 148c8aa24..458b6b14e 100644 --- a/core/net/ipv6/uip-ds6.c +++ b/core/net/ipv6/uip-ds6.c @@ -186,7 +186,9 @@ uip_ds6_periodic(void) } #endif /* !UIP_CONF_ROUTER */ +#if UIP_ND6_SEND_NA uip_ds6_neighbor_periodic(); +#endif /* UIP_ND6_SEND_RA */ #if UIP_CONF_ROUTER && UIP_ND6_SEND_RA /* Periodic RA sending */ diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 3732dec92..4f79d91ec 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -243,8 +243,10 @@ dio_input(void) if((nbr = uip_ds6_nbr_add(&from, (uip_lladdr_t *) packetbuf_addr(PACKETBUF_ADDR_SENDER), 0, NBR_REACHABLE)) != NULL) { +#if UIP_ND6_SEND_NA /* set reachable timer */ stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000); +#endif /* UIP_ND6_SEND_NA */ PRINTF("RPL: Neighbor added to neighbor cache "); PRINT6ADDR(&from); PRINTF(", "); @@ -754,8 +756,10 @@ dao_input(void) if((nbr = uip_ds6_nbr_add(&dao_sender_addr, (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER), 0, NBR_REACHABLE)) != NULL) { +#if UIP_ND6_SEND_NA /* set reachable timer */ stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000); +#endif /* UIP_ND6_SEND_NA */ PRINTF("RPL: Neighbor added to neighbor cache "); PRINT6ADDR(&dao_sender_addr); PRINTF(", "); diff --git a/core/net/rpl/rpl.c b/core/net/rpl/rpl.c index 82b11721a..7e7947e34 100644 --- a/core/net/rpl/rpl.c +++ b/core/net/rpl/rpl.c @@ -285,7 +285,11 @@ rpl_ipv6_neighbor_callback(uip_ds6_nbr_t *nbr) PRINTF("RPL: Neighbor state changed for "); PRINT6ADDR(&nbr->ipaddr); +#if UIP_ND6_SEND_NA || UIP_ND6_SEND_RA PRINTF(", nscount=%u, state=%u\n", nbr->nscount, nbr->state); +#else /* UIP_ND6_SEND_NA || UIP_ND6_SEND_RA */ + PRINTF(", state=%u\n", nbr->state); +#endif /* UIP_ND6_SEND_NA || UIP_ND6_SEND_RA */ for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) { if(instance->used == 1 ) { p = rpl_find_parent_any_dag(instance, &nbr->ipaddr); From 1eb1f88aa4ad8e5263abea172db7c28b20a8f1a9 Mon Sep 17 00:00:00 2001 From: Tommy Sparber Date: Wed, 28 Oct 2015 23:32:04 +1100 Subject: [PATCH 008/374] collect-view gui: Add support for OS X serialdump and motelist Select the tools for macos when checking for motes or opening a serial dump connection on OS X. --- .../src/org/contikios/contiki/collect/MoteFinder.java | 7 ++++++- .../contikios/contiki/collect/SerialDumpConnection.java | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/collect-view/src/org/contikios/contiki/collect/MoteFinder.java b/tools/collect-view/src/org/contikios/contiki/collect/MoteFinder.java index 9afcf028b..2c3c86d5b 100644 --- a/tools/collect-view/src/org/contikios/contiki/collect/MoteFinder.java +++ b/tools/collect-view/src/org/contikios/contiki/collect/MoteFinder.java @@ -54,9 +54,11 @@ public class MoteFinder { public static final String MOTELIST_WINDOWS = "./tools/motelist-windows.exe"; public static final String MOTELIST_LINUX = "./tools/motelist-linux"; + public static final String MOTELIST_MACOS = "./tools/motelist-macos"; private final Pattern motePattern; private final boolean isWindows; + private final boolean isMacos; private Process moteListProcess; // private boolean hasVerifiedProcess; private ArrayList comList = new ArrayList(); @@ -65,7 +67,8 @@ public class MoteFinder { public MoteFinder() { String osName = System.getProperty("os.name", "").toLowerCase(); isWindows = osName.startsWith("win"); - motePattern = Pattern.compile("\\s(COM|/dev/[a-zA-Z]+)(\\d+)\\s"); + isMacos = osName.startsWith("mac"); + motePattern = Pattern.compile("\\s(COM|/dev/[a-zA-Z]+|/dev/tty.usbserial-)(\\d+|[A-Z0-9]+)\\s"); } public String[] getMotes() throws IOException { @@ -87,6 +90,8 @@ public class MoteFinder { String fullCommand; if (isWindows) { fullCommand = MOTELIST_WINDOWS; + } else if (isMacos) { + fullCommand = MOTELIST_MACOS; } else { fullCommand = MOTELIST_LINUX; } diff --git a/tools/collect-view/src/org/contikios/contiki/collect/SerialDumpConnection.java b/tools/collect-view/src/org/contikios/contiki/collect/SerialDumpConnection.java index 9669b89f4..c624ea64a 100644 --- a/tools/collect-view/src/org/contikios/contiki/collect/SerialDumpConnection.java +++ b/tools/collect-view/src/org/contikios/contiki/collect/SerialDumpConnection.java @@ -46,6 +46,7 @@ public class SerialDumpConnection extends CommandConnection { public static final String SERIALDUMP_WINDOWS = "./tools/serialdump-windows.exe"; public static final String SERIALDUMP_LINUX = "./tools/serialdump-linux"; + public static final String SERIALDUMP_MACOS = "./tools/serialdump-macos"; public SerialDumpConnection(SerialConnectionListener listener) { super(listener); @@ -72,6 +73,8 @@ public class SerialDumpConnection extends CommandConnection { String fullCommand; if (osName.startsWith("win")) { fullCommand = SERIALDUMP_WINDOWS + " " + "-b115200" + " " + getMappedComPortForWindows(comPort); + } else if (osName.startsWith("mac")) { + fullCommand = SERIALDUMP_MACOS + " " + "-b115200" + " " + comPort; } else { fullCommand = SERIALDUMP_LINUX + " " + "-b115200" + " " + comPort; } From 7dc15816317e75ffe429e0f82f6e3fad990ba7c4 Mon Sep 17 00:00:00 2001 From: Jeff Kent Date: Mon, 28 Dec 2015 09:47:12 -0600 Subject: [PATCH 009/374] jsonparse: multiple improvements * input string now can be any json value type * syntax handling completed * stack is now used more efficiently for objects * implemented atomic values true, false, and null * jsonparse_copy_value now handles escapes --- apps/json/json.h | 1 + apps/json/jsonparse.c | 156 +++++++++++++++++++++++++++++++++--------- 2 files changed, 125 insertions(+), 32 deletions(-) diff --git a/apps/json/json.h b/apps/json/json.h index a698464a5..8a443a8be 100644 --- a/apps/json/json.h +++ b/apps/json/json.h @@ -62,6 +62,7 @@ enum { JSON_ERROR_UNEXPECTED_ARRAY, JSON_ERROR_UNEXPECTED_END_OF_ARRAY, JSON_ERROR_UNEXPECTED_OBJECT, + JSON_ERROR_UNEXPECTED_END_OF_OBJECT, JSON_ERROR_UNEXPECTED_STRING }; diff --git a/apps/json/jsonparse.c b/apps/json/jsonparse.c index 8089ae9fb..6277b56c4 100644 --- a/apps/json/jsonparse.c +++ b/apps/json/jsonparse.c @@ -43,6 +43,14 @@ push(struct jsonparse_state *state, char c) return state->depth < JSONPARSE_MAX_DEPTH; } /*--------------------------------------------------------------------*/ +static void +modify(struct jsonparse_state *state, char c) +{ + if(state->depth > 0) { + state->stack[state->depth - 1] = c; + } +} +/*--------------------------------------------------------------------*/ static char pop(struct jsonparse_state *state) { @@ -50,25 +58,31 @@ pop(struct jsonparse_state *state) return JSON_TYPE_ERROR; } state->depth--; + state->vtype = state->stack[state->depth]; return state->stack[state->depth]; } /*--------------------------------------------------------------------*/ /* will pass by the value and store the start and length of the value for atomic types */ /*--------------------------------------------------------------------*/ -static void +static char atomic(struct jsonparse_state *state, char type) { char c; + const char *str; + int len; state->vstart = state->pos; - state->vtype = type; if(type == JSON_TYPE_STRING || type == JSON_TYPE_PAIR_NAME) { while((c = state->json[state->pos++]) && c != '"') { if(c == '\\') { state->pos++; /* skip current char */ } } + if (c != '"') { + state->error = JSON_ERROR_SYNTAX; + return JSON_TYPE_ERROR; + } state->vlen = state->pos - state->vstart - 1; } else if(type == JSON_TYPE_NUMBER) { do { @@ -82,8 +96,31 @@ atomic(struct jsonparse_state *state, char type) /* need to back one step since first char is already gone */ state->vstart--; state->vlen = state->pos - state->vstart; + } else if(type == JSON_TYPE_NULL || type == JSON_TYPE_TRUE || type == JSON_TYPE_FALSE) { + state->vstart--; + switch (type) { + case JSON_TYPE_NULL: str = "null"; break; + case JSON_TYPE_TRUE: str = "true"; break; + case JSON_TYPE_FALSE: str = "false"; break; + default: str = ""; break; + } + + while ((c = state->json[state->pos]) && c != ' ' && c != ',' && c != ']' && c != '}') { + state->pos++; + } + + state->vlen = state->pos - state->vstart; + len = strlen(str); + len = state->vlen > len ? state->vlen : len; + + if (strncmp(str, &state->json[state->vstart], len) != 0) { + state->error = JSON_ERROR_SYNTAX; + return JSON_TYPE_ERROR; + } } - /* no other types for now... */ + + state->vtype = type; + return state->vtype; } /*--------------------------------------------------------------------*/ static void @@ -97,6 +134,17 @@ skip_ws(struct jsonparse_state *state) } } /*--------------------------------------------------------------------*/ +static int +is_atomic(struct jsonparse_state *state) +{ + char v = state->vtype; + if(v == 'N' || v == '"' || v == '0' || v == 'n' || v == 't' || v == 'f') { + return 1; + } else { + return 0; + } +} +/*--------------------------------------------------------------------*/ void jsonparse_setup(struct jsonparse_state *state, const char *json, int len) { @@ -105,6 +153,7 @@ jsonparse_setup(struct jsonparse_state *state, const char *json, int len) state->pos = 0; state->depth = 0; state->error = 0; + state->vtype = 0; state->stack[0] = 0; } /*--------------------------------------------------------------------*/ @@ -113,31 +162,33 @@ jsonparse_next(struct jsonparse_state *state) { char c; char s; + char v; skip_ws(state); c = state->json[state->pos]; s = jsonparse_get_type(state); + v = state->vtype; state->pos++; switch(c) { case '{': - push(state, c); + if((s == 0 && v == 0) || s == '[' || s == ':') { + push(state, c); + } else { + state->error = JSON_ERROR_UNEXPECTED_OBJECT; + return JSON_TYPE_ERROR; + } return c; case '}': - if(s == ':' && state->vtype != 0) { -/* printf("Popping vtype: '%c'\n", state->vtype); */ - pop(state); - s = jsonparse_get_type(state); - } - if(s == '{') { + if((s == ':' && v != ',' && v != 0 ) || (s == '{' && v == 0)) { pop(state); } else { - state->error = JSON_ERROR_SYNTAX; + state->error = JSON_ERROR_UNEXPECTED_END_OF_OBJECT; return JSON_TYPE_ERROR; } return c; case ']': - if(s == '[') { + if(s == '[' && v != ',') { pop(state); } else { state->error = JSON_ERROR_UNEXPECTED_END_OF_ARRAY; @@ -145,41 +196,67 @@ jsonparse_next(struct jsonparse_state *state) } return c; case ':': - push(state, c); - return c; + if(s == '{' && v == 'N') { + modify(state, ':'); + state->vtype = 0; + } else { + state->error = JSON_ERROR_SYNTAX; + return JSON_TYPE_ERROR; + } + return jsonparse_next(state); case ',': - /* if x:y ... , */ - if(s == ':' && state->vtype != 0) { - pop(state); + if(s == ':' && v != 0) { + modify(state, '{'); + state->vtype = c; } else if(s == '[') { - /* ok! */ + state->vtype = c; } else { state->error = JSON_ERROR_SYNTAX; return JSON_TYPE_ERROR; } return c; case '"': - if(s == '{' || s == '[' || s == ':') { - atomic(state, c = (s == '{' ? JSON_TYPE_PAIR_NAME : c)); + if((s == 0 && v == 0) || s == '{' || s == '[' || s == ':') { + return atomic(state, c = (s == '{' ? JSON_TYPE_PAIR_NAME : c)); } else { state->error = JSON_ERROR_UNEXPECTED_STRING; return JSON_TYPE_ERROR; } return c; case '[': - if(s == '{' || s == '[' || s == ':') { + if((s == 0 && v == 0) || s == '[' || s == ':') { push(state, c); } else { state->error = JSON_ERROR_UNEXPECTED_ARRAY; return JSON_TYPE_ERROR; } return c; + case 0: + if(v == 0 || state->depth > 0) { + state->error = JSON_ERROR_SYNTAX; + } + return JSON_TYPE_ERROR; default: - if(s == ':' || s == '[') { - if(c <= '9' && c >= '0') { - atomic(state, JSON_TYPE_NUMBER); - return JSON_TYPE_NUMBER; + if(s == 0 || s == ':' || s == '[') { + if (v != 0 && v != ',') { + state->error = JSON_ERROR_SYNTAX; + return JSON_TYPE_ERROR; } + if(c == '-' || (c <= '9' && c >= '0')) { + return atomic(state, JSON_TYPE_NUMBER); + } else if(c == 'n') { + return atomic(state, JSON_TYPE_NULL); + } else if(c == 't') { + return atomic(state, JSON_TYPE_TRUE); + } else if(c == 'f') { + return atomic(state, JSON_TYPE_FALSE); + } else { + state->error = JSON_ERROR_SYNTAX; + return JSON_TYPE_ERROR; + } + } else if(s == '{') { + state->error = JSON_ERROR_SYNTAX; + return JSON_TYPE_ERROR; } } return 0; @@ -192,16 +269,31 @@ jsonparse_next(struct jsonparse_state *state) int jsonparse_copy_value(struct jsonparse_state *state, char *str, int size) { - int i; + int i, o; + char c; - if(state->vtype == 0) { + if(!is_atomic(state)) { return 0; } - size = size <= state->vlen ? (size - 1) : state->vlen; - for(i = 0; i < size; i++) { - str[i] = state->json[state->vstart + i]; + for(i = 0, o = 0; i < state->vlen && o < size - 1; i++) { + c = state->json[state->vstart + i]; + if(c == '\\') { + i++; + switch(state->json[state->vstart + i]) { + case '"': str[o++] = '"'; break; + case '\\': str[o++] = '\\'; break; + case '/': str[o++] = '/'; break; + case 'b': str[o++] = '\b'; break; + case 'f': str[o++] = '\f'; break; + case 'n': str[o++] = '\n'; break; + case 'r': str[o++] = '\r'; break; + case 't': str[o++] = '\t'; break; + } + continue; + } + str[o++] = c; } - str[i] = 0; + str[o] = 0; return state->vtype; } /*--------------------------------------------------------------------*/ @@ -228,7 +320,7 @@ jsonparse_get_value_as_long(struct jsonparse_state *state) int jsonparse_strcmp_value(struct jsonparse_state *state, const char *str) { - if(state->vtype == 0) { + if(!is_atomic(state)) { return -1; } return strncmp(str, &state->json[state->vstart], state->vlen); From 8456b8333fc58d865f4eb6d441a01eeb7869f223 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Fri, 8 Jan 2016 14:30:38 +0100 Subject: [PATCH 010/374] Added sensniff support for the CC1200 --- dev/cc1200/cc1200.c | 31 +++++- .../zolertia/zoul/cc1200-sniffer/Makefile | 10 ++ .../zoul/cc1200-sniffer/Makefile.target | 1 + .../zolertia/zoul/cc1200-sniffer/README.md | 35 +++++++ .../zolertia/zoul/cc1200-sniffer/netstack.c | 46 +++++++++ .../zoul/cc1200-sniffer/project-conf.h | 59 ++++++++++++ .../zolertia/zoul/cc1200-sniffer/sniffer.c | 67 +++++++++++++ .../zolertia/zoul/cc1200-sniffer/stub-rdc.c | 96 +++++++++++++++++++ 8 files changed, 344 insertions(+), 1 deletion(-) create mode 100644 examples/zolertia/zoul/cc1200-sniffer/Makefile create mode 100644 examples/zolertia/zoul/cc1200-sniffer/Makefile.target create mode 100644 examples/zolertia/zoul/cc1200-sniffer/README.md create mode 100644 examples/zolertia/zoul/cc1200-sniffer/netstack.c create mode 100644 examples/zolertia/zoul/cc1200-sniffer/project-conf.h create mode 100644 examples/zolertia/zoul/cc1200-sniffer/sniffer.c create mode 100644 examples/zolertia/zoul/cc1200-sniffer/stub-rdc.c diff --git a/dev/cc1200/cc1200.c b/dev/cc1200/cc1200.c index 1f3bfd499..bed33c5b6 100644 --- a/dev/cc1200/cc1200.c +++ b/dev/cc1200/cc1200.c @@ -374,6 +374,17 @@ extern const cc1200_rf_cfg_t CC1200_RF_CFG; } while(0) #endif /*---------------------------------------------------------------------------*/ +/* Sniffer configuration */ +#if CC1200_SNIFFER +static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 }; +#include "dev/uart.h" +#define write_byte(b) uart_write_byte(CC1200_RF_CONF_SNIFFER_UART, b) +#define flush() +#else /* CC1200_SNIFFER */ +#define write_byte(b) +#define flush() +#endif /* CC1200_SNIFFER */ +/*---------------------------------------------------------------------------*/ /* Variables */ /*---------------------------------------------------------------------------*/ /* Flag indicating whether non-interrupt routines are using SPI */ @@ -870,6 +881,10 @@ read(void *buf, unsigned short buf_len) int len = 0; + #if CC1200_SNIFFER + uint8_t i; + #endif + if(rx_pkt_len > 0) { int8_t rssi = rx_pkt[rx_pkt_len - 2]; @@ -896,8 +911,22 @@ read(void *buf, unsigned short buf_len) packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, crc_lqi & ~(1 << 7)); - RIMESTATS_ADD(llrx); + #if CC1200_SNIFFER + write_byte(magic[0]); + write_byte(magic[1]); + write_byte(magic[2]); + write_byte(magic[3]); + write_byte(len + 2); + for(i = 0; i < len; ++i) { + write_byte(((unsigned char *)(buf))[i]); + } + write_byte(rssi); + write_byte(crc_lqi); + flush(); + #endif + + RIMESTATS_ADD(llrx); } } diff --git a/examples/zolertia/zoul/cc1200-sniffer/Makefile b/examples/zolertia/zoul/cc1200-sniffer/Makefile new file mode 100644 index 000000000..5c2fa1675 --- /dev/null +++ b/examples/zolertia/zoul/cc1200-sniffer/Makefile @@ -0,0 +1,10 @@ +DEFINES+=PROJECT_CONF_H=\"project-conf.h\" +PROJECT_SOURCEFILES += stub-rdc.c + +CONTIKI_PROJECT = sniffer + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../../.. +CONTIKI_WITH_RIME = 1 +include $(CONTIKI)/Makefile.include diff --git a/examples/zolertia/zoul/cc1200-sniffer/Makefile.target b/examples/zolertia/zoul/cc1200-sniffer/Makefile.target new file mode 100644 index 000000000..75430a6e4 --- /dev/null +++ b/examples/zolertia/zoul/cc1200-sniffer/Makefile.target @@ -0,0 +1 @@ +TARGET = zoul diff --git a/examples/zolertia/zoul/cc1200-sniffer/README.md b/examples/zolertia/zoul/cc1200-sniffer/README.md new file mode 100644 index 000000000..95ec65193 --- /dev/null +++ b/examples/zolertia/zoul/cc1200-sniffer/README.md @@ -0,0 +1,35 @@ +CC1200 README +======================== + +The CC1200 sniffer is heavily based on the CC2538 sniffer, used with the +IEEE 802.15.4 Sensniff application by George Oikonomou. + +Sensniff requires [Wireshark](http://www.wireshark.org/). + +Get Wireshark +----------------- +The best way is to go to the Wireshark site and follow the instructions for your +specific OS, in a bundle this will install for Ubuntu/LInux systems: + +`sudo apt-get install wireshark` + +To allow non-super users to capture packets: + +`sudo dpkg-reconfigure wireshark` + +Flash the sniffer application to the Zoul +----------------- +make sniffer.upload + +Run Sensniff +----------------- +``` +git clone https://github.com/g-oikonomou/sensniff +cd sensniff/host +python sensniff.py --non-interactive -d /dev/ttyUSB0 -b 460800 +``` + +On another terminal run: + +`sudo wireshark -i /tmp/sensnifff` + diff --git a/examples/zolertia/zoul/cc1200-sniffer/netstack.c b/examples/zolertia/zoul/cc1200-sniffer/netstack.c new file mode 100644 index 000000000..3aeb6968e --- /dev/null +++ b/examples/zolertia/zoul/cc1200-sniffer/netstack.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2010, Loughborough University - 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. + */ +/** + * \file + * Stub file overriding core/net/netstack.c. What we want to achieve + * here is call netstack_init from main without initialising the RDC, + * MAC and Network layers. It will just turn on the radio instead. + * + * \author + * George Oikonomou - + */ +#include "netstack.h" +/*---------------------------------------------------------------------------*/ +void +netstack_init(void) +{ + NETSTACK_RADIO.init(); + NETSTACK_RADIO.on(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/zolertia/zoul/cc1200-sniffer/project-conf.h b/examples/zolertia/zoul/cc1200-sniffer/project-conf.h new file mode 100644 index 000000000..fca02e711 --- /dev/null +++ b/examples/zolertia/zoul/cc1200-sniffer/project-conf.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/** + * \addtogroup zoul-cc1200-sniffer + * @{ + * + * \file + * Project specific configuration defines for the CC1200 sniffer + */ +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +#define CC1200_CONF_SNIFFER 1 +#define CC1200_RF_CONF_SNIFFER_UART 0 +#define CC1200_CONF_RF_CFG cc1200_802154g_863_870_fsk_50kbps + +#undef NETSTACK_CONF_RADIO +#define NETSTACK_CONF_RADIO cc1200_driver + +#define CC1200_CONF_USE_GPIO2 0 +#define CC1200_CONF_USE_RX_WATCHDOG 0 +#define ANTENNA_SW_SELECT_DEF_CONF ANTENNA_SW_SELECT_SUBGHZ + +#undef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC stub_rdc_driver + +#define UART0_CONF_BAUD_RATE 460800 + +#endif /* PROJECT_CONF_H_ */ + +/** @} */ diff --git a/examples/zolertia/zoul/cc1200-sniffer/sniffer.c b/examples/zolertia/zoul/cc1200-sniffer/sniffer.c new file mode 100644 index 000000000..a0241f795 --- /dev/null +++ b/examples/zolertia/zoul/cc1200-sniffer/sniffer.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/** + * \addtogroup zoul-examples + * @{ + * + * \defgroup zoul-cc1200-sniffer CC1200 Sniffer + * + * Sniffer for the Zolertia's Zoul CC1200 on-board radio + * + * This example is to be used combined with the sensniff host-side tool, + * which can be downloaded from: https://github.com/g-oikonomou/sensniff + * + * @{ + * + * \file + * Implementation of a Sniffer Process Thread + */ +#include "contiki.h" + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" +/*---------------------------------------------------------------------------*/ +PROCESS(sniffer_process, "Sniffer process"); +AUTOSTART_PROCESSES(&sniffer_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(sniffer_process, ev, data) +{ + PROCESS_BEGIN(); + PRINTF("Sniffer started\n"); + PROCESS_EXIT(); + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ + +/** + * @} + * @} + */ diff --git a/examples/zolertia/zoul/cc1200-sniffer/stub-rdc.c b/examples/zolertia/zoul/cc1200-sniffer/stub-rdc.c new file mode 100644 index 000000000..a8c54de6a --- /dev/null +++ b/examples/zolertia/zoul/cc1200-sniffer/stub-rdc.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2010, Loughborough University - 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. + */ +/** + * \file + * Definition of a fake RDC driver to be used with passive + * examples. The sniffer will never send packets and it will never + * push incoming packets up the stack. We do this by defining this + * driver as our RDC. We then drop everything + * + * \author + * George Oikonomou - + */ +#include "net/mac/mac.h" +#include "net/mac/rdc.h" +/*---------------------------------------------------------------------------*/ +static void +send(mac_callback_t sent, void *ptr) +{ + if(sent) { + sent(ptr, MAC_TX_OK, 1); + } +} +/*---------------------------------------------------------------------------*/ +static void +send_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *list) +{ + if(sent) { + sent(ptr, MAC_TX_OK, 1); + } +} +/*---------------------------------------------------------------------------*/ +static void +input(void) +{ +} +/*---------------------------------------------------------------------------*/ +static int +on(void) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +off(int keep_radio_on) +{ + return keep_radio_on; +} +/*---------------------------------------------------------------------------*/ +static unsigned short +cca(void) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ +} +/*---------------------------------------------------------------------------*/ +const struct rdc_driver stub_rdc_driver = { + "stub-rdc", + init, + send, + send_list, + input, + on, + off, + cca, +}; +/*---------------------------------------------------------------------------*/ From a40e28a7c8f9167d8d32cc6c52e9b822907dff1f Mon Sep 17 00:00:00 2001 From: Michael Klemm Date: Sat, 16 Jan 2016 12:45:21 +0100 Subject: [PATCH 011/374] Fixed using target AVR ATmega128RFA1 Set operating speed to 16MHz and added missing dependency to llsec. This fix was tested with sparkfun ATmega128RFA1 Dev Board. --- platform/avr-atmega128rfa1/Makefile.avr-atmega128rfa1 | 4 ++-- platform/avr-atmega128rfa1/contiki-conf.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/avr-atmega128rfa1/Makefile.avr-atmega128rfa1 b/platform/avr-atmega128rfa1/Makefile.avr-atmega128rfa1 index f99e85291..2fd8a9ac2 100644 --- a/platform/avr-atmega128rfa1/Makefile.avr-atmega128rfa1 +++ b/platform/avr-atmega128rfa1/Makefile.avr-atmega128rfa1 @@ -9,7 +9,7 @@ CONTIKI_TARGET_SOURCEFILES += button-sensor.c sensors.c slip_uart0.c slip.c CONTIKIAVR=$(CONTIKI)/cpu/avr CONTIKIBOARD=. -CONTIKI_PLAT_DEFS = -DF_CPU=8000000UL -DAUTO_CRC_PADDING=2 +CONTIKI_PLAT_DEFS = -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 MCU=atmega128rfa1 @@ -31,4 +31,4 @@ AVRDUDE_MCU=m128rfa1 include $(CONTIKIAVR)/Makefile.avr include $(CONTIKIAVR)/radio/Makefile.radio -MODULES += core/net/mac core/net core/net/mac/sicslowmac core/net/mac/contikimac +MODULES += core/net/mac core/net core/net/mac/sicslowmac core/net/mac/contikimac core/net/llsec diff --git a/platform/avr-atmega128rfa1/contiki-conf.h b/platform/avr-atmega128rfa1/contiki-conf.h index 9dfbd9518..21fb497c3 100644 --- a/platform/avr-atmega128rfa1/contiki-conf.h +++ b/platform/avr-atmega128rfa1/contiki-conf.h @@ -45,7 +45,7 @@ #define PLATFORM_NAME "RFA1" #define PLATFORM_TYPE ATMEGA128RFA1 #ifndef F_CPU -#define F_CPU 8000000UL +#define F_CPU 16000000UL #endif #include From 24871b070253c218a8a427a334e3f2ec09d5f2c1 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 24 Jan 2016 16:49:51 +0000 Subject: [PATCH 012/374] Extend the Sensortag external flash Driver to support more parts The driver currently supports two Winbond external flash parts with identical instruction sets. The instruction set of the Macronix MX25R8035F appears to be a superset. We therefore change the driver to add the MID/DID of the Macronix to the list of supported parts. This will subsequently allow us to share the same driver for both the SensorTag and the CC2650 LauchPad. --- platform/srf06-cc26xx/sensortag/ext-flash.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/platform/srf06-cc26xx/sensortag/ext-flash.c b/platform/srf06-cc26xx/sensortag/ext-flash.c index c35bd4d0f..d469c1d56 100644 --- a/platform/srf06-cc26xx/sensortag/ext-flash.c +++ b/platform/srf06-cc26xx/sensortag/ext-flash.c @@ -72,8 +72,10 @@ /* Part specific constants */ #define BLS_DEVICE_ID_W25X20CL 0x11 #define BLS_DEVICE_ID_W25X40CL 0x12 +#define BLS_DEVICE_ID_MX25R8035F 0x14 -#define BLS_MANUFACTURER_ID 0xEF +#define BLS_WINBOND_MID 0xEF +#define BLS_MACRONIX_MID 0xC2 #define BLS_PROGRAM_PAGE_SIZE 256 #define BLS_ERASE_SECTOR_SIZE 4096 @@ -175,8 +177,9 @@ verify_part(void) return VERIFY_PART_ERROR; } - if(rbuf[0] != BLS_MANUFACTURER_ID || - (rbuf[1] != BLS_DEVICE_ID_W25X20CL && rbuf[1] != BLS_DEVICE_ID_W25X40CL)) { + if((rbuf[0] != BLS_WINBOND_MID && rbuf[0] != BLS_MACRONIX_MID) || + (rbuf[1] != BLS_DEVICE_ID_W25X20CL && rbuf[1] != BLS_DEVICE_ID_W25X40CL + && rbuf[1] != BLS_DEVICE_ID_MX25R8035F)) { return VERIFY_PART_POWERED_DOWN; } return VERIFY_PART_OK; From 5eb0470ad403cd398de0d4e2f8e25e0b0e1f6277 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 24 Jan 2016 16:52:56 +0000 Subject: [PATCH 013/374] Move the SPI and Ext Flash Driver to a common directory This commit creates a `common` directory, aimed to host drivers supported by multiple boards of the CC13xx/CC26xx family. We move the Sensortag SPI and External Flash drivers to this location and we change the Sensortag build system to pull the respective files from therein. --- .../{sensortag => common}/board-spi.c | 4 ++-- .../{sensortag => common}/board-spi.h | 15 ++++++++++++--- .../{sensortag => common}/ext-flash.c | 4 ++-- .../{sensortag => common}/ext-flash.h | 6 +++--- .../srf06-cc26xx/sensortag/Makefile.sensortag | 2 +- 5 files changed, 20 insertions(+), 11 deletions(-) rename platform/srf06-cc26xx/{sensortag => common}/board-spi.c (98%) rename platform/srf06-cc26xx/{sensortag => common}/board-spi.h (89%) rename platform/srf06-cc26xx/{sensortag => common}/ext-flash.c (99%) rename platform/srf06-cc26xx/{sensortag => common}/ext-flash.h (95%) diff --git a/platform/srf06-cc26xx/sensortag/board-spi.c b/platform/srf06-cc26xx/common/board-spi.c similarity index 98% rename from platform/srf06-cc26xx/sensortag/board-spi.c rename to platform/srf06-cc26xx/common/board-spi.c index 960db75c8..fb9fecd63 100644 --- a/platform/srf06-cc26xx/sensortag/board-spi.c +++ b/platform/srf06-cc26xx/common/board-spi.c @@ -33,7 +33,7 @@ * @{ * * \file - * Board-specific SPI driver for the Sensortag-CC26xx + * Board-specific SPI driver common to the Sensortag and LaunchPad */ /*---------------------------------------------------------------------------*/ #include "contiki.h" @@ -120,7 +120,7 @@ board_spi_open(uint32_t bit_rate, uint32_t clk_pin) /* First, make sure the SERIAL PD is on */ ti_lib_prcm_power_domain_on(PRCM_DOMAIN_SERIAL); while((ti_lib_prcm_power_domain_status(PRCM_DOMAIN_SERIAL) - != PRCM_DOMAIN_POWER_ON)); + != PRCM_DOMAIN_POWER_ON)); /* Enable clock in active mode */ ti_lib_rom_prcm_peripheral_run_enable(PRCM_PERIPH_SSI0); diff --git a/platform/srf06-cc26xx/sensortag/board-spi.h b/platform/srf06-cc26xx/common/board-spi.h similarity index 89% rename from platform/srf06-cc26xx/sensortag/board-spi.h rename to platform/srf06-cc26xx/common/board-spi.h index 26bdff162..3699db120 100644 --- a/platform/srf06-cc26xx/sensortag/board-spi.h +++ b/platform/srf06-cc26xx/common/board-spi.h @@ -29,14 +29,22 @@ */ /*---------------------------------------------------------------------------*/ /** - * \addtogroup sensortag-cc26xx-peripherals + * \addtogroup cc26xx-srf-tag * @{ * - * \defgroup sensortag-cc26xx-spi SensorTag 2.0 SPI functions + * \defgroup common-cc26xx-peripherals CC13xx/CC26xx peripheral driver pool + * + * Drivers for peripherals present on more than one CC13xx/CC26xx board. For + * example, the same external flash driver is used for both the part found on + * the Sensortag as well as the part on the LaunchPad. + * + * @{ + * + * \defgroup sensortag-cc26xx-spi SensorTag/LaunchPad SPI functions * @{ * * \file - * Header file for the Sensortag-CC26xx SPI Driver + * Header file for the Sensortag/LaunchPad SPI Driver */ /*---------------------------------------------------------------------------*/ #ifndef BOARD_SPI_H_ @@ -100,6 +108,7 @@ bool board_spi_write(const uint8_t *buf, size_t length); #endif /* BOARD_SPI_H_ */ /*---------------------------------------------------------------------------*/ /** + * @} * @} * @} */ diff --git a/platform/srf06-cc26xx/sensortag/ext-flash.c b/platform/srf06-cc26xx/common/ext-flash.c similarity index 99% rename from platform/srf06-cc26xx/sensortag/ext-flash.c rename to platform/srf06-cc26xx/common/ext-flash.c index d469c1d56..721a36424 100644 --- a/platform/srf06-cc26xx/sensortag/ext-flash.c +++ b/platform/srf06-cc26xx/common/ext-flash.c @@ -33,7 +33,7 @@ * @{ * * \file - * Driver for the Sensortag-CC26xx WinBond W25X20CL Flash + * Driver for the LaunchPad Flash and the Sensortag WinBond W25X20CL/W25X40CL */ /*---------------------------------------------------------------------------*/ #include "contiki.h" @@ -158,7 +158,7 @@ static uint8_t verify_part(void) { const uint8_t wbuf[] = { BLS_CODE_MDID, 0xFF, 0xFF, 0x00 }; - uint8_t rbuf[2] = {0, 0}; + uint8_t rbuf[2] = { 0, 0 }; bool ret; select_on_bus(); diff --git a/platform/srf06-cc26xx/sensortag/ext-flash.h b/platform/srf06-cc26xx/common/ext-flash.h similarity index 95% rename from platform/srf06-cc26xx/sensortag/ext-flash.h rename to platform/srf06-cc26xx/common/ext-flash.h index 3038872cd..5f2717edb 100644 --- a/platform/srf06-cc26xx/sensortag/ext-flash.h +++ b/platform/srf06-cc26xx/common/ext-flash.h @@ -29,14 +29,14 @@ */ /*---------------------------------------------------------------------------*/ /** - * \addtogroup sensortag-cc26xx-peripherals + * \addtogroup common-cc26xx-peripherals * @{ * - * \defgroup sensortag-cc26xx-ext-flash SensorTag 2.0 External Flash + * \defgroup sensortag-cc26xx-ext-flash SensorTag/LaunchPad External Flash * @{ * * \file - * Header file for the Sensortag-CC26xx External Flash Driver + * Header file for the Sensortag/LaunchPad External Flash Driver */ /*---------------------------------------------------------------------------*/ #ifndef EXT_FLASH_H_ diff --git a/platform/srf06-cc26xx/sensortag/Makefile.sensortag b/platform/srf06-cc26xx/sensortag/Makefile.sensortag index a37f8dd05..68e4b007f 100644 --- a/platform/srf06-cc26xx/sensortag/Makefile.sensortag +++ b/platform/srf06-cc26xx/sensortag/Makefile.sensortag @@ -1,7 +1,7 @@ CFLAGS += -DBOARD_SENSORTAG=1 CFLAGS += -DBACKDOOR_IOID=0x00000000 -CONTIKI_TARGET_DIRS += sensortag +CONTIKI_TARGET_DIRS += sensortag common BOARD_SOURCEFILES += sensortag-sensors.c sensor-common.c BOARD_SOURCEFILES += bmp-280-sensor.c tmp-007-sensor.c opt-3001-sensor.c From 387bb96ca47a824828b6024beac623006a950e79 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 24 Jan 2016 16:53:47 +0000 Subject: [PATCH 014/374] Add support for the CC2650 LaunchPad --- .../srf06-cc26xx/launchpad/Makefile.launchpad | 6 + .../launchpad/board-peripherals.h | 56 +++++ platform/srf06-cc26xx/launchpad/board.c | 115 +++++++++ .../srf06-cc26xx/launchpad/button-sensor.c | 218 ++++++++++++++++++ .../srf06-cc26xx/launchpad/button-sensor.h | 65 ++++++ .../launchpad/cc2650/Makefile.cc2650 | 8 + .../srf06-cc26xx/launchpad/cc2650/board.h | 189 +++++++++++++++ .../launchpad/launchpad-sensors.c | 47 ++++ platform/srf06-cc26xx/launchpad/leds-arch.c | 81 +++++++ 9 files changed, 785 insertions(+) create mode 100644 platform/srf06-cc26xx/launchpad/Makefile.launchpad create mode 100644 platform/srf06-cc26xx/launchpad/board-peripherals.h create mode 100644 platform/srf06-cc26xx/launchpad/board.c create mode 100644 platform/srf06-cc26xx/launchpad/button-sensor.c create mode 100644 platform/srf06-cc26xx/launchpad/button-sensor.h create mode 100644 platform/srf06-cc26xx/launchpad/cc2650/Makefile.cc2650 create mode 100644 platform/srf06-cc26xx/launchpad/cc2650/board.h create mode 100644 platform/srf06-cc26xx/launchpad/launchpad-sensors.c create mode 100644 platform/srf06-cc26xx/launchpad/leds-arch.c diff --git a/platform/srf06-cc26xx/launchpad/Makefile.launchpad b/platform/srf06-cc26xx/launchpad/Makefile.launchpad new file mode 100644 index 000000000..deefeed81 --- /dev/null +++ b/platform/srf06-cc26xx/launchpad/Makefile.launchpad @@ -0,0 +1,6 @@ +CFLAGS += -DBOARD_LAUNCHPAD=1 + +CONTIKI_TARGET_DIRS += launchpad common + +BOARD_SOURCEFILES += board.c launchpad-sensors.c leds-arch.c button-sensor.c +BOARD_SOURCEFILES += ext-flash.c board-spi.c diff --git a/platform/srf06-cc26xx/launchpad/board-peripherals.h b/platform/srf06-cc26xx/launchpad/board-peripherals.h new file mode 100644 index 000000000..3e1220234 --- /dev/null +++ b/platform/srf06-cc26xx/launchpad/board-peripherals.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +/** \addtogroup cc26xx-srf-tag + * @{ + * + * \defgroup launchpad-peripherals LaunchPad peripherals + * + * Defines related to LaunchPad peripherals. + * + * @{ + * + * \file + * Header file with definitions related to LaunchPad peripherals + * + * \note Do not include this file directly. + */ +/*---------------------------------------------------------------------------*/ +#ifndef BOARD_PERIPHERALS_H_ +#define BOARD_PERIPHERALS_H_ +/*---------------------------------------------------------------------------*/ +#include "ext-flash.h" +/*---------------------------------------------------------------------------*/ +#endif /* BOARD_PERIPHERALS_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/launchpad/board.c b/platform/srf06-cc26xx/launchpad/board.c new file mode 100644 index 000000000..6482212d8 --- /dev/null +++ b/platform/srf06-cc26xx/launchpad/board.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup launchpad-peripherals + * @{ + * + * \file + * LaunchPad-specific board initialisation driver + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "lib/sensors.h" +#include "lpm.h" +#include "ti-lib.h" +#include "board-peripherals.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +static void +wakeup_handler(void) +{ + /* Turn on the PERIPH PD */ + ti_lib_prcm_power_domain_on(PRCM_DOMAIN_PERIPH); + while((ti_lib_prcm_power_domain_status(PRCM_DOMAIN_PERIPH) + != PRCM_DOMAIN_POWER_ON)); +} +/*---------------------------------------------------------------------------*/ +/* + * Declare a data structure to register with LPM. + * We don't care about what power mode we'll drop to, we don't care about + * getting notified before deep sleep. All we need is to be notified when we + * wake up so we can turn power domains back on + */ +LPM_MODULE(launchpad_module, NULL, NULL, wakeup_handler, LPM_DOMAIN_NONE); +/*---------------------------------------------------------------------------*/ +static void +configure_unused_pins(void) +{ + uint32_t pins[] = { + BOARD_IOID_CS, BOARD_IOID_TDO, BOARD_IOID_TDI, BOARD_IOID_DIO12, + BOARD_IOID_DIO15, BOARD_IOID_DIO21, BOARD_IOID_DIO22, BOARD_IOID_DIO23, + BOARD_IOID_DIO24, BOARD_IOID_DIO25, BOARD_IOID_DIO26, BOARD_IOID_DIO27, + BOARD_IOID_DIO28, BOARD_IOID_DIO29, BOARD_IOID_DIO30, + IOID_UNUSED + }; + + uint32_t *pin; + + for(pin = pins; *pin != IOID_UNUSED; pin++) { + ti_lib_ioc_pin_type_gpio_input(*pin); + ti_lib_ioc_io_port_pull_set(*pin, IOC_IOPULL_DOWN); + } +} +/*---------------------------------------------------------------------------*/ +void +board_init() +{ + /* Disable global interrupts */ + bool int_disabled = ti_lib_int_master_disable(); + + /* Turn on relevant PDs */ + wakeup_handler(); + + /* Enable GPIO peripheral */ + ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_GPIO); + + /* Apply settings and wait for them to take effect */ + ti_lib_prcm_load_set(); + while(!ti_lib_prcm_load_get()); + + /* Make sure the external flash is in the lower power mode */ + ext_flash_init(); + + lpm_register_module(&launchpad_module); + + /* For unsupported peripherals, select a default pin configuration */ + configure_unused_pins(); + + /* Re-enable interrupt if initially enabled. */ + if(!int_disabled) { + ti_lib_int_master_enable(); + } +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/launchpad/button-sensor.c b/platform/srf06-cc26xx/launchpad/button-sensor.c new file mode 100644 index 000000000..d37369d0a --- /dev/null +++ b/platform/srf06-cc26xx/launchpad/button-sensor.c @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup launchpad-button-sensor + * @{ + * + * \file + * Driver for LaunchPad buttons + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "lib/sensors.h" +#include "launchpad/button-sensor.h" +#include "gpio-interrupt.h" +#include "sys/timer.h" +#include "lpm.h" + +#include "ti-lib.h" + +#include +/*---------------------------------------------------------------------------*/ +#ifdef BUTTON_SENSOR_CONF_ENABLE_SHUTDOWN +#define BUTTON_SENSOR_ENABLE_SHUTDOWN BUTTON_SENSOR_CONF_ENABLE_SHUTDOWN +#else +#define BUTTON_SENSOR_ENABLE_SHUTDOWN 1 +#endif +/*---------------------------------------------------------------------------*/ +#define BUTTON_GPIO_CFG (IOC_CURRENT_2MA | IOC_STRENGTH_AUTO | \ + IOC_IOPULL_UP | IOC_SLEW_DISABLE | \ + IOC_HYST_DISABLE | IOC_BOTH_EDGES | \ + IOC_INT_ENABLE | IOC_IOMODE_NORMAL | \ + IOC_NO_WAKE_UP | IOC_INPUT_ENABLE) +/*---------------------------------------------------------------------------*/ +#define DEBOUNCE_DURATION (CLOCK_SECOND >> 5) + +struct btn_timer { + struct timer debounce; + clock_time_t start; + clock_time_t duration; +}; + +static struct btn_timer left_timer, right_timer; +/*---------------------------------------------------------------------------*/ +static void +button_press_handler(uint8_t ioid) +{ + if(ioid == BOARD_IOID_KEY_LEFT) { + if(!timer_expired(&left_timer.debounce)) { + return; + } + + timer_set(&left_timer.debounce, DEBOUNCE_DURATION); + + /* + * Start press duration counter on press (falling), notify on release + * (rising) + */ + if(ti_lib_gpio_pin_read(BOARD_KEY_LEFT) == 0) { + left_timer.start = clock_time(); + left_timer.duration = 0; + } else { + left_timer.duration = clock_time() - left_timer.start; + sensors_changed(&button_left_sensor); + } + } + + if(ioid == BOARD_IOID_KEY_RIGHT) { + if(BUTTON_SENSOR_ENABLE_SHUTDOWN == 0) { + if(!timer_expired(&right_timer.debounce)) { + return; + } + + timer_set(&right_timer.debounce, DEBOUNCE_DURATION); + + /* + * Start press duration counter on press (falling), notify on release + * (rising) + */ + if(ti_lib_gpio_pin_read(BOARD_KEY_RIGHT) == 0) { + right_timer.start = clock_time(); + right_timer.duration = 0; + } else { + right_timer.duration = clock_time() - right_timer.start; + sensors_changed(&button_right_sensor); + } + } else { + lpm_shutdown(BOARD_IOID_KEY_RIGHT, IOC_IOPULL_UP, IOC_WAKE_ON_LOW); + } + } +} +/*---------------------------------------------------------------------------*/ +static void +config_buttons(int type, int c, uint32_t key) +{ + switch(type) { + case SENSORS_HW_INIT: + ti_lib_gpio_event_clear(1 << key); + ti_lib_ioc_port_configure_set(key, IOC_PORT_GPIO, BUTTON_GPIO_CFG); + ti_lib_gpio_dir_mode_set((1 << key), GPIO_DIR_MODE_IN); + gpio_interrupt_register_handler(key, button_press_handler); + break; + case SENSORS_ACTIVE: + if(c) { + ti_lib_gpio_event_clear(1 << key); + ti_lib_ioc_port_configure_set(key, IOC_PORT_GPIO, BUTTON_GPIO_CFG); + ti_lib_gpio_dir_mode_set((1 << key), GPIO_DIR_MODE_IN); + ti_lib_ioc_int_enable(key); + } else { + ti_lib_ioc_int_disable(key); + } + break; + default: + break; + } +} +/*---------------------------------------------------------------------------*/ +static int +config_left(int type, int value) +{ + config_buttons(type, value, BOARD_IOID_KEY_LEFT); + + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +config_right(int type, int value) +{ + config_buttons(type, value, BOARD_IOID_KEY_RIGHT); + + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type, uint32_t key_io_id) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + if(ti_lib_ioc_port_configure_get(key_io_id) & IOC_INT_ENABLE) { + return 1; + } + break; + default: + break; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value_left(int type) +{ + if(type == BUTTON_SENSOR_VALUE_STATE) { + return ti_lib_gpio_pin_read(BOARD_KEY_LEFT) == 0 ? + BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED; + } else if(type == BUTTON_SENSOR_VALUE_DURATION) { + return (int)left_timer.duration; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value_right(int type) +{ + if(type == BUTTON_SENSOR_VALUE_STATE) { + return ti_lib_gpio_pin_read(BOARD_KEY_RIGHT) == 0 ? + BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED; + } else if(type == BUTTON_SENSOR_VALUE_DURATION) { + return (int)right_timer.duration; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status_left(int type) +{ + return status(type, BOARD_IOID_KEY_LEFT); +} +/*---------------------------------------------------------------------------*/ +static int +status_right(int type) +{ + return status(type, BOARD_IOID_KEY_RIGHT); +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(button_left_sensor, BUTTON_SENSOR, value_left, config_left, + status_left); +SENSORS_SENSOR(button_right_sensor, BUTTON_SENSOR, value_right, config_right, + status_right); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/launchpad/button-sensor.h b/platform/srf06-cc26xx/launchpad/button-sensor.h new file mode 100644 index 000000000..0c945d3f7 --- /dev/null +++ b/platform/srf06-cc26xx/launchpad/button-sensor.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup launchpad-peripherals + * @{ + * + * \defgroup launchpad-button-sensor LaunchPad Button Driver + * + * One of the buttons can be configured as general purpose or as an on/off key + * @{ + * + * \file + * Header file for the LaunchPad Button Driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef BUTTON_SENSOR_H_ +#define BUTTON_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define BUTTON_SENSOR "Button" +/*---------------------------------------------------------------------------*/ +#define BUTTON_SENSOR_VALUE_STATE 0 +#define BUTTON_SENSOR_VALUE_DURATION 1 + +#define BUTTON_SENSOR_VALUE_RELEASED 0 +#define BUTTON_SENSOR_VALUE_PRESSED 1 +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor button_left_sensor; +extern const struct sensors_sensor button_right_sensor; +/*---------------------------------------------------------------------------*/ +#endif /* BUTTON_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/launchpad/cc2650/Makefile.cc2650 b/platform/srf06-cc26xx/launchpad/cc2650/Makefile.cc2650 new file mode 100644 index 000000000..72e50de3a --- /dev/null +++ b/platform/srf06-cc26xx/launchpad/cc2650/Makefile.cc2650 @@ -0,0 +1,8 @@ +### Will allow the inclusion of the correct CPU makefile +CPU_FAMILY = cc26xx + +### Add to the source dirs +CONTIKI_TARGET_DIRS += launchpad/cc2650 + +### Include the common launchpad makefile +include $(PLATFORM_ROOT_DIR)/launchpad/Makefile.launchpad diff --git a/platform/srf06-cc26xx/launchpad/cc2650/board.h b/platform/srf06-cc26xx/launchpad/cc2650/board.h new file mode 100644 index 000000000..a65ca5361 --- /dev/null +++ b/platform/srf06-cc26xx/launchpad/cc2650/board.h @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +/** \addtogroup launchpad-peripherals + * @{ + * + * \defgroup launchpad-cc26xx-specific CC2650 LaunchPad Peripherals + * + * Defines related to the CC2650 LaunchPad + * + * This file provides connectivity information on LEDs, Buttons, UART and + * other peripherals + * + * This file is not meant to be modified by the user. + * @{ + * + * \file + * Header file with definitions related to the I/O connections on the TI + * CC2650 LaunchPad + * + * \note Do not include this file directly. It gets included by contiki-conf + * after all relevant directives have been set. + */ +/*---------------------------------------------------------------------------*/ +#ifndef BOARD_H_ +#define BOARD_H_ +/*---------------------------------------------------------------------------*/ +#include "ioc.h" +/*---------------------------------------------------------------------------*/ +/** + * \name LED configurations + * + * Those values are not meant to be modified by the user + * @{ + */ +/* Some files include leds.h before us, so we need to get rid of defaults in + * leds.h before we provide correct definitions */ +#undef LEDS_GREEN +#undef LEDS_YELLOW +#undef LEDS_RED +#undef LEDS_CONF_ALL + +#define LEDS_RED 1 +#define LEDS_GREEN 2 +#define LEDS_YELLOW LEDS_GREEN +#define LEDS_ORANGE LEDS_RED + +#define LEDS_CONF_ALL 3 + +/* Notify various examples that we have LEDs */ +#define PLATFORM_HAS_LEDS 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name LED IOID mappings + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_LED_1 IOID_6 +#define BOARD_IOID_LED_2 IOID_7 +#define BOARD_LED_1 (1 << BOARD_IOID_LED_1) +#define BOARD_LED_2 (1 << BOARD_IOID_LED_2) +#define BOARD_LED_ALL (BOARD_LED_1 | BOARD_LED_2) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name UART IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_UART_RX IOID_2 +#define BOARD_IOID_UART_TX IOID_3 +#define BOARD_IOID_UART_RTS IOID_18 +#define BOARD_IOID_UART_CTS IOID_19 +#define BOARD_UART_RX (1 << BOARD_IOID_UART_RX) +#define BOARD_UART_TX (1 << BOARD_IOID_UART_TX) +#define BOARD_UART_RTS (1 << BOARD_IOID_UART_RTS) +#define BOARD_UART_CTS (1 << BOARD_IOID_UART_CTS) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Button IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_KEY_LEFT IOID_13 +#define BOARD_IOID_KEY_RIGHT IOID_14 +#define BOARD_KEY_LEFT (1 << BOARD_IOID_KEY_LEFT) +#define BOARD_KEY_RIGHT (1 << BOARD_IOID_KEY_RIGHT) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \brief SPI IOID mappings + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_SPI_MOSI IOID_9 +#define BOARD_IOID_SPI_MISO IOID_8 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name External flash IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_FLASH_CS IOID_20 +#define BOARD_FLASH_CS (1 << BOARD_IOID_FLASH_CS) +#define BOARD_IOID_SPI_CLK_FLASH IOID_10 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \brief I2C IOID mappings + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_SCL IOID_4 +#define BOARD_IOID_SDA IOID_5 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \brief Remaining pins + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_CS IOID_11 +#define BOARD_IOID_TDO IOID_16 +#define BOARD_IOID_TDI IOID_17 +#define BOARD_IOID_DIO12 IOID_12 +#define BOARD_IOID_DIO15 IOID_15 +#define BOARD_IOID_DIO21 IOID_21 +#define BOARD_IOID_DIO22 IOID_22 +#define BOARD_IOID_DIO23 IOID_23 +#define BOARD_IOID_DIO24 IOID_24 +#define BOARD_IOID_DIO25 IOID_25 +#define BOARD_IOID_DIO26 IOID_26 +#define BOARD_IOID_DIO27 IOID_27 +#define BOARD_IOID_DIO28 IOID_28 +#define BOARD_IOID_DIO29 IOID_29 +#define BOARD_IOID_DIO30 IOID_30 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Device string used on startup + * @{ + */ +#define BOARD_STRING "TI CC2650 LaunchPad" + +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* BOARD_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/launchpad/launchpad-sensors.c b/platform/srf06-cc26xx/launchpad/launchpad-sensors.c new file mode 100644 index 000000000..c940ec68c --- /dev/null +++ b/platform/srf06-cc26xx/launchpad/launchpad-sensors.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup launchpad-peripherals + * @{ + * + * \file + * Generic module controlling LaunchPad sensors + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "launchpad/button-sensor.h" + +#include +/*---------------------------------------------------------------------------*/ +/** \brief Exports a global symbol to be used by the sensor API */ +SENSORS(&button_left_sensor, &button_right_sensor); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/launchpad/leds-arch.c b/platform/srf06-cc26xx/launchpad/leds-arch.c new file mode 100644 index 000000000..e853487fd --- /dev/null +++ b/platform/srf06-cc26xx/launchpad/leds-arch.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup launchpad-peripherals + * @{ + * + * \file + * Driver for LaunchPad LEDs + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/leds.h" + +#include "ti-lib.h" +/*---------------------------------------------------------------------------*/ +static unsigned char c; +static int inited = 0; +/*---------------------------------------------------------------------------*/ +void +leds_arch_init(void) +{ + if(inited) { + return; + } + inited = 1; + + ti_lib_rom_ioc_pin_type_gpio_output(BOARD_IOID_LED_1); + ti_lib_rom_ioc_pin_type_gpio_output(BOARD_IOID_LED_2); + + ti_lib_gpio_pin_write(BOARD_LED_ALL, 0); +} +/*---------------------------------------------------------------------------*/ +unsigned char +leds_arch_get(void) +{ + return c; +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set(unsigned char leds) +{ + c = leds; + ti_lib_gpio_pin_write(BOARD_LED_ALL, 0); + + if((leds & LEDS_RED) == LEDS_RED) { + ti_lib_gpio_pin_write(BOARD_LED_1, 1); + } + if((leds & LEDS_YELLOW) == LEDS_YELLOW) { + ti_lib_gpio_pin_write(BOARD_LED_2, 1); + } +} +/*---------------------------------------------------------------------------*/ +/** @} */ From 54f0a2ecbd8cdd64f8e022d5478ae8e383bcff1a Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 24 Jan 2016 16:54:20 +0000 Subject: [PATCH 015/374] Extend the CC26xx demo to support the LaunchPad --- examples/cc26xx/cc26xx-demo.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/examples/cc26xx/cc26xx-demo.c b/examples/cc26xx/cc26xx-demo.c index 544ae4dd8..53c607837 100644 --- a/examples/cc26xx/cc26xx-demo.c +++ b/examples/cc26xx/cc26xx-demo.c @@ -44,6 +44,7 @@ * This example will work for the following boards: * - srf06-cc26xx: SmartRF06EB + CC26XX EM * - sensortag-cc26xx: CC26XX sensortag + * - The CC2650 LaunchPad * * By default, the example will build for the srf06-cc26xx board. To switch * between platforms: @@ -114,6 +115,10 @@ #define CC26XX_DEMO_SENSOR_3 CC26XX_DEMO_SENSOR_NONE #define CC26XX_DEMO_SENSOR_4 CC26XX_DEMO_SENSOR_NONE #define CC26XX_DEMO_SENSOR_5 &reed_relay_sensor +#elif BOARD_LAUNCHPAD +#define CC26XX_DEMO_SENSOR_3 CC26XX_DEMO_SENSOR_NONE +#define CC26XX_DEMO_SENSOR_4 CC26XX_DEMO_SENSOR_NONE +#define CC26XX_DEMO_SENSOR_5 CC26XX_DEMO_SENSOR_NONE #else #define CC26XX_DEMO_SENSOR_3 &button_up_sensor #define CC26XX_DEMO_SENSOR_4 &button_down_sensor @@ -423,7 +428,7 @@ PROCESS_THREAD(cc26xx_demo_process, ev, data) get_tmp_reading(); } else if(ev == sensors_event && data == &mpu_9250_sensor) { get_mpu_reading(); -#else +#elif BOARD_SMARTRF06EB printf("Sel: Pin %d, press duration %d clock ticks\n", button_select_sensor.value(BUTTON_SENSOR_VALUE_STATE), button_select_sensor.value(BUTTON_SENSOR_VALUE_DURATION)); From 61e619dfcd340d22b7e79a37963389f7cadabae8 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 24 Jan 2016 16:54:45 +0000 Subject: [PATCH 016/374] Extend the CC26xx web demo to support the LaunchPad --- .../cc26xx/cc26xx-web-demo/cc26xx-web-demo.c | 4 ++-- .../cc26xx/cc26xx-web-demo/cc26xx-web-demo.h | 2 ++ examples/cc26xx/cc26xx-web-demo/coap-server.c | 18 ++++++++---------- .../cc26xx-web-demo/resources/res-leds.c | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/examples/cc26xx/cc26xx-web-demo/cc26xx-web-demo.c b/examples/cc26xx/cc26xx-web-demo/cc26xx-web-demo.c index 1eaf35648..a363c31d5 100644 --- a/examples/cc26xx/cc26xx-web-demo/cc26xx-web-demo.c +++ b/examples/cc26xx/cc26xx-web-demo/cc26xx-web-demo.c @@ -175,7 +175,7 @@ static void save_config() { /* Dump current running config to flash */ -#if BOARD_SENSORTAG +#if BOARD_SENSORTAG || BOARD_LAUNCHPAD int rv; cc26xx_web_demo_sensor_reading_t *reading = NULL; @@ -218,7 +218,7 @@ save_config() static void load_config() { -#if BOARD_SENSORTAG +#if BOARD_SENSORTAG || BOARD_LAUNCHPAD /* Read from flash into a temp buffer */ cc26xx_web_demo_config_t tmp_cfg; cc26xx_web_demo_sensor_reading_t *reading = NULL; diff --git a/examples/cc26xx/cc26xx-web-demo/cc26xx-web-demo.h b/examples/cc26xx/cc26xx-web-demo/cc26xx-web-demo.h index 026461f32..14bf3150c 100644 --- a/examples/cc26xx/cc26xx-web-demo/cc26xx-web-demo.h +++ b/examples/cc26xx/cc26xx-web-demo/cc26xx-web-demo.h @@ -100,6 +100,8 @@ #if BOARD_SENSORTAG /* Force an MQTT publish on sensor event */ #define CC26XX_WEB_DEMO_MQTT_PUBLISH_TRIGGER &reed_relay_sensor +#elif BOARD_LAUNCHPAD +#define CC26XX_WEB_DEMO_MQTT_PUBLISH_TRIGGER &button_left_sensor #else #define CC26XX_WEB_DEMO_MQTT_PUBLISH_TRIGGER &button_down_sensor #endif diff --git a/examples/cc26xx/cc26xx-web-demo/coap-server.c b/examples/cc26xx/cc26xx-web-demo/coap-server.c index 9b4155d00..518065f6e 100644 --- a/examples/cc26xx/cc26xx-web-demo/coap-server.c +++ b/examples/cc26xx/cc26xx-web-demo/coap-server.c @@ -63,6 +63,9 @@ extern resource_t res_parent_ip; extern resource_t res_ble_advd; #endif +extern resource_t res_toggle_red; +extern resource_t res_toggle_green; + /* Board-specific resources */ #if BOARD_SENSORTAG extern resource_t res_bmp280_temp; @@ -78,11 +81,7 @@ extern resource_t res_mpu_acc_z; extern resource_t res_mpu_gyro_x; extern resource_t res_mpu_gyro_y; extern resource_t res_mpu_gyro_z; -extern resource_t res_toggle_red; -extern resource_t res_toggle_green; #else -extern resource_t res_toggle_red; -extern resource_t res_toggle_green; extern resource_t res_toggle_orange; extern resource_t res_toggle_yellow; #endif @@ -96,6 +95,11 @@ const char *coap_server_supported_msg = "Supported:" static void start_board_resources(void) { + + rest_activate_resource(&res_toggle_green, "lt/g"); + rest_activate_resource(&res_toggle_red, "lt/r"); + rest_activate_resource(&res_leds, "lt"); + #if BOARD_SENSORTAG rest_activate_resource(&res_bmp280_temp, "sen/bar/temp"); rest_activate_resource(&res_bmp280_press, "sen/bar/pres"); @@ -110,14 +114,8 @@ start_board_resources(void) rest_activate_resource(&res_mpu_gyro_x, "sen/mpu/gyro/x"); rest_activate_resource(&res_mpu_gyro_y, "sen/mpu/gyro/y"); rest_activate_resource(&res_mpu_gyro_z, "sen/mpu/gyro/z"); - rest_activate_resource(&res_leds, "lt"); - rest_activate_resource(&res_toggle_green, "lt/g"); - rest_activate_resource(&res_toggle_red, "lt/r"); #elif BOARD_SMARTRF06EB - rest_activate_resource(&res_leds, "lt"); - rest_activate_resource(&res_toggle_red, "lt/r"); rest_activate_resource(&res_toggle_yellow, "lt/y"); - rest_activate_resource(&res_toggle_green, "lt/g"); rest_activate_resource(&res_toggle_orange, "lt/o"); #endif } diff --git a/examples/cc26xx/cc26xx-web-demo/resources/res-leds.c b/examples/cc26xx/cc26xx-web-demo/resources/res-leds.c index 2a86ad25b..85ce353b5 100644 --- a/examples/cc26xx/cc26xx-web-demo/resources/res-leds.c +++ b/examples/cc26xx/cc26xx-web-demo/resources/res-leds.c @@ -94,7 +94,7 @@ res_post_put_handler(void *request, void *response, uint8_t *buffer, * A simple actuator example, depending on the color query parameter and post * variable mode, corresponding led is activated or deactivated */ -#if BOARD_SENSORTAG +#if BOARD_SENSORTAG || BOARD_LAUNCHPAD #define RESOURCE_PARAMS "r|g" #elif BOARD_SMARTRF06EB #define RESOURCE_PARAMS "r|g|y|o" From c71eacbcc92e232e95250e3a905a93c16d075a6c Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 24 Jan 2016 16:56:22 +0000 Subject: [PATCH 017/374] Compile-test CC2650 LaunchPad sources --- regression-tests/18-compile-arm-ports/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/regression-tests/18-compile-arm-ports/Makefile b/regression-tests/18-compile-arm-ports/Makefile index a292bb3e3..4243e05b0 100644 --- a/regression-tests/18-compile-arm-ports/Makefile +++ b/regression-tests/18-compile-arm-ports/Makefile @@ -11,6 +11,7 @@ cc26xx/cc26xx-web-demo/srf06-cc26xx \ cc26xx/very-sleepy-demo/srf06-cc26xx:BOARD=sensortag/cc2650 \ cc26xx/cc26xx-web-demo/srf06-cc26xx:BOARD=sensortag/cc2650 \ cc26xx/cc26xx-web-demo/srf06-cc26xx:BOARD=srf06/cc13xx \ +cc26xx/cc26xx-web-demo/srf06-cc26xx:BOARD=launchpad/cc2650 \ cc26xx/very-sleepy-demo/srf06-cc26xx \ hello-world/cc2538dk \ ipv6/rpl-border-router/cc2538dk \ From deb633216cc3150db632a51e3c1b976bcf310bed Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 24 Jan 2016 16:57:08 +0000 Subject: [PATCH 018/374] Document support for the CC2650 LaunchPad --- platform/srf06-cc26xx/README.md | 6 ++++++ platform/srf06-cc26xx/contiki-main.c | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/platform/srf06-cc26xx/README.md b/platform/srf06-cc26xx/README.md index 32071745c..1be849c3b 100644 --- a/platform/srf06-cc26xx/README.md +++ b/platform/srf06-cc26xx/README.md @@ -7,6 +7,7 @@ platform supports two different boards: * SmartRF 06 Evaluation Board with a CC26xx or CC13xx Evaluation Module (relevant files and drivers are under `srf06/`) * CC2650 SensorTag 2.0 (relevant drivers under `sensortag/cc2650`) +* CC2650 LaunchPad (relevant drivers under `launchpad/cc2650`) The CPU code, common for both platforms, can be found under `$(CONTIKI)/cpu/cc26xx-cc13xx`. The port was developed and tested with CC2650s, but the intention is for it to @@ -44,6 +45,10 @@ In terms of hardware support, the following drivers have been implemented: * OPT3001 sensor * Buzzer * External SPI flash +* Launchpad + * LEDs + * Buttons + * External SPI flash Requirements ============ @@ -93,6 +98,7 @@ Other options for the `BOARD` make variable are: * Srf06+CC26xxEM: Set `BOARD=srf06/cc26xx` * Srf06+CC13xxEM: Set `BOARD=srf06/cc13xx` * CC2650 tag: Set `BOARD=sensortag/cc2650` +* CC2650 Launchpad: Set `BOARD=launchpad/cc2650` If the `BOARD` variable is unspecified, an image for the Srf06 CC26XXEM will be built. diff --git a/platform/srf06-cc26xx/contiki-main.c b/platform/srf06-cc26xx/contiki-main.c index 83b67118f..b103918e7 100644 --- a/platform/srf06-cc26xx/contiki-main.c +++ b/platform/srf06-cc26xx/contiki-main.c @@ -32,12 +32,13 @@ * \addtogroup cc26xx-platforms * @{ * - * \defgroup cc26xx-srf-tag SmartRF+CC13xx/CC26xx EM and the CC2650 SensorTag + * \defgroup cc26xx-srf-tag SmartRF+CC13xx/CC26xx EM, CC2650 SensorTag and LaunchPad * * This platform supports a number of different boards: * - A standard TI SmartRF06EB with a CC26xx EM mounted on it * - A standard TI SmartRF06EB with a CC1310 EM mounted on it * - The new TI SensorTag2.0 + * - The TI CC2650 LaunchPad * @{ */ #include "ti-lib.h" From 16145f645a1a48abb865f978ffea847ae7f4b027 Mon Sep 17 00:00:00 2001 From: Michael LeMay Date: Fri, 12 Feb 2016 13:45:25 -0800 Subject: [PATCH 019/374] galileo: build_newlib.sh: Only apply patch files with the extension ".patch" This avoids treating as patches other files that may happen to be present in the newlib patch directory in a working tree. --- platform/galileo/bsp/libc/build_newlib.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/galileo/bsp/libc/build_newlib.sh b/platform/galileo/bsp/libc/build_newlib.sh index cef167e14..a3354a286 100755 --- a/platform/galileo/bsp/libc/build_newlib.sh +++ b/platform/galileo/bsp/libc/build_newlib.sh @@ -38,7 +38,7 @@ prepare() { tar xf ${TARBALL} cd ${SRC_DIR} - for i in `ls ${PATCH_DIR}`; do patch -p0 < ${PATCH_DIR}/${i}; done + for i in `ls ${PATCH_DIR}/*.patch`; do patch -p0 < ${i}; done } From 1cc659d882bbb07f1bb9c2f993cc4127163c0e9f Mon Sep 17 00:00:00 2001 From: Wojciech Bober Date: Sat, 24 Oct 2015 18:21:05 +0200 Subject: [PATCH 020/374] Allow for using a fixed frame header length. When SICSLOWPAN_FRAMER_HDRLEN is defined its value is used as a frame header length. This allows for using sicslowpan without calling a framer. This is usefull if framer is not used on a given platform or when header length is always the same. In addition this commit also fixes an inline define. --- core/net/ipv6/sicslowpan.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/core/net/ipv6/sicslowpan.c b/core/net/ipv6/sicslowpan.c index d0bf14799..7fbdbefc7 100644 --- a/core/net/ipv6/sicslowpan.c +++ b/core/net/ipv6/sicslowpan.c @@ -169,6 +169,14 @@ void uip_log(char *msg); #define COMPRESSION_THRESHOLD 0 #endif +/** \brief Fixed size of a frame header. This value is + * used in case framer returns an error or if SICSLOWPAN_USE_FIXED_HDRLEN + * is defined. + */ +#ifndef SICSLOWPAN_FIXED_HDRLEN +#define SICSLOWPAN_FIXED_HDRLEN 21 +#endif + /** \name General variables * @{ */ @@ -1345,16 +1353,15 @@ output(const uip_lladdr_t *localdest) /* Calculate NETSTACK_FRAMER's header length, that will be added in the NETSTACK_RDC. * We calculate it here only to make a better decision of whether the outgoing packet * needs to be fragmented or not. */ -#define USE_FRAMER_HDRLEN 1 -#if USE_FRAMER_HDRLEN +#ifndef SICSLOWPAN_USE_FIXED_HDRLEN packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &dest); framer_hdrlen = NETSTACK_FRAMER.length(); if(framer_hdrlen < 0) { /* Framing failed, we assume the maximum header length */ - framer_hdrlen = 21; + framer_hdrlen = SICSLOWPAN_FIXED_HDRLEN; } #else /* USE_FRAMER_HDRLEN */ - framer_hdrlen = 21; + framer_hdrlen = SICSLOWPAN_FIXED_HDRLEN; #endif /* USE_FRAMER_HDRLEN */ max_payload = MAC_MAX_PAYLOAD - framer_hdrlen; From 803d170b55ab8725c8a3733c83ae06afea126bab Mon Sep 17 00:00:00 2001 From: Wojciech Bober Date: Wed, 23 Dec 2015 21:21:51 +0100 Subject: [PATCH 021/374] Fixed unsused variable warning when SICSLOWPAN_CONF_FRAG is undefined --- core/net/ipv6/sicslowpan.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/core/net/ipv6/sicslowpan.c b/core/net/ipv6/sicslowpan.c index 7fbdbefc7..5453d9e21 100644 --- a/core/net/ipv6/sicslowpan.c +++ b/core/net/ipv6/sicslowpan.c @@ -1285,11 +1285,6 @@ output(const uip_lladdr_t *localdest) /* The MAC address of the destination of the packet */ linkaddr_t dest; -#if SICSLOWPAN_CONF_FRAG - /* Number of bytes processed. */ - uint16_t processed_ip_out_len; -#endif /* SICSLOWPAN_CONF_FRAG */ - /* init */ uncomp_hdr_len = 0; packetbuf_hdr_len = 0; @@ -1367,6 +1362,9 @@ output(const uip_lladdr_t *localdest) max_payload = MAC_MAX_PAYLOAD - framer_hdrlen; if((int)uip_len - (int)uncomp_hdr_len > max_payload - (int)packetbuf_hdr_len) { #if SICSLOWPAN_CONF_FRAG + /* Number of bytes processed. */ + uint16_t processed_ip_out_len; + struct queuebuf *q; uint16_t frag_tag; From 0671640ea285beffb11e8d0f074c194e4d090119 Mon Sep 17 00:00:00 2001 From: Wojciech Bober Date: Wed, 23 Dec 2015 21:29:03 +0100 Subject: [PATCH 022/374] Extended SOURCEDIRS variable with EXTRALDIRS variable in Makefile.include Directories listed in this variable are added to include and source (vpath) search paths. Contents of this variable aren't automatically prefixed with Contki root. This allows for inclusion of folders that are outside Contiki root. --- Makefile.include | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.include b/Makefile.include index 36b5e06ca..67b0ff595 100644 --- a/Makefile.include +++ b/Makefile.include @@ -182,7 +182,7 @@ CONTIKI_CPU_DIRS_CONCAT = ${addprefix $(CONTIKI_CPU)/, \ $(CONTIKI_CPU_DIRS)} SOURCEDIRS = . $(PROJECTDIRS) $(CONTIKI_TARGET_DIRS_CONCAT) \ - $(CONTIKI_CPU_DIRS_CONCAT) $(CONTIKIDIRS) $(APPDS) ${dir $(target_makefile)} + $(CONTIKI_CPU_DIRS_CONCAT) $(CONTIKIDIRS) $(APPDS) $(EXTERNALDIRS) ${dir $(target_makefile)} vpath %.c $(SOURCEDIRS) vpath %.S $(SOURCEDIRS) From 20f9515ed1b7fdf7cdd097e19ea0821e3f6cd86c Mon Sep 17 00:00:00 2001 From: Wojciech Bober Date: Sat, 9 Jan 2016 14:44:18 +0100 Subject: [PATCH 023/374] nrf52dk: cpu/nrf52832 support --- cpu/nrf52832/Makefile.nrf52832 | 262 ++++++++++++++++++ cpu/nrf52832/ble/ble-core.c | 238 +++++++++++++++++ cpu/nrf52832/ble/ble-core.h | 61 +++++ cpu/nrf52832/ble/ble-mac.c | 386 +++++++++++++++++++++++++++ cpu/nrf52832/ble/ble-mac.h | 53 ++++ cpu/nrf52832/dev/clock.c | 171 ++++++++++++ cpu/nrf52832/dev/lpm.h | 67 +++++ cpu/nrf52832/dev/random.c | 90 +++++++ cpu/nrf52832/dev/uart0.c | 118 ++++++++ cpu/nrf52832/dev/uart0.h | 57 ++++ cpu/nrf52832/dev/watchdog.c | 93 +++++++ cpu/nrf52832/erase.jlink | 2 + cpu/nrf52832/flash.jlink | 4 + cpu/nrf52832/ld/nrf52-pca10036-sd.ld | 12 + cpu/nrf52832/ld/nrf52-pca10040-sd.ld | 12 + cpu/nrf52832/ld/nrf52.ld | 12 + cpu/nrf52832/mtarch.h | 48 ++++ cpu/nrf52832/putchar.c | 70 +++++ cpu/nrf52832/rtimer-arch.c | 110 ++++++++ cpu/nrf52832/rtimer-arch.h | 52 ++++ 20 files changed, 1918 insertions(+) create mode 100644 cpu/nrf52832/Makefile.nrf52832 create mode 100644 cpu/nrf52832/ble/ble-core.c create mode 100644 cpu/nrf52832/ble/ble-core.h create mode 100644 cpu/nrf52832/ble/ble-mac.c create mode 100644 cpu/nrf52832/ble/ble-mac.h create mode 100644 cpu/nrf52832/dev/clock.c create mode 100644 cpu/nrf52832/dev/lpm.h create mode 100644 cpu/nrf52832/dev/random.c create mode 100644 cpu/nrf52832/dev/uart0.c create mode 100644 cpu/nrf52832/dev/uart0.h create mode 100644 cpu/nrf52832/dev/watchdog.c create mode 100644 cpu/nrf52832/erase.jlink create mode 100644 cpu/nrf52832/flash.jlink create mode 100644 cpu/nrf52832/ld/nrf52-pca10036-sd.ld create mode 100644 cpu/nrf52832/ld/nrf52-pca10040-sd.ld create mode 100644 cpu/nrf52832/ld/nrf52.ld create mode 100644 cpu/nrf52832/mtarch.h create mode 100644 cpu/nrf52832/putchar.c create mode 100644 cpu/nrf52832/rtimer-arch.c create mode 100644 cpu/nrf52832/rtimer-arch.h diff --git a/cpu/nrf52832/Makefile.nrf52832 b/cpu/nrf52832/Makefile.nrf52832 new file mode 100644 index 000000000..f93f063f3 --- /dev/null +++ b/cpu/nrf52832/Makefile.nrf52832 @@ -0,0 +1,262 @@ +ifndef NRF52_SDK_ROOT + $(error NRF52_SDK_ROOT not defined! You must specify where nRF52 SDK resides!) +endif + +ifneq ($(filter %.flash erase,$(MAKECMDGOALS)),) +ifeq ($(NRF52_JLINK_PATH),) +NRF52_JLINK_PATH=$(shell location=$$(which JLinkExe) && dirname $$location) +endif +ifeq ($(NRF52_JLINK_PATH),) + $(error JLink not found in PATH and NRF52_JLINK_PATH path is not defined) +endif +endif + +ifeq ($(CONTIKI_WITH_RIME),1) + $(error Rime stack is not supported!) +endif + +ifneq ($(CONTIKI_WITH_IPV6),1) + $(error Only IPv6 stack is supported!) +endif + +$(info SDK: $(NRF52_SDK_ROOT)) + +ifeq ($(NRF52_DK_REVISION),) +NRF52_DK_REVISION=pca10040 +endif + +ifneq ($(NRF52_WITHOUT_SOFTDEVICE),1) + ifeq ($(NRF52_SOFTDEVICE),) + NRF52_SOFTDEVICE := $(shell find $(NRF52_SDK_ROOT) -name *iot*_softdevice.hex | head -n 1) + endif + $(info SoftDevice: $(NRF52_SOFTDEVICE)) + LINKER_SCRIPT := $(CONTIKI_CPU)/ld/nrf52-$(NRF52_DK_REVISION)-sd.ld +else + LINKER_SCRIPT := $(CONTIKI_CPU)/ld/nrf52.ld +endif + +OUTPUT_FILENAME := $(CONTIKI_PROJECT) +MAKEFILE_NAME := $(MAKEFILE_LIST) +MAKEFILE_DIR := $(dir $(MAKEFILE_NAME) ) + +TEMPLATE_PATH = $(NRF52_SDK_ROOT)/components/toolchain/gcc + +OBJECT_DIRECTORY = $(OBJECTDIR) +LISTING_DIRECTORY := $(OBJECTDIR) +OUTPUT_BINARY_DIRECTORY := bin_$(TARGET) + +MK := mkdir +RM := rm -rf + +# Toolchain commands +CC := arm-none-eabi-gcc +AS := arm-none-eabi-as +AR := arm-none-eabi-ar +LD := arm-none-eabi-ld +NM := arm-none-eabi-nm +OBJDUMP := arm-none-eabi-objdump +OBJCOPY := arm-none-eabi-objcopy +SIZE := arm-none-eabi-size + +# JLink +JLINK := $(NRF52_JLINK_PATH)/JLinkExe +JLINK_OPTS = -Device NRF52 -if swd -speed 1000 +ifneq ($(NRF52_JLINK_SN),) +JLINK_OPTS += -SelectEmuBySN $(NRF52_JLINK_SN) +endif + +#function for removing duplicates in a list +remduplicates = $(strip $(if $1,$(firstword $1) $(call remduplicates,$(filter-out $(firstword $1),$1)))) + +### CPU-dependent directories +CONTIKI_CPU_DIRS += . dev ble #compat + +### CPU-dependent source files +CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c uart0.c putchar.c watchdog.c + +ifneq ($(NRF52_WITHOUT_SOFTDEVICE),1) +CONTIKI_CPU_SOURCEFILES += ble-core.c ble-mac.c +endif + +CONTIKI_SOURCEFILES += $(CONTIKI_CPU_SOURCEFILES) + +#source common to all targets +C_SOURCE_FILES += $(NRF52_SDK_ROOT)/components/drivers_nrf/common/nrf_drv_common.c \ + $(NRF52_SDK_ROOT)/components/drivers_nrf/gpiote/nrf_drv_gpiote.c \ + $(NRF52_SDK_ROOT)/components/drivers_nrf/rtc/nrf_drv_rtc.c \ + $(NRF52_SDK_ROOT)/components/drivers_nrf/clock/nrf_drv_clock.c \ + $(NRF52_SDK_ROOT)/components/drivers_nrf/timer/nrf_drv_timer.c \ + $(NRF52_SDK_ROOT)/components/drivers_nrf/wdt/nrf_drv_wdt.c \ + $(NRF52_SDK_ROOT)/components/drivers_nrf/rng/nrf_drv_rng.c \ + $(NRF52_SDK_ROOT)/components/drivers_nrf/delay/nrf_delay.c \ + $(NRF52_SDK_ROOT)/components/drivers_nrf/uart/nrf_drv_uart.c \ + $(NRF52_SDK_ROOT)/components/libraries/util/app_error.c \ + $(NRF52_SDK_ROOT)/components/toolchain/system_nrf52.c + +ifneq ($(NRF52_WITHOUT_SOFTDEVICE),1) +C_SOURCE_FILES += $(NRF52_SDK_ROOT)/components/softdevice/common/softdevice_handler/softdevice_handler.c \ + $(NRF52_SDK_ROOT)/components/ble/common/ble_advdata.c +else +C_SOURCE_FILES += $(NRF52_SDK_ROOT)/components/libraries/fifo/app_fifo.c \ + $(NRF52_SDK_ROOT)/components/libraries/util/app_util_platform.c +endif + +#assembly files common to all targets +ASM_SOURCE_FILES = $(NRF52_SDK_ROOT)/components/toolchain/gcc/gcc_startup_nrf52.s + +#includes common to all targets +INC_PATHS += components/drivers_nrf/gpiote +INC_PATHS += components/drivers_nrf/hal +INC_PATHS += components/drivers_nrf/config +INC_PATHS += components/drivers_nrf/delay +INC_PATHS += components/drivers_nrf/uart +INC_PATHS += components/drivers_nrf/common +INC_PATHS += components/drivers_nrf/rtc +INC_PATHS += components/drivers_nrf/wdt +INC_PATHS += components/drivers_nrf/rng +INC_PATHS += components/drivers_nrf/clock +INC_PATHS += components/drivers_nrf/timer +INC_PATHS += components/libraries/util +INC_PATHS += components/libraries/timer +INC_PATHS += components/device +INC_PATHS += components/toolchain/gcc +INC_PATHS += components/toolchain +INC_PATHS += examples/bsp + +ifneq ($(NRF52_WITHOUT_SOFTDEVICE),1) +INC_PATHS += components/softdevice/s1xx_iot/headers +INC_PATHS += components/softdevice/s1xx_iot/headers/nrf52 +INC_PATHS += components/softdevice/common/softdevice_handler +INC_PATHS += components/ble/common +INC_PATHS += components/iot/common +INC_PATHS += components/iot/ble_ipsp +else +INC_PATHS += components/drivers_nrf/nrf_soc_nosd +INC_PATHS += components/libraries/fifo +endif + +EXTERNALDIRS += $(addprefix $(NRF52_SDK_ROOT)/, $(INC_PATHS)) + +# Sorting removes duplicates +BUILD_DIRECTORIES := $(sort $(OUTPUT_BINARY_DIRECTORY) $(LISTING_DIRECTORY)) + +# Clean files and directories +CLEAN += bin_$(TARGET) lst_$(TARGET) nrf52832.a *.elf *.hex + +#flags common to all targets +ifneq ($(NRF52_WITHOUT_SOFTDEVICE),1) +CFLAGS += -DSOFTDEVICE_PRESENT +CFLAGS += -DS132 +endif + +ifeq ($(SMALL),1) +CFLAGS += -Os +else +CFLAGS += -O2 +endif + +CFLAGS += -DNRF52 +CFLAGS += -DBOARD_$(shell echo $(NRF52_DK_REVISION) | tr a-z A-Z) +CFLAGS += -D__HEAP_SIZE=512 +CFLAGS += -DSWI_DISABLE0 +CFLAGS += -DCONFIG_GPIO_AS_PINRESET +CFLAGS += -DBLE_STACK_SUPPORT_REQD +CFLAGS += -mcpu=cortex-m4 +CFLAGS += -mthumb -mabi=aapcs --std=gnu99 +CFLAGS += -Wall -Werror +CFLAGS += -ggdb +CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16 +# keep every function in separate section. This will allow linker to dump unused functions +CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing +CFLAGS += -fno-builtin --short-enums + +# keep every function in separate section. This will allow linker to dump unused functions +LDFLAGS += -Xlinker -Map=$(LISTING_DIRECTORY)/$(OUTPUT_FILENAME).map +LDFLAGS += -mthumb -mabi=aapcs -L $(TEMPLATE_PATH) -T$(LINKER_SCRIPT) +LDFLAGS += -mcpu=cortex-m4 +LDFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16 +# let linker to dump unused sections +LDFLAGS += -Wl,--gc-sections +# use newlib in nano version +LDFLAGS += --specs=nano.specs -lc -lnosys + +# Assembler flags +ifneq ($(NRF52_WITHOUT_SOFTDEVICE),1) +ASMFLAGS += -DSOFTDEVICE_PRESENT +ASMFLAGS += -DS132 +endif +ASMFLAGS += -x assembler-with-cpp +ASMFLAGS += -DSWI_DISABLE0 +ASMFLAGS += -DNRF52 +ASMFLAGS += -DBOARD_$(shell echo $(NRF52_DK_REVISION) | tr a-z A-Z) +ASMFLAGS += -DCONFIG_GPIO_AS_PINRESET +ASMFLAGS += -DBLE_STACK_SUPPORT_REQD + +C_SOURCE_FILE_NAMES = $(notdir $(C_SOURCE_FILES)) +C_PATHS = $(call remduplicates, $(dir $(C_SOURCE_FILES) ) ) +C_OBJECTS = $(addprefix $(OBJECT_DIRECTORY)/, $(C_SOURCE_FILE_NAMES:.c=.o) ) + +ASM_SOURCE_FILE_NAMES = $(notdir $(ASM_SOURCE_FILES)) +ASM_PATHS = $(call remduplicates, $(dir $(ASM_SOURCE_FILES) )) +ASM_OBJECTS = $(addprefix $(OBJECT_DIRECTORY)/, $(ASM_SOURCE_FILE_NAMES:.s=.o) ) + +vpath %.c $(C_PATHS) +vpath %.s $(ASM_PATHS) + +OBJECTS = $(C_OBJECTS) $(ASM_OBJECTS) + +TARGET_LIBS= nrf52832.a $(NRF52_SDK_ROOT)/components/iot/ble_6lowpan/lib/ble_6lowpan.a + +### Don't treat the .elf as intermediate +.PRECIOUS: %.hex %.bin + +nrf52832.a: $(OBJECTS) + $(TRACE_AR) + $(Q)$(AR) $(AROPTS) $@ $^ + +### Compilation rules +CUSTOM_RULE_LINK=1 + +%.elf: $(TARGET_STARTFILES) %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a $(TARGET_LIBS) + $(TRACE_LD) + $(Q)$(CC) $(LDFLAGS) ${filter %o %.co %.a,$^} -o $@ + +# Assemble files +$(OBJECT_DIRECTORY)/%.o: %.s + @echo Compiling file: $(notdir $<) + $(Q)$(CC) $(ASMFLAGS) $(addprefix -I$(NRF52_SDK_ROOT)/, $(INC_PATHS)) -c -o $@ $< + +# Create binary file from the .out file +%.bin: %.elf + @echo Preparing: $@ + $(Q)$(OBJCOPY) -O binary $^ $@ + +# Create binary .hex file from the .out file +%.hex: %.elf + @echo Preparing: $@ + $(Q)$(OBJCOPY) -O ihex $^ $@ + +### We don't really need the .hex and .bin for the .$(TARGET) but let's make +### sure they get built +%.$(TARGET): %.elf %.hex %.bin + cp $*.elf $@ + $(Q)$(SIZE) $@ + +%.jlink: + sed -e 's/#OUTPUT_FILENAME#/$*.hex/' $(CONTIKI_CPU)/flash.jlink > $@ + +%.flash: %.hex %.jlink + @echo Flashing: $^ + $(JLINK) $(JLINK_OPTS) -CommanderScript $*.jlink + +softdevice.jlink: + sed -e 's,#OUTPUT_FILENAME#,$(NRF52_SOFTDEVICE),' $(CONTIKI_CPU)/flash.jlink > $@ + +softdevice.flash: softdevice.jlink + @echo Flashing: $(notdir $(NRF52_SOFTDEVICE)) + $(JLINK) $(JLINK_OPTS) -CommanderScript $^ + +erase: + $(JLINK) $(JLINK_OPTS) -CommanderScript $(CONTIKI_CPU)/erase.jlink + +.PHONY: softdevice.jlink diff --git a/cpu/nrf52832/ble/ble-core.c b/cpu/nrf52832/ble/ble-core.c new file mode 100644 index 000000000..cb3d4ce66 --- /dev/null +++ b/cpu/nrf52832/ble/ble-core.c @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * 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. + * + */ +/** + * \addtogroup cpu + * @{ + * + * \addtogroup nrf52832 + * @{ + * + * \addtogroup nrf52832-ble Bluetooth Low Energy drivers + * @{ + * + * \file + * Basic BLE functions. + * \author + * Wojciech Bober + * + */ +#include +#include +#include "boards.h" +#include "nordic_common.h" +#include "nrf_delay.h" +#include "nrf_sdm.h" +#include "ble_advdata.h" +#include "ble_srv_common.h" +#include "ble_ipsp.h" +#include "softdevice_handler.h" +#include "app_error.h" +#include "iot_defines.h" +#include "ble-core.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#define IS_SRVC_CHANGED_CHARACT_PRESENT 1 +#define APP_ADV_TIMEOUT 0 /**< Time for which the device must be advertising in non-connectable mode (in seconds). 0 disables timeout. */ +#define APP_ADV_ADV_INTERVAL MSEC_TO_UNITS(333, UNIT_0_625_MS) /**< The advertising interval. This value can vary between 100ms to 10.24s). */ + +static ble_gap_adv_params_t m_adv_params; /**< Parameters to be passed to the stack when starting advertising. */ + +static void +ble_evt_dispatch(ble_evt_t * p_ble_evt); +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize and enable the BLE stack. + */ +void +ble_stack_init(void) +{ + uint32_t err_code; + + // Enable BLE stack. + ble_enable_params_t ble_enable_params; + memset(&ble_enable_params, 0, sizeof(ble_enable_params)); + ble_enable_params.gatts_enable_params.attr_tab_size = + BLE_GATTS_ATTR_TAB_SIZE_DEFAULT; + ble_enable_params.gatts_enable_params.service_changed = + IS_SRVC_CHANGED_CHARACT_PRESENT; + err_code = sd_ble_enable(&ble_enable_params); + APP_ERROR_CHECK(err_code); + + // Register with the SoftDevice handler module for BLE events. + err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch); + APP_ERROR_CHECK(err_code); + + // Setup address + ble_gap_addr_t ble_addr; + err_code = sd_ble_gap_address_get(&ble_addr); + APP_ERROR_CHECK(err_code); + + ble_addr.addr[5] = 0x00; + ble_addr.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC; + + err_code = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &ble_addr); + APP_ERROR_CHECK(err_code); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Return device EUI64 MAC address + * \param addr pointer to a buffer to store the address + */ +void +ble_get_mac(uint8_t addr[8]) +{ + uint32_t err_code; + ble_gap_addr_t ble_addr; + + err_code = sd_ble_gap_address_get(&ble_addr); + APP_ERROR_CHECK(err_code); + + IPV6_EUI64_CREATE_FROM_EUI48(addr, ble_addr.addr, ble_addr.addr_type); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize BLE advertising data. + * \param name Human readable device name that will be advertised + */ +void +ble_advertising_init(const char *name) +{ + uint32_t err_code; + ble_advdata_t advdata; + uint8_t flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; + ble_gap_conn_sec_mode_t sec_mode; + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); + + err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *)name, + strlen(name)); + APP_ERROR_CHECK(err_code); + + ble_uuid_t adv_uuids[] = {{BLE_UUID_IPSP_SERVICE, BLE_UUID_TYPE_BLE}}; + + // Build and set advertising data. + memset(&advdata, 0, sizeof(advdata)); + + advdata.name_type = BLE_ADVDATA_FULL_NAME; + advdata.flags = flags; + advdata.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]); + advdata.uuids_complete.p_uuids = adv_uuids; + + err_code = ble_advdata_set(&advdata, NULL); + APP_ERROR_CHECK(err_code); + + // Initialize advertising parameters (used when starting advertising). + memset(&m_adv_params, 0, sizeof(m_adv_params)); + + m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND; + m_adv_params.p_peer_addr = NULL; // Undirected advertisement. + m_adv_params.fp = BLE_GAP_ADV_FP_ANY; + m_adv_params.interval = APP_ADV_ADV_INTERVAL; + m_adv_params.timeout = APP_ADV_TIMEOUT; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Start BLE advertising. + */ +void +ble_advertising_start(void) +{ + uint32_t err_code; + + err_code = sd_ble_gap_adv_start(&m_adv_params); + APP_ERROR_CHECK(err_code); + + PRINTF("ble-core: advertising started\n"); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Print GAP address. + * \param addr a pointer to address + */ +void +ble_gap_addr_print(const ble_gap_addr_t *addr) +{ + unsigned int i; + for(i = 0; i < sizeof(addr->addr); i++) { + if(i > 0) { + PRINTF(":"); + }PRINTF("%02x", addr->addr[i]); + }PRINTF(" (%d)", addr->addr_type); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Function for handling the Application's BLE Stack events. + * \param[in] p_ble_evt Bluetooth stack event. + */ +static void +on_ble_evt(ble_evt_t *p_ble_evt) +{ + switch(p_ble_evt->header.evt_id) { + case BLE_GAP_EVT_CONNECTED: + PRINTF("ble-core: connected [handle:%d, peer: ", p_ble_evt->evt.gap_evt.conn_handle); + ble_gap_addr_print(&(p_ble_evt->evt.gap_evt.params.connected.peer_addr)); + PRINTF("]\n"); + sd_ble_gap_rssi_start(p_ble_evt->evt.gap_evt.conn_handle, + BLE_GAP_RSSI_THRESHOLD_INVALID, + 0); + break; + + case BLE_GAP_EVT_DISCONNECTED: + PRINTF("ble-core: disconnected [handle:%d]\n", p_ble_evt->evt.gap_evt.conn_handle); + ble_advertising_start(); + break; + default: + break; + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief SoftDevice BLE event callback. + * \param[in] p_ble_evt Bluetooth stack event. + */ +static void +ble_evt_dispatch(ble_evt_t *p_ble_evt) +{ + ble_ipsp_evt_handler(p_ble_evt); + on_ble_evt(p_ble_evt); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + * @} + */ diff --git a/cpu/nrf52832/ble/ble-core.h b/cpu/nrf52832/ble/ble-core.h new file mode 100644 index 000000000..84c181d2e --- /dev/null +++ b/cpu/nrf52832/ble/ble-core.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * 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. + * + */ +/** + * \addtogroup cpu + * @{ + * + * \addtogroup nrf52832 + * @{ + * + * \addtogroup nrf52832-ble Bluetooth Low Energy drivers + * @{ + * + * \file + * Basic BLE functions. + * \author + * Wojciech Bober + */ +#ifndef DEV_BLE_H_ +#define DEV_BLE_H_ + +#include + +void ble_stack_init(void); +void ble_advertising_init(const char *name); +void ble_advertising_start(void); +void ble_get_mac(uint8_t addr[8]); + +#endif /* DEV_BLE_H_ */ + +/** + * @} + * @} + * @} + */ diff --git a/cpu/nrf52832/ble/ble-mac.c b/cpu/nrf52832/ble/ble-mac.c new file mode 100644 index 000000000..6ffd87a82 --- /dev/null +++ b/cpu/nrf52832/ble/ble-mac.c @@ -0,0 +1,386 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * 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. + * + */ +/** + * \addtogroup nrf52832-ble + * @{ + * + * \file + * A MAC protocol implementation that uses nRF52 IPSP implementation + * as a link layer. + * \author + * Wojciech Bober + */ +#include +#include +#include "app_error.h" +#include "ble_ipsp.h" +#include "nrf_soc.h" +#include "iot_defines.h" + +#include "net/mac/nullmac.h" +#include "net/netstack.h" +#include "net/ip/uip.h" +#include "net/ip/tcpip.h" +#include "net/packetbuf.h" +#include "net/netstack.h" +#include "net/linkaddr.h" + +#include "dev/watchdog.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#ifndef BLE_MAC_MAX_INTERFACE_NUM +#define BLE_MAC_MAX_INTERFACE_NUM 1 /**< Maximum number of interfaces, i.e., connection to master devices */ +#endif + +/*---------------------------------------------------------------------------*/ +process_event_t ble_event_interface_added; /**< This event is broadcast when BLE connection is established */ +process_event_t ble_event_interface_deleted; /**< This event is broadcast when BLE connection is destroyed */ + +/*---------------------------------------------------------------------------*/ +PROCESS(ble_ipsp_process, "BLE IPSP process"); + +/*---------------------------------------------------------------------------*/ +/** + * \brief A structure that binds IPSP connection with a peer address. + */ +typedef struct { + eui64_t peer_addr; + ble_ipsp_handle_t handle; +} ble_mac_interface_t; + +static ble_mac_interface_t interfaces[BLE_MAC_MAX_INTERFACE_NUM]; + +static volatile int busy_tx; /**< Flag is set to 1 when the driver is busy transmitting a packet. */ +static volatile int busy_rx; /**< Flag is set to 1 when there is a received packet pending. */ + +struct { + eui64_t src; + uint8_t payload[PACKETBUF_SIZE]; + uint16_t len; + int8_t rssi; +} input_packet; + +static mac_callback_t mac_sent_cb; +static void *mac_sent_ptr; + +/*---------------------------------------------------------------------------*/ +/** + * \brief Lookup interface by IPSP connection. + * + * \param handle a pointer to IPSP handle. + * \retval a pointer to interface structure + * \retval NULL if no interface has been found for a given handle + */ +static ble_mac_interface_t * +ble_mac_interface_lookup(ble_ipsp_handle_t *handle) +{ + int i; + for(i = 0; i < BLE_MAC_MAX_INTERFACE_NUM; i++) { + if(interfaces[i].handle.conn_handle == handle->conn_handle && + interfaces[i].handle.cid == handle->cid) { + return &interfaces[i]; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Add IPSP connection to the interface table. + * + * This function binds IPSP connection with peer address. + * + * \param peer a pointer to eui64 address + * \param handle a pointer to IPSP handle + * + * \retval a pointer to an interface structure on success + * \retval NULL if interface table is full + */ +static ble_mac_interface_t * +ble_mac_interface_add(eui64_t *peer, ble_ipsp_handle_t *handle) +{ + int i; + for(i = 0; i < BLE_MAC_MAX_INTERFACE_NUM; i++) { + if(interfaces[i].handle.conn_handle == 0 && interfaces[i].handle.cid == 0) { + memcpy(&interfaces[i].handle, handle, sizeof(ble_ipsp_handle_t)); + memcpy(&interfaces[i].peer_addr, peer, sizeof(eui64_t)); + process_post(PROCESS_BROADCAST, ble_event_interface_added, NULL); + return &interfaces[i]; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Remove interface from the interface table. + * \param interface a pointer to interface + */ +static void +ble_mac_interface_delete(ble_mac_interface_t *interface) +{ + memset(interface, 0, sizeof(ble_mac_interface_t)); + process_post(PROCESS_BROADCAST, ble_event_interface_deleted, NULL); +} + +/*---------------------------------------------------------------------------*/ +/** + * \brief Callback registered with IPSP to receive asynchronous events from the module. + * \note This function is called from SoftDevice interrupt context. + * + * \param[in] p_handle Pointer to IPSP handle. + * \param[in] p_evt Pointer to specific event, generated by IPSP module. + * + * \return NRF_SUCCESS on success, otherwise NRF_ERROR_NO_MEM error. + */ +static uint32_t +ble_mac_ipsp_evt_handler_irq(ble_ipsp_handle_t *p_handle, ble_ipsp_evt_t *p_evt) +{ + uint32_t retval = NRF_SUCCESS; + + ble_mac_interface_t *p_instance = NULL; + p_instance = ble_mac_interface_lookup(p_handle); + + if(p_handle) { + PRINTF("ble-mac: IPSP event [handle:%d CID 0x%04X]\n", p_handle->conn_handle, p_handle->cid); + } + + switch(p_evt->evt_id) { + case BLE_IPSP_EVT_CHANNEL_CONNECTED: { + eui64_t peer_addr; + + PRINTF("ble-mac: channel connected\n"); + + IPV6_EUI64_CREATE_FROM_EUI48( + peer_addr.identifier, + p_evt->evt_param->params.ch_conn_request.peer_addr.addr, + p_evt->evt_param->params.ch_conn_request.peer_addr.addr_type); + + p_instance = ble_mac_interface_add(&peer_addr, p_handle); + + if(p_instance != NULL) { + PRINTF("ble-mac: added new IPSP interface\n"); + } else { + PRINTF("ble-mac: cannot add new interface. Table is full\n"); + ble_ipsp_disconnect(p_handle); + } + break; + } + + case BLE_IPSP_EVT_CHANNEL_DISCONNECTED: { + PRINTF("ble-mac: channel disconnected\n"); + if(p_instance != NULL) { + PRINTF("ble-mac: removed IPSP interface\n"); + ble_mac_interface_delete(p_instance); + } + break; + } + + case BLE_IPSP_EVT_CHANNEL_DATA_RX: { + PRINTF("ble-mac: data received\n"); + if(p_instance != NULL) { + if(busy_rx) { + PRINTF("ble-mac: packet dropped as input buffer is busy\n"); + break; + } + + if(p_evt->evt_param->params.ch_rx.len > PACKETBUF_SIZE) { + PRINTF("ble-mac: packet buffer is too small!\n"); + break; + } + + busy_rx = 1; + + input_packet.len = p_evt->evt_param->params.ch_rx.len; + memcpy(input_packet.payload, p_evt->evt_param->params.ch_rx.p_data, input_packet.len); + memcpy(input_packet.src.identifier, p_instance->peer_addr.identifier, sizeof(eui64_t)); + sd_ble_gap_rssi_get(p_handle->conn_handle, &input_packet.rssi); + + process_poll(&ble_ipsp_process); + } else { + PRINTF("ble-mac: got data to unknown interface!\n"); + } + break; + } + + case BLE_IPSP_EVT_CHANNEL_DATA_TX_COMPLETE: { + PRINTF("ble-mac: data transmitted\n"); + busy_tx = 0; + break; + } + } + + return retval; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(ble_ipsp_process, ev, data) +{ + PROCESS_BEGIN(); + + while(1) { + PROCESS_WAIT_EVENT(); + if(ev == PROCESS_EVENT_POLL) { + packetbuf_copyfrom(input_packet.payload, input_packet.len); + packetbuf_set_attr(PACKETBUF_ATTR_RSSI, input_packet.rssi); + packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (const linkaddr_t *)input_packet.src.identifier); + packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &linkaddr_node_addr); + busy_rx = 0; + NETSTACK_LLSEC.input(); + } + } + + PROCESS_END(); +} + +/*---------------------------------------------------------------------------*/ +/** + * \brief Lookup IPSP handle by peer address. + * + * \param addr a pointer to eui64 address. + * \retval a pointer to IPSP handle on success + * \retval NULL if an IPSP handle for given address haven't been found + */ +static ble_ipsp_handle_t * +find_handle(const linkaddr_t *addr) +{ + int i; + for(i = 0; i < BLE_MAC_MAX_INTERFACE_NUM; i++) { + if(linkaddr_cmp((const linkaddr_t *)&interfaces[i].peer_addr, addr)) { + return &interfaces[i].handle; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Send packet on a given IPSP handle. + * + * \param handle a pointer to IPSP handle. + * \return 1 on success, 0 otherwise + */ +static int +send_to_peer(ble_ipsp_handle_t *handle) +{ + PRINTF("ble-mac: sending packet[GAP handle:%d CID:0x%04X]\n", handle->conn_handle, handle->cid); + return (ble_ipsp_send(handle, packetbuf_dataptr(), packetbuf_datalen()) == NRF_SUCCESS); +} +/*---------------------------------------------------------------------------*/ +static void +send_packet(mac_callback_t sent, void *ptr) +{ + int i; + const linkaddr_t *dest; + ble_ipsp_handle_t *handle; + int ret = 0; + + mac_sent_cb = sent; + mac_sent_ptr = ptr; + + dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER); + + if(linkaddr_cmp(dest, &linkaddr_null)) { + for(i = 0; i < BLE_MAC_MAX_INTERFACE_NUM; i++) { + if(interfaces[i].handle.cid != 0 && interfaces[i].handle.conn_handle != 0) { + ret = send_to_peer(&interfaces[i].handle); + watchdog_periodic(); + } + } + } else if((handle = find_handle(dest)) != NULL) { + ret = send_to_peer(handle); + } else { + PRINTF("ble-mac: no connection found for peer"); + } + + if(ret) { + busy_tx = 1; + while(busy_tx) { + watchdog_periodic(); + sd_app_evt_wait(); + } + mac_call_sent_callback(sent, ptr, MAC_TX_OK, 1); + } else { + mac_call_sent_callback(sent, ptr, MAC_TX_ERR, 1); + } +} +/*---------------------------------------------------------------------------*/ +static int +on(void) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +off(int keep_radio_on) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +static unsigned short +channel_check_interval(void) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ +// Initialize IPSP service + uint32_t err_code; + ble_ipsp_init_t ipsp_init_params; + + memset(&ipsp_init_params, 0, sizeof(ipsp_init_params)); + ipsp_init_params.evt_handler = ble_mac_ipsp_evt_handler_irq; + err_code = ble_ipsp_init(&ipsp_init_params); + APP_ERROR_CHECK(err_code); + + ble_event_interface_added = process_alloc_event(); + ble_event_interface_deleted = process_alloc_event(); + + process_start(&ble_ipsp_process, NULL); +} +/*---------------------------------------------------------------------------*/ +const struct mac_driver ble_ipsp_mac_driver = { + "nRF52 IPSP driver", + init, + send_packet, + NULL, + on, + off, + channel_check_interval, +}; +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/cpu/nrf52832/ble/ble-mac.h b/cpu/nrf52832/ble/ble-mac.h new file mode 100644 index 000000000..3dd9b82af --- /dev/null +++ b/cpu/nrf52832/ble/ble-mac.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * 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. + * + */ +/** + * \addtogroup nrf52832-ble + * @{ + * + * \file + * A MAC protocol implementation that uses nRF52 IPSP implementation + * as a link layer. + * \author + * Wojciech Bober + */ +#ifndef BLE_MAC_H_ +#define BLE_MAC_H_ + +#include "sys/process.h" +#include "net/mac/mac.h" + +extern const struct mac_driver ble_ipsp_mac_driver; /**< BLE over IPSP MAC driver structure */ +extern process_event_t ble_event_interface_added; /**< This event is broadcast when a new IPSP connection is established */ +extern process_event_t ble_event_interface_deleted; /**< This event is broadcast when a IPSP connection is deleted */ + +#endif /* BLE_MAC_H_ */ +/** + * @} + */ diff --git a/cpu/nrf52832/dev/clock.c b/cpu/nrf52832/dev/clock.c new file mode 100644 index 000000000..4ee09839d --- /dev/null +++ b/cpu/nrf52832/dev/clock.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2015 Nordic Semiconductor. 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +/** + * \addtogroup nrf52832 + * @{ + * + * \addtogroup nrf52832-dev Device drivers + * @{ + * + * \addtogroup nrf52832-clock Clock driver + * @{ + * + * \file + * Software clock implementation for the nRF52. + * \author + * Wojciech Bober + * + */ +/*---------------------------------------------------------------------------*/ +#include +#include +#include "nrf.h" +#include "nrf_drv_config.h" +#include "nrf_drv_rtc.h" +#include "nrf_drv_clock.h" +#include "nrf_delay.h" +#include "app_error.h" +#include "contiki.h" +#include "platform-conf.h" + +/*---------------------------------------------------------------------------*/ +const nrf_drv_rtc_t rtc = NRF_DRV_RTC_INSTANCE(PLATFORM_RTC_INSTANCE_ID); /**< RTC instance used for platform clock */ +/*---------------------------------------------------------------------------*/ +static volatile uint32_t ticks; +void clock_update(void); + +#define TICKS (RTC1_CONFIG_FREQUENCY/CLOCK_CONF_SECOND) + +/** + * \brief Function for handling the RTC0 interrupts + * \param int_type Type of interrupt to be handled + */ +static void +rtc_handler(nrf_drv_rtc_int_type_t int_type) +{ + if (int_type == NRF_DRV_RTC_INT_TICK) { + clock_update(); + } +} + +#ifndef SOFTDEVICE_PRESENT +/** \brief Function starting the internal LFCLK XTAL oscillator. + */ +static void +lfclk_config(void) +{ + ret_code_t err_code = nrf_drv_clock_init(NULL); + APP_ERROR_CHECK(err_code); + + nrf_drv_clock_lfclk_request(); +} +#endif + +/** + * \brief Function initialization and configuration of RTC driver instance. + */ +static void +rtc_config(void) +{ + uint32_t err_code; + + //Initialize RTC instance + err_code = nrf_drv_rtc_init(&rtc, NULL, rtc_handler); + APP_ERROR_CHECK(err_code); + + //Enable tick event & interrupt + nrf_drv_rtc_tick_enable(&rtc, true); + + //Power on RTC instance + nrf_drv_rtc_enable(&rtc); +} +/*---------------------------------------------------------------------------*/ +void +clock_init(void) +{ + ticks = 0; +#ifndef SOFTDEVICE_PRESENT + lfclk_config(); +#endif + rtc_config(); +} +/*---------------------------------------------------------------------------*/ +CCIF clock_time_t +clock_time(void) +{ + return (clock_time_t)(ticks & 0xFFFFFFFF); +} +/*---------------------------------------------------------------------------*/ +void +clock_update(void) +{ + ticks++; + if (etimer_pending()) { + etimer_request_poll(); + } +} +/*---------------------------------------------------------------------------*/ +CCIF unsigned long +clock_seconds(void) +{ + return (unsigned long)ticks/CLOCK_CONF_SECOND; +} +/*---------------------------------------------------------------------------*/ +void +clock_wait(clock_time_t i) +{ + clock_time_t start; + start = clock_time(); + while (clock_time() - start < (clock_time_t)i) { + __WFE(); + } +} +/*---------------------------------------------------------------------------*/ +void +clock_delay_usec(uint16_t dt) +{ + nrf_delay_us(dt); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Obsolete delay function but we implement it here since some code + * still uses it + */ +void +clock_delay(unsigned int i) +{ + clock_delay_usec(i); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + * @} + */ diff --git a/cpu/nrf52832/dev/lpm.h b/cpu/nrf52832/dev/lpm.h new file mode 100644 index 000000000..192165a49 --- /dev/null +++ b/cpu/nrf52832/dev/lpm.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * 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. + * + */ +/** + * \addtogroup nrf52832-dev Device drivers + * @{ + * + * \addtogroup nrf52832-lpm Low power mode functions + * @{ + * + * \file + * A header file for low power mode functions. + * \author + * Wojciech Bober + */ +#ifndef LPM_H +#define LPM_H + +#ifdef SOFTDEVICE_PRESENT +#include "nrf_soc.h" +#endif + +/** + * \brief Stop and wait for an event + * + */ +static inline void +lpm_drop(void) +{ +#ifdef SOFTDEVICE_PRESENT + sd_app_evt_wait(); +#else + __WFI(); +#endif +} + +#endif /* DEV_LPM_H_ */ +/** + * @} + * @} + */ diff --git a/cpu/nrf52832/dev/random.c b/cpu/nrf52832/dev/random.c new file mode 100644 index 000000000..d21bf18ff --- /dev/null +++ b/cpu/nrf52832/dev/random.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * 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. + * + */ +/** + * \addtogroup nrf52832 + * @{ + * + * \addtogroup nrf52832-dev Device drivers + * @{ + * + * \addtogroup nrf52832-rng Hardware random number generator + * @{ + * + * \file + * Random number generator routines exploiting the nRF52 hardware + * capabilities. + * + * This file overrides core/lib/random.c. + * + * \author + * Wojciech Bober + */ +#include +#include +#include "app_error.h" +/*---------------------------------------------------------------------------*/ +/** + * \brief Generates a new random number using the nRF52 RNG. + * \return a random number. + */ +unsigned short +random_rand(void) +{ + unsigned short value = 42; + uint8_t available; + ret_code_t err_code; + + do { + nrf_drv_rng_bytes_available(&available); + } while (available < sizeof(value)); + + err_code = nrf_drv_rng_rand((uint8_t *)&value, sizeof(value)); + APP_ERROR_CHECK(err_code); + + return value; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize the nRF52 random number generator. + * \param seed Ignored. It's here because the function prototype is in core. + * + */ +void +random_init(unsigned short seed) +{ + (void)seed; + ret_code_t err_code = nrf_drv_rng_init(NULL); + APP_ERROR_CHECK(err_code); +} +/** + * @} + * @} + * @} + */ diff --git a/cpu/nrf52832/dev/uart0.c b/cpu/nrf52832/dev/uart0.c new file mode 100644 index 000000000..df9c7b9e3 --- /dev/null +++ b/cpu/nrf52832/dev/uart0.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * 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. + * + */ +/** + * \addtogroup nrf52832-dev Device drivers + * @{ + * + * \addtogroup nrf52832-uart UART driver + * @{ + * + * \file + * Contiki compatible UART driver. + * \author + * Wojciech Bober + */ +#include +#include "nrf.h" +#include "nrf_drv_config.h" +#include "nrf_drv_uart.h" +#include "app_util_platform.h" +#include "app_error.h" + +#include "contiki.h" +#include "dev/uart0.h" +#include "dev/watchdog.h" +#include "lib/ringbuf.h" + +#define TXBUFSIZE 128 +static uint8_t rx_buffer[1]; + +static int (*uart0_input_handler)(unsigned char c); + +static struct ringbuf txbuf; +static uint8_t txbuf_data[TXBUFSIZE]; + +/*---------------------------------------------------------------------------*/ +static void +uart_event_handler(nrf_drv_uart_event_t * p_event, void * p_context) +{ + ENERGEST_ON(ENERGEST_TYPE_IRQ); + + if (p_event->type == NRF_DRV_UART_EVT_RX_DONE) { + if (uart0_input_handler != NULL) { + uart0_input_handler(p_event->data.rxtx.p_data[0]); + } + (void)nrf_drv_uart_rx(rx_buffer, 1); + } else if (p_event->type == NRF_DRV_UART_EVT_TX_DONE) { + if (ringbuf_elements(&txbuf) > 0) { + uint8_t c = ringbuf_get(&txbuf); + nrf_drv_uart_tx(&c, 1); + } + } + + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +/*---------------------------------------------------------------------------*/ +void +uart0_set_input(int (*input)(unsigned char c)) +{ + uart0_input_handler = input; +} +/*---------------------------------------------------------------------------*/ +void +uart0_writeb(unsigned char c) +{ + if (nrf_drv_uart_tx(&c, 1) == NRF_ERROR_BUSY) { + while (ringbuf_put(&txbuf, c) == 0) { + __WFE(); + } + } +} +/*---------------------------------------------------------------------------*/ +/** + * Initialize the RS232 port. + * + */ +void +uart0_init(unsigned long ubr) +{ + nrf_drv_uart_config_t config = NRF_DRV_UART_DEFAULT_CONFIG; + ret_code_t retcode = nrf_drv_uart_init(&config, uart_event_handler); + APP_ERROR_CHECK(retcode); + + ringbuf_init(&txbuf, txbuf_data, sizeof(txbuf_data)); + + nrf_drv_uart_rx_enable(); + nrf_drv_uart_rx(rx_buffer, 1); +} +/** + * @} + * @} + */ diff --git a/cpu/nrf52832/dev/uart0.h b/cpu/nrf52832/dev/uart0.h new file mode 100644 index 000000000..c6b3938ea --- /dev/null +++ b/cpu/nrf52832/dev/uart0.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * 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. + * + */ +/** + * \addtogroup nrf52832-dev Device drivers + * @{ + * + * \addtogroup nrf52832-uart UART driver + * @{ + * + * \file + * A header file for Contiki compatible UART driver. + * \author + * Wojciech Bober + */ +#ifndef UART_0_H +#define UART_0_H + +#include +#include "contiki-conf.h" + +void uart0_init(); +void uart0_writeb(uint8_t byte); + +void uart0_set_input(int (* input)(unsigned char c)); + +#endif /* UART_0_H */ +/** + * @} + * @} + */ diff --git a/cpu/nrf52832/dev/watchdog.c b/cpu/nrf52832/dev/watchdog.c new file mode 100644 index 000000000..50e26d72b --- /dev/null +++ b/cpu/nrf52832/dev/watchdog.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * 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. + * + */ +/** + * \addtogroup nrf52832-dev Device drivers + * @{ + * + * \addtogroup nrf52832-watchdog Watchdog driver + * @{ + * + * \file + * Contiki compatible watchdog driver implementation. + * \author + * Wojciech Bober + */ +#include +#include "app_error.h" +#include "contiki-conf.h" + +static nrf_drv_wdt_channel_id wdt_channel_id; +static uint8_t wdt_initialized = 0; + +/** + * \brief WDT events handler. + */ +static void wdt_event_handler(void) +{ + LEDS_OFF(LEDS_MASK); +} + +/*---------------------------------------------------------------------------*/ +void +watchdog_init(void) +{ + ret_code_t err_code; + err_code = nrf_drv_wdt_init(NULL, &wdt_event_handler); + APP_ERROR_CHECK(err_code); + err_code = nrf_drv_wdt_channel_alloc(&wdt_channel_id); + APP_ERROR_CHECK(err_code); + wdt_initialized = 1; +} +/*---------------------------------------------------------------------------*/ +void +watchdog_start(void) +{ + if(wdt_initialized) { + nrf_drv_wdt_enable(); + } +} +/*---------------------------------------------------------------------------*/ +void +watchdog_periodic(void) +{ + if(wdt_initialized) { + nrf_drv_wdt_channel_feed(wdt_channel_id); + } +} +/*---------------------------------------------------------------------------*/ +void +watchdog_reboot(void) +{ + NVIC_SystemReset(); +} +/** + * @} + * @} + */ diff --git a/cpu/nrf52832/erase.jlink b/cpu/nrf52832/erase.jlink new file mode 100644 index 000000000..5f08d8d86 --- /dev/null +++ b/cpu/nrf52832/erase.jlink @@ -0,0 +1,2 @@ +erase +q \ No newline at end of file diff --git a/cpu/nrf52832/flash.jlink b/cpu/nrf52832/flash.jlink new file mode 100644 index 000000000..787670d55 --- /dev/null +++ b/cpu/nrf52832/flash.jlink @@ -0,0 +1,4 @@ +loadfile #OUTPUT_FILENAME# +r +g +q \ No newline at end of file diff --git a/cpu/nrf52832/ld/nrf52-pca10036-sd.ld b/cpu/nrf52832/ld/nrf52-pca10036-sd.ld new file mode 100644 index 000000000..455749e29 --- /dev/null +++ b/cpu/nrf52832/ld/nrf52-pca10036-sd.ld @@ -0,0 +1,12 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x1f000, LENGTH = 0x61000 + RAM (rwx) : ORIGIN = 0x08000000, LENGTH = 0x8000 +} + +INCLUDE "nrf5x_common.ld" \ No newline at end of file diff --git a/cpu/nrf52832/ld/nrf52-pca10040-sd.ld b/cpu/nrf52832/ld/nrf52-pca10040-sd.ld new file mode 100644 index 000000000..f30aad455 --- /dev/null +++ b/cpu/nrf52832/ld/nrf52-pca10040-sd.ld @@ -0,0 +1,12 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x1f000, LENGTH = 0x61000 + RAM (rwx) : ORIGIN = 0x20002800, LENGTH = 0xD800 +} + +INCLUDE "nrf5x_common.ld" \ No newline at end of file diff --git a/cpu/nrf52832/ld/nrf52.ld b/cpu/nrf52832/ld/nrf52.ld new file mode 100644 index 000000000..268794d04 --- /dev/null +++ b/cpu/nrf52832/ld/nrf52.ld @@ -0,0 +1,12 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x80000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x8000 +} + +INCLUDE "nrf5x_common.ld" \ No newline at end of file diff --git a/cpu/nrf52832/mtarch.h b/cpu/nrf52832/mtarch.h new file mode 100644 index 000000000..4f696669d --- /dev/null +++ b/cpu/nrf52832/mtarch.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2010, Loughborough University - 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. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 + * Stub header file for multi-threading. It doesn't do anything, it + * just exists so that mt.c can compile cleanly. + * + * This is based on the original mtarch.h for z80 by Takahide Matsutsuka + * + * \author + * George Oikonomou - + */ +#ifndef __MTARCH_H__ +#define __MTARCH_H__ + +struct mtarch_thread { + unsigned char *sp; +}; + +#endif /* __MTARCH_H__ */ diff --git a/cpu/nrf52832/putchar.c b/cpu/nrf52832/putchar.c new file mode 100644 index 000000000..c4163ba3d --- /dev/null +++ b/cpu/nrf52832/putchar.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * 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. + * + */ +/** + * \addtogroup nrf52832 + * @{ + * + * \file + * Hardware specific implementation of putchar() and puts() functions. + * \author + * Wojciech Bober + * + */ +/*---------------------------------------------------------------------------*/ +#include +#include "dev/uart0.h" +/*---------------------------------------------------------------------------*/ +int +putchar(int c) +{ + uart0_writeb(c); + return c; +} +/*---------------------------------------------------------------------------*/ +int +puts(const char *str) +{ + int i; + + if (str == NULL) { + return 0; + } + + for (i = 0; i < strlen(str); i++) { + uart0_writeb(str[i]); + } + + uart0_writeb('\n'); + return i; +} +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/cpu/nrf52832/rtimer-arch.c b/cpu/nrf52832/rtimer-arch.c new file mode 100644 index 000000000..78f4790f2 --- /dev/null +++ b/cpu/nrf52832/rtimer-arch.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2015 Nordic Semiconductor. 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +/** + * \addtogroup nrf52832 + * @{ + * + * \file + * Implementation of the architecture dependent rtimer functions for the nRF52 + * + * \author + * Wojciech Bober + */ +/*---------------------------------------------------------------------------*/ +#include +#include +#include "nrf.h" +#include "nrf_drv_timer.h" +#include "app_error.h" +#include "contiki.h" +#include "platform-conf.h" + +static const nrf_drv_timer_t timer = NRF_DRV_TIMER_INSTANCE(PLATFORM_TIMER_INSTANCE_ID); /**< Timer instance used for rtimer */ + +/** + * \brief Handler for timer events. + * + * \param event_type type of an event that should be handled + * \param p_context opaque data pointer passed from nrf_drv_timer_init() + */ +static void +timer_event_handler(nrf_timer_event_t event_type, void* p_context) +{ + switch (event_type) { + case NRF_TIMER_EVENT_COMPARE1: + rtimer_run_next(); + break; + + default: + //Do nothing. + break; + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize platform rtimer + */ +void +rtimer_arch_init(void) +{ + ret_code_t err_code = nrf_drv_timer_init(&timer, NULL, timer_event_handler); + APP_ERROR_CHECK(err_code); + nrf_drv_timer_enable(&timer); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Schedules an rtimer task to be triggered at time t + * \param t The time when the task will need executed. + * + * \e t is an absolute time, in other words the task will be executed AT + * time \e t, not IN \e t rtimer ticks. + * + * This function schedules a one-shot event with the nRF RTC. + */ +void +rtimer_arch_schedule(rtimer_clock_t t) +{ + nrf_drv_timer_compare(&timer, NRF_TIMER_CC_CHANNEL1, t, true); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns the current real-time clock time + * \return The current rtimer time in ticks + * + */ +rtimer_clock_t +rtimer_arch_now() +{ + return nrf_drv_timer_capture(&timer, NRF_TIMER_CC_CHANNEL0); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/cpu/nrf52832/rtimer-arch.h b/cpu/nrf52832/rtimer-arch.h new file mode 100644 index 000000000..da709dae2 --- /dev/null +++ b/cpu/nrf52832/rtimer-arch.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * 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. + * + */ +/** + * \addtogroup nrf52832 nRF52832 + * @{ + * + * \file + * Architecture dependent rtimer implementation header file. + * \author + * Wojciech Bober + * + */ +/*---------------------------------------------------------------------------*/ +#ifndef RTIMER_ARCH_H_ +#define RTIMER_ARCH_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +/*---------------------------------------------------------------------------*/ +rtimer_clock_t rtimer_arch_now(void); +/*---------------------------------------------------------------------------*/ +#endif /* RTIMER_ARCH_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + */ From d39ad95db5f1625dac61b91a1d0a6d16c0b43938 Mon Sep 17 00:00:00 2001 From: Wojciech Bober Date: Sat, 9 Jan 2016 14:44:39 +0100 Subject: [PATCH 024/374] nrf52dk: platform support --- platform/nrf52dk/Makefile.nrf52dk | 34 + platform/nrf52dk/README-BLE-6LoWPAN.md | 100 ++ platform/nrf52dk/README.md | 254 +++++ platform/nrf52dk/config/nrf_drv_config.h | 329 ++++++ platform/nrf52dk/config/pstorage_platform.h | 74 ++ platform/nrf52dk/contiki-conf.h | 153 +++ platform/nrf52dk/contiki-main.c | 203 ++++ platform/nrf52dk/dbg-io/dbg.c | 72 ++ platform/nrf52dk/dbg-io/dbg.h | 67 ++ platform/nrf52dk/dbg-io/debug-uart.h | 54 + platform/nrf52dk/dev/button-sensor.c | 330 ++++++ platform/nrf52dk/dev/button-sensor.h | 72 ++ platform/nrf52dk/dev/leds-arch.c | 77 ++ platform/nrf52dk/dev/nrf52dk-sensors.c | 66 ++ platform/nrf52dk/dev/temperature-sensor.c | 109 ++ platform/nrf52dk/dev/temperature-sensor.h | 59 + platform/nrf52dk/platform-conf.h | 145 +++ platform/nrf52dk/rtt/rtt-printf.c | 24 + platform/nrf52dk/rtt/segger-rtt-conf.h | 135 +++ platform/nrf52dk/rtt/segger-rtt-printf.c | 510 +++++++++ platform/nrf52dk/rtt/segger-rtt.c | 1102 +++++++++++++++++++ platform/nrf52dk/rtt/segger-rtt.h | 204 ++++ 22 files changed, 4173 insertions(+) create mode 100644 platform/nrf52dk/Makefile.nrf52dk create mode 100644 platform/nrf52dk/README-BLE-6LoWPAN.md create mode 100644 platform/nrf52dk/README.md create mode 100644 platform/nrf52dk/config/nrf_drv_config.h create mode 100644 platform/nrf52dk/config/pstorage_platform.h create mode 100644 platform/nrf52dk/contiki-conf.h create mode 100644 platform/nrf52dk/contiki-main.c create mode 100644 platform/nrf52dk/dbg-io/dbg.c create mode 100644 platform/nrf52dk/dbg-io/dbg.h create mode 100644 platform/nrf52dk/dbg-io/debug-uart.h create mode 100644 platform/nrf52dk/dev/button-sensor.c create mode 100644 platform/nrf52dk/dev/button-sensor.h create mode 100644 platform/nrf52dk/dev/leds-arch.c create mode 100644 platform/nrf52dk/dev/nrf52dk-sensors.c create mode 100644 platform/nrf52dk/dev/temperature-sensor.c create mode 100644 platform/nrf52dk/dev/temperature-sensor.h create mode 100644 platform/nrf52dk/platform-conf.h create mode 100644 platform/nrf52dk/rtt/rtt-printf.c create mode 100644 platform/nrf52dk/rtt/segger-rtt-conf.h create mode 100644 platform/nrf52dk/rtt/segger-rtt-printf.c create mode 100644 platform/nrf52dk/rtt/segger-rtt.c create mode 100644 platform/nrf52dk/rtt/segger-rtt.h diff --git a/platform/nrf52dk/Makefile.nrf52dk b/platform/nrf52dk/Makefile.nrf52dk new file mode 100644 index 000000000..8fa911cc4 --- /dev/null +++ b/platform/nrf52dk/Makefile.nrf52dk @@ -0,0 +1,34 @@ +ifndef CONTIKI + $(error CONTIKI not defined! You must specify where CONTIKI resides!) +endif + +### Include the board-specific makefile +PLATFORM_ROOT_DIR = $(CONTIKI)/platform/$(TARGET) + +CONTIKI_TARGET_DIRS += . dev config +CONTIKI_SOURCEFILES += contiki-main.c leds-arch.c nrf52dk-sensors.c button-sensor.c temperature-sensor.c + +ifeq ($(NRF52_USE_RTT),1) +### Use the existing debug I/O in cpu/arm/common +CONTIKI_TARGET_DIRS += rtt +CONTIKI_SOURCEFILES += rtt-printf.c segger-rtt.c segger-rtt-printf.c +else +CONTIKI_TARGET_DIRS += dbg-io +CONTIKI_SOURCEFILES += dbg.c +CONTIKI_CPU_DIRS += ../arm/common/dbg-io +CONTIKI_CPU_SOURCEFILES += dbg-printf.c dbg-putchar.c dbg-snprintf.c dbg-sprintf.c strformat.c +endif + +CLEAN += *.nrf52dk + +### Unless the example dictates otherwise, build with code size optimisations switched +### off +ifndef SMALL + SMALL = 0 +endif + +### Define the CPU directory and pull in the correct CPU makefile. +CONTIKI_CPU=$(CONTIKI)/cpu/nrf52832 +include $(CONTIKI_CPU)/Makefile.nrf52832 + +MODULES += core/net core/net/mac core/net/llsec diff --git a/platform/nrf52dk/README-BLE-6LoWPAN.md b/platform/nrf52dk/README-BLE-6LoWPAN.md new file mode 100644 index 000000000..e4c9ef5f6 --- /dev/null +++ b/platform/nrf52dk/README-BLE-6LoWPAN.md @@ -0,0 +1,100 @@ +This README contains information how to establish an IPv6 connecton between +Linux BLE router and an IPSP enabled BLE device. + +Prerequisites +============= +In general, any device capable of running Linux operating system, can be used +as a BLE router provided the following conditions are met: + +* Linux Kernel >3.18 is used +* bluez, libcap-ng0, radvd tools are present. + +If a built-in Bluetooth device is not available then Bluetooth 4.0 compatible +USB dongle can be used. + +The following procedures have been tested on Ubuntu 15.10. + +Establishing an IPv6 connection +=============================== +Use the following procedure to establish a connection between an nRF52 device +and Linux router: + +First enable 6LoWPAN module. This is neccessary only once per session: + + # Log in as a root user. + sudo su + + # Mount debugfs file system. + mount -t debugfs none /sys/kernel/debug + + # Load 6LoWPAN module. + modprobe bluetooth_6lowpan + + # Enable the bluetooth 6lowpan module. + echo 1 > /sys/kernel/debug/bluetooth/6lowpan_enable + + # Look for available HCI devices. + hciconfig + + # Reset HCI device - for example hci0 device. + hciconfig hci0 reset + + # Read 00:AA:BB:XX:YY:ZZ address of the nRF5x device. + hcitool lescan + +If you see device name and address in lescan output then you can connect to the +device: + + echo "connect 00:AA:BB:XX:YY:ZZ 1" > /sys/kernel/debug/bluetooth/6lowpan_control + +If above is successful then LED1 will stop blinking and LED2 will switch on. +You can then check the connection using the following commands: + + # Check if bt0 interface is present and up + ifconfig + + # Try to ping the device using its link-local address, for example, on bt0 interface. + ping6 -I bt0 fe80::2aa:bbff:fexx:yyzz + +If you'd like to learn more about the procedure please refer to +[Connecting devices to the router]. + +Distributing routable IPv6 prefix +================================= +In Linux, Router Advertisement Daemon (RADVD) can be used to distribute prefixes +in the network, hance configure routable IPv6 address. + +To configure RADVD create `/etc/radvd.conf` file and paste the following contents: + + interface bt0 + { + AdvSendAdvert on; + prefix 2001:db8::/64 + { + AdvOnLink off; + AdvAutonomous on; + AdvRouterAddr on; + }; + }; + +Next, start RADVD daemon: + + # Set IPv6 forwarding (must be present). + sudo echo 1 > /proc/sys/net/ipv6/conf/all/forwarding + # Run radvd daemon. + sudo service radvd restart + +If successfull then all devices connected to the host will receive +a routable `2001:db8` prefix. + +This can be verified by sending echo request to the full address: + + ping6 -I bt0 2001:db8::2aa:bbff:fexx:yyzz + +where `aa:bbff:fexx:yyzz` is device Bluetooth address. + +If you'd like to learn more about the procedure please refer to +[Distributing a global IPv6 prefix]. + +* [Connecting devices to the router]: http://developer.nordicsemi.com/nRF5_IoT_SDK/doc/0.9.0/html/a00089.html +* [Distributing a global IPv6 prefix]: http://developer.nordicsemi.com/nRF5_IoT_SDK/doc/0.9.0/html/a00090.html \ No newline at end of file diff --git a/platform/nrf52dk/README.md b/platform/nrf52dk/README.md new file mode 100644 index 000000000..236892858 --- /dev/null +++ b/platform/nrf52dk/README.md @@ -0,0 +1,254 @@ +Contiki for nRF52 Development Kit +================================= +This guide's aim is to help you with using Contiki for +Nordic Semiconductor's nRF52 DK. + +The port depends on Nordic Semiconductor IoT SDK for nRF52. +The IoT SDK contains source code and libraries which are +required for successfull port compilation. It also contains +SoftDevice binary driver which is required for BLE operation. +See prerequisites section for details on how to set up the SDK. + +For more information about SoftDevice please refer to the SDK +docummentation [nRF52 Datasheet and SDK documentation]. + +This port supports DK versions PCA10040 and PCA10036. + +Port Features +============= +The following features have been implemented: +* Support for IPv6 over BLE using Contiki 6LoWPAN implementation +* Contiki system clock and rtimers (using 32kHz and 1MHz timers) +* UART driver +* Watchdog driver +* Hardware RNG +* Temperature sensor driver +* DK LED driver +* DK Buttons driver +* Real Time Transfer (RTT) I/O support + +Note that this port supports only IPv6 network stack. + +The port is organized as follows: +* nRF52832 CPU and BLE drivers are located in `cpu/nrf52832` folder +* nRF52 Development Kit drivers are located in `platform/nrf52dk` folder +* Platform examples are located in `examples/nrf52dk` folder + +Prerequisites and Setup +======================= +In order to compile for the nRF52 DK platform you'll need: + +* nRF5 IOT SDK + https://developer.nordicsemi.com + + Download nRF5 IOT SDK, extract it to a folder of your choice, + and point `NRF52_SDK_ROOT` environmental variable to it, e.g.,: + + ``` + wget https://developer.nordicsemi.com/nRF5_IoT_SDK/nRF5_IoT_SDK_v0.9.x/nrf5_iot_sdk_3288530.zip + unzip nrf5_iot_sdk_3288530.zip -d /path/to/sdk + export NRF52_SDK_ROOT=/path/to/sdk + ``` + +* An ARM compatible toolchain + The port has been tested with GNU Tools for ARM Embedded Processors + version 5.2.1. + + For Ubuntu you can use package version provided by your distribution: + ``` + sudo apt-get install gcc-arm-none-eabi + ``` + + Alternatively, install the toolchain from PPA to get the latest version + of the compiler: https://launchpad.net/~team-gcc-arm-embedded/+archive/ubuntu/ppa + + For other systems please download and install toolchain available at + https://launchpad.net/gcc-arm-embedded + +* GNU make + +* Segger JLink Software for Linux + https://www.segger.com/jlink-software.html + + This package contains tools necessary for programming and debugging nRF52 DK. + + For Ubuntu you can download and install a .deb package. Alternatively download + tar.gz archive and extract it to a folder of your choice. In this case you + need to set `NRF52_JLINK_PATH` environmental variable to point to the + JLink tools location: + + ``` + export NRF52_JLINK_PATH=/path/to/jlink/tools + ``` + + To keep this variable set between sessions please add the above line to your + `rc.local` file. + + In order to access the DK as a regular Linux user create a `99-jlink.rules` + file in your udev rules folder (e.g., `/etc/udev/rules.d/`) and add the + following line to it: + + ``` + ATTRS{idProduct}=="1015", ATTRS{idVendor}=="1366", MODE="0666" + ``` + When installing from a deb package, the `99-jlink.rules` file is added + automatically to /etc/udev/rules.d folder. However, the syntax of the file + doesn't work on newer udev versions. To fix this problem edit this file and + replace ATTR keyword with ATTRS. + +To fully use the platform a BLE enabled router device is needed. Please refer +to `Preqrequisites` section in `README-BLE-6LoWPAN.md` for details. + +Getting Started +=============== +Once all tools are installed it is recommended to start by compiling +and flashing `examples/hello-word` application. This allows to verify +that toolchain setup is correct. + +To compile the example, go to `examples/hello-world` and execute: + + make TARGET=nrf52dk + +If you haven't used the device with Contiki before we advise to +erase the device and flash new SoftDevice: + + make TARGET=nrf52dk erase + make TARGET=nrf52dk softdevice.flash + +If the compilation is completed without errors flash the board: + + make TARGET=nrf52dk hello-world.flash + +The device will start BLE advertising as soon as initialized. By +default the device name is set to 'Contiki nRF52 DK'. To verify +that the device is advertising properly run: + + sudo hcitool lescan + +And observe if the device name appears in the output. Also, observe +if LED1 is blinking what indicates that device is waiting for a connection +from BLE master. + +If device is functioning as expected you can test IPv6 connection +to the device. Please refer to `README-BLE-6LoWPAN.md` on details how to do +this. + +Examples +======== +Examples specific for nRF52 DK can be found in `examples/nrf52dk` folder. Please +refer to README.md in respective examples for detailed description. + +The DK has also been tested with the `examples/hello-world` and `examples/webserver-ipv6` +generic examples. + +Compilation Options +=================== +The Contiki TARGET name for this port is `nrf52dk`, so in order to compile +an application you need to invoke GNU make as follows: + + make TARGET=nrf52dk + +In addition to this port supports the following variables which can be +set on the compilation command line: + +* `NRF52_SDK_ROOT=` + This variable allows to specify a path to the nRF52 SDK which should + be used for the build. + +* `NRF52_WITHOUT_SOFTDEVICE={0|1}` + Disables SoftDevice support if set to 1. By default, SoftDevice support + is used. Note that SoftDevice must be present (flashed) in the device + before you run an application that requires it's presence. + +* `NRF52_USE_RTT={0|1}` + Enables RealTime Terminal I/O. See VCOM and RTT for details. By default, + RTT is disabled and IO is done using Virtual COM port. + +* `NRF52_JLINK_SN=` + Allows to choose a particular DK by its serial number (printed on the + label). This is useful if you have more than one DK connected to your + PC and whish to flash a particular device. + +* `NRF52_DK_REVISION={pca10040|pca10036}` + Allows to specify DK revision. By default, pca10040 is used. + +Compilation Targets +=================== +Invoking make solely with the `TARGET` variable set will build all +applications in a given folder. A particular application can be built +by invoking make with its name as a compilation target: + + make TARGET=nrf52dk hello-world + +In order to flash the application binary to the device use `.flash` +as make target, e.g.: + + make TARGET=nrf52dk hello-world.flash + +In addition, the SoftDevice binary can be flashed to the DK by invoking: + + make TARGET=nrf52dk softdevice.flash + +To remove all build results invoke: + + make TARGET=nrf52dk clean + +The device memory can be erased using: + + make TARGET=nrf52dk erase + +Note, that once the device is erased, the SoftDevice must be programmed again. + +Virtual COM and Real Time Transfer +================================== +By default, the nRF52 DK uses a Virtual COM port to output logs. Once +the DK is plugged in a `/tty/ACM` or `/ttyUSB` device should appear in +your filesystem. A terminal emulator, such as picocom or minicom, can be +used to connect to the device. Default serial port speed is 38400 bps. + +To connect to serial port using picocom invoke: + + picocom -fh -b 38400 --imap lfcrlf /dev/ttyACM0 + +Note, that if you have not fixed file permissions for `/dev/ttyACM0` +according to section `Segger JLink Software for Linux` you'll need to use +root or sudo to open the port with `picocom`. + +In addition to Virtual COM the port supports SEGGER's Real Time Transfer +for low overhead I/O support. This allows for outputting debugging information +at much higher rate with significantly lower overhead than regular I/O. + +To compile an application with RTT rather that VCOM set `NRF52_USE_RTT` to 1 on +the compilation command line: + + make TARGET=nrf52dk NRF52_USE_RTT=1 hello-world + +You can then connect to the device terminal using `JLinkRTTClient`. Note that +a JLlink gdb or commander must be connected to the target for the RTT to work. + +More details regarding RTT can be found at https://www.segger.com/jlink-rtt.html + +Docummentation +============== +This port provides doxygen source code docummentation. To build the +docummentation please run: + + sudo apt-get install doxygen + cd \doc + make + +Support +======= +This port is officially supported by Nordic Semiconductor. Please send bug +reports or/and suggestions to . + +License +======= +All files in the port are under BSD license. nRF52 SDK and SoftDevice are +licensed on a separate terms. + +Resources +========= +* nRF52 Datasheet and SDK documentation (http://infocenter.nordicsemi.com) +* nRF52 SDK Downloads (https://developer.nordicsemi.com/) +* JLink Tools (https://www.segger.com/) \ No newline at end of file diff --git a/platform/nrf52dk/config/nrf_drv_config.h b/platform/nrf52dk/config/nrf_drv_config.h new file mode 100644 index 000000000..cfc3595b2 --- /dev/null +++ b/platform/nrf52dk/config/nrf_drv_config.h @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * 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. + * + */ + +/** + * \addtogroup nrf52dk + * @{ + * + * \defgroup nrf52dk-config nRF52 SDK configuration + * @{ + */ + +#ifndef NRF_DRV_CONFIG_H +#define NRF_DRV_CONFIG_H + +/* CLOCK */ +#define CLOCK_CONFIG_XTAL_FREQ NRF_CLOCK_XTALFREQ_Default +#define CLOCK_CONFIG_LF_SRC NRF_CLOCK_LF_SRC_Xtal +#define CLOCK_CONFIG_LF_RC_CAL_INTERVAL RC_2000MS_CALIBRATION_INTERVAL +#define CLOCK_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +/* GPIOTE */ +#define GPIOTE_ENABLED 1 + +#if (GPIOTE_ENABLED == 1) +#define GPIOTE_CONFIG_USE_SWI_EGU false +#define GPIOTE_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_HIGH +#define GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 4 +#endif + +/* TIMER */ +#define TIMER0_ENABLED 0 + +#if (TIMER0_ENABLED == 1) +#define TIMER0_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz +#define TIMER0_CONFIG_MODE TIMER_MODE_MODE_Timer +#define TIMER0_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_32Bit +#define TIMER0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define TIMER0_INSTANCE_INDEX 0 +#endif + +#define TIMER1_ENABLED 1 + +#if (TIMER1_ENABLED == 1) +#define TIMER1_CONFIG_FREQUENCY NRF_TIMER_FREQ_62500Hz +#define TIMER1_CONFIG_MODE TIMER_MODE_MODE_Timer +#define TIMER1_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_32Bit +#define TIMER1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define TIMER1_INSTANCE_INDEX (TIMER0_ENABLED) +#endif + +#define TIMER2_ENABLED 0 + +#if (TIMER2_ENABLED == 1) +#define TIMER2_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz +#define TIMER2_CONFIG_MODE TIMER_MODE_MODE_Timer +#define TIMER2_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit +#define TIMER2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define TIMER2_INSTANCE_INDEX (TIMER1_ENABLED+TIMER0_ENABLED) +#endif + +#define TIMER3_ENABLED 0 + +#if (TIMER3_ENABLED == 1) +#define TIMER3_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz +#define TIMER3_CONFIG_MODE TIMER_MODE_MODE_Timer +#define TIMER3_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit +#define TIMER3_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define TIMER3_INSTANCE_INDEX (TIMER2_ENABLED+TIMER2_INSTANCE_INDEX) +#endif + +#define TIMER4_ENABLED 0 + +#if (TIMER4_ENABLED == 1) +#define TIMER4_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz +#define TIMER4_CONFIG_MODE TIMER_MODE_MODE_Timer +#define TIMER4_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit +#define TIMER4_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define TIMER4_INSTANCE_INDEX (TIMER3_ENABLED+TIMER3_INSTANCE_INDEX) +#endif + + +#define TIMER_COUNT (TIMER0_ENABLED + TIMER1_ENABLED + TIMER2_ENABLED + TIMER3_ENABLED + TIMER4_ENABLED) + +/* RTC */ +#define RTC0_ENABLED 0 + +#if (RTC0_ENABLED == 1) +#define RTC0_CONFIG_FREQUENCY 32678 +#define RTC0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define RTC0_CONFIG_RELIABLE false + +#define RTC0_INSTANCE_INDEX 0 +#endif + +#define RTC1_ENABLED 1 + +#if (RTC1_ENABLED == 1) +#define RTC1_CONFIG_FREQUENCY 128 +#define RTC1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define RTC1_CONFIG_RELIABLE false + +#define RTC1_INSTANCE_INDEX (RTC0_ENABLED) +#endif + +#define RTC_COUNT (RTC0_ENABLED+RTC1_ENABLED) + +#define NRF_MAXIMUM_LATENCY_US 2000 + +/* RNG */ +#define RNG_ENABLED 1 + +#if (RNG_ENABLED == 1) +#define RNG_CONFIG_ERROR_CORRECTION true +#define RNG_CONFIG_POOL_SIZE 8 +#define RNG_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#endif + +/* SPI */ +#define SPI0_ENABLED 0 + +#if (SPI0_ENABLED == 1) +#define SPI0_USE_EASY_DMA 0 + +#define SPI0_CONFIG_SCK_PIN 2 +#define SPI0_CONFIG_MOSI_PIN 3 +#define SPI0_CONFIG_MISO_PIN 4 +#define SPI0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define SPI0_INSTANCE_INDEX 0 +#endif + +#define SPI1_ENABLED 0 + +#if (SPI1_ENABLED == 1) +#define SPI1_USE_EASY_DMA 0 + +#define SPI1_CONFIG_SCK_PIN 2 +#define SPI1_CONFIG_MOSI_PIN 3 +#define SPI1_CONFIG_MISO_PIN 4 +#define SPI1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define SPI1_INSTANCE_INDEX (SPI0_ENABLED) +#endif + +#define SPI2_ENABLED 0 + +#if (SPI2_ENABLED == 1) +#define SPI2_USE_EASY_DMA 0 + +#define SPI2_CONFIG_SCK_PIN 2 +#define SPI2_CONFIG_MOSI_PIN 3 +#define SPI2_CONFIG_MISO_PIN 4 +#define SPI2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define SPI2_INSTANCE_INDEX (SPI0_ENABLED + SPI1_ENABLED) +#endif + +#define SPI_COUNT (SPI0_ENABLED + SPI1_ENABLED + SPI2_ENABLED) + +/* UART */ +#define UART0_ENABLED 1 + +#if (UART0_ENABLED == 1) +#define UART0_CONFIG_HWFC NRF_UART_HWFC_DISABLED +#define UART0_CONFIG_PARITY NRF_UART_PARITY_EXCLUDED +#define UART0_CONFIG_BAUDRATE NRF_UART_BAUDRATE_38400 +#define UART0_CONFIG_PSEL_TXD 6 +#define UART0_CONFIG_PSEL_RXD 8 +#define UART0_CONFIG_PSEL_CTS 7 +#define UART0_CONFIG_PSEL_RTS 5 +#define UART0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#ifdef NRF52 +#define UART0_CONFIG_USE_EASY_DMA false +//Compile time flag +#define UART_EASY_DMA_SUPPORT 1 +#define UART_LEGACY_SUPPORT 1 +#endif //NRF52 +#endif + +#define TWI0_ENABLED 0 + +#if (TWI0_ENABLED == 1) +#define TWI0_CONFIG_FREQUENCY NRF_TWI_FREQ_100K +#define TWI0_CONFIG_SCL 0 +#define TWI0_CONFIG_SDA 1 +#define TWI0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_HIGH + +#define TWI0_INSTANCE_INDEX 0 +#endif + +#define TWI1_ENABLED 0 + +#if (TWI1_ENABLED == 1) +#define TWI1_CONFIG_FREQUENCY NRF_TWI_FREQ_100K +#define TWI1_CONFIG_SCL 0 +#define TWI1_CONFIG_SDA 1 +#define TWI1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_HIGH + +#define TWI1_INSTANCE_INDEX (TWI0_ENABLED) +#endif + +#define TWI_COUNT (TWI0_ENABLED+TWI1_ENABLED) + +/* TWIS */ +#define TWIS0_ENABLED 0 + +#if (TWIS0_ENABLED == 1) + #define TWIS0_CONFIG_ADDR0 0 + #define TWIS0_CONFIG_ADDR1 0 /* 0: Disabled */ + #define TWIS0_CONFIG_SCL 0 + #define TWIS0_CONFIG_SDA 1 + #define TWIS0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_HIGH + + #define TWIS0_INSTANCE_INDEX 0 +#endif + +#define TWIS1_ENABLED 0 + +#if (TWIS1_ENABLED == 1) + #define TWIS1_CONFIG_ADDR0 0 + #define TWIS1_CONFIG_ADDR1 0 /* 0: Disabled */ + #define TWIS1_CONFIG_SCL 0 + #define TWIS1_CONFIG_SDA 1 + #define TWIS1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_HIGH + + #define TWIS1_INSTANCE_INDEX (TWIS0_ENABLED) +#endif + +#define TWIS_COUNT (TWIS0_ENABLED + TWIS1_ENABLED) +/* For more documentation see nrf_drv_twis.h file */ +#define TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 +/* For more documentation see nrf_drv_twis.h file */ +#define TWIS_NO_SYNC_MODE 0 +/** + * \brief Definition for patching PAN problems + * + * Set this definition to nonzero value to patch anomalies + * from MPW3 - first lunch microcontroller. + * + * Concerns: + * - PAN-29: TWIS: incorrect bits in ERRORSRC + * - PAN-30: TWIS: STOP task does not work as expected + */ +#define NRF_TWIS_PATCH_FOR_MPW3 1 + + +/* QDEC */ +#define QDEC_ENABLED 0 + +#if (QDEC_ENABLED == 1) +#define QDEC_CONFIG_REPORTPER NRF_QDEC_REPORTPER_10 +#define QDEC_CONFIG_SAMPLEPER NRF_QDEC_SAMPLEPER_16384us +#define QDEC_CONFIG_PIO_A 1 +#define QDEC_CONFIG_PIO_B 2 +#define QDEC_CONFIG_PIO_LED 3 +#define QDEC_CONFIG_LEDPRE 511 +#define QDEC_CONFIG_LEDPOL NRF_QDEC_LEPOL_ACTIVE_HIGH +#define QDEC_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define QDEC_CONFIG_DBFEN false +#define QDEC_CONFIG_SAMPLE_INTEN false +#endif + +/* SAADC */ +#define SAADC_ENABLED 0 + +#if (SAADC_ENABLED == 1) +#define SAADC_CONFIG_RESOLUTION NRF_SAADC_RESOLUTION_10BIT +#define SAADC_CONFIG_OVERSAMPLE NRF_SAADC_OVERSAMPLE_DISABLED +#define SAADC_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#endif + +/* LPCOMP */ +#define LPCOMP_ENABLED 0 + +#if (LPCOMP_ENABLED == 1) +#define LPCOMP_CONFIG_REFERENCE NRF_LPCOMP_REF_SUPPLY_4_8 +#define LPCOMP_CONFIG_DETECTION NRF_LPCOMP_DETECT_DOWN +#define LPCOMP_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define LPCOMP_CONFIG_INPUT NRF_LPCOMP_INPUT_0 +#endif + +/* WDT */ +#define WDT_ENABLED 1 + +#if (WDT_ENABLED == 1) +#define WDT_CONFIG_BEHAVIOUR NRF_WDT_BEHAVIOUR_RUN_SLEEP +#define WDT_CONFIG_RELOAD_VALUE 2000 +#define WDT_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_HIGH +#endif + +#include "nrf_drv_config_validation.h" +#endif // NRF_DRV_CONFIG_H + +/** + * @} + * @} + */ diff --git a/platform/nrf52dk/config/pstorage_platform.h b/platform/nrf52dk/config/pstorage_platform.h new file mode 100644 index 000000000..3102b2097 --- /dev/null +++ b/platform/nrf52dk/config/pstorage_platform.h @@ -0,0 +1,74 @@ +/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. + * + * The information contained herein is property of Nordic Semiconductor ASA. + * Terms and conditions of usage are described in detail in NORDIC + * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. + * + * Licensees are granted free, non-transferable use of the information. NO + * WARRANTY of ANY KIND is provided. This heading must NOT be removed from + * the file. + * + */ + + /** @cond To make doxygen skip this file */ + +/** @file + * This header contains defines with respect persistent storage that are specific to + * persistent storage implementation and application use case. + */ +#ifndef PSTORAGE_PL_H__ +#define PSTORAGE_PL_H__ + +#include +#include "nrf.h" + +static __INLINE uint16_t pstorage_flash_page_size() +{ + return (uint16_t)NRF_FICR->CODEPAGESIZE; +} + +#define PSTORAGE_FLASH_PAGE_SIZE pstorage_flash_page_size() /**< Size of one flash page. */ +#define PSTORAGE_FLASH_EMPTY_MASK 0xFFFFFFFF /**< Bit mask that defines an empty address in flash. */ + +#ifdef NRF51 +#define BOOTLOADER_ADDRESS (NRF_UICR->BOOTLOADERADDR) +#elif defined NRF52 +#define BOOTLOADER_ADDRESS (PSTORAGE_FLASH_EMPTY_MASK) +#endif + +#define PSTORAGE_FLASH_PAGE_END \ + ((BOOTLOADER_ADDRESS != PSTORAGE_FLASH_EMPTY_MASK) \ + ? (BOOTLOADER_ADDRESS / PSTORAGE_FLASH_PAGE_SIZE) \ + : NRF_FICR->CODESIZE) + + +#define PSTORAGE_NUM_OF_PAGES 2 /**< Number of flash pages allocated for the pstorage module excluding the swap page, configurable based on system requirements. */ +#define PSTORAGE_MIN_BLOCK_SIZE 0x0010 /**< Minimum size of block that can be registered with the module. Should be configured based on system requirements, recommendation is not have this value to be at least size of word. */ + +#define PSTORAGE_DATA_START_ADDR ((PSTORAGE_FLASH_PAGE_END - PSTORAGE_NUM_OF_PAGES - 1) \ + * PSTORAGE_FLASH_PAGE_SIZE) /**< Start address for persistent data, configurable according to system requirements. */ +#define PSTORAGE_DATA_END_ADDR ((PSTORAGE_FLASH_PAGE_END - 1) * PSTORAGE_FLASH_PAGE_SIZE) /**< End address for persistent data, configurable according to system requirements. */ +#define PSTORAGE_SWAP_ADDR PSTORAGE_DATA_END_ADDR /**< Top-most page is used as swap area for clear and update. */ + +#define PSTORAGE_MAX_BLOCK_SIZE PSTORAGE_FLASH_PAGE_SIZE /**< Maximum size of block that can be registered with the module. Should be configured based on system requirements. And should be greater than or equal to the minimum size. */ +#define PSTORAGE_CMD_QUEUE_SIZE 30 /**< Maximum number of flash access commands that can be maintained by the module for all applications. Configurable. */ + + +/** Abstracts persistently memory block identifier. */ +typedef uint32_t pstorage_block_t; + +typedef struct +{ + uint32_t module_id; /**< Module ID.*/ + pstorage_block_t block_id; /**< Block ID.*/ +} pstorage_handle_t; + +typedef uint16_t pstorage_size_t; /** Size of length and offset fields. */ + +/**\brief Handles Flash Access Result Events. To be called in the system event dispatcher of the application. */ +void pstorage_sys_event_handler (uint32_t sys_evt); + +#endif // PSTORAGE_PL_H__ + +/** @} */ +/** @endcond */ diff --git a/platform/nrf52dk/contiki-conf.h b/platform/nrf52dk/contiki-conf.h new file mode 100644 index 000000000..6303c90db --- /dev/null +++ b/platform/nrf52dk/contiki-conf.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * 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. + * + */ +/** + * \addtogroup nrf52dk + * @{ + * + * \addtogroup nrf52dk-contikic-conf Contiki configuration + * @{ + * + * \file + * Contiki configuration for the nRF52 DK + */ +#ifndef CONTIKI_CONF_H +#define CONTIKI_CONF_H + +#include +/*---------------------------------------------------------------------------*/ +/* Include Project Specific conf */ +#ifdef PROJECT_CONF_H +#include PROJECT_CONF_H +#endif /* PROJECT_CONF_H */ +/*---------------------------------------------------------------------------*/ +/* Include platform peripherals configuration */ +#include "platform-conf.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Network Stack Configuration + * + * @{ + */ +#ifndef NETSTACK_CONF_NETWORK +#define NETSTACK_CONF_NETWORK sicslowpan_driver +#endif /* NETSTACK_CONF_NETWORK */ + +#ifndef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC ble_ipsp_mac_driver +#endif /* NETSTACK_CONF_MAC */ + +/* 6LoWPAN */ +#define SICSLOWPAN_CONF_MAC_MAX_PAYLOAD 1280 +#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 +#define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 0 /**< Always compress IPv6 packets. */ +#define SICSLOWPAN_CONF_FRAG 0 /**< We don't use 6LoWPAN fragmentation as IPSP takes care of that for us.*/ +#define SICSLOWPAN_FRAMER_HDRLEN 0 /**< Use fixed header len rather than framer.length() function */ + +/* Packet buffer */ +#define PACKETBUF_CONF_SIZE 1280 /**< Required IPv6 MTU size */ +/** @} */ + +/** + * \name BLE configuration + * @{ + */ +#ifndef DEVICE_NAME +#define DEVICE_NAME "Contiki nRF52dk" /**< Device name used in BLE undirected advertisement. */ +#endif +/** + * @} + */ + +/** + * \name IPv6 network buffer configuration + * + * @{ + */ +/* Don't let contiki-default-conf.h decide if we are an IPv6 build */ +#ifndef NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_WITH_IPV6 0 +#endif + +#if NETSTACK_CONF_WITH_IPV6 +/*---------------------------------------------------------------------------*/ +/* Addresses, Sizes and Interfaces */ +#define LINKADDR_CONF_SIZE 8 +#define UIP_CONF_LL_802154 1 +#define UIP_CONF_LLH_LEN 0 + +/* The size of the uIP main buffer */ +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 1280 +#endif + +/* ND and Routing */ +#define UIP_CONF_ROUTER 0 /**< BLE master role, which allows for routing, isn't supported. */ +#define UIP_CONF_ND6_SEND_NA 1 +#define UIP_CONF_IP_FORWARD 0 /**< No packet forwarding. */ + +#define UIP_CONF_ND6_REACHABLE_TIME 600000 +#define UIP_CONF_ND6_RETRANS_TIMER 10000 + +#ifndef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 20 +#endif + +#ifndef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 20 +#endif + +#ifndef UIP_CONF_TCP +#define UIP_CONF_TCP 1 +#endif + +#ifndef UIP_CONF_TCP_MSS +#define UIP_CONF_TCP_MSS 64 +#endif + +#define UIP_CONF_UDP 1 +#define UIP_CONF_UDP_CHECKSUMS 1 +#define UIP_CONF_ICMP6 1 +#endif /* NETSTACK_CONF_WITH_IPV6 */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Generic Configuration directives + * + * @{ + */ +#ifndef ENERGEST_CONF_ON +#define ENERGEST_CONF_ON 1 /**< Energest Module */ +#endif +/** @} */ +#endif /* CONTIKI_CONF_H */ +/** + * @} + * @} + */ diff --git a/platform/nrf52dk/contiki-main.c b/platform/nrf52dk/contiki-main.c new file mode 100644 index 000000000..50fcfcd28 --- /dev/null +++ b/platform/nrf52dk/contiki-main.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup nrf52dk nRF52 Development Kit + * @{ + */ +#include +#include + +#include "nordic_common.h" +#include "nrf_drv_config.h" +#include "nrf_drv_gpiote.h" +#ifdef SOFTDEVICE_PRESENT +#include "softdevice_handler.h" +#include "ble/ble-core.h" +#include "ble/ble-mac.h" +#endif + +#include "contiki.h" +#include "contiki-net.h" +#include "leds.h" +#include "lib/sensors.h" + +#include "dev/watchdog.h" +#include "dev/serial-line.h" +#include "dev/uart0.h" +#include "dev/lpm.h" + +#define DEBUG 0 + +#if NETSTACK_CONF_WITH_IPV6 +#include "uip-debug.h" +#include "net/ipv6/uip-ds6.h" +#else +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +#endif + +#if defined(SOFTDEVICE_PRESENT) && PLATFORM_INDICATE_BLE_STATE +PROCESS(ble_iface_observer, "BLE interface observer"); + +/** + * \brief A process that handles adding/removing + * BLE IPSP interfaces. + */ +PROCESS_THREAD(ble_iface_observer, ev, data) +{ + static struct etimer led_timer; + + PROCESS_BEGIN(); + + etimer_set(&led_timer, CLOCK_SECOND/2); + + while(1) { + PROCESS_WAIT_EVENT(); + if(ev == ble_event_interface_added) { + etimer_stop(&led_timer); + leds_off(LEDS_1); + leds_on(LEDS_2); + } else if(ev == ble_event_interface_deleted) { + etimer_set(&led_timer, CLOCK_SECOND/2); + leds_off(LEDS_2); + } else if(ev == PROCESS_EVENT_TIMER && etimer_expired(&led_timer)) { + etimer_reset(&led_timer); + leds_toggle(LEDS_1); + } + } + PROCESS_END(); +} +#endif +/*---------------------------------------------------------------------------*/ +/** + * \brief Board specific initialization + * + * This function will enable SoftDevice is present. + */ +static void +board_init(void) +{ +#ifdef SOFTDEVICE_PRESENT + // Initialize the SoftDevice handler module. + SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, NULL); +#endif +#ifdef PLATFORM_HAS_BUTTON + if (!nrf_drv_gpiote_is_init()) { + nrf_drv_gpiote_init(); + } +#endif +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Main function for nRF52dk platform. + * \note This function doesn't return. + */ +int +main(void) +{ + board_init(); + leds_init(); + + clock_init(); + rtimer_init(); + + watchdog_init(); + process_init(); + + // Seed value is ignored since hardware RNG is used. + random_init(0); + +#ifdef UART0_ENABLED + uart0_init(); +#if SLIP_ARCH_CONF_ENABLE + slip_arch_init(0); +#else + uart0_set_input(serial_line_input_byte); + serial_line_init(); +#endif +#endif + + PRINTF("Starting " CONTIKI_VERSION_STRING "\n"); + + process_start(&etimer_process, NULL); + ctimer_init(); + +#if ENERGEST_CONF_ON + energest_init(); + ENERGEST_ON(ENERGEST_TYPE_CPU); +#endif + +#ifdef SOFTDEVICE_PRESENT + ble_stack_init(); + ble_advertising_init(DEVICE_NAME); + +#if NETSTACK_CONF_WITH_IPV6 + netstack_init(); + linkaddr_t linkaddr; + ble_get_mac(linkaddr.u8); + // Set link layer address + linkaddr_set_node_addr(&linkaddr); + // Set device link layer address in uip stack. + memcpy(&uip_lladdr.addr, &linkaddr, sizeof(uip_lladdr.addr)); + uip_debug_lladdr_print(&uip_lladdr); + PRINTF("\n"); + process_start(&ble_iface_observer, NULL); + process_start(&tcpip_process, NULL); +#endif /* NETSTACK_CONF_WITH_IPV6 */ +#endif /* SOFTDEVICE_PRESENT */ + + process_start(&sensors_process, NULL); + autostart_start(autostart_processes); + + watchdog_start(); + +#ifdef SOFTDEVICE_PRESENT + ble_advertising_start(); + PRINTF("Advertising name [%s]\n", DEVICE_NAME); +#endif + + while(1) { + uint8_t r; + do { + r = process_run(); + watchdog_periodic(); + } while(r > 0); + + lpm_drop(); + } +} +/** + * @} + */ diff --git a/platform/nrf52dk/dbg-io/dbg.c b/platform/nrf52dk/dbg-io/dbg.c new file mode 100644 index 000000000..db9bb63c0 --- /dev/null +++ b/platform/nrf52dk/dbg-io/dbg.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * 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. + * + */ + +/** + * \addtogroup nrf52dk + * @{ + * + * \addtogroup nrf52dk-dbg-io Debug IO over UART + * @{ + * + * \file + * Function implementations for debug io module. + * \author + * Wojciech Bober + * + */ +#include "dev/uart0.h" +/*---------------------------------------------------------------------------*/ +unsigned int +dbg_send_bytes(const unsigned char *s, unsigned int len) +{ + unsigned int i = 0; + + while (s && *s != 0) { + if (i >= len) { + break; + } + uart0_writeb(*s++); + i++; + } + + return i; +} +/*---------------------------------------------------------------------------*/ +int +dbg_putchar(int c) +{ + uart0_writeb(c); + return c; +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/nrf52dk/dbg-io/dbg.h b/platform/nrf52dk/dbg-io/dbg.h new file mode 100644 index 000000000..7c623336b --- /dev/null +++ b/platform/nrf52dk/dbg-io/dbg.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * +3 * 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. + * + */ +/** + * \addtogroup nrf52dk + * @{ + * + * \addtogroup nrf52dk-dbg-io Debug IO over UART + * @{ + * + * \file + * Header file for the debug module. + * \author + * Wojciech Bober + * + */ +#ifndef DBG_H_ +#define DBG_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +/*---------------------------------------------------------------------------*/ +/** + * \brief Print a stream of bytes + * \param seq A pointer to the stream + * \param len The number of bytes to print + * \return The number of printed bytes + */ +unsigned int dbg_send_bytes(const unsigned char *seq, unsigned int len); +/** + * \brief Print a character to debug output + * \param c Character to print + * \return Printed character + */ +int dbg_putchar(int c); +/*---------------------------------------------------------------------------*/ +#endif /* DBG_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/nrf52dk/dbg-io/debug-uart.h b/platform/nrf52dk/dbg-io/debug-uart.h new file mode 100644 index 000000000..b52d2fb50 --- /dev/null +++ b/platform/nrf52dk/dbg-io/debug-uart.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * 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. + * + */ +/** + * \addtogroup nrf52dk + * @{ + * + * \addtogroup nrf52dk-dbg-io Debug IO over UART + * @{ + * + * \file + * A header file to maintain compatibility with DBG I/O. + * \author + * Wojciech Bober + * + */ +/*---------------------------------------------------------------------------*/ +#ifndef DEBUG_UART_H_ +#define DEBUG_UART_H_ +/*---------------------------------------------------------------------------*/ +#include "dbg.h" +/*---------------------------------------------------------------------------*/ +#endif /* DEBUG_UART_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/nrf52dk/dev/button-sensor.c b/platform/nrf52dk/dev/button-sensor.c new file mode 100644 index 000000000..3c218a439 --- /dev/null +++ b/platform/nrf52dk/dev/button-sensor.c @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup nrf52dk-devices Device drivers + * @{ + * + * \addtogroup nrf52dk-devices-button Buttons driver + * @{ + * + * \file + * Driver for nRF52 DK buttons. + * \author + * Wojciech Bober + */ +/*---------------------------------------------------------------------------*/ +#include +#include "nordic_common.h" +#include "nrf_drv_gpiote.h" +#include "nrf_assert.h" +#include "boards.h" +#include "contiki.h" +#include "lib/sensors.h" +#include "button-sensor.h" + +/*---------------------------------------------------------------------------*/ +#define DEBOUNCE_DURATION (CLOCK_SECOND >> 5) /**< Delay before button state is assumed to be stable */ + +/*---------------------------------------------------------------------------*/ +struct btn_timer +{ + struct timer debounce; + clock_time_t start; + clock_time_t duration; +}; + +static struct btn_timer btn_timer[BUTTONS_NUMBER]; +static int btn_state = 0; + +/*---------------------------------------------------------------------------*/ +/** + * \brief Button toggle handler + * \param pin GPIO pin which has been triggered + * \param action toggle direction + * + */ +static void +gpiote_event_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) +{ + int id = pin - BUTTON_START; + + if(!timer_expired(&(btn_timer[id].debounce))) { + return; + } + + /* Set timer to ignore consecutive changes for + * DEBOUNCE_DURATION. + */ + timer_set(&(btn_timer[id].debounce), DEBOUNCE_DURATION); + + /* + * Start measuring duration on falling edge, stop on rising edge. + */ + if(nrf_drv_gpiote_in_is_set(pin) == 0) { + btn_timer[id].start = clock_time(); + btn_timer[id].duration = 0; + } else { + btn_timer[id].duration = clock_time() - btn_timer[id].start; + } + sensors_changed(&buttons[id]); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for the button sensor for all buttons. + * + * \param type if \a SENSORS_HW_INIT is passed the function will initialize + * given button + * if \a SENSORS_ACTIVE is passed then \p c parameter defines + * whether button should be set active or inactive + * \param c 0 to disable the button, non-zero: enable + * \param pin GPIOE pin number + */ +static int +config(int type, int c, nrf_drv_gpiote_pin_t pin) +{ + int id = pin - BUTTON_START; + + switch(type) { + case SENSORS_HW_INIT: { + nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false); + config.pull = NRF_GPIO_PIN_PULLUP; + nrf_drv_gpiote_in_init(pin, &config, gpiote_event_handler); + timer_set(&(btn_timer[id].debounce), DEBOUNCE_DURATION); + return 1; + } + case SENSORS_ACTIVE: { + if(c) { + nrf_drv_gpiote_in_event_enable(pin, true); + btn_state |= (1 << id); + } else { + nrf_drv_gpiote_in_event_disable(pin); + btn_state &= ~(1 << id); + } + return 1; + } + default: + return 0; + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for button 1 + * + * \param type passed to config() as-is + * \param value passed to config() as-is + * \return same as config() return value + */ +static int +config_button_1(int type, int value) +{ + return config(type, value, BSP_BUTTON_0); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for button 2 + * + * \param type passed to config() as-is + * \param value passed to config() as-is + * \return same as config() return value + */ +static int +config_button_2(int type, int value) +{ + return config(type, value, BSP_BUTTON_1); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for button 3 + * + * \param type passed to config() as-is + * \param value passed to config() as-is + * \return same as config() return value + */ +static int +config_button_3(int type, int value) +{ + return config(type, value, BSP_BUTTON_2); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for button 4 + * + * \param type passed to config() as-is + * \param value passed to config() as-is + * \return same as config() return value + */ +static int +config_button_4(int type, int value) +{ + return config(type, value, BSP_BUTTON_3); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Return current state of a button + * \param type pass \ref BUTTON_SENSOR_VALUE_STATE to get current button state + * or \ref BUTTON_SENSOR_VALUE_DURATION to get active state duration + * \param pin GPIOE pin number + * + * \retval BUTTON_SENSOR_VALUE_PRESSED + * \retval BUTTON_SENSOR_VALUE_RELEASED when \a type is \ref BUTTON_SENSOR_VALUE_STATE + * \retval duration Active state duration in clock ticks + */ +static int +value(int type, nrf_drv_gpiote_pin_t pin) +{ + + if(type == BUTTON_SENSOR_VALUE_STATE) { + return nrf_drv_gpiote_in_is_set(pin) == 0 ? + BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED; + } else if(type == BUTTON_SENSOR_VALUE_DURATION) { + return btn_timer[pin - BUTTON_START].duration; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Return current state of a button 1 + * \param type passed to value() as-is + * \return same as value returned by value() + */ +static int +value_button_1(int type) +{ + return value(type, BSP_BUTTON_0); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Return current state of a button 2 + * \param type passed to value() as-is + * \return same as value returned by value() + */ +static int +value_button_2(int type) +{ + return value(type, BSP_BUTTON_1); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Return current state of a button 3 + * \param type passed to value() as-is + * \return same as value returned by value() + */ +static int +value_button_3(int type) +{ + return value(type, BSP_BUTTON_2); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Return current state of a button 4 + * \param type passed to value() as-is + * \return same as value returned by value() + */ +static int +value_button_4(int type) +{ + return value(type, BSP_BUTTON_3); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Get status of a given button + * \param type \a SENSORS_ACTIVE or \a SENSORS_READY + * \param pin GPIOE pin number + * \return 1 if the button's port interrupt is enabled + */ +static int +status(int type, nrf_drv_gpiote_pin_t pin) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return (btn_state & (1 << (pin - BUTTON_START))); + default: + break; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Status function for button 1 + * \param type passed to state() as-is + * \return value returned by state() + */ +static int +status_button_1(int type) +{ + return status(type, BSP_BUTTON_0); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Status function for button 2 + * \param type passed to state() as-is + * \return value returned by state() + */ +static int +status_button_2(int type) +{ + return status(type, BSP_BUTTON_1); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Status function for button 3 + * \param type passed to state() as-is + * \return value returned by state() + */ +static int +status_button_3(int type) +{ + return status(type, BSP_BUTTON_2); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Status function for button 3 + * \param type passed to state() as-is + * \return value returned by state() + */ +static int +status_button_4(int type) +{ + return status(type, BSP_BUTTON_3); +} +/*---------------------------------------------------------------------------*/ +const struct sensors_sensor buttons[BUTTONS_NUMBER] = { + {BUTTON_SENSOR, value_button_1, config_button_1, status_button_1}, + {BUTTON_SENSOR, value_button_2, config_button_2, status_button_2}, + {BUTTON_SENSOR, value_button_3, config_button_3, status_button_3}, + {BUTTON_SENSOR, value_button_4, config_button_4, status_button_4}, }; +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/nrf52dk/dev/button-sensor.h b/platform/nrf52dk/dev/button-sensor.h new file mode 100644 index 000000000..ababb1c1c --- /dev/null +++ b/platform/nrf52dk/dev/button-sensor.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup nrf52dk-devices Device drivers + * @{ + * + * \addtogroup nrf52dk-devices-button Buttons driver + * @{ + * + * \file + * Header file for the nRF52dk button driver. + * \author + * Wojciech Bober + * + */ +/*---------------------------------------------------------------------------*/ +#ifndef BUTTON_SENSOR_H_ +#define BUTTON_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define BUTTON_SENSOR "Button" +/*---------------------------------------------------------------------------*/ +#define BUTTON_SENSOR_VALUE_STATE 0 /**< Can be passed to value() function + to get current button state */ +#define BUTTON_SENSOR_VALUE_DURATION 1 /**< Can be passed to value() function + to get low state duration */ + +#define BUTTON_SENSOR_VALUE_RELEASED 0 +#define BUTTON_SENSOR_VALUE_PRESSED 1 +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor buttons[]; +/*---------------------------------------------------------------------------*/ +#define button_1 buttons[0] +#define button_2 buttons[1] +#define button_3 buttons[2] +#define button_4 buttons[3] +/*---------------------------------------------------------------------------*/ +#endif /* BUTTON_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/nrf52dk/dev/leds-arch.c b/platform/nrf52dk/dev/leds-arch.c new file mode 100644 index 000000000..019589493 --- /dev/null +++ b/platform/nrf52dk/dev/leds-arch.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * 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. + * + */ + +/** + * \addtogroup nrf52dk + * @{ + * + * \addtogroup nrf52dk-devices Device drivers + * @{ + * + * \addtogroup nrf52dk-devices-led LED driver + * @{ + * + * \file + * Architecture specific LED driver implementation for nRF52 DK. + * \author + * Wojciech Bober + */ +#include "boards.h" +#include "contiki.h" +#include "dev/leds.h" + +/*---------------------------------------------------------------------------*/ +void +leds_arch_init(void) +{ + LEDS_CONFIGURE(LEDS_MASK); + LEDS_OFF(LEDS_MASK); +} +/*---------------------------------------------------------------------------*/ +unsigned char +leds_arch_get(void) +{ + return (unsigned char)(LED_IS_ON(LEDS_MASK) >> LED_START); +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set(unsigned char leds) +{ + unsigned int mask = (unsigned int)leds << LED_START; + LEDS_OFF(LEDS_MASK); + LEDS_ON(mask); +} +/*---------------------------------------------------------------------------*/ + +/** + * @} + * @} + * @} + */ diff --git a/platform/nrf52dk/dev/nrf52dk-sensors.c b/platform/nrf52dk/dev/nrf52dk-sensors.c new file mode 100644 index 000000000..3d56e91d1 --- /dev/null +++ b/platform/nrf52dk/dev/nrf52dk-sensors.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * 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. + * + */ + +/** + * \addtogroup nrf52dk + * @{ + * + * \addtogroup nrf52dk-devices Device drivers + * @{ + * + * \addtogroup nrf52dk-sensors Sensors + * The nRF52 DK exports 4 button sensors and an internal temperature sensor. + * @{ + * + * \file + * This file exports a global sensors table. + * \author + * Wojciech Bober + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "lib/sensors.h" +#include "dev/button-sensor.h" +#include "dev/temperature-sensor.h" +/*---------------------------------------------------------------------------*/ +SENSORS( + &button_1, + &button_2, + &button_3, + &button_4, + &temperature_sensor +); +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + * @} + */ diff --git a/platform/nrf52dk/dev/temperature-sensor.c b/platform/nrf52dk/dev/temperature-sensor.c new file mode 100644 index 000000000..5aac8b3ef --- /dev/null +++ b/platform/nrf52dk/dev/temperature-sensor.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * 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. + * + */ + +/** + * \addtogroup nrf52dk-devices Device drivers + * @{ + * + * \addtogroup nrf52dk-devices-temp Temperature sensor driver + * This is a driver for nRF52832 hardware sensor. + * + * @{ + * + * \file + * Temperature sensor implementation. + * \author + * Wojciech Bober + * + */ +#ifndef SOFTDEVICE_PRESENT +#include "nrf_temp.h" +#else +#include "nrf_soc.h" +#endif +#include "contiki.h" +#include "dev/temperature-sensor.h" + + +const struct sensors_sensor temperature_sensor; + +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns device temperature + * \param type ignored + * \return Device temperature in degrees Celsius + */ +static int +value(int type) +{ +#ifndef SOFTDEVICE_PRESENT + return nrf_temp_read(); +#else + int32_t temp; + sd_temp_get(&temp); + return temp >> 2; +#endif +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configures temperature sensor + * \param type initializes the hardware sensor when \a type is set to + * \a SENSORS_HW_INIT + * \param c ignored + * \return 1 + * \note This function does nothing when SoftDevice is present + */ +static int +configure(int type, int c) +{ +#ifndef SOFTDEVICE_PRESENT + if (type == SENSORS_HW_INIT) { + nrf_temp_init(); + } +#endif + return 1; +} +/** + * \brief Return temperature sensor status + * \param type ignored + * \return 1 + */ +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(temperature_sensor, TEMPERATURE_SENSOR, value, configure, status); +/** + * @} + * @} + */ diff --git a/platform/nrf52dk/dev/temperature-sensor.h b/platform/nrf52dk/dev/temperature-sensor.h new file mode 100644 index 000000000..27b246b2d --- /dev/null +++ b/platform/nrf52dk/dev/temperature-sensor.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * 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. + * + */ + +/** + * \addtogroup nrf52dk-devices Device drivers + * @{ + * + * \addtogroup nrf52dk-devices-temp Temperature sensor driver + * @{ + * + * \file + * Temperature sensor header file. + * \author + * Wojciech Bober + * + */ + +#ifndef TEMPERATURE_SENSOR_H_ +#define TEMPERATURE_SENSOR_H_ + +#include "lib/sensors.h" + +extern const struct sensors_sensor temperature_sensor; + +#define TEMPERATURE_SENSOR "Temperature" + +#endif /* TEMPERATURE_SENSOR_H_ */ + +/** + * @} + * @} + */ diff --git a/platform/nrf52dk/platform-conf.h b/platform/nrf52dk/platform-conf.h new file mode 100644 index 000000000..931a3c275 --- /dev/null +++ b/platform/nrf52dk/platform-conf.h @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * 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. + * + */ + +/** + * \addtogroup platform + * @{ + * + * \addtogroup nrf52dk nRF52 Development Kit + * @{ + * + * \addtogroup nrf52dk-platform-conf Platform configuration + * @{ + * \file + * Platform features configuration. + * \author + * Wojciech Bober + * + */ +#ifndef PLATFORM_CONF_H_ +#define PLATFORM_CONF_H_ + +#include "boards.h" + +#define PLATFORM_HAS_BATTERY 0 +#define PLATFORM_HAS_RADIO 0 +#define PLATFORM_HAS_TEMPERATURE 1 + +/** + * \name Leds configurations + * + * On nRF52dk all leds are green. + * + * @{ + */ +#define PLATFORM_HAS_LEDS 1 + +#define LEDS_1 (1 << (LED_1 - LED_START)) // 1 +#define LEDS_2 (1 << (LED_2 - LED_START)) // 2 +#define LEDS_3 (1 << (LED_3 - LED_START)) // 4 +#define LEDS_4 (1 << (LED_4 - LED_START)) // 8 + +#define LEDS_GREEN LEDS_1 +#define LEDS_YELLOW LEDS_2 +#define LEDS_RED LEDS_3 +#define LEDS_BLUE LEDS_4 + +#define LEDS_CONF_ALL (LEDS_1 | LEDS_2 | LEDS_3 | LEDS_4) + +/** + * \brief If set to 1 then LED1 and LED2 are used by the + * platform to indicate BLE connection state. + */ +#define PLATFORM_INDICATE_BLE_STATE 1 +/** @} */ + +/** + * \name Button configurations + * + * @{ + */ +/* Notify various examples that we have Buttons */ +#define PLATFORM_HAS_BUTTON 1 + +/* + * Override button symbols from dev/button-sensor.h, for the examples that + * include it + */ +#define button_sensor button_1 +#define button_sensor2 button_2 + +/** + * \brief nRF52 RTC instance to be used for Contiki clock driver. + * \note RTC 0 is used by the SoftDevice. + */ +#define PLATFORM_RTC_INSTANCE_ID 1 + +/** + * \brief nRF52 timer instance to be used for Contiki rtimer driver. + * \note Timer 0 is used by the SoftDevice. + */ +#define PLATFORM_TIMER_INSTANCE_ID 1 + +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Compiler configuration and platform-specific type definitions + * + * Those values are not meant to be modified by the user + * @{ + */ +#define CLOCK_CONF_SECOND 128 + +/* Compiler configurations */ +#define CCIF +#define CLIF + +/* Platform typedefs */ +typedef uint32_t clock_time_t; +typedef uint32_t uip_stats_t; + +/* Clock (time) comparison macro */ +#define CLOCK_LT(a, b) ((signed long)((a) - (b)) < 0) + +#define RTIMER_ARCH_SECOND 62500 +/* + * rtimer.h typedefs rtimer_clock_t as unsigned short. We need to define + * RTIMER_CLOCK_LT to override this + */ +typedef uint32_t rtimer_clock_t; +#define RTIMER_CLOCK_LT(a, b) ((int32_t)((a) - (b)) < 0) + +/** @} */ +/*---------------------------------------------------------------------------*/ +/** @} + * @} + * @} + */ +#endif /* PLATFORM_CONF_H_ */ diff --git a/platform/nrf52dk/rtt/rtt-printf.c b/platform/nrf52dk/rtt/rtt-printf.c new file mode 100644 index 000000000..416fff0ab --- /dev/null +++ b/platform/nrf52dk/rtt/rtt-printf.c @@ -0,0 +1,24 @@ +#include +#include "segger-rtt.h" + +int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList); + +int +putchar(int c) +{ + SEGGER_RTT_Write(0, &c, 1); + return c; +} + +int +printf(const char *fmt, ...) +{ + int res; + va_list ap; + va_start(ap, fmt); + res = SEGGER_RTT_vprintf(0, fmt, &ap); + va_end(ap); + return res; +} + + diff --git a/platform/nrf52dk/rtt/segger-rtt-conf.h b/platform/nrf52dk/rtt/segger-rtt-conf.h new file mode 100644 index 000000000..ac996644f --- /dev/null +++ b/platform/nrf52dk/rtt/segger-rtt-conf.h @@ -0,0 +1,135 @@ +/********************************************************************* +* SEGGER MICROCONTROLLER GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 2014 - 2015 SEGGER Microcontroller GmbH & Co. KG * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +---------------------------------------------------------------------- +File : SEGGER_RTT_Conf.h +Purpose : Implementation of SEGGER real-time transfer (RTT) which + allows real-time communication on targets which support + debugger memory accesses while the CPU is running. +---------------------------END-OF-HEADER------------------------------ +*/ + +#ifndef SEGGER_RTT_CONF_H +#define SEGGER_RTT_CONF_H + +#ifdef __ICCARM__ + #include +#endif + +/********************************************************************* +* +* Defines, configurable +* +********************************************************************** +*/ + +#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (2) // Max. number of up-buffers (T->H) available on this target (Default: 2) +#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (2) // Max. number of down-buffers (H->T) available on this target (Default: 2) + +#define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k) +#define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16) + +#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64) + +#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0) + +// +// Target is not allowed to perform other RTT operations while string still has not been stored completely. +// Otherwise we would probably end up with a mixed string in the buffer. +// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here. +// +/********************************************************************* +* +* RTT lock configuration for SEGGER Embedded Studio, +* Rowley CrossStudio and GCC +*/ +#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__) + #ifdef __ARM_ARCH_6M__ + #define SEGGER_RTT_LOCK(SavedState) { \ + asm volatile ("mrs %0, primask \n\t" \ + "mov r1, $1 \n\t" \ + "msr primask, r1 \n\t" \ + : "=r" (SavedState) \ + : \ + : "r1" \ + ); \ + } + + #define SEGGER_RTT_UNLOCK(SavedState) { \ + asm volatile ("msr primask, %0 \n\t" \ + : \ + : "r" (SavedState) \ + : \ + ); \ + } + + #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)) + #define SEGGER_RTT_LOCK(SavedState) { \ + asm volatile ("mrs %0, basepri \n\t" \ + "mov r1, $128 \n\t" \ + "msr basepri, r1 \n\t" \ + : "=r" (SavedState) \ + : \ + : "r1" \ + ); \ + } + #define SEGGER_RTT_UNLOCK(SavedState) { \ + asm volatile ("msr basepri, %0 \n\t" \ + : \ + : "r" (SavedState) \ + : \ + ); \ + } + #else + #define SEGGER_RTT_LOCK(SavedState) (void)(SavedState) + #define SEGGER_RTT_UNLOCK(SavedState) (void)(SavedState) + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR EWARM +*/ +#ifdef __ICCARM__ + #if (defined (__ARM7M__) && (__CORE__ == __ARM7M__)) + #define SEGGER_RTT_LOCK(SavedState) { \ + SavedState = __get_PRIMASK(); \ + __set_PRIMASK(1); \ + } + + #define SEGGER_RTT_UNLOCK(SavedState) { \ + __set_PRIMASK(SavedState); \ + } + #elif (defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) + #define SEGGER_RTT_LOCK(SavedState) { \ + SavedState = __get_BASEPRI(); \ + __set_BASEPRI(128); \ + } + + #define SEGGER_RTT_UNLOCK(SavedState) { \ + __set_BASEPRI(SavedState); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration fallback +*/ +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK(SavedState) (void)(SavedState) +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK(SavedState) (void)(SavedState) +#endif + +#endif +/*************************** End of file ****************************/ diff --git a/platform/nrf52dk/rtt/segger-rtt-printf.c b/platform/nrf52dk/rtt/segger-rtt-printf.c new file mode 100644 index 000000000..e992e7a36 --- /dev/null +++ b/platform/nrf52dk/rtt/segger-rtt-printf.c @@ -0,0 +1,510 @@ +/********************************************************************* +* SEGGER MICROCONTROLLER GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 2014 - 2015 SEGGER Microcontroller GmbH & Co. KG * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* * This software may in its unmodified form be freely redistributed * +* in source form. * +* * The source code may be modified, provided the source code * +* retains the above copyright notice, this list of conditions and * +* the following disclaimer. * +* * Modified versions of this software in source or linkable form * +* may not be distributed without prior consent of SEGGER. * +* * This software may only be used for communication with SEGGER * +* J-Link debug probes. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 SEGGER Microcontroller 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. * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT_printf.c +Purpose : Replacement for printf to write formatted data via RTT +---------------------------------------------------------------------- +*/ +#include "segger-rtt.h" +#include "segger-rtt-conf.h" + +/********************************************************************* +* +* Defines, configurable +* +********************************************************************** +*/ + +#ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE + #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64) +#endif + +#include +#include + + +#define FORMAT_FLAG_LEFT_JUSTIFY (1u << 0) +#define FORMAT_FLAG_PAD_ZERO (1u << 1) +#define FORMAT_FLAG_PRINT_SIGN (1u << 2) +#define FORMAT_FLAG_ALTERNATE (1u << 3) + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +typedef struct { + char* pBuffer; + unsigned BufferSize; + unsigned Cnt; + + int ReturnValue; + + unsigned RTTBufferIndex; +} SEGGER_RTT_PRINTF_DESC; + +/********************************************************************* +* +* Function prototypes +* +********************************************************************** +*/ +int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList); + +/********************************************************************* +* +* Static code +* +********************************************************************** +*/ +/********************************************************************* +* +* _StoreChar +*/ +static void _StoreChar(SEGGER_RTT_PRINTF_DESC * p, char c) { + unsigned Cnt; + + Cnt = p->Cnt; + if ((Cnt + 1u) <= p->BufferSize) { + *(p->pBuffer + Cnt) = c; + p->Cnt = Cnt + 1u; + p->ReturnValue++; + } + // + // Write part of string, when the buffer is full + // + if (p->Cnt == p->BufferSize) { + if (SEGGER_RTT_Write(p->RTTBufferIndex, p->pBuffer, p->Cnt) != p->Cnt) { + p->ReturnValue = -1; + } else { + p->Cnt = 0u; + } + } +} + +/********************************************************************* +* +* _PrintUnsigned +*/ +static void _PrintUnsigned(SEGGER_RTT_PRINTF_DESC * pBufferDesc, unsigned v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) { + static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + unsigned Div; + unsigned Digit; + unsigned Number; + unsigned Width; + char c; + + Number = v; + Digit = 1u; + // + // Get actual field width + // + Width = 1u; + while (Number >= Base) { + Number = (Number / Base); + Width++; + } + if (NumDigits > Width) { + Width = NumDigits; + } + // + // Print leading chars if necessary + // + if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) { + if (FieldWidth != 0u) { + if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) { + c = '0'; + } else { + c = ' '; + } + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, c); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Compute Digit. + // Loop until Digit has the value of the highest digit required. + // Example: If the output is 345 (Base 10), loop 2 times until Digit is 100. + // + while (1) { + if (NumDigits > 1u) { // User specified a min number of digits to print? => Make sure we loop at least that often, before checking anything else (> 1 check avoids problems with NumDigits being signed / unsigned) + NumDigits--; + } else { + Div = v / Digit; + if (Div < Base) { // Is our divider big enough to extract the highest digit from value? => Done + break; + } + } + Digit *= Base; + } + // + // Output digits + // + do { + Div = v / Digit; + v -= Div * Digit; + _StoreChar(pBufferDesc, _aV2C[Div]); + if (pBufferDesc->ReturnValue < 0) { + break; + } + Digit /= Base; + } while (Digit); + // + // Print trailing spaces if necessary + // + if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, ' '); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + } +} + +/********************************************************************* +* +* _PrintInt +*/ +static void _PrintInt(SEGGER_RTT_PRINTF_DESC * pBufferDesc, int v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) { + unsigned Width; + int Number; + + Number = (v < 0) ? -v : v; + + // + // Get actual field width + // + Width = 1u; + while (Number >= (int)Base) { + Number = (Number / (int)Base); + Width++; + } + if (NumDigits > Width) { + Width = NumDigits; + } + if ((FieldWidth > 0u) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) { + FieldWidth--; + } + + // + // Print leading spaces if necessary + // + if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, ' '); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + // + // Print sign if necessary + // + if (pBufferDesc->ReturnValue >= 0) { + if (v < 0) { + v = -v; + _StoreChar(pBufferDesc, '-'); + } else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) { + _StoreChar(pBufferDesc, '+'); + } else { + + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Print leading zeros if necessary + // + if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, '0'); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Print number without sign + // + _PrintUnsigned(pBufferDesc, (unsigned)v, Base, NumDigits, FieldWidth, FormatFlags); + } + } + } +} + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +/********************************************************************* +* +* SEGGER_RTT_vprintf +* +* Function description +* Stores a formatted string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal") +* sFormat Pointer to format string +* pParamList Pointer to the list of arguments for the format string +* +* Return values +* >= 0: Number of bytes which have been stored in the "Up"-buffer. +* < 0: Error +*/ +int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList) { + char c; + SEGGER_RTT_PRINTF_DESC BufferDesc; + int v; + unsigned NumDigits; + unsigned FormatFlags; + unsigned FieldWidth; + char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE]; + + BufferDesc.pBuffer = acBuffer; + BufferDesc.BufferSize = SEGGER_RTT_PRINTF_BUFFER_SIZE; + BufferDesc.Cnt = 0u; + BufferDesc.RTTBufferIndex = BufferIndex; + BufferDesc.ReturnValue = 0; + + do { + c = *sFormat; + sFormat++; + if (c == 0u) { + break; + } + if (c == '%') { + // + // Filter out flags + // + FormatFlags = 0u; + v = 1; + do { + c = *sFormat; + switch (c) { + case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break; + case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO; sFormat++; break; + case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN; sFormat++; break; + case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE; sFormat++; break; + default: v = 0; break; + } + } while (v); + // + // filter out field with + // + FieldWidth = 0u; + do { + c = *sFormat; + if ((c < '0') || (c > '9')) { + break; + } + sFormat++; + FieldWidth = (FieldWidth * 10u) + ((unsigned)c - '0'); + } while (1); + + // + // Filter out precision (number of digits to display) + // + NumDigits = 0u; + c = *sFormat; + if (c == '.') { + sFormat++; + do { + c = *sFormat; + if (c == '*') { + sFormat++; + v = va_arg(*pParamList, int); + NumDigits = (unsigned)v; + break; + } + if ((c < '0') || (c > '9')) { + break; + } + sFormat++; + NumDigits = NumDigits * 10u + ((unsigned)c - '0'); + } while (1); + } + // + // Filter out length modifier + // + c = *sFormat; + do { + if ((c == 'l') || (c == 'h')) { + c = *sFormat; + sFormat++; + } else { + break; + } + } while (1); + // + // Handle specifiers + // + switch (c) { + case 'c': { + char c0; + v = va_arg(*pParamList, int); + c0 = (char)v; + _StoreChar(&BufferDesc, c0); + break; + } + case 'd': + v = va_arg(*pParamList, int); + _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags); + break; + case 'u': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 10u, NumDigits, FieldWidth, FormatFlags); + break; + case 'x': + case 'X': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, NumDigits, FieldWidth, FormatFlags); + break; + case 's': + { + const char * s = va_arg(*pParamList, const char *); + if (NumDigits > 0) { + do { + c = *s; + s++; + if (NumDigits == 0) { + break; + } + NumDigits--; + _StoreChar(&BufferDesc, c); + } while (BufferDesc.ReturnValue >= 0); + } else { + do { + c = *s; + s++; + if (c == '\0' || NumDigits == 0) { + break; + } + _StoreChar(&BufferDesc, c); + } while (BufferDesc.ReturnValue >= 0); + } + } + break; + case 'p': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, 8u, 8u, 0u); + break; + case '%': + _StoreChar(&BufferDesc, '%'); + break; + default: + break; + } + sFormat++; + } else { + _StoreChar(&BufferDesc, c); + } + } while (BufferDesc.ReturnValue >= 0); + + if (BufferDesc.ReturnValue > 0) { + // + // Write remaining data, if any + // + if (BufferDesc.Cnt != 0u) { + SEGGER_RTT_Write(BufferIndex, acBuffer, BufferDesc.Cnt); + } + BufferDesc.ReturnValue += (int)BufferDesc.Cnt; + } + return BufferDesc.ReturnValue; +} + +/********************************************************************* +* +* SEGGER_RTT_printf +* +* Function description +* Stores a formatted string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal") +* sFormat Pointer to format string, followed by the arguments for conversion +* +* Return values +* >= 0: Number of bytes which have been stored in the "Up"-buffer. +* < 0: Error +* +* Notes +* (1) Conversion specifications have following syntax: +* %[flags][FieldWidth][.Precision]ConversionSpecifier +* (2) Supported flags: +* -: Left justify within the field width +* +: Always print sign extension for signed conversions +* 0: Pad with 0 instead of spaces. Ignored when using '-'-flag or precision +* Supported conversion specifiers: +* c: Print the argument as one char +* d: Print the argument as a signed integer +* u: Print the argument as an unsigned integer +* x: Print the argument as an hexadecimal integer +* s: Print the string pointed to by the argument +* p: Print the argument as an 8-digit hexadecimal integer. (Argument shall be a pointer to void.) +*/ +int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...) { + va_list ParamList; + + va_start(ParamList, sFormat); + return SEGGER_RTT_vprintf(BufferIndex, sFormat, &ParamList); +} +/*************************** End of file ****************************/ diff --git a/platform/nrf52dk/rtt/segger-rtt.c b/platform/nrf52dk/rtt/segger-rtt.c new file mode 100644 index 000000000..453a6a0e4 --- /dev/null +++ b/platform/nrf52dk/rtt/segger-rtt.c @@ -0,0 +1,1102 @@ +/********************************************************************* +* SEGGER MICROCONTROLLER GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 2014 - 2015 SEGGER Microcontroller GmbH & Co. KG * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* * This software may in its unmodified form be freely redistributed * +* in source form. * +* * The source code may be modified, provided the source code * +* retains the above copyright notice, this list of conditions and * +* the following disclaimer. * +* * Modified versions of this software in source or linkable form * +* may not be distributed without prior consent of SEGGER. * +* * This software may only be used for communication with SEGGER * +* J-Link debug probes. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 SEGGER Microcontroller 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. * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT.c +Purpose : Implementation of SEGGER real-time transfer (RTT) which + allows real-time communication on targets which support + debugger memory accesses while the CPU is running. + +Additional information: + Type "int" is assumed to be 32-bits in size + H->T Host to target communication + T->H Target to host communication + + RTT channel 0 is always present and reserved for Terminal usage. + Name is fixed to "Terminal" + +---------------------------------------------------------------------- +*/ + +#include "segger-rtt.h" + +#include // for memcpy + +/********************************************************************* +* +* Configuration, default values +* +********************************************************************** +*/ + +#ifndef BUFFER_SIZE_UP + #define BUFFER_SIZE_UP 1024 // Size of the buffer for terminal output of target, up to host +#endif + +#ifndef BUFFER_SIZE_DOWN + #define BUFFER_SIZE_DOWN 16 // Size of the buffer for terminal input to target from host (Usually keyboard input) +#endif + +#ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS + #define SEGGER_RTT_MAX_NUM_UP_BUFFERS 2 // Number of up-buffers (T->H) available on this target +#endif + +#ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS + #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS 2 // Number of down-buffers (H->T) available on this target +#endif + +#ifndef SEGGER_RTT_MODE_DEFAULT + #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP +#endif + +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK(SavedState) +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK(SavedState) +#endif + +#ifndef STRLEN + #define STRLEN(a) strlen((a)) +#endif + +#ifndef MEMCPY + #define MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes)) +#endif + +#ifndef MIN + #define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX + #define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif +// +// For some environments, NULL may not be defined until certain headers are included +// +#ifndef NULL + #define NULL 0 +#endif + +/********************************************************************* +* +* Static const data +* +********************************************************************** +*/ + +static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + +/********************************************************************* +* +* Static data +* +********************************************************************** +*/ +// +// Allocate buffers for channel 0 +// +static char _acUpBuffer [BUFFER_SIZE_UP]; +static char _acDownBuffer[BUFFER_SIZE_DOWN]; +// +// Initialize SEGGER Real-time-Terminal control block (CB) +// +SEGGER_RTT_CB _SEGGER_RTT; + +static char _ActiveTerminal; + +/********************************************************************* +* +* Static functions +* +********************************************************************** +*/ + +/********************************************************************* +* +* _DoInit() +* +* Function description +* Initializes the control block an buffers. +* May only be called via INIT() to avoid overriding settings. +* +*/ +#define INIT() do { \ + if (_SEGGER_RTT.acID[0] == '\0') { _DoInit(); } \ + } while (0) +static void _DoInit(void) { + SEGGER_RTT_CB* p; + // + // Initialize control block + // + p = &_SEGGER_RTT; + p->MaxNumUpBuffers = SEGGER_RTT_MAX_NUM_UP_BUFFERS; + p->MaxNumDownBuffers = SEGGER_RTT_MAX_NUM_DOWN_BUFFERS; + // + // Initialize up buffer 0 + // + p->aUp[0].sName = "Terminal"; + p->aUp[0].pBuffer = _acUpBuffer; + p->aUp[0].SizeOfBuffer = sizeof(_acUpBuffer); + p->aUp[0].RdOff = 0u; + p->aUp[0].WrOff = 0u; + p->aUp[0].Flags = SEGGER_RTT_MODE_DEFAULT; + // + // Initialize down buffer 0 + // + p->aDown[0].sName = "Terminal"; + p->aDown[0].pBuffer = _acDownBuffer; + p->aDown[0].SizeOfBuffer = sizeof(_acDownBuffer); + p->aDown[0].RdOff = 0u; + p->aDown[0].WrOff = 0u; + p->aDown[0].Flags = SEGGER_RTT_MODE_DEFAULT; + // + // Finish initialization of the control block. + // Copy Id string in three steps to make sure "SEGGER RTT" is not found + // in initializer memory (usually flash) by J-Link + // + strcpy(&p->acID[7], "RTT"); + strcpy(&p->acID[0], "SEGGER"); + p->acID[6] = ' '; +} + +/********************************************************************* +* +* _WriteBlocking() +* +* Function description +* Stores a specified number of characters in SEGGER RTT ring buffer +* and updates the associated write pointer which is periodically +* read by the host. +* The caller is responsible for managing the write chunk sizes as +* _WriteBlocking() will block until all data has been posted successfully. +* +* Parameters +* pRing Ring buffer to post to. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* >= 0 - Number of bytes written into buffer. +*/ +static unsigned _WriteBlocking(SEGGER_RTT_RING_BUFFER *pRing, const char* pBuffer, unsigned NumBytes) { + unsigned NumBytesToWrite; + unsigned NumBytesWritten; + unsigned RdOff; + unsigned WrOff; + // + // Write data to buffer and handle wrap-around if necessary + // + NumBytesWritten = 0u; + WrOff = pRing->WrOff; + do { + RdOff = pRing->RdOff; // May be changed by host (debug probe) in the meantime + if (RdOff > WrOff) { + NumBytesToWrite = RdOff - WrOff - 1u; + } else { + NumBytesToWrite = pRing->SizeOfBuffer - (WrOff - RdOff + 1u); + } + NumBytesToWrite = MIN(NumBytesToWrite, (pRing->SizeOfBuffer - WrOff)); // Number of bytes that can be written until buffer wrap-around + NumBytesToWrite = MIN(NumBytesToWrite, NumBytes); + memcpy(pRing->pBuffer + WrOff, pBuffer, NumBytesToWrite); + NumBytesWritten += NumBytesToWrite; + pBuffer += NumBytesToWrite; + NumBytes -= NumBytesToWrite; + WrOff += NumBytesToWrite; + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0u; + } + pRing->WrOff = WrOff; + } while (NumBytes); + // + return NumBytesWritten; +} + +/********************************************************************* +* +* _WriteNoCheck() +* +* Function description +* Stores a specified number of characters in SEGGER RTT ring buffer +* and updates the associated write pointer which is periodically +* read by the host. +* It is callers responsibility to make sure data actually fits in buffer. +* +* Parameters +* pRing Ring buffer to post to. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Notes +* (1) If there might not be enough space in the "Up"-buffer, call _WriteBlocking +*/ +static void _WriteNoCheck(SEGGER_RTT_RING_BUFFER *pRing, const char* pData, unsigned NumBytes) { + unsigned NumBytesAtOnce; + unsigned WrOff; + unsigned Rem; + + WrOff = pRing->WrOff; + Rem = pRing->SizeOfBuffer - WrOff; + if (Rem > NumBytes) { + // + // All data fits before wrap around + // + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; + } else { + // + // We reach the end of the buffer, so need to wrap around + // + NumBytesAtOnce = Rem; + memcpy(pRing->pBuffer + WrOff, pData, NumBytesAtOnce); + NumBytesAtOnce = NumBytes - Rem; + memcpy(pRing->pBuffer, pData + Rem, NumBytesAtOnce); + pRing->WrOff = NumBytesAtOnce; + } +} + +/********************************************************************* +* +* _PostTerminalSwitch() +* +* Function description +* Switch terminal to the given terminal ID. It is the caller's +* responsibility to ensure the terminal ID is correct and there is +* enough space in the buffer for this to complete successfully. +* +* Parameters +* pRing Ring buffer to post to. +* TerminalId Terminal ID to switch to. +*/ +static void _PostTerminalSwitch(SEGGER_RTT_RING_BUFFER *pRing, char TerminalId) { + char ac[2]; + + ac[0] = 0xFFu; + ac[1] = _aTerminalId[(int)TerminalId]; // Caller made already sure that TerminalId does not exceed our terminal limit + _WriteBlocking(pRing, ac, 2u); +} + +/********************************************************************* +* +* _GetAvailWriteSpace() +* +* Function description +* Returns the number of bytes that can be written to the ring +* buffer without blocking. +* +* Parameters +* pRing Ring buffer to check. +* +* Return value +* Number of bytes that are free in the buffer. +*/ +static unsigned _GetAvailWriteSpace(SEGGER_RTT_RING_BUFFER *pRing) { + unsigned RdOff; + unsigned WrOff; + unsigned r; + // + // Avoid warnings regarding volatile access order. It's not a problem + // in this case, but dampen compiler enthusiasm. + // + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + if (RdOff <= WrOff) { + r = pRing->SizeOfBuffer - 1u - WrOff + RdOff; + } else { + r = RdOff - WrOff - 1u; + } + return r; +} + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +/********************************************************************* +* +* SEGGER_RTT_ReadNoLock() +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the host. +* Do not lock against interrupts and multiple access. +* +* Parameters +* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +*/ +unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) { + unsigned NumBytesRem; + unsigned NumBytesRead; + unsigned RdOff; + unsigned WrOff; + unsigned char* pBuffer; + SEGGER_RTT_RING_BUFFER* pRing; + // + INIT(); + pRing = &_SEGGER_RTT.aDown[BufferIndex]; + pBuffer = (unsigned char*)pData; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + NumBytesRead = 0u; + // + // Read from current read position to wrap-around of buffer, first + // + if (RdOff > WrOff) { + NumBytesRem = pRing->SizeOfBuffer - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); + memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + // + // Handle wrap-around of buffer + // + if (RdOff == pRing->SizeOfBuffer) { + RdOff = 0u; + } + } + // + // Read remaining items of buffer + // + NumBytesRem = WrOff - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); + if (NumBytesRem > 0u) { + memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + } + if (NumBytesRead) { + pRing->RdOff = RdOff; + } + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_Read +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the host. +* +* Parameters +* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +*/ +unsigned SEGGER_RTT_Read(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) { + unsigned NumBytesRead; + volatile unsigned SavedState; + // + SEGGER_RTT_LOCK(SavedState); + // + // Call the non-locking read function + // + NumBytesRead = SEGGER_RTT_ReadNoLock(BufferIndex, pBuffer, BufferSize); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(SavedState); + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteSkipNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteSkipNoLock does not lock the application and +* skips all data, if the data does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, all data is dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ +unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + const char* pData; + SEGGER_RTT_RING_BUFFER* pRing; + unsigned Avail; + unsigned RdOff; + unsigned WrOff; + unsigned Rem; + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer and copy some elements into local variables. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + // + // Handle the most common cases fastest. + // Which is: + // RdOff <= WrOff -> Space until wrap around is free. + // AND + // WrOff + NumBytes < SizeOfBuffer -> No Wrap around necessary. + // + // OR + // + // RdOff > WrOff -> Space until RdOff - 1 is free. + // AND + // WrOff + NumBytes < RdOff -> Data fits into buffer + // + if (RdOff <= WrOff) { + // + // Get space until WrOff will be at wrap around. + // + Avail = pRing->SizeOfBuffer - 1u - WrOff ; + if (Avail >= NumBytes) { + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; + return 1; + } + // + // If data did not fit into space until wrap around calculate complete space in buffer. + // + Avail += RdOff; + // + // If there is still no space for the whole of this output, don't bother. + // + if (Avail >= NumBytes) { + // + // OK, we have enough space in buffer. Copy in one or 2 chunks + // + Rem = pRing->SizeOfBuffer - WrOff; // Space until end of buffer + if (Rem > NumBytes) { + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; + } else { + // + // We reach the end of the buffer, so need to wrap around + // + memcpy(pRing->pBuffer + WrOff, pData, Rem); + memcpy(pRing->pBuffer, pData + Rem, NumBytes - Rem); + pRing->WrOff = NumBytes - Rem; + } + return 1; + } + } else { + Avail = RdOff - WrOff - 1u; + if (Avail >= NumBytes) { + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; + return 1; + } + } + // + // If we reach this point no data has been written + // + return 0; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteNoLock does not lock the application. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ +unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + unsigned Avail; + const char* pData; + SEGGER_RTT_RING_BUFFER *pRing; + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // How we output depends upon the mode... + // + switch (pRing->Flags) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother. + // + Avail = _GetAvailWriteSpace(pRing); + if (Avail < NumBytes) { + Status = 0u; + } else { + Status = NumBytes; + _WriteNoCheck(pRing, pData, NumBytes); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode, trim to what we can output without blocking. + // + Avail = _GetAvailWriteSpace(pRing); + Status = Avail < NumBytes ? Avail : NumBytes; + _WriteNoCheck(pRing, pData, Status); + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + Status = _WriteBlocking(pRing, pData, NumBytes); + break; + default: + Status = 0u; + break; + } + // + // Finish up. + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_Write +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped. +*/ +unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + volatile unsigned SavedState; + // + INIT(); + SEGGER_RTT_LOCK(SavedState); + // + // Call the non-locking write function + // + Status = SEGGER_RTT_WriteNoLock(BufferIndex, pBuffer, NumBytes); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(SavedState); + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteString +* +* Function description +* Stores string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* s Pointer to string. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, depending on configuration, +* remaining characters may be dropped or RTT module waits until there is more space in the buffer. +* (2) String passed to this function has to be \0 terminated +* (3) \0 termination character is *not* stored in RTT buffer +*/ +unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) { + unsigned Len; + + Len = STRLEN(s); + return SEGGER_RTT_Write(BufferIndex, s, Len); +} + +/********************************************************************* +* +* SEGGER_RTT_GetKey +* +* Function description +* Reads one character from the SEGGER RTT buffer. +* Host has previously stored data there. +* +* Return value +* < 0 - No character available (buffer empty). +* >= 0 - Character which has been read. (Possible values: 0 - 255) +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0. +*/ +int SEGGER_RTT_GetKey(void) { + char c; + int r; + + r = (int)SEGGER_RTT_Read(0u, &c, 1u); + if (r == 1) { + r = (int)(unsigned char)c; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_WaitKey +* +* Function description +* Waits until at least one character is avaible in the SEGGER RTT buffer. +* Once a character is available, it is read and this function returns. +* +* Return value +* >=0 - Character which has been read. +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0 +* (2) This function is blocking if no character is present in RTT buffer +*/ +int SEGGER_RTT_WaitKey(void) { + int r; + + do { + r = SEGGER_RTT_GetKey(); + } while (r < 0); + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_HasKey +* +* Function description +* Checks if at least one character for reading is available in the SEGGER RTT buffer. +* +* Return value +* == 0 - No characters are available to read. +* == 1 - At least one character is available. +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0 +*/ +int SEGGER_RTT_HasKey(void) { + unsigned RdOff; + int r; + + INIT(); + RdOff = _SEGGER_RTT.aDown[0].RdOff; + if (RdOff != _SEGGER_RTT.aDown[0].WrOff) { + r = 1; + } else { + r = 0; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_HasData +* +* Function description +* Check if there is data from the host in the given buffer. +* +* Return value: +* ==0: No data +* !=0: Data in buffer +* +*/ +unsigned SEGGER_RTT_HasData(unsigned BufferIndex) { + SEGGER_RTT_RING_BUFFER *pRing; + unsigned v; + + pRing = &_SEGGER_RTT.aDown[BufferIndex]; + v = pRing->WrOff; + return v - pRing->RdOff; +} + + +/********************************************************************* +* +* SEGGER_RTT_ConfigUpBuffer +* +* Function description +* Run-time configuration of a specific up-buffer (T->H). +* Buffer to be configured is specified by index. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* BufferIndex Index of the buffer to configure. +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. +* < 0 - Error +*/ +int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int r; + volatile unsigned SavedState; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { + SEGGER_RTT_LOCK(SavedState); + if (BufferIndex > 0u) { + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + _SEGGER_RTT.aUp[BufferIndex].pBuffer = pBuffer; + _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; + } + _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(SavedState); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_ConfigDownBuffer +* +* Function description +* Run-time configuration of a specific down-buffer (H->T). +* Buffer to be configured is specified by index. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* BufferIndex Index of the buffer to configure. +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int r; + volatile unsigned SavedState; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { + SEGGER_RTT_LOCK(SavedState); + if (BufferIndex > 0u) { + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + _SEGGER_RTT.aDown[BufferIndex].pBuffer = pBuffer; + _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; + } + _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(SavedState); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetNameUpBuffer +* +* Function description +* Run-time configuration of a specific up-buffer name (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* sName Pointer to a constant name string. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) { + int r; + volatile unsigned SavedState; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { + SEGGER_RTT_LOCK(SavedState); + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + SEGGER_RTT_UNLOCK(SavedState); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetNameDownBuffer +* +* Function description +* Run-time configuration of a specific Down-buffer name (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* sName Pointer to a constant name string. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) { + int r; + volatile unsigned SavedState; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { + SEGGER_RTT_LOCK(SavedState); + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + SEGGER_RTT_UNLOCK(SavedState); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_Init +* +* Function description +* Initializes the RTT Control Block. +* Should be used in RAM targets, at start of the application. +* +*/ +void SEGGER_RTT_Init (void) { + INIT(); +} + +/********************************************************************* +* +* SEGGER_RTT_SetTerminal +* +* Function description +* Sets the terminal to be used for output on channel 0. +* +* Parameters +* TerminalId Index of the terminal. +* +* Return value +* >= 0 O.K. +* < 0 Error (e.g. if RTT is configured for non-blocking mode and there was no space in the buffer to set the new terminal Id) +*/ +int SEGGER_RTT_SetTerminal (char TerminalId) { + char ac[2]; + SEGGER_RTT_RING_BUFFER *pRing; + volatile unsigned SavedState; + unsigned Avail; + int r; + // + INIT(); + // + r = 0; + ac[0] = 0xFFU; + if (TerminalId < (char)sizeof(_aTerminalId)) { // We only support a certain number of channels + ac[1] = _aTerminalId[(int)TerminalId]; + pRing = &_SEGGER_RTT.aUp[0]; // Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed + SEGGER_RTT_LOCK(SavedState); // Lock to make sure that no other task is writing into buffer, while we are and number of free bytes in buffer does not change downwards after checking and before writing + if ((pRing->Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { + _ActiveTerminal = TerminalId; + _WriteBlocking(pRing, ac, 2u); + } else { // Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes + Avail = _GetAvailWriteSpace(pRing); + if (Avail >= 2) { + _ActiveTerminal = TerminalId; // Only change active terminal in case of success + _WriteNoCheck(pRing, ac, 2u); + } else { + r = -1; + } + } + SEGGER_RTT_UNLOCK(SavedState); + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_TerminalOut +* +* Function description +* Writes a string to the given terminal +* without changing the terminal for channel 0. +* +* Parameters +* TerminalId Index of the terminal. +* s String to be printed on the terminal. +* +* Return value +* >= 0 - Number of bytes written. +* < 0 - Error. +* +*/ +int SEGGER_RTT_TerminalOut (char TerminalId, const char* s) { + int Status; + unsigned FragLen; + unsigned Avail; + SEGGER_RTT_RING_BUFFER *pRing; + volatile unsigned SavedState; + // + INIT(); + // + // Validate terminal ID. + // + if (TerminalId < (char)sizeof(_aTerminalId)) { // We only support a certain number of channels + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[0]; + // + // Need to be able to change terminal, write data, change back. + // Compute the fixed and variable sizes. + // + FragLen = strlen(s); + // + // How we output depends upon the mode... + // + SEGGER_RTT_LOCK(SavedState); + Avail = _GetAvailWriteSpace(pRing); + switch (pRing->Flags & SEGGER_RTT_MODE_MASK) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother switching terminals at all. + // + if (Avail < (FragLen + 4u)) { + Status = 0; + } else { + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, FragLen); + _PostTerminalSwitch(pRing, _ActiveTerminal); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode and there is not enough space for everything, + // trim the output but always include the terminal switch. If no room + // for terminal switch, skip that totally. + // + if (Avail < 4u) { + Status = -1; + } else { + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, (FragLen < (Avail - 4u)) ? FragLen : (Avail - 4u)); + _PostTerminalSwitch(pRing, _ActiveTerminal); + } + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, FragLen); + _PostTerminalSwitch(pRing, _ActiveTerminal); + break; + default: + Status = -1; + break; + } + // + // Finish up. + // + SEGGER_RTT_UNLOCK(SavedState); + } else { + Status = -1; + } + return Status; +} + + +/*************************** End of file ****************************/ diff --git a/platform/nrf52dk/rtt/segger-rtt.h b/platform/nrf52dk/rtt/segger-rtt.h new file mode 100644 index 000000000..e3436c462 --- /dev/null +++ b/platform/nrf52dk/rtt/segger-rtt.h @@ -0,0 +1,204 @@ +/********************************************************************* +* SEGGER MICROCONTROLLER GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 2014 - 2015 SEGGER Microcontroller GmbH & Co. KG * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* * This software may in its unmodified form be freely redistributed * +* in source form. * +* * The source code may be modified, provided the source code * +* retains the above copyright notice, this list of conditions and * +* the following disclaimer. * +* * Modified versions of this software in source or linkable form * +* may not be distributed without prior consent of SEGGER. * +* * This software may only be used for communication with SEGGER * +* J-Link debug probes. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 SEGGER Microcontroller 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. * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT.h +Purpose : Implementation of SEGGER real-time transfer which allows + real-time communication on targets which support debugger + memory accesses while the CPU is running. +---------------------------------------------------------------------- +*/ + +#ifndef SEGGER_RTT_H +#define SEGGER_RTT_H + +#include "segger-rtt-conf.h" + +/********************************************************************* +* +* Defines, fixed +* +********************************************************************** +*/ + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +// +// Description for a circular buffer (also called "ring buffer") +// which is used as up- (T->H) or down-buffer (H->T) +// +typedef struct { + const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" + char* pBuffer; // Pointer to start of buffer + unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. + volatile unsigned WrOff; // Position of next item to be written by either host (down-buffer) or target (up-buffer). Must be volatile since it may be modified by host (down-buffer) + volatile unsigned RdOff; // Position of next item to be read by target (down-buffer) or host (up-buffer). Must be volatile since it may be modified by host (up-buffer) + unsigned Flags; // Contains configuration flags +} SEGGER_RTT_RING_BUFFER; + +// +// RTT control block which describes the number of buffers available +// as well as the configuration for each buffer +// +// +typedef struct { + char acID[16]; // Initialized to "SEGGER RTT" + int MaxNumUpBuffers; // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2) + int MaxNumDownBuffers; // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2) + SEGGER_RTT_RING_BUFFER aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS]; // Up buffers, transferring information up from target via debug probe to host + SEGGER_RTT_RING_BUFFER aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS]; // Down buffers, transferring information down from host via debug probe to target +} SEGGER_RTT_CB; + +/********************************************************************* +* +* Global data +* +********************************************************************** +*/ +extern SEGGER_RTT_CB _SEGGER_RTT; + +/********************************************************************* +* +* RTT API functions +* +********************************************************************** +*/ +int SEGGER_RTT_ConfigUpBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_GetKey (void); +unsigned SEGGER_RTT_HasData (unsigned BufferIndex); +int SEGGER_RTT_HasKey (void); +void SEGGER_RTT_Init (void); +unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize); +unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize); +int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName); +int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName); +int SEGGER_RTT_WaitKey (void); +unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s); +// +// Function macro for performance optimization +// +#define SEGGER_RTT_HASDATA(n) (_SEGGER_RTT.aDown[n].WrOff - _SEGGER_RTT.aDown[n].RdOff) + +/********************************************************************* +* +* RTT "Terminal" API functions +* +********************************************************************** +*/ +int SEGGER_RTT_SetTerminal (char TerminalId); +int SEGGER_RTT_TerminalOut (char TerminalId, const char* s); + +/********************************************************************* +* +* RTT printf functions (require SEGGER_RTT_printf.c) +* +********************************************************************** +*/ +int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...); + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ + +// +// Operating modes. Define behavior if buffer is full (not enough space for entire message) +// +#define SEGGER_RTT_MODE_NO_BLOCK_SKIP (0U) // Skip. Do not block, output nothing. (Default) +#define SEGGER_RTT_MODE_NO_BLOCK_TRIM (1U) // Trim: Do not block, output as much as fits. +#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (2U) // Block: Wait until there is space in the buffer. +#define SEGGER_RTT_MODE_MASK (3U) + +// +// Control sequences, based on ANSI. +// Can be used to control color, and clear the screen +// +#define RTT_CTRL_RESET "\e[0m" // Reset to default colors +#define RTT_CTRL_CLEAR "\e[2J" // Clear screen, reposition cursor to top left + +#define RTT_CTRL_TEXT_BLACK "\e[2;30m" +#define RTT_CTRL_TEXT_RED "\e[2;31m" +#define RTT_CTRL_TEXT_GREEN "\e[2;32m" +#define RTT_CTRL_TEXT_YELLOW "\e[2;33m" +#define RTT_CTRL_TEXT_BLUE "\e[2;34m" +#define RTT_CTRL_TEXT_MAGENTA "\e[2;35m" +#define RTT_CTRL_TEXT_CYAN "\e[2;36m" +#define RTT_CTRL_TEXT_WHITE "\e[2;37m" + +#define RTT_CTRL_TEXT_BRIGHT_BLACK "\e[1;30m" +#define RTT_CTRL_TEXT_BRIGHT_RED "\e[1;31m" +#define RTT_CTRL_TEXT_BRIGHT_GREEN "\e[1;32m" +#define RTT_CTRL_TEXT_BRIGHT_YELLOW "\e[1;33m" +#define RTT_CTRL_TEXT_BRIGHT_BLUE "\e[1;34m" +#define RTT_CTRL_TEXT_BRIGHT_MAGENTA "\e[1;35m" +#define RTT_CTRL_TEXT_BRIGHT_CYAN "\e[1;36m" +#define RTT_CTRL_TEXT_BRIGHT_WHITE "\e[1;37m" + +#define RTT_CTRL_BG_BLACK "\e[24;40m" +#define RTT_CTRL_BG_RED "\e[24;41m" +#define RTT_CTRL_BG_GREEN "\e[24;42m" +#define RTT_CTRL_BG_YELLOW "\e[24;43m" +#define RTT_CTRL_BG_BLUE "\e[24;44m" +#define RTT_CTRL_BG_MAGENTA "\e[24;45m" +#define RTT_CTRL_BG_CYAN "\e[24;46m" +#define RTT_CTRL_BG_WHITE "\e[24;47m" + +#define RTT_CTRL_BG_BRIGHT_BLACK "\e[4;40m" +#define RTT_CTRL_BG_BRIGHT_RED "\e[4;41m" +#define RTT_CTRL_BG_BRIGHT_GREEN "\e[4;42m" +#define RTT_CTRL_BG_BRIGHT_YELLOW "\e[4;43m" +#define RTT_CTRL_BG_BRIGHT_BLUE "\e[4;44m" +#define RTT_CTRL_BG_BRIGHT_MAGENTA "\e[4;45m" +#define RTT_CTRL_BG_BRIGHT_CYAN "\e[4;46m" +#define RTT_CTRL_BG_BRIGHT_WHITE "\e[4;47m" + + +#endif + +/*************************** End of file ****************************/ From 38481c513d3f7222a738973ccbbd17e012f0a898 Mon Sep 17 00:00:00 2001 From: Wojciech Bober Date: Sat, 9 Jan 2016 14:44:58 +0100 Subject: [PATCH 025/374] nrf52dk: added examples --- examples/nrf52dk/blink-hello/Makefile | 9 + examples/nrf52dk/blink-hello/README.md | 14 + examples/nrf52dk/blink-hello/blink-hello.c | 182 +++++ examples/nrf52dk/coap-demo/Makefile | 35 + examples/nrf52dk/coap-demo/README.md | 63 ++ examples/nrf52dk/coap-demo/coap-client.c | 185 +++++ examples/nrf52dk/coap-demo/coap-server.c | 130 ++++ examples/nrf52dk/coap-demo/project-conf.h | 85 +++ .../nrf52dk/coap-demo/resources/res-leds.c | 106 +++ examples/nrf52dk/mqtt-demo/Makefile | 11 + examples/nrf52dk/mqtt-demo/README.md | 74 ++ examples/nrf52dk/mqtt-demo/mqtt-demo.c | 721 ++++++++++++++++++ examples/nrf52dk/mqtt-demo/project-conf.h | 51 ++ examples/nrf52dk/timer-test/Makefile | 9 + examples/nrf52dk/timer-test/README.md | 20 + examples/nrf52dk/timer-test/timer-test.c | 131 ++++ 16 files changed, 1826 insertions(+) create mode 100644 examples/nrf52dk/blink-hello/Makefile create mode 100644 examples/nrf52dk/blink-hello/README.md create mode 100644 examples/nrf52dk/blink-hello/blink-hello.c create mode 100644 examples/nrf52dk/coap-demo/Makefile create mode 100644 examples/nrf52dk/coap-demo/README.md create mode 100644 examples/nrf52dk/coap-demo/coap-client.c create mode 100644 examples/nrf52dk/coap-demo/coap-server.c create mode 100644 examples/nrf52dk/coap-demo/project-conf.h create mode 100644 examples/nrf52dk/coap-demo/resources/res-leds.c create mode 100644 examples/nrf52dk/mqtt-demo/Makefile create mode 100644 examples/nrf52dk/mqtt-demo/README.md create mode 100644 examples/nrf52dk/mqtt-demo/mqtt-demo.c create mode 100644 examples/nrf52dk/mqtt-demo/project-conf.h create mode 100644 examples/nrf52dk/timer-test/Makefile create mode 100644 examples/nrf52dk/timer-test/README.md create mode 100644 examples/nrf52dk/timer-test/timer-test.c diff --git a/examples/nrf52dk/blink-hello/Makefile b/examples/nrf52dk/blink-hello/Makefile new file mode 100644 index 000000000..5b056a518 --- /dev/null +++ b/examples/nrf52dk/blink-hello/Makefile @@ -0,0 +1,9 @@ +CONTIKI_PROJECT = blink-hello + +CONTIKI_WITH_RPL=0 +NRF52_WITHOUT_SOFTDEVICE=1 + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/nrf52dk/blink-hello/README.md b/examples/nrf52dk/blink-hello/README.md new file mode 100644 index 000000000..00064f993 --- /dev/null +++ b/examples/nrf52dk/blink-hello/README.md @@ -0,0 +1,14 @@ +Blink Hello example +=================== +This example shows basic usage of DK's buttons and LEDs. It also shows basic +usage of Contiki's processes. The application autostarts 5 processes: 4 processes +for button and LED control and 1 to display current temperature to the console. + +A process reacts to a press of a respective button (process 1 reacts to button 1, etc.) +and doubles the current blinking frequency. The cycle restarts for beginning when blinking +frequency is greater than 8Hz. + +The example requires one DK and it doesn't use SoftDevice. To compile and flash the +example run: + + make TARGET=nrf52dk blink-hello.flash \ No newline at end of file diff --git a/examples/nrf52dk/blink-hello/blink-hello.c b/examples/nrf52dk/blink-hello/blink-hello.c new file mode 100644 index 000000000..ebc1e451c --- /dev/null +++ b/examples/nrf52dk/blink-hello/blink-hello.c @@ -0,0 +1,182 @@ +/* This is a very simple hello_world program. + * It aims to demonstrate the co-existence of two processes: + * One of them prints a hello world message and the other blinks the LEDs + * + * It is largely based on hello_world in $(CONTIKI)/examples/sensinode + * + * Author: George Oikonomou - + */ + +/** + * \addtogroup nrf52dk nRF52 Development Kit + * @{ + * + * \addtogroup nrf52dk-examples Demo projects for nRF52 DK + * @{ + * + * \defgroup nrf52dk-blink-hello Basic sensors and LEDs demo + * @{ + * + * This demo demonstrates use of Contiki processes, sensors, and LEDs + * on nRF52 DK. Pressing a button will start a timer that blinks a + * respective LED (e.g., button 1 controls LED 1). Each time the button + * is pressed blinking frequency is doubled. On 4th press the LED is + * switched off and the sequence can be started from the beginning. + * + * \file Main file for Basic sensors and LEDs demo. + */ +#include /* For printf() */ +#include +#include "contiki.h" +#include "dev/leds.h" +#include "dev/temperature-sensor.h" +#include "lib/sensors.h" +#include "button-sensor.h" + +/*---------------------------------------------------------------------------*/ +PROCESS(blink_process_1, "LED1 blink process"); +PROCESS(blink_process_2, "LED2 blink process"); +PROCESS(blink_process_3, "LED3 blink process"); +PROCESS(blink_process_4, "LED4 blink process"); +PROCESS(temp, "Temperautre"); + +AUTOSTART_PROCESSES( + &blink_process_1, + &blink_process_2, + &blink_process_3, + &blink_process_4, + &temp +); + +struct blink_process_ctx { + struct etimer et_blink; + unsigned char c; + const struct sensors_sensor *button; + unsigned char led; +}; + +static void handle_event(process_event_t ev, process_data_t data, struct blink_process_ctx *ctx) +{ + if (ev == PROCESS_EVENT_TIMER && etimer_expired(&ctx->et_blink)) { + leds_toggle(ctx->led); + etimer_set(&ctx->et_blink, CLOCK_SECOND / ctx->c); + printf("Blink %d\n", ctx->led); + } else if (ev == sensors_event && data == ctx->button) { + if (ctx->button->value(BUTTON_SENSOR_VALUE_STATE) == 0) { + if (ctx->c == 0) { + ctx->c = 1; + } else if (ctx->c < 8){ + ctx->c <<= 1; + } else { + ctx->c = 0; + leds_off(ctx->led); + } + if (ctx->c) { + etimer_set(&ctx->et_blink, CLOCK_SECOND / ctx->c); + } else { + etimer_stop(&ctx->et_blink); + } + } + } +} + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(blink_process_1, ev, data) +{ + static struct blink_process_ctx ctx; + + PROCESS_BEGIN(); + + ctx.button = &button_1; + ctx.c = 0; + ctx.led = LEDS_1; + ctx.button->configure(SENSORS_ACTIVE, 1); + + while (1) { + PROCESS_WAIT_EVENT(); + handle_event(ev, data, &ctx); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(blink_process_2, ev, data) +{ + static struct blink_process_ctx ctx; + + PROCESS_BEGIN(); + + ctx.button = &button_2; + ctx.c = 0; + ctx.led = LEDS_2; + ctx.button->configure(SENSORS_ACTIVE, 1); + + while (1) { + PROCESS_WAIT_EVENT(); + handle_event(ev, data, &ctx); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(blink_process_3, ev, data) +{ + static struct blink_process_ctx ctx; + + PROCESS_BEGIN(); + + ctx.button = &button_3; + ctx.c = 0; + ctx.led = LEDS_3; + ctx.button->configure(SENSORS_ACTIVE, 1); + + while (1) { + PROCESS_WAIT_EVENT(); + handle_event(ev, data, &ctx); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(blink_process_4, ev, data) +{ + static struct blink_process_ctx ctx; + + PROCESS_BEGIN(); + + ctx.button = &button_4; + ctx.c = 0; + ctx.led = LEDS_4; + ctx.button->configure(SENSORS_ACTIVE, 1); + + while (1) { + PROCESS_WAIT_EVENT(); + handle_event(ev, data, &ctx); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(temp, ev, data) +{ + static struct etimer tick; + PROCESS_BEGIN(); + + etimer_set(&tick, CLOCK_SECOND); + + while (1) { + PROCESS_WAIT_EVENT(); + if (ev == PROCESS_EVENT_TIMER && etimer_expired(&tick)) { + int32_t temp = temperature_sensor.value(0); + printf("temp: %"PRId32".%02"PRId32"\n", temp >> 2, (temp & 0x03)*25); + etimer_reset(&tick); + } + } + + PROCESS_END(); +} +/** + * @} + * @} + * @} + */ diff --git a/examples/nrf52dk/coap-demo/Makefile b/examples/nrf52dk/coap-demo/Makefile new file mode 100644 index 000000000..077e469be --- /dev/null +++ b/examples/nrf52dk/coap-demo/Makefile @@ -0,0 +1,35 @@ +CONTIKI=../../.. +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +ifeq ($(MAKECMDGOALS),) +$(error Please specify whether coap-client or coap-server should be built) +endif + +ifneq ($(filter coap-client coap-client.flash, $(MAKECMDGOALS)),) +ifeq ($(SERVER_IPV6_ADDR),) +$(error Please define SERVER_IPV6_ADDR=) +else +CFLAGS += -DSERVER_IPV6_ADDR=\"$(SERVER_IPV6_ADDR)\" +CFLAGS += -DDEVICE_NAME=\"nRF52_DK_CoAP_Client\" +endif +else +CFLAGS += -DDEVICE_NAME=\"nRF52-DK-CoAP-Server\" +endif + +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_FILES = $(notdir $(shell find $(REST_RESOURCES_DIR) -name '*.c' ! -name 'res-plugtest*')) + +PROJECTDIRS += $(REST_RESOURCES_DIR) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) + +# linker optimizations +SMALL=1 + +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine + +CONTIKI_WITH_RPL = 0 + +include $(CONTIKI)/Makefile.include diff --git a/examples/nrf52dk/coap-demo/README.md b/examples/nrf52dk/coap-demo/README.md new file mode 100644 index 000000000..1262ce114 --- /dev/null +++ b/examples/nrf52dk/coap-demo/README.md @@ -0,0 +1,63 @@ +A CoAP demo for nRF52 DK +======================== +This demo contains two applications: coap-server and coap-client which are similar to +[Coap Observable Server] and [Coap Observer Client] examples provided by the nRF5 IoT SDK. + +Note that before any CoAP requests can be made you'll need to configure an IPv6 connection +to the device and assign a routable IPv6 address. + +For details how to do this please refer to sections 'Establishing an IPv6 connection' +and 'Distributing routable IPv6 prefix' in `platform/nrf52dk/README-BLE-6LoWPAN.md`. + +CoAP Server +=========== +The server exposes the following resources: + + host + |-- .well-known + | `-- core + `-- lights + `-- led3 + +The state of LED 3 can be set and queried via CoAP through the observable resource `lights/led3`. Current +state of LED 3 is returned as a text string in the payload. The value 0 means that LED 3 is off, 1 otherwise. + +Button 1 can be used to toggle state of the LED 3. This will cause a notification to be sent to +any subscriber observing `lights/led3`. The state of the resource can also be changed by using POST/PUT to +the resource with desired state encoded as a text in the payload. Send 1 to switch on and 0 to switch off. + +In order to compile and flash the CoAP server to a DK execute: + + make TARGET=nrf52dk coap-server.flash + +Note, if you haven't previously used a given device with Contiki it is recommended +to erase the device and flash SoftDevice before flashing CoAP application, i.e., + + make TARGET=nrf52dk erase + make TARGET=nrf52dk softdevice.flash + +Please refer to the *Testing* and *Python Example* sections of [Coap Observable Server] tutorial for detailed description how to query the Coap Server using a PC. + +CoAP Client +=========== +CoAP client compliments the CoAP server application. When Button 1 on the DK is pressed the the +client subscribes to `lights/led3` resource. If successful the LED 4 will blink briefly. From this moment +any change of the `lights/led3` resource will be automatically reflected by the client's LED 3. + +Note that the client must know the server's IPv6 address. The address is specified as a make variable +during compliation. + +In order to compile and flash the CoAP client to DK execute: + + make TARGET=nrf52dk SERVER_IPV6_ADDR= coap-client.flash + +Note, that you can use `NRF52_JLINK_SN=` to select a particular devkit in a case when +you have more than one boards connected to PC. Please refer to `platform/README.md` for +details. + +Please refer to the *Testing* and *Python Server Example* sections of [Coap Observer Client] tutorial for detailed description how to use CoAP client demo with a PC. + +Resources +========= +[Coap Observable Server] http://developer.nordicsemi.com/nRF5_IoT_SDK/doc/0.9.0/html/a00054.html +[Coap Observer Client] http://developer.nordicsemi.com/nRF5_IoT_SDK/doc/0.9.0/html/a00051.html diff --git a/examples/nrf52dk/coap-demo/coap-client.c b/examples/nrf52dk/coap-demo/coap-client.c new file mode 100644 index 000000000..2ec1f5ab1 --- /dev/null +++ b/examples/nrf52dk/coap-demo/coap-client.c @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2014, Daniele Alessandrelli. + * Copyright (c) 2015, Nordic Semiconductor + * 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. + */ + +/** + * \addtogroup nrf52dk-examples Demo projects for nRF52 DK + * @{ + * + * \defgroup nrf52dk-coap-demo CoAP demo for nRF52 DK + * @{ + * + * \file + * Erbium (Er) CoAP observe client example. + * \author + * Daniele Alessandrelli + * \author + * Wojciech Bober + */ + +#include +#include +#include +#include "contiki.h" +#include "contiki-net.h" +#include "er-coap-engine.h" +#include "dev/button-sensor.h" +#include "dev/leds.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/*----------------------------------------------------------------------------*/ +#define REMOTE_PORT UIP_HTONS(COAP_DEFAULT_PORT) +#define OBS_RESOURCE_URI "lights/led3" +#define SUBS_LED LEDS_4 +#define OBS_LED LEDS_3 + +/*----------------------------------------------------------------------------*/ +static uip_ipaddr_t server_ipaddr[1]; /* holds the server ip address */ +static coap_observee_t *obs; +static struct ctimer ct; +/*----------------------------------------------------------------------------*/ +PROCESS(er_example_observe_client, "nRF52 DK Coap Observer Client"); +AUTOSTART_PROCESSES(&er_example_observe_client); +/*----------------------------------------------------------------------------*/ +static void +observe_led_off(void *d) +{ + leds_off(SUBS_LED); +} +/*----------------------------------------------------------------------------*/ +/* + * Handle the response to the observe request and the following notifications + */ +static void +notification_callback(coap_observee_t *obs, void *notification, + coap_notification_flag_t flag) +{ + int len = 0; + const uint8_t *payload = NULL; + + + PRINTF("Notification handler\n"); + PRINTF("Observee URI: %s\n", obs->url); + + if (notification) { + len = coap_get_payload(notification, &payload); + } + + (void)len; + + switch (flag) { + case NOTIFICATION_OK: + PRINTF("NOTIFICATION OK: %*s\n", len, (char *)payload); + if (*payload == '1') { + leds_on(OBS_LED); + } else { + leds_off(OBS_LED); + } + break; + case OBSERVE_OK: /* server accepeted observation request */ + PRINTF("OBSERVE_OK: %*s\n", len, (char *)payload); + if (*payload == '1') { + leds_on(OBS_LED); + } else { + leds_off(OBS_LED); + } + leds_on(SUBS_LED); + ctimer_set(&ct, CLOCK_SECOND, observe_led_off, NULL); + break; + case OBSERVE_NOT_SUPPORTED: + PRINTF("OBSERVE_NOT_SUPPORTED: %*s\n", len, (char *)payload); + obs = NULL; + break; + case ERROR_RESPONSE_CODE: + PRINTF("ERROR_RESPONSE_CODE: %*s\n", len, (char *)payload); + obs = NULL; + break; + case NO_REPLY_FROM_SERVER: + PRINTF("NO_REPLY_FROM_SERVER: " + "removing observe registration with token %x%x\n", + obs->token[0], obs->token[1]); + obs = NULL; + break; + } +} +/*----------------------------------------------------------------------------*/ +/* + * The main (proto-)thread. It starts/stops the observation of the remote + * resource every time the timer elapses or the button (if available) is + * pressed + */ +PROCESS_THREAD(er_example_observe_client, ev, data) +{ + PROCESS_BEGIN(); + + uiplib_ipaddrconv(SERVER_IPV6_ADDR, server_ipaddr); + + /* receives all CoAP messages */ + coap_init_engine(); + +#if PLATFORM_HAS_BUTTON + SENSORS_ACTIVATE(button_1); + SENSORS_ACTIVATE(button_2); +#endif + + /* toggle observation every time the timer elapses or the button is pressed */ + while (1) { + PROCESS_YIELD(); +#if PLATFORM_HAS_BUTTON + if (ev == sensors_event) { + if (data == &button_1 && button_1.value(BUTTON_SENSOR_VALUE_STATE) == 0) { + PRINTF("Starting observation\n"); + obs = coap_obs_request_registration(server_ipaddr, REMOTE_PORT, + OBS_RESOURCE_URI, notification_callback, + NULL); + } + if (data == &button_2 && button_2.value(BUTTON_SENSOR_VALUE_STATE) == 0) { + PRINTF("Stopping observation\n"); + coap_obs_remove_observee(obs); + obs = NULL; + } + } +#endif + } + PROCESS_END(); +} + +/** + * @} + * @} + */ diff --git a/examples/nrf52dk/coap-demo/coap-server.c b/examples/nrf52dk/coap-demo/coap-server.c new file mode 100644 index 000000000..9bab7e60d --- /dev/null +++ b/examples/nrf52dk/coap-demo/coap-server.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * Copyright (c) 2015, Nordic Semiconductor + * + * 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. + */ + +/** + * \addtogroup nrf52dk-examples Demo projects for nRF52 DK + * @{ + * + * \defgroup nrf52dk-coap-demo CoAP demo for nRF52dk + * @{ + * + * \file + * Erbium (Er) REST Engine example. + * \author + * Matthias Kovatsch + * \author + * Wojciech Bober + */ + +#include +#include +#include +#include "contiki.h" +#include "contiki-net.h" +#include "rest-engine.h" +#include "uip.h" +#include "dev/button-sensor.h" +#include "dev/leds.h" + +#define DEBUG DEBUG_PRINT +#include "net/ip/uip-debug.h" + +/* + * Resources to be activated need to be imported through the extern keyword. + * The build system automatically compiles the resources in the corresponding sub-directory. + */ +extern resource_t res_led3; + +static void +print_local_addresses(void) +{ + int i; + uint8_t state; + + PRINTF("Server IPv6 addresses:\n"); + 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)) { + PRINTF(" "); + PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); + PRINTF("\n"); + if(state == ADDR_TENTATIVE) { + uip_ds6_if.addr_list[i].state = ADDR_PREFERRED; + } + } + } +} + +PROCESS(er_example_server, "nRF52 DK Coap Server"); +AUTOSTART_PROCESSES(&er_example_server); + +PROCESS_THREAD(er_example_server, ev, data) +{ + PROCESS_BEGIN(); + PROCESS_PAUSE(); + + PRINTF("Starting Erbium Example Server\n"); + + PRINTF("uIP buffer: %u\n", UIP_BUFSIZE); + PRINTF("LL header: %u\n", UIP_LLH_LEN); + PRINTF("IP+UDP header: %u\n", UIP_IPUDPH_LEN); + PRINTF("REST max chunk: %u\n", REST_MAX_CHUNK_SIZE); + + print_local_addresses(); + + /* Initialize the REST engine. */ + rest_init_engine(); + rest_activate_resource(&res_led3, "lights/led3"); + + SENSORS_ACTIVATE(button_1); + + /* Define application-specific events here. */ + while (1) { + PROCESS_WAIT_EVENT(); + + if (ev == sensors_event) { + if (data == &button_1 && button_1.value(BUTTON_SENSOR_VALUE_STATE) == 0) { + leds_toggle(LEDS_3); + res_led3.trigger(); + } + } + } + + PROCESS_END(); +} + +/** + * @} + * @} + */ diff --git a/examples/nrf52dk/coap-demo/project-conf.h b/examples/nrf52dk/coap-demo/project-conf.h new file mode 100644 index 000000000..2b097e8a8 --- /dev/null +++ b/examples/nrf52dk/coap-demo/project-conf.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * 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. + */ + +/** + * \addtogroup nrf52dk-examples Demo projects for nRF52 DK + * @{ + * + * \defgroup nrf52dk-coap-demo CoAP demo for nRF52dk + * @{ + * + * \file + * Erbium (Er) example project configuration. + * \author + * Matthias Kovatsch + */ + +#ifndef __PROJECT_ERBIUM_CONF_H__ +#define __PROJECT_ERBIUM_CONF_H__ + +/* Disabling TCP on CoAP nodes. */ +#undef UIP_CONF_TCP +#define UIP_CONF_TCP 0 + +/* Increase rpl-border-router IP-buffer when using more than 64. */ +#undef REST_MAX_CHUNK_SIZE +#define REST_MAX_CHUNK_SIZE 48 + +/* Estimate your header size, especially when using Proxy-Uri. */ +/* + #undef COAP_MAX_HEADER_SIZE + #define COAP_MAX_HEADER_SIZE 70 + */ + +/* Multiplies with chunk size, be aware of memory constraints. */ +#undef COAP_MAX_OPEN_TRANSACTIONS +#define COAP_MAX_OPEN_TRANSACTIONS 4 + +/* Must be <= open transactions, default is COAP_MAX_OPEN_TRANSACTIONS-1. */ +/* + #undef COAP_MAX_OBSERVERS + #define COAP_MAX_OBSERVERS 2 + */ + +/* Filtering .well-known/core per query can be disabled to save space. */ +#undef COAP_LINK_FORMAT_FILTERING +#define COAP_LINK_FORMAT_FILTERING 0 +#undef COAP_PROXY_OPTION_PROCESSING +#define COAP_PROXY_OPTION_PROCESSING 0 + +/* Enable client-side support for COAP observe */ +#define COAP_OBSERVE_CLIENT 1 +#endif /* __PROJECT_ERBIUM_CONF_H__ */ + +/** + * @} + * @} + */ diff --git a/examples/nrf52dk/coap-demo/resources/res-leds.c b/examples/nrf52dk/coap-demo/resources/res-leds.c new file mode 100644 index 000000000..468a165bf --- /dev/null +++ b/examples/nrf52dk/coap-demo/resources/res-leds.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * 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. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + * \author + * Wojciech Bober + */ + +#include +#include "contiki.h" +#include "rest-engine.h" +#include "dev/leds.h" + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" + +static void +res_post_put_handler(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset); + +static void +res_event_handler(); + +/*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ +EVENT_RESOURCE(res_led3, + "title=\"LED3\"; obs", + res_get_handler, + res_post_put_handler, + res_post_put_handler, + NULL, + res_event_handler + ); + +static void +res_post_put_handler(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *payload; + REST.get_request_payload(request, &payload); + + if (*payload == '0' || *payload == '1') { + if (*payload == '1') { + leds_on(LEDS_3); + } else { + leds_off(LEDS_3); + } + REST.notify_subscribers(&res_led3); + REST.set_response_status(response, REST.status.CHANGED); + } else { + REST.set_response_status(response, REST.status.BAD_REQUEST); + } +} + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "%d", (leds_get() & LEDS_3) ? 1 : 0)); +} + +/* + * Additionally, res_event_handler must be implemented for each EVENT_RESOURCE. + * It is called through .trigger(), usually from the server process. + */ +static void +res_event_handler() +{ + /* Notify the registered observers which will trigger the res_get_handler to create the response. */ + REST.notify_subscribers(&res_led3); +} diff --git a/examples/nrf52dk/mqtt-demo/Makefile b/examples/nrf52dk/mqtt-demo/Makefile new file mode 100644 index 000000000..bfdeccfb7 --- /dev/null +++ b/examples/nrf52dk/mqtt-demo/Makefile @@ -0,0 +1,11 @@ +DEFINES+=PROJECT_CONF_H=\"project-conf.h\" + +all: mqtt-demo + +CONTIKI_WITH_IPV6 = 1 +CONTIKI_WITH_RPL = 0 + +APPS += mqtt + +CONTIKI=../../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/nrf52dk/mqtt-demo/README.md b/examples/nrf52dk/mqtt-demo/README.md new file mode 100644 index 000000000..a4a9a6ff1 --- /dev/null +++ b/examples/nrf52dk/mqtt-demo/README.md @@ -0,0 +1,74 @@ +MQTT Demo +========= +The MQTT client can be used to: + +* Publish sensor readings to an MQTT broker. +* Subscribe to a topic and receive commands from an MQTT broker + +The demo will give some visual feedback with the green LED: +* Very fast blinking: Searching for a network +* Fast blinking: Connecting to broker +* Slow, long blinking: Sending a publish message + +Note that before any MQTT messages can be sent or received you'll +need to configure an IPv6 connection to the device and assign a routable +IPv6 address. + +For details how to do this please refer to sections 'Establishing an IPv6 connection' +and 'Distributing routable IPv6 prefix' in `platform/nrf52dk/README-BLE-6LoWPAN.md`. + +Broker setup +------------ +By default the example will attempt to publish readings to an MQTT broker +running on the IPv6 address specified as `MQTT_DEMO_BROKER_IP_ADDR` in +`project-conf.h`. This functionality was tested successfully with +[mosquitto](http://mosquitto.org/). + +On Ubuntu you can install and run mosquitto broker using the following +commands: + + apt-get install mosquitto mosquitto_clients + killall mosquitto + mosquitto -p 1883 -v + +Publishing +---------- +The publish messages include sensor readings but also some other information, +such as device uptime in seconds and a message sequence number. The demo will +publish to topic `iot-2/evt/status/fmt/json`. The device will connect using +client-id `d:quickstart:cc2538:`, where `` gets +constructed from the device's IEEE address. + +Subscribing +----------- +You can also subscribe to topics and receive commands, but this will only +work if you use "Org ID" != 'quickstart'. To achieve this, you will need to +change 'Org ID' (`DEFAULT_ORG_ID`). In this scenario, the device will subscribe +to: + +`iot-2/cmd/+/fmt/json` + +You can then use this to toggle LEDs. To do this, you can for example +use mosquitto client to publish to `iot-2/cmd/leds/fmt/json`. So, to change +the state of an LED, you would do this: + +`mosquitto_pub -h -m "1" -t iot-2/cmd/leds/fmt/json` + +Where `broker IP` should be replaced with the IP address of your mosquitto +broker (the one where you device has subscribed). Replace `-m "1'` with `-m "0"` +to turn the LED back off. + +Bear in mind that, even though the topic suggests that messages are of json +format, they are in fact not. This was done in order to avoid linking a json +parser into the firmware. This comment only applies to parsing incoming +messages, outgoing publish messages use proper json payload. + +IBM Quickstart Service +---------------------- +It is also possible to publish to IBM's quickstart service. To do so, you need +to undefine `MQTT_DEMO_BROKER_IP_ADDR`. + +If you want to use IBM's cloud service with a registered device, change +'Org ID' (`DEFAULT_ORG_ID`) and provide the 'Auth Token' (`DEFAULT_AUTH_TOKEN`), +which acts as a 'password', but bear in mind that it gets transported in clear +text. \ No newline at end of file diff --git a/examples/nrf52dk/mqtt-demo/mqtt-demo.c b/examples/nrf52dk/mqtt-demo/mqtt-demo.c new file mode 100644 index 000000000..6a3482073 --- /dev/null +++ b/examples/nrf52dk/mqtt-demo/mqtt-demo.c @@ -0,0 +1,721 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (c) 2015, Nordic Semiconductor + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup nrf52dk-examples Demo projects for nRF52 DK + * @{ + * + * \defgroup nrf52dk-mqtt-demo nRF52 DK MQTT Demo Project + * + * Demonstrates MQTT functionality. Works with mosquitto. + * @{ + * + * \file + * An MQTT example for the nrf52dk platform + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "mqtt.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-icmp6.h" +#include "net/ipv6/sicslowpan.h" +#include "sys/etimer.h" +#include "sys/ctimer.h" +#include "lib/sensors.h" +#include "dev/button-sensor.h" +#include "dev/temperature-sensor.h" +#include "dev/leds.h" + +#include +/*---------------------------------------------------------------------------*/ +/* + * IBM server: quickstart.messaging.internetofthings.ibmcloud.com + * (184.172.124.189) mapped in an NAT64 (prefix 64:ff9b::/96) IPv6 address + * Note: If not able to connect; lookup the IP address again as it may change. + * + * Alternatively, publish to a local MQTT broker (e.g. mosquitto) running on + * the node that hosts your border router + */ +#ifdef MQTT_DEMO_BROKER_IP_ADDR +static const char *broker_ip = MQTT_DEMO_BROKER_IP_ADDR; +#define DEFAULT_ORG_ID "mqtt-demo" +#else +static const char *broker_ip = "0064:ff9b:0000:0000:0000:0000:b8ac:7cbd"; +#define DEFAULT_ORG_ID "quickstart" +#endif +/*---------------------------------------------------------------------------*/ +/* + * A timeout used when waiting for something to happen (e.g. to connect or to + * disconnect) + */ +#define STATE_MACHINE_PERIODIC (CLOCK_SECOND >> 1) +/*---------------------------------------------------------------------------*/ +/* Provide visible feedback via LEDS during various states */ +/* When connecting to broker */ +#define CONNECTING_LED_DURATION (CLOCK_SECOND >> 2) + +/* Each time we try to publish */ +#define PUBLISH_LED_ON_DURATION (CLOCK_SECOND) +/*---------------------------------------------------------------------------*/ +/* Connections and reconnections */ +#define RETRY_FOREVER 0xFF +#define RECONNECT_INTERVAL (CLOCK_SECOND * 2) + +/* + * Number of times to try reconnecting to the broker. + * Can be a limited number (e.g. 3, 10 etc) or can be set to RETRY_FOREVER + */ +#define RECONNECT_ATTEMPTS RETRY_FOREVER +#define CONNECTION_STABLE_TIME (CLOCK_SECOND * 5) +static struct timer connection_life; +static uint8_t connect_attempt; +/*---------------------------------------------------------------------------*/ +/* Various states */ +static uint8_t state; +#define STATE_INIT 0 +#define STATE_REGISTERED 1 +#define STATE_CONNECTING 2 +#define STATE_CONNECTED 3 +#define STATE_PUBLISHING 4 +#define STATE_DISCONNECTED 5 +#define STATE_NEWCONFIG 6 +#define STATE_CONFIG_ERROR 0xFE +#define STATE_ERROR 0xFF +/*---------------------------------------------------------------------------*/ +#define CONFIG_ORG_ID_LEN 32 +#define CONFIG_TYPE_ID_LEN 32 +#define CONFIG_AUTH_TOKEN_LEN 32 +#define CONFIG_EVENT_TYPE_ID_LEN 32 +#define CONFIG_CMD_TYPE_LEN 8 +#define CONFIG_IP_ADDR_STR_LEN 64 +/*---------------------------------------------------------------------------*/ +#define RSSI_MEASURE_INTERVAL_MAX 86400 /* secs: 1 day */ +#define RSSI_MEASURE_INTERVAL_MIN 5 /* secs */ +#define PUBLISH_INTERVAL_MAX 86400 /* secs: 1 day */ +#define PUBLISH_INTERVAL_MIN 5 /* secs */ +/*---------------------------------------------------------------------------*/ +/* A timeout used when waiting to connect to a network */ +#define NET_CONNECT_PERIODIC CLOCK_SECOND +#define NO_NET_LED_DURATION (NET_CONNECT_PERIODIC >> 1) +/*---------------------------------------------------------------------------*/ +/* Default configuration values */ +#define DEFAULT_TYPE_ID "nrf52dk" +#define DEFAULT_AUTH_TOKEN "AUTHZ" +#define DEFAULT_EVENT_TYPE_ID "status" +#define DEFAULT_SUBSCRIBE_CMD_TYPE "+" +#define DEFAULT_BROKER_PORT 1883 +#define DEFAULT_PUBLISH_INTERVAL (30 * CLOCK_SECOND) +#define DEFAULT_KEEP_ALIVE_TIMER 60 +#define DEFAULT_RSSI_MEAS_INTERVAL (CLOCK_SECOND * 30) +/*---------------------------------------------------------------------------*/ +/* Take a sensor reading on button press */ +#define PUBLISH_TRIGGER (&button_sensor) + +/* Payload length of ICMPv6 echo requests used to measure RSSI with def rt */ +#define ECHO_REQ_PAYLOAD_LEN 20 +/*---------------------------------------------------------------------------*/ +PROCESS_NAME(mqtt_demo_process); +AUTOSTART_PROCESSES(&mqtt_demo_process); +/*---------------------------------------------------------------------------*/ +/** + * \brief Data structure declaration for the MQTT client configuration + */ +typedef struct mqtt_client_config { + char org_id[CONFIG_ORG_ID_LEN]; + char type_id[CONFIG_TYPE_ID_LEN]; + char auth_token[CONFIG_AUTH_TOKEN_LEN]; + char event_type_id[CONFIG_EVENT_TYPE_ID_LEN]; + char broker_ip[CONFIG_IP_ADDR_STR_LEN]; + char cmd_type[CONFIG_CMD_TYPE_LEN]; + clock_time_t pub_interval; + int def_rt_ping_interval; + uint16_t broker_port; +} mqtt_client_config_t; +/*---------------------------------------------------------------------------*/ +/* Maximum TCP segment size for outgoing segments of our socket */ +#define MAX_TCP_SEGMENT_SIZE 32 +/*---------------------------------------------------------------------------*/ +#define STATUS_LED LEDS_GREEN +/*---------------------------------------------------------------------------*/ +/* + * Buffers for Client ID and Topic. + * Make sure they are large enough to hold the entire respective string + * + * d:quickstart:status:EUI64 is 32 bytes long + * iot-2/evt/status/fmt/json is 25 bytes + * We also need space for the null termination + */ +#define BUFFER_SIZE 64 +static char client_id[BUFFER_SIZE]; +static char pub_topic[BUFFER_SIZE]; +static char sub_topic[BUFFER_SIZE]; +/*---------------------------------------------------------------------------*/ +/* + * The main MQTT buffers. + * We will need to increase if we start publishing more data. + */ +#define APP_BUFFER_SIZE 128 +static struct mqtt_connection conn; +static char app_buffer[APP_BUFFER_SIZE]; +/*---------------------------------------------------------------------------*/ +#define QUICKSTART "quickstart" +/*---------------------------------------------------------------------------*/ +static struct mqtt_message *msg_ptr = 0; +static struct etimer publish_periodic_timer; +static struct ctimer ct; +static char *buf_ptr; +static uint16_t seq_nr_value = 0; +/*---------------------------------------------------------------------------*/ +/* Parent RSSI functionality */ +static struct uip_icmp6_echo_reply_notification echo_reply_notification; +static struct etimer echo_request_timer; +static int def_rt_rssi = 0; +/*---------------------------------------------------------------------------*/ +static mqtt_client_config_t conf; +/*---------------------------------------------------------------------------*/ +PROCESS(mqtt_demo_process, "MQTT Demo"); +/*---------------------------------------------------------------------------*/ +int +ipaddr_sprintf(char *buf, uint8_t buf_len, const uip_ipaddr_t *addr) +{ + uint16_t a; + uint8_t len = 0; + int i, f; + for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { + a = (addr->u8[i] << 8) + addr->u8[i + 1]; + if(a == 0 && f >= 0) { + if(f++ == 0) { + len += snprintf(&buf[len], buf_len - len, "::"); + } + } else { + if(f > 0) { + f = -1; + } else if(i > 0) { + len += snprintf(&buf[len], buf_len - len, ":"); + } + len += snprintf(&buf[len], buf_len - len, "%x", a); + } + } + + return len; +} +/*---------------------------------------------------------------------------*/ +static void +echo_reply_handler(uip_ipaddr_t *source, uint8_t ttl, uint8_t *data, + uint16_t datalen) +{ + if(uip_ip6addr_cmp(source, uip_ds6_defrt_choose())) { + def_rt_rssi = sicslowpan_get_last_rssi(); + } +} +/*---------------------------------------------------------------------------*/ +static void +publish_led_off(void *d) +{ + leds_off(STATUS_LED); +} +/*---------------------------------------------------------------------------*/ +static void +pub_handler(const char *topic, uint16_t topic_len, const uint8_t *chunk, + uint16_t chunk_len) +{ + DBG("Pub Handler: topic='%s' (len=%u), chunk_len=%u\n", topic, topic_len, + chunk_len); + + /* If we don't like the length, ignore */ + if(topic_len != 23 || chunk_len != 1) { + printf("Incorrect topic or chunk len. Ignored\n"); + return; + } + + /* If the format != json, ignore */ + if(strncmp(&topic[topic_len - 4], "json", 4) != 0) { + printf("Incorrect format\n"); + } + + if(strncmp(&topic[10], "leds", 4) == 0) { + if(chunk[0] == '1') { + leds_on(LEDS_RED); + } else if(chunk[0] == '0') { + leds_off(LEDS_RED); + } + return; + } +} +/*---------------------------------------------------------------------------*/ +static void +mqtt_event(struct mqtt_connection *m, mqtt_event_t event, void *data) +{ + switch(event) { + case MQTT_EVENT_CONNECTED: { + DBG("APP - Application has a MQTT connection\n"); + timer_set(&connection_life, CONNECTION_STABLE_TIME); + state = STATE_CONNECTED; + break; + } + case MQTT_EVENT_DISCONNECTED: { + DBG("APP - MQTT Disconnect. Reason %u\n", *((mqtt_event_t *)data)); + + state = STATE_DISCONNECTED; + process_poll(&mqtt_demo_process); + break; + } + case MQTT_EVENT_PUBLISH: { + msg_ptr = data; + + /* Implement first_flag in publish message? */ + if(msg_ptr->first_chunk) { + msg_ptr->first_chunk = 0; + DBG("APP - Application received a publish on topic '%s'. Payload " + "size is %i bytes. Content:\n\n", + msg_ptr->topic, msg_ptr->payload_length); + } + + pub_handler(msg_ptr->topic, strlen(msg_ptr->topic), msg_ptr->payload_chunk, + msg_ptr->payload_length); + break; + } + case MQTT_EVENT_SUBACK: { + DBG("APP - Application is subscribed to topic successfully\n"); + break; + } + case MQTT_EVENT_UNSUBACK: { + DBG("APP - Application is unsubscribed to topic successfully\n"); + break; + } + case MQTT_EVENT_PUBACK: { + DBG("APP - Publishing complete\n"); + break; + } + default: + DBG("APP - Application got a unhandled MQTT event: %i\n", event); + break; + } +} +/*---------------------------------------------------------------------------*/ +static int +construct_pub_topic(void) +{ + int len = snprintf(pub_topic, BUFFER_SIZE, "iot-2/evt/%s/fmt/json", + conf.event_type_id); + + /* len < 0: Error. Len >= BUFFER_SIZE: Buffer too small */ + if(len < 0 || len >= BUFFER_SIZE) { + printf("Pub Topic: %d, Buffer %d\n", len, BUFFER_SIZE); + return 0; + } + + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +construct_sub_topic(void) +{ + int len = snprintf(sub_topic, BUFFER_SIZE, "iot-2/cmd/%s/fmt/json", + conf.cmd_type); + + /* len < 0: Error. Len >= BUFFER_SIZE: Buffer too small */ + if(len < 0 || len >= BUFFER_SIZE) { + printf("Sub Topic: %d, Buffer %d\n", len, BUFFER_SIZE); + return 0; + } + + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +construct_client_id(void) +{ + int len = snprintf(client_id, BUFFER_SIZE, "d:%s:%s:%02x%02x%02x%02x%02x%02x", + conf.org_id, conf.type_id, + linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1], + linkaddr_node_addr.u8[2], linkaddr_node_addr.u8[5], + linkaddr_node_addr.u8[6], linkaddr_node_addr.u8[7]); + + /* len < 0: Error. Len >= BUFFER_SIZE: Buffer too small */ + if(len < 0 || len >= BUFFER_SIZE) { + printf("Client ID: %d, Buffer %d\n", len, BUFFER_SIZE); + return 0; + } + + return 1; +} +/*---------------------------------------------------------------------------*/ +static void +update_config(void) +{ + if(construct_client_id() == 0) { + /* Fatal error. Client ID larger than the buffer */ + state = STATE_CONFIG_ERROR; + return; + } + + if(construct_sub_topic() == 0) { + /* Fatal error. Topic larger than the buffer */ + state = STATE_CONFIG_ERROR; + return; + } + + if(construct_pub_topic() == 0) { + /* Fatal error. Topic larger than the buffer */ + state = STATE_CONFIG_ERROR; + return; + } + + /* Reset the counter */ + seq_nr_value = 0; + + state = STATE_INIT; + + /* + * Schedule next timer event ASAP + * + * If we entered an error state then we won't do anything when it fires. + * + * Since the error at this stage is a config error, we will only exit this + * error state if we get a new config. + */ + etimer_set(&publish_periodic_timer, 0); + + return; +} +/*---------------------------------------------------------------------------*/ +static int +init_config() +{ + /* Populate configuration with default values */ + memset(&conf, 0, sizeof(mqtt_client_config_t)); + + memcpy(conf.org_id, DEFAULT_ORG_ID, strlen(DEFAULT_ORG_ID)); + memcpy(conf.type_id, DEFAULT_TYPE_ID, strlen(DEFAULT_TYPE_ID)); + memcpy(conf.auth_token, DEFAULT_AUTH_TOKEN, strlen(DEFAULT_AUTH_TOKEN)); + memcpy(conf.event_type_id, DEFAULT_EVENT_TYPE_ID, + strlen(DEFAULT_EVENT_TYPE_ID)); + memcpy(conf.broker_ip, broker_ip, strlen(broker_ip)); + memcpy(conf.cmd_type, DEFAULT_SUBSCRIBE_CMD_TYPE, 1); + + conf.broker_port = DEFAULT_BROKER_PORT; + conf.pub_interval = DEFAULT_PUBLISH_INTERVAL; + conf.def_rt_ping_interval = DEFAULT_RSSI_MEAS_INTERVAL; + + return 1; +} +/*---------------------------------------------------------------------------*/ +static void +subscribe(void) +{ + /* Publish MQTT topic in IBM quickstart format */ + mqtt_status_t status; + + status = mqtt_subscribe(&conn, NULL, sub_topic, MQTT_QOS_LEVEL_0); + + DBG("APP - Subscribing!\n"); + if(status == MQTT_STATUS_OUT_QUEUE_FULL) { + DBG("APP - Tried to subscribe but command queue was full!\n"); + } +} +/*---------------------------------------------------------------------------*/ +static void +publish(void) +{ + /* Publish MQTT topic in IBM quickstart format */ + int len; + int remaining = APP_BUFFER_SIZE; + + seq_nr_value++; + + buf_ptr = app_buffer; + + len = snprintf(buf_ptr, remaining, + "{" + "\"d\":{" + "\"Seq #\":%d," + "\"Uptime (sec)\":%lu", seq_nr_value, clock_seconds()); + + if(len < 0 || len >= remaining) { + printf("Buffer too short. Have %d, need %d + \\0\n", remaining, len); + return; + } + + remaining -= len; + buf_ptr += len; + + /* Put our Default route's string representation in a buffer */ + char def_rt_str[64]; + memset(def_rt_str, 0, sizeof(def_rt_str)); + ipaddr_sprintf(def_rt_str, sizeof(def_rt_str), uip_ds6_defrt_choose()); + + len = snprintf(buf_ptr, remaining, ",\"Def Route\":\"%s\",\"RSSI (dBm)\":%d", + def_rt_str, def_rt_rssi); + + if(len < 0 || len >= remaining) { + printf("Buffer too short. Have %d, need %d + \\0\n", remaining, len); + return; + } + remaining -= len; + buf_ptr += len; + + len = snprintf(buf_ptr, remaining, ",\"On-Chip Temp (deg.C)\":%d", + temperature_sensor.value(0)); + + if(len < 0 || len >= remaining) { + printf("Buffer too short. Have %d, need %d + \\0\n", remaining, len); + return; + } + remaining -= len; + buf_ptr += len; + + len = snprintf(buf_ptr, remaining, "}}"); + + if(len < 0 || len >= remaining) { + printf("Buffer too short. Have %d, need %d + \\0\n", remaining, len); + return; + } + + mqtt_publish(&conn, NULL, pub_topic, (uint8_t *)app_buffer, + strlen(app_buffer), MQTT_QOS_LEVEL_0, MQTT_RETAIN_OFF); + + DBG("APP - Publish!\n"); +} +/*---------------------------------------------------------------------------*/ +static void +connect_to_broker(void) +{ + /* Connect to MQTT server */ + mqtt_connect(&conn, conf.broker_ip, conf.broker_port, + conf.pub_interval * 3); + + state = STATE_CONNECTING; +} +/*---------------------------------------------------------------------------*/ +static void +ping_parent(void) +{ + if(uip_ds6_get_global(ADDR_PREFERRED) == NULL) { + return; + } + + uip_icmp6_send(uip_ds6_defrt_choose(), ICMP6_ECHO_REQUEST, 0, + ECHO_REQ_PAYLOAD_LEN); +} +/*---------------------------------------------------------------------------*/ +static void +state_machine(void) +{ + switch(state) { + case STATE_INIT: + /* If we have just been configured register MQTT connection */ + mqtt_register(&conn, &mqtt_demo_process, client_id, mqtt_event, + MAX_TCP_SEGMENT_SIZE); + + /* + * If we are not using the quickstart service (thus we are an IBM + * registered device), we need to provide user name and password + */ + if(strncasecmp(conf.org_id, QUICKSTART, strlen(conf.org_id)) != 0) { + if(strlen(conf.auth_token) == 0) { + printf("User name set, but empty auth token\n"); + state = STATE_ERROR; + break; + } else { + mqtt_set_username_password(&conn, "use-token-auth", + conf.auth_token); + } + } + + /* _register() will set auto_reconnect. We don't want that. */ + conn.auto_reconnect = 0; + connect_attempt = 1; + + state = STATE_REGISTERED; + DBG("Init\n"); + /* Continue */ + case STATE_REGISTERED: + if(uip_ds6_get_global(ADDR_PREFERRED) != NULL) { + /* Registered and with a public IP. Connect */ + DBG("Registered. Connect attempt %u\n", connect_attempt); + ping_parent(); + connect_to_broker(); + } else { + leds_on(STATUS_LED); + ctimer_set(&ct, NO_NET_LED_DURATION, publish_led_off, NULL); + } + etimer_set(&publish_periodic_timer, NET_CONNECT_PERIODIC); + return; + break; + case STATE_CONNECTING: + leds_on(STATUS_LED); + ctimer_set(&ct, CONNECTING_LED_DURATION, publish_led_off, NULL); + /* Not connected yet. Wait */ + DBG("Connecting (%u)\n", connect_attempt); + break; + case STATE_CONNECTED: + /* Don't subscribe unless we are a registered device */ + if(strncasecmp(conf.org_id, QUICKSTART, strlen(conf.org_id)) == 0) { + DBG("Using 'quickstart': Skipping subscribe\n"); + state = STATE_PUBLISHING; + } + /* Continue */ + case STATE_PUBLISHING: + /* If the timer expired, the connection is stable. */ + if(timer_expired(&connection_life)) { + /* + * Intentionally using 0 here instead of 1: We want RECONNECT_ATTEMPTS + * attempts if we disconnect after a successful connect + */ + connect_attempt = 0; + } + + if(mqtt_ready(&conn) && conn.out_buffer_sent) { + /* Connected. Publish */ + if(state == STATE_CONNECTED) { + subscribe(); + state = STATE_PUBLISHING; + } else { + leds_on(STATUS_LED); + ctimer_set(&ct, PUBLISH_LED_ON_DURATION, publish_led_off, NULL); + publish(); + } + etimer_set(&publish_periodic_timer, conf.pub_interval); + + DBG("Publishing\n"); + /* Return here so we don't end up rescheduling the timer */ + return; + } else { + /* + * Our publish timer fired, but some MQTT packet is already in flight + * (either not sent at all, or sent but not fully ACKd). + * + * This can mean that we have lost connectivity to our broker or that + * simply there is some network delay. In both cases, we refuse to + * trigger a new message and we wait for TCP to either ACK the entire + * packet after retries, or to timeout and notify us. + */ + DBG("Publishing... (MQTT state=%d, q=%u)\n", conn.state, + conn.out_queue_full); + } + break; + case STATE_DISCONNECTED: + DBG("Disconnected\n"); + if(connect_attempt < RECONNECT_ATTEMPTS || + RECONNECT_ATTEMPTS == RETRY_FOREVER) { + /* Disconnect and backoff */ + clock_time_t interval; + mqtt_disconnect(&conn); + connect_attempt++; + + interval = connect_attempt < 3 ? RECONNECT_INTERVAL << connect_attempt : + RECONNECT_INTERVAL << 3; + + DBG("Disconnected. Attempt %u in %lu ticks\n", connect_attempt, interval); + + etimer_set(&publish_periodic_timer, interval); + + state = STATE_REGISTERED; + return; + } else { + /* Max reconnect attempts reached. Enter error state */ + state = STATE_ERROR; + DBG("Aborting connection after %u attempts\n", connect_attempt - 1); + } + break; + case STATE_CONFIG_ERROR: + /* Idle away. The only way out is a new config */ + printf("Bad configuration\n"); + return; + case STATE_ERROR: + default: + leds_on(STATUS_LED); + /* + * 'default' should never happen. + * + * If we enter here it's because of some error. Stop timers. The only thing + * that can bring us out is a new config event + */ + printf("Default case: State=0x%02x\n", state); + return; + } + + /* If we didn't return so far, reschedule ourselves */ + etimer_set(&publish_periodic_timer, STATE_MACHINE_PERIODIC); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(mqtt_demo_process, ev, data) +{ + + PROCESS_BEGIN(); + + printf("MQTT Demo Process\n"); + + if(init_config() != 1) { + PROCESS_EXIT(); + } + + update_config(); + + def_rt_rssi = 0x8000000; + uip_icmp6_echo_reply_callback_add(&echo_reply_notification, + echo_reply_handler); + etimer_set(&echo_request_timer, conf.def_rt_ping_interval); + + PUBLISH_TRIGGER->configure(SENSORS_ACTIVE, 1); + + /* Main loop */ + while(1) { + + PROCESS_YIELD(); + + if(ev == sensors_event && data == PUBLISH_TRIGGER) { + if(state == STATE_ERROR) { + connect_attempt = 1; + state = STATE_REGISTERED; + } + } + + if((ev == PROCESS_EVENT_TIMER && data == &publish_periodic_timer) || + ev == PROCESS_EVENT_POLL || + (ev == sensors_event && data == PUBLISH_TRIGGER && PUBLISH_TRIGGER->value(BUTTON_SENSOR_VALUE_STATE) == 0)) { + state_machine(); + } + + if(ev == PROCESS_EVENT_TIMER && data == &echo_request_timer) { + ping_parent(); + etimer_set(&echo_request_timer, conf.def_rt_ping_interval); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/examples/nrf52dk/mqtt-demo/project-conf.h b/examples/nrf52dk/mqtt-demo/project-conf.h new file mode 100644 index 000000000..b52e1a48f --- /dev/null +++ b/examples/nrf52dk/mqtt-demo/project-conf.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc2538-mqtt-demo + * @{ + * + * \file + * Project specific configuration defines for the MQTT demo + */ +/*---------------------------------------------------------------------------*/ +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ +/*---------------------------------------------------------------------------*/ +/* User configuration */ +#define MQTT_DEMO_STATUS_LED LEDS_GREEN + +/* If undefined, the demo will attempt to connect to IBM's quickstart */ +#define MQTT_DEMO_BROKER_IP_ADDR "fd00::215:83ff:fed2:dbd7" +/*---------------------------------------------------------------------------*/ +#endif /* PROJECT_CONF_H_ */ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/examples/nrf52dk/timer-test/Makefile b/examples/nrf52dk/timer-test/Makefile new file mode 100644 index 000000000..ac89a34a4 --- /dev/null +++ b/examples/nrf52dk/timer-test/Makefile @@ -0,0 +1,9 @@ +CONTIKI_PROJECT = timer-test + +CONTIKI_WITH_RPL=0 +NRF52_WITHOUT_SOFTDEVICE=1 + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/nrf52dk/timer-test/README.md b/examples/nrf52dk/timer-test/README.md new file mode 100644 index 000000000..9ce7cad94 --- /dev/null +++ b/examples/nrf52dk/timer-test/README.md @@ -0,0 +1,20 @@ +Timers test +=========== +Timers test is an application allows for testing clocks implementation for nRF52 DK. +The results of different tests are output to the console. + +There are 4 tests performed: + + 1) TEST clock_delay_usec() - measures duration of a NOP delay using rtimer. It's expected + that difference is close to 0. + + 2) TEST rtimer - schedules an rtimer callback after 1 second. Prints actual time difference + in rtimer and clock ticks. It's expected that both values are close to 0. + + 3) TEST etimer - schedules an event timer and measures time difference. It is expected that + the value is close to 0. + +The example requires one DK and it doesn't use SoftDevice. To compile and flash the +example run: + + make TARGET=nrf52dk timer-test.flash \ No newline at end of file diff --git a/examples/nrf52dk/timer-test/timer-test.c b/examples/nrf52dk/timer-test/timer-test.c new file mode 100644 index 000000000..e0ced7293 --- /dev/null +++ b/examples/nrf52dk/timer-test/timer-test.c @@ -0,0 +1,131 @@ +/** + * \file + * Tests related to clocks and timers + * This is based on clock_test.c from the original sensinode port + * + * \author + * Zach Shelby (Original) + * George Oikonomou - (rtimer code) + * Wojciech Bober (nRF52 DK adaptation) + * + */ + +/** + * \addtogroup nrf52dk-examples Demo projects for nRF52 DK + * @{ + */ +#include "contiki.h" +#include "sys/clock.h" +#include "sys/rtimer.h" +#include "dev/leds.h" + +#include "nrf_delay.h" + +#include +/*---------------------------------------------------------------------------*/ +#define TEST_CLOCK_DELAY_USEC 1 +#define TEST_RTIMER 1 +#define TEST_ETIMER 1 +/*---------------------------------------------------------------------------*/ +static struct etimer et; + +#if TEST_CLOCK_DELAY_USEC +static rtimer_clock_t start_count, end_count, diff; +#endif + +#if TEST_ETIMER +static clock_time_t count; +#endif + +#if TEST_RTIMER +static struct rtimer rt; +static clock_time_t ct_now; +rtimer_clock_t rt_now, rt_until; + +static volatile rtimer_clock_t rt_now_cb; +static volatile clock_time_t ct_cb; +#endif + +static uint8_t i; +/*---------------------------------------------------------------------------*/ +PROCESS(clock_test_process, "Clock test process"); +AUTOSTART_PROCESSES(&clock_test_process); +/*---------------------------------------------------------------------------*/ +#if TEST_RTIMER +void +rt_callback(struct rtimer *t, void *ptr) +{ + rt_now_cb = RTIMER_NOW(); + ct_cb = clock_time(); +} +#endif +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(clock_test_process, ev, data) +{ + + PROCESS_BEGIN(); + etimer_set(&et, 2 * CLOCK_SECOND); + PROCESS_YIELD(); + + printf("RTIMER_SECOND=%d CLOCK_SECOND=%d\n", RTIMER_SECOND, CLOCK_SECOND); + +#if TEST_CLOCK_DELAY_USEC + printf("=======================\n"); + printf("TEST clock_delay_usec()\n"); + printf("=======================\n"); + i = 1; + while(i < 7) { + start_count = RTIMER_NOW(); + clock_delay_usec(10000 * i); + end_count = RTIMER_NOW(); + diff = end_count - start_count; + printf("difference [usec]: %ld\n", 10000 * i - (diff*(1000000/RTIMER_SECOND))); + i++; + } +#endif + +#if TEST_RTIMER + printf("=======================\n"); + printf("TEST rtimer\n"); + printf("=======================\n"); + i = 0; + while(i < 5) { + etimer_set(&et, 2 * CLOCK_SECOND); + rt_now = RTIMER_NOW(); + ct_now = clock_time(); + rt_until = rt_now + RTIMER_SECOND; + printf("now [ticks]: %lu until[ticks]: %lu\n", rt_now, rt_until); + if (rtimer_set(&rt, rt_until, 1, rt_callback, NULL) != RTIMER_OK) { + printf("Error setting\n"); + } + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + printf("rtimer difference [ticks]: %ld\n", RTIMER_SECOND - (rt_now_cb - rt_now)); + printf("clock difference [ticks]: %ld\n", CLOCK_SECOND - (ct_cb - ct_now)); + i++; + } +#endif + +#if TEST_ETIMER + printf("=======================\n"); + printf("TEST etimer\n"); + printf("=======================\n"); + i = 0; + while(i < 5) { + etimer_set(&et, i*CLOCK_SECOND); + count = clock_time(); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + etimer_reset(&et); + printf("difference [ticks]: %lu\n", i*CLOCK_SECOND - (clock_time() - count)); + leds_toggle(LEDS_RED); + i++; + } +#endif + + printf("Done!\n"); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + */ From 2d45a4207a57c6a523436911cac65b192c75f127 Mon Sep 17 00:00:00 2001 From: Wojciech Bober Date: Fri, 22 Jan 2016 11:13:07 +0100 Subject: [PATCH 026/374] nrf52dk: regression tests --- .travis.yml | 13 +++++++++++++ .../23-compile-nrf52-ports/Makefile | 19 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 regression-tests/23-compile-nrf52-ports/Makefile diff --git a/.travis.yml b/.travis.yml index 1814ee6fa..74ce552e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -89,6 +89,18 @@ before_script: rm -rf /tmp/ba-elf-gcc* /tmp/jn516x-sdk* && ba-elf-gcc --version ; fi + + ## Install mainline ARM toolchain and download nRF52 SDK + - if [ ${BUILD_ARCH:-0} = nrf52dk ] ; then + sudo add-apt-repository -y ppa:terry.guo/gcc-arm-embedded && + sudo apt-get -qq update && + sudo apt-get -qq install gcc-arm-none-eabi srecord && + arm-none-eabi-gcc --version && + $WGET https://developer.nordicsemi.com/nRF5_IoT_SDK/nRF5_IoT_SDK_v0.9.x/nrf5_iot_sdk_3288530.zip && + mkdir /tmp/nrf52-sdk && + unzip nrf5_iot_sdk_3288530.zip -d /tmp/nrf52-sdk && + export NRF52_SDK_ROOT=/tmp/nrf52-sdk ; + fi ## Compile cooja.jar only when it's going to be needed - if [ ${BUILD_CATEGORY:-sim} = sim ] ; then @@ -138,5 +150,6 @@ env: - BUILD_TYPE='compile-6502-ports' BUILD_CATEGORY='compile' BUILD_ARCH='6502' - BUILD_TYPE='compile-arm-ports' BUILD_CATEGORY='compile' BUILD_ARCH='arm-aapcs' - BUILD_TYPE='compile-nxp-ports' BUILD_CATEGORY='compile' BUILD_ARCH='jn516x' + - BUILD_TYPE='compile-nrf52-ports' BUILD_CATEGORY='compile' BUILD_ARCH='nrf52dk' - BUILD_TYPE='slip-radio' MAKE_TARGETS='cooja' - BUILD_TYPE='llsec' MAKE_TARGETS='cooja' diff --git a/regression-tests/23-compile-nrf52-ports/Makefile b/regression-tests/23-compile-nrf52-ports/Makefile new file mode 100644 index 000000000..5e9ee19de --- /dev/null +++ b/regression-tests/23-compile-nrf52-ports/Makefile @@ -0,0 +1,19 @@ +EXAMPLESDIR=../../examples +TOOLSDIR=../../tools + +# Note, that SERVER_IPV6_ADDR variable is set to ffff on purpose +# even though it's not a valid IPV6 address. This is due to limitation +# of the testing framework which splits compliation arguments using +# a colon. + +EXAMPLES = \ +hello-world/nrf52dk \ +nrf52dk/blink-hello/nrf52dk \ +nrf52dk/coap-demo/nrf52dk:coap-server \ +nrf52dk/coap-demo/nrf52dk:coap-client:SERVER_IPV6_ADDR=ffff \ +nrf52dk/mqtt-demo/nrf52dk \ +nrf52dk/timer-test/nrf52dk + +TOOLS= + +include ../Makefile.compile-test From 943e5268601e3efba24dd9a19412b2235145c5e1 Mon Sep 17 00:00:00 2001 From: Wojciech Bober Date: Fri, 22 Jan 2016 12:42:45 +0100 Subject: [PATCH 027/374] nrf52dk: added build artifacts to git ignore --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index c166681da..304d18b7b 100644 --- a/.gitignore +++ b/.gitignore @@ -125,3 +125,7 @@ platform/galileo/bsp/grub/bin/ *.galileo.dll *.galileo.efi LOG_OPENOCD + +# nRF52 build artifacts +*.jlink +*.nrf52dk From 66629ae58f7494eea0cc9f822ca38b7f20c29b5e Mon Sep 17 00:00:00 2001 From: Michael LeMay Date: Fri, 12 Feb 2016 13:49:19 -0800 Subject: [PATCH 028/374] galileo: build_newlib.sh: Exit on configuration error This patch adds a check for the result of the newlib configure command and immediately exits the build_newlib.sh script if configure fails. --- platform/galileo/bsp/libc/build_newlib.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/galileo/bsp/libc/build_newlib.sh b/platform/galileo/bsp/libc/build_newlib.sh index cef167e14..d0a1926ef 100755 --- a/platform/galileo/bsp/libc/build_newlib.sh +++ b/platform/galileo/bsp/libc/build_newlib.sh @@ -1,5 +1,7 @@ #!/bin/bash +set -e + JOBS=5 TARGET=i586-elf VERSION=2.2.0-1 @@ -99,7 +101,9 @@ cleanup() { # By default we always call prepare, build and setup. -prepare && build && setup +prepare +build +setup # But we only cleanup if -c is used. case $1 in From c815fa451186b4bf06073dbb9b59d7b1e410e213 Mon Sep 17 00:00:00 2001 From: Michael LeMay Date: Wed, 6 Jan 2016 17:00:45 -0800 Subject: [PATCH 029/374] x86: Use shared ISR for I2C and GPIO This patch permits interrupts to be generated by both the I2C and GPIO controllers for simultaneously-executing applications. The controllers share a single interrupt pin, INTC. Prior to this patch, quarkX1000_gpio_init() routed INTA to PIRQC and IRQ 10 (due to an incorrect assumption that INTA is connected to the GPIO controller), and quarkX1000_i2c_init() routed INTC to PIRQC and IRQ 9. The I2C controller initialization is a prerequisite for GPIO initialization, so the final configuration was that INTA and INTC were both routed to PIRQC and IRQ 10. Thus, only the GPIO ISR was being invoked, even if the I2C controller was actually responsible for the interrupt. This patch refactors the I2C and GPIO ISR setup and handler code so that the shared portions are combined in cpu/x86/drivers/legacy_pc/shared-isr.[ch]. The I2C and GPIO drivers communicate their interrupt information to the shared component by placing structures in a specific section of the binary. --- cpu/x86/Makefile.x86_quarkX1000 | 2 +- cpu/x86/drivers/legacy_pc/shared-isr.c | 107 +++++++++++++++++++++++++ cpu/x86/drivers/legacy_pc/shared-isr.h | 67 ++++++++++++++++ cpu/x86/drivers/quarkX1000/gpio.c | 34 +++----- cpu/x86/drivers/quarkX1000/i2c.c | 41 +++++----- cpu/x86/init/common/interrupt.h | 25 +++--- cpu/x86/quarkX1000.ld | 4 + platform/galileo/contiki-main.c | 7 +- 8 files changed, 229 insertions(+), 58 deletions(-) create mode 100644 cpu/x86/drivers/legacy_pc/shared-isr.c create mode 100644 cpu/x86/drivers/legacy_pc/shared-isr.h diff --git a/cpu/x86/Makefile.x86_quarkX1000 b/cpu/x86/Makefile.x86_quarkX1000 index 00f352102..ec9da64be 100644 --- a/cpu/x86/Makefile.x86_quarkX1000 +++ b/cpu/x86/Makefile.x86_quarkX1000 @@ -2,7 +2,7 @@ include $(CONTIKI)/cpu/x86/Makefile.x86_common CONTIKI_CPU_DIRS += drivers/legacy_pc drivers/quarkX1000 init/legacy_pc -CONTIKI_SOURCEFILES += bootstrap_quarkX1000.S rtc.c pit.c pic.c irq.c nmi.c pci.c uart-16x50.c uart.c gpio.c i2c.c eth.c +CONTIKI_SOURCEFILES += bootstrap_quarkX1000.S rtc.c pit.c pic.c irq.c nmi.c pci.c uart-16x50.c uart.c gpio.c i2c.c eth.c shared-isr.c CFLAGS += -m32 -march=i586 -mtune=i586 LDFLAGS += -m32 -Xlinker -T -Xlinker $(CONTIKI)/cpu/x86/quarkX1000.ld diff --git a/cpu/x86/drivers/legacy_pc/shared-isr.c b/cpu/x86/drivers/legacy_pc/shared-isr.c new file mode 100644 index 000000000..e13c7ab93 --- /dev/null +++ b/cpu/x86/drivers/legacy_pc/shared-isr.c @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2016, Intel Corporation. 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +#include +#include "idt.h" +#include "interrupt.h" +#include "pic.h" +#include "shared-isr.h" + +/* Defined in linker script */ +extern shared_isr_client_t _sdata_shared_isr, _edata_shared_isr; + +static void __attribute__((used)) +shared_handler(void) +{ + shared_isr_client_t *client; + for(client = &_sdata_shared_isr; client < &_edata_shared_isr; client++) { + if(client->handler()) { + pic_eoi(client->irq); + return; + } + } +} + +/** + * \brief Initialize shared ISR by iterating through all of its clients and + * configuring their interrupts to route to the shared ISR. + */ +void +shared_isr_init(void) +{ + shared_isr_client_t *client = &_sdata_shared_isr; + shared_isr_client_t *consistency_check_client; + bool prev_conf; + + void shared_isr_stub(void); + __asm__ __volatile__ ( + ISR_STUB("shared_isr_stub", 0, "shared_handler") + ); + + while(client < &_edata_shared_isr) { + consistency_check_client = &_sdata_shared_isr; + + prev_conf = false; + + while(consistency_check_client < client) { + if((client->irq == consistency_check_client->irq) || + (client->pin == consistency_check_client->pin) || + (client->pirq == consistency_check_client->pirq)) { + + prev_conf = true; + + /* This interrupt was previously configured. */ + break; + } + + consistency_check_client++; + } + + if(prev_conf) { + /* The requested configurations for each IRQ must be consistent. */ + assert((client->irq == consistency_check_client->irq) && + (client->agent == consistency_check_client->agent) && + (client->pin == consistency_check_client->pin) && + (client->pirq == consistency_check_client->pirq)); + } else { + idt_set_intr_gate_desc(PIC_INT(client->irq), (uint32_t)shared_isr_stub); + + assert(pci_irq_agent_set_pirq(client->agent, + client->pin, + client->pirq) == 0); + + pci_pirq_set_irq(client->pirq, client->irq, 1); + + pic_unmask_irq(client->irq); + } + + client++; + } +} diff --git a/cpu/x86/drivers/legacy_pc/shared-isr.h b/cpu/x86/drivers/legacy_pc/shared-isr.h new file mode 100644 index 000000000..e8a92e442 --- /dev/null +++ b/cpu/x86/drivers/legacy_pc/shared-isr.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2016, Intel Corporation. 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +#ifndef CPU_X86_DRIVERS_LEGACY_PC_SHARED_ISR_H_ +#define CPU_X86_DRIVERS_LEGACY_PC_SHARED_ISR_H_ + +#include +#include "pci.h" + +/** + * The handler function should return true if and only if it handled the + * interrupt. + */ +typedef bool (*shared_isr_handler_t)(void); + +typedef struct shared_isr_client { + uint8_t irq; + IRQAGENT agent; + INTR_PIN pin; + PIRQ pirq; + shared_isr_handler_t handler; +} shared_isr_client_t; + +/* Unlike a non-shared interrupt handler function, an individual interrupt + * handler for a shared interrupt must not issue an EOI. The EOI is issued by + * the shared-isr subsystem. + */ +#define DEFINE_SHARED_IRQ(irq_, agent_, pin_, pirq_, handler_) \ +static struct shared_isr_client \ + __attribute__((used, section(".shared_isr_data"))) _shared_irq_##irq_ = { \ + .irq = irq_, \ + .agent = agent_, \ + .pin = pin_, \ + .pirq = pirq_, \ + .handler = handler_ \ +} + +void shared_isr_init(void); + +#endif /* CPU_X86_DRIVERS_LEGACY_PC_SHARED_ISR_H_ */ diff --git a/cpu/x86/drivers/quarkX1000/gpio.c b/cpu/x86/drivers/quarkX1000/gpio.c index 92438b456..7d7d7dd64 100644 --- a/cpu/x86/drivers/quarkX1000/gpio.c +++ b/cpu/x86/drivers/quarkX1000/gpio.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015, Intel Corporation. All rights reserved. + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,9 +29,9 @@ */ #include "gpio.h" + #include "helpers.h" -#include "interrupt.h" -#include "pic.h" +#include "shared-isr.h" /* GPIO Controler Registers */ #define SWPORTA_DR 0x00 @@ -49,8 +49,7 @@ #define PINS 8 -#define GPIO_IRQ 10 -#define GPIO_INT PIC_INT(GPIO_IRQ) +#define GPIO_IRQ 9 struct gpio_internal_data { pci_driver_t pci; @@ -87,17 +86,23 @@ set_bit(uint32_t offset, uint32_t bit, uint32_t value) write(offset, reg); } -static void +static bool gpio_isr(void) { uint32_t int_status; int_status = read(INTSTATUS); + if(int_status == 0) { + return false; + } + if (data.callback) data.callback(int_status); write(PORTA_EOI, -1); + + return true; } static void @@ -211,13 +216,7 @@ quarkX1000_gpio_clock_disable(void) set_bit(LS_SYNC, 0, 0); } -static void -gpio_handler(void) -{ - gpio_isr(); - - pic_eoi(GPIO_IRQ); -} +DEFINE_SHARED_IRQ(GPIO_IRQ, IRQAGENT3, INTC, PIRQC, gpio_isr); int quarkX1000_gpio_init(void) @@ -232,13 +231,6 @@ quarkX1000_gpio_init(void) pci_command_enable(pci_addr, PCI_CMD_1_MEM_SPACE_EN); - SET_INTERRUPT_HANDLER(GPIO_INT, 0, gpio_handler); - - if (pci_irq_agent_set_pirq(IRQAGENT3, INTA, PIRQC) < 0) - return -1; - - pci_pirq_set_irq(PIRQC, GPIO_IRQ, 1); - pci_init(&data.pci, pci_addr, 0); data.callback = 0; @@ -250,7 +242,5 @@ quarkX1000_gpio_init(void) write(INTMASK, 0); write(PORTA_EOI, 0); - pic_unmask_irq(GPIO_IRQ); - return 0; } diff --git a/cpu/x86/drivers/quarkX1000/i2c.c b/cpu/x86/drivers/quarkX1000/i2c.c index b781bcc35..b16a79205 100644 --- a/cpu/x86/drivers/quarkX1000/i2c.c +++ b/cpu/x86/drivers/quarkX1000/i2c.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015, Intel Corporation. All rights reserved. + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,9 +30,9 @@ #include "contiki.h" #include "i2c.h" + #include "i2c-registers.h" -#include "interrupt.h" -#include "pic.h" +#include "shared-isr.h" #define I2C_CLOCK_SPEED 25 /* kHz */ #define I2C_FIFO_DEPTH 16 @@ -48,7 +48,6 @@ #define I2C_POLLING_TIMEOUT (CLOCK_SECOND / 10) #define I2C_IRQ 9 -#define I2C_INT PIC_INT(I2C_IRQ) typedef enum { I2C_DIRECTION_READ, @@ -169,9 +168,11 @@ i2c_data_send(void) device.tx_buffer += i; } -static void +static bool i2c_isr(void) { + bool handled = false; + if (read(QUARKX1000_IC_INTR_STAT) & QUARKX1000_IC_INTR_STAT_STOP_DET_MASK) { i2c_data_read(); @@ -185,6 +186,8 @@ i2c_isr(void) if (device.config.cb_rx) device.config.cb_rx(); } + + handled = true; } if (read(QUARKX1000_IC_INTR_STAT) & QUARKX1000_IC_INTR_STAT_TX_EMPTY_MASK) { @@ -195,11 +198,16 @@ i2c_isr(void) set_value(QUARKX1000_IC_INTR_MASK, QUARKX1000_IC_INTR_STAT_STOP_DET_MASK, QUARKX1000_IC_INTR_STAT_STOP_DET_SHIFT, 1); } + + handled = true; } - if (read(QUARKX1000_IC_INTR_STAT) & QUARKX1000_IC_INTR_STAT_RX_FULL_MASK) + if(read(QUARKX1000_IC_INTR_STAT) & QUARKX1000_IC_INTR_STAT_RX_FULL_MASK) { i2c_data_read(); + handled = true; + } + if (read(QUARKX1000_IC_INTR_STAT) & (QUARKX1000_IC_INTR_STAT_TX_ABRT_MASK | QUARKX1000_IC_INTR_STAT_TX_OVER_MASK | QUARKX1000_IC_INTR_STAT_RX_OVER_MASK | QUARKX1000_IC_INTR_STAT_RX_UNDER_MASK)) { @@ -208,7 +216,11 @@ i2c_isr(void) if (device.config.cb_err) device.config.cb_err(); + + handled = true; } + + return handled; } int @@ -480,13 +492,7 @@ quarkX1000_i2c_is_available(void) return device.pci.mmio ? 1 : 0; } -static void -i2c_handler() -{ - i2c_isr(); - - pic_eoi(I2C_IRQ); -} +DEFINE_SHARED_IRQ(I2C_IRQ, IRQAGENT3, INTC, PIRQC, i2c_isr); int quarkX1000_i2c_init(void) @@ -501,16 +507,7 @@ quarkX1000_i2c_init(void) pci_command_enable(pci_addr, PCI_CMD_1_MEM_SPACE_EN); - SET_INTERRUPT_HANDLER(I2C_INT, 0, i2c_handler); - - if (pci_irq_agent_set_pirq(IRQAGENT3, INTC, PIRQC) < 0) - return -1; - - pci_pirq_set_irq(PIRQC, I2C_IRQ, 1); - pci_init(&device.pci, pci_addr, 0); - pic_unmask_irq(I2C_IRQ); - return 0; } diff --git a/cpu/x86/init/common/interrupt.h b/cpu/x86/init/common/interrupt.h index 2ab228c72..601695bde 100644 --- a/cpu/x86/init/common/interrupt.h +++ b/cpu/x86/init/common/interrupt.h @@ -48,6 +48,19 @@ struct interrupt_context { uint32_t eip; }; +#define ISR_STUB(label_str, has_error_code, handler_str) \ + "jmp 2f\n\t" \ + ".align 4\n\t" \ + label_str ":\n\t" \ + " pushal\n\t" \ + " call " handler_str "\n\t" \ + " popal\n\t" \ + " .if " #has_error_code "\n\t" \ + " add $4, %%esp\n\t" \ + " .endif\n\t" \ + " iret\n\t" \ + "2:\n\t" + /* Helper macro to register interrupt handler function. * * num: Interrupt number (0-255) @@ -75,17 +88,7 @@ struct interrupt_context { "push %0\n\t" \ "call %P1\n\t" \ "add $8, %%esp\n\t" \ - "jmp 2f\n\t" \ - ".align 4\n\t" \ - "1:\n\t" \ - " pushal\n\t" \ - " call %P2\n\t" \ - " popal\n\t" \ - " .if " #has_error_code "\n\t" \ - " add $4, %%esp\n\t" \ - " .endif\n\t" \ - " iret\n\t" \ - "2:\n\t" \ + ISR_STUB("1", has_error_code, "%P2") \ :: "g" (num), "i" (idt_set_intr_gate_desc), "i" (handler) \ : "eax", "ecx", "edx" \ ); \ diff --git a/cpu/x86/quarkX1000.ld b/cpu/x86/quarkX1000.ld index b50c47bb8..ba437d540 100644 --- a/cpu/x86/quarkX1000.ld +++ b/cpu/x86/quarkX1000.ld @@ -61,6 +61,10 @@ SECTIONS { .rodata ALIGN (32) : { *(.rodata*) + + _sdata_shared_isr = .; + KEEP(*(.shared_isr_data*)) + _edata_shared_isr = .; } .data ALIGN (32) : diff --git a/platform/galileo/contiki-main.c b/platform/galileo/contiki-main.c index 943ac3174..bb6d0c5cb 100644 --- a/platform/galileo/contiki-main.c +++ b/platform/galileo/contiki-main.c @@ -33,9 +33,10 @@ #include "contiki.h" #include "contiki-net.h" #include "cpu.h" -#include "interrupt.h" -#include "uart.h" #include "eth-conf.h" +#include "interrupt.h" +#include "shared-isr.h" +#include "uart.h" PROCINIT( &etimer_process , &tcpip_process @@ -64,6 +65,8 @@ main(void) eth_init(); + shared_isr_init(); + while(1) { process_run(); } From c9bffe6d5a7780f339ca76617502318d85c54eaa Mon Sep 17 00:00:00 2001 From: Michael LeMay Date: Wed, 6 Jan 2016 17:17:25 -0800 Subject: [PATCH 030/374] galileo: Convert README for examples into README.md This patch renames and reformats examples/galileo/README to use Markdown. --- examples/galileo/{README => README.md} | 33 ++++++++++++-------------- 1 file changed, 15 insertions(+), 18 deletions(-) rename examples/galileo/{README => README.md} (90%) diff --git a/examples/galileo/README b/examples/galileo/README.md similarity index 90% rename from examples/galileo/README rename to examples/galileo/README.md index 643a2e418..4222ea076 100644 --- a/examples/galileo/README +++ b/examples/galileo/README.md @@ -1,5 +1,5 @@ Galileo Specific Examples -======================= +========================= This directory contains galileo-specific example applications to illustrate how to use galileo APIs. @@ -7,14 +7,15 @@ how to use galileo APIs. In order to build a application, you should set the EXAMPLE environment variable to the name of the application you want to build. For instance, if you want to build gpio-output application, run the following command: + +``` $ make TARGET=galileo EXAMPLE=gpio-output +``` -============ -= GPIO = -============ +GPIO +---- -GPIO Output -=========== +### GPIO Output This application shows how to use the GPIO driver APIs to manipulate output pins. This application sets the GPIO 4 pin as output pin and toggles its @@ -23,16 +24,14 @@ state at every half second. For a visual effect, you should wire shield pin IO1 to a led in a protoboard. Once the application is running, you should see a blinking LED. -GPIO Input -========== +### GPIO Input This application shows how to use the GPIO driver APIs to manipulate input pins. This application uses default galileo pinmux initialization and sets the GPIO 5 (IO2) as output pin and GPIO 6 (IO3) as input. It toggles the output pin state at every half second and checks the value on input pin. -GPIO Interrupt -============== +### GPIO Interrupt This application shows how to use the GPIO driver APIs to manipulate interrupt pins. This application uses default galileo pinmux initialization and sets @@ -41,12 +40,11 @@ output pin stat at every half second in order to emulate an interrupt. This triggers an interrupt and the application callback is called. You can confirm that though the UART output. -======= -= I2C = -======= +I2C +--- + +### I2C LSM9DS0 -I2C LSM9DS0 -=========== This application shows how to use I2C driver APIs to configure I2C Master controller and communicate with LSM9DS0 sensor. At every 5 seconds, the application reads the "who am I" register from gyroscope sensor and prints if @@ -65,9 +63,8 @@ The wiring setup is as follows (left column from Galileo and right column from L - SDA and SDA - SCL and SCL -============== -= References = -============== +References +---------- [1] http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00087365.pdf From 3e644476319d131782d0112905bc889d164d3af0 Mon Sep 17 00:00:00 2001 From: Michael LeMay Date: Wed, 6 Jan 2016 17:21:36 -0800 Subject: [PATCH 031/374] galileo: Expand README for examples This patch expands the instructions in examples/galileo/README.md. --- examples/galileo/README.md | 44 ++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/examples/galileo/README.md b/examples/galileo/README.md index 4222ea076..ce4cb03a9 100644 --- a/examples/galileo/README.md +++ b/examples/galileo/README.md @@ -12,10 +12,13 @@ you want to build gpio-output application, run the following command: $ make TARGET=galileo EXAMPLE=gpio-output ``` +The corresponding EXAMPLE variable setting for each application is +listed to the right of its heading. + GPIO ---- -### GPIO Output +### GPIO Output (EXAMPLE=gpio-output) This application shows how to use the GPIO driver APIs to manipulate output pins. This application sets the GPIO 4 pin as output pin and toggles its @@ -24,31 +27,36 @@ state at every half second. For a visual effect, you should wire shield pin IO1 to a led in a protoboard. Once the application is running, you should see a blinking LED. -### GPIO Input +### GPIO Input (EXAMPLE=gpio-input) -This application shows how to use the GPIO driver APIs to manipulate input -pins. This application uses default galileo pinmux initialization and sets -the GPIO 5 (IO2) as output pin and GPIO 6 (IO3) as input. It toggles the -output pin state at every half second and checks the value on input pin. +This application shows how to use the GPIO driver APIs to manipulate +input pins. This application uses default galileo pinmux +initialization and sets the GPIO 5 (shield pin IO2) as output pin and +GPIO 6 (shield pin IO3) as input. A jumper should be used to connect +the two pins. The application toggles the output pin state at every +half second and checks the value on input pin. -### GPIO Interrupt +### GPIO Interrupt (EXAMPLE=gpio-interrupt) -This application shows how to use the GPIO driver APIs to manipulate interrupt -pins. This application uses default galileo pinmux initialization and sets -the GPIO 5 (IO2) as output pin and GPIO 6 (IO3) as interrupt. It toggles the -output pin stat at every half second in order to emulate an interrupt. This -triggers an interrupt and the application callback is called. You can confirm -that though the UART output. +This application shows how to use the GPIO driver APIs to manipulate +interrupt pins. This application uses default galileo pinmux +initialization and sets the GPIO 5 (shield pin IO2) as output pin and +GPIO 6 (shield pin IO3) as interrupt. A jumper should be used to +connect the two pins. It toggles the output pin stat at every half +second in order to emulate an interrupt. This triggers an interrupt +and the application callback is called. You can confirm that though +the UART output. I2C --- -### I2C LSM9DS0 +### I2C LSM9DS0 (EXAMPLE=i2c-LSM9DS0) -This application shows how to use I2C driver APIs to configure I2C Master -controller and communicate with LSM9DS0 sensor. At every 5 seconds, the -application reads the "who am I" register from gyroscope sensor and prints if -the register value matches the expected value described in the spec [1]. +This application shows how to use I2C driver APIs to configure I2C +Master controller and communicate with an LSM9DS0 sensor if one has +been connected as described below. At every 5 seconds, the application +reads the "who am I" register from gyroscope sensor and prints if the +register value matches the expected value described in the spec [1]. According to the sensor spec, to read the value in "who am I" register, we should first perform an i2c write operation to select the register we want From 58874ea25df3f5328a4429348a13b2451f9435de Mon Sep 17 00:00:00 2001 From: Michael LeMay Date: Tue, 5 Jan 2016 23:05:09 -0800 Subject: [PATCH 032/374] x86, galileo: Refactor I2C and GPIO initialization This patch revises the I2C and GPIO initialization code to always be run during platform boot rather than within each process that requires it. This patch also revises the gpio-output example to use a pin that is set as an output by the default pinmux configuration. Previously, it used a pin that was set as an output by the pinmux configuration that is in effect when the OS does not change the pinmux configuration. --- cpu/x86/drivers/quarkX1000/i2c.c | 31 +++++++++++++++++------ cpu/x86/drivers/quarkX1000/i2c.h | 17 +++++-------- examples/galileo/README.md | 4 +-- examples/galileo/gpio-input.c | 15 +---------- examples/galileo/gpio-interrupt.c | 15 +---------- examples/galileo/gpio-output.c | 5 ++-- examples/galileo/i2c-LSM9DS0.c | 18 ++----------- platform/galileo/README.md | 3 +++ platform/galileo/contiki-main.c | 14 +++++++++- platform/galileo/drivers/galileo-pinmux.c | 2 +- 10 files changed, 54 insertions(+), 70 deletions(-) diff --git a/cpu/x86/drivers/quarkX1000/i2c.c b/cpu/x86/drivers/quarkX1000/i2c.c index b16a79205..4e5669079 100644 --- a/cpu/x86/drivers/quarkX1000/i2c.c +++ b/cpu/x86/drivers/quarkX1000/i2c.c @@ -54,6 +54,15 @@ typedef enum { I2C_DIRECTION_WRITE } I2C_DIRECTION; +struct quarkX1000_i2c_config { + QUARKX1000_I2C_SPEED speed; + QUARKX1000_I2C_ADDR_MODE addressing_mode; + + quarkX1000_i2c_callback cb_rx; + quarkX1000_i2c_callback cb_tx; + quarkX1000_i2c_callback cb_err; +}; + struct i2c_internal_data { struct quarkX1000_i2c_config config; @@ -223,17 +232,15 @@ i2c_isr(void) return handled; } -int -quarkX1000_i2c_configure(struct quarkX1000_i2c_config *config) +void +quarkX1000_i2c_configure(QUARKX1000_I2C_SPEED speed, + QUARKX1000_I2C_ADDR_MODE addressing_mode) { uint32_t hcnt, lcnt; uint8_t ic_fs_spklen; - device.config.speed = config->speed; - device.config.addressing_mode = config->addressing_mode; - device.config.cb_rx = config->cb_rx; - device.config.cb_tx = config->cb_tx; - device.config.cb_err = config->cb_err; + device.config.speed = speed; + device.config.addressing_mode = addressing_mode; if (device.config.speed == QUARKX1000_I2C_SPEED_STANDARD) { lcnt = I2C_STD_LCNT; @@ -252,8 +259,16 @@ quarkX1000_i2c_configure(struct quarkX1000_i2c_config *config) /* Clear interrupts. */ read(QUARKX1000_IC_CLR_INTR); +} - return 0; +void +quarkX1000_i2c_set_callbacks(quarkX1000_i2c_callback rx, + quarkX1000_i2c_callback tx, + quarkX1000_i2c_callback err) +{ + device.config.cb_rx = rx; + device.config.cb_tx = tx; + device.config.cb_err = err; } static int diff --git a/cpu/x86/drivers/quarkX1000/i2c.h b/cpu/x86/drivers/quarkX1000/i2c.h index b5292524f..ed2db18fb 100644 --- a/cpu/x86/drivers/quarkX1000/i2c.h +++ b/cpu/x86/drivers/quarkX1000/i2c.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015, Intel Corporation. All rights reserved. + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -45,17 +45,12 @@ typedef enum { typedef void (*quarkX1000_i2c_callback)(void); -struct quarkX1000_i2c_config { - QUARKX1000_I2C_SPEED speed; - QUARKX1000_I2C_ADDR_MODE addressing_mode; - - quarkX1000_i2c_callback cb_rx; - quarkX1000_i2c_callback cb_tx; - quarkX1000_i2c_callback cb_err; -}; - int quarkX1000_i2c_init(void); -int quarkX1000_i2c_configure(struct quarkX1000_i2c_config *config); +void quarkX1000_i2c_configure(QUARKX1000_I2C_SPEED speed, + QUARKX1000_I2C_ADDR_MODE addressing_mode); +void quarkX1000_i2c_set_callbacks(quarkX1000_i2c_callback rx, + quarkX1000_i2c_callback tx, + quarkX1000_i2c_callback err); int quarkX1000_i2c_is_available(void); int quarkX1000_i2c_read(uint8_t *buf, uint8_t len, uint16_t addr); diff --git a/examples/galileo/README.md b/examples/galileo/README.md index ce4cb03a9..61e8ea713 100644 --- a/examples/galileo/README.md +++ b/examples/galileo/README.md @@ -21,10 +21,10 @@ GPIO ### GPIO Output (EXAMPLE=gpio-output) This application shows how to use the GPIO driver APIs to manipulate output -pins. This application sets the GPIO 4 pin as output pin and toggles its +pins. This application sets the GPIO 5 pin as output pin and toggles its state at every half second. -For a visual effect, you should wire shield pin IO1 to a led in a protoboard. +For a visual effect, you should wire shield pin IO2 to a led in a protoboard. Once the application is running, you should see a blinking LED. ### GPIO Input (EXAMPLE=gpio-input) diff --git a/examples/galileo/gpio-input.c b/examples/galileo/gpio-input.c index 8728d5088..196ea9193 100644 --- a/examples/galileo/gpio-input.c +++ b/examples/galileo/gpio-input.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015, Intel Corporation. All rights reserved. + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,16 +33,13 @@ #include "contiki.h" #include "sys/ctimer.h" -#include "galileo-pinmux.h" #include "gpio.h" -#include "i2c.h" #define PIN_OUTPUT 5 #define PIN_INPUT 6 static uint32_t value; static struct ctimer timer; -static struct quarkX1000_i2c_config i2c_config; PROCESS(gpio_input_process, "GPIO Input Process"); AUTOSTART_PROCESSES(&gpio_input_process); @@ -70,16 +67,6 @@ PROCESS_THREAD(gpio_input_process, ev, data) { PROCESS_BEGIN(); - i2c_config.speed = QUARKX1000_I2C_SPEED_STANDARD; - i2c_config.addressing_mode = QUARKX1000_I2C_ADDR_MODE_7BIT; - - quarkX1000_i2c_init(); - quarkX1000_i2c_configure(&i2c_config); - - /* use default pinmux configuration */ - galileo_pinmux_initialize(); - - quarkX1000_gpio_init(); quarkX1000_gpio_config(PIN_OUTPUT, QUARKX1000_GPIO_OUT); quarkX1000_gpio_config(PIN_INPUT, QUARKX1000_GPIO_IN); diff --git a/examples/galileo/gpio-interrupt.c b/examples/galileo/gpio-interrupt.c index 149279f6f..04fb4cc1b 100644 --- a/examples/galileo/gpio-interrupt.c +++ b/examples/galileo/gpio-interrupt.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015, Intel Corporation. All rights reserved. + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -34,14 +34,11 @@ #include "sys/ctimer.h" #include "gpio.h" -#include "i2c.h" -#include "galileo-pinmux.h" #define PIN_OUTPUT 5 #define PIN_INTR 6 static struct ctimer timer; -static struct quarkX1000_i2c_config i2c_config; PROCESS(gpio_interrupt_process, "GPIO Interrupt Process"); AUTOSTART_PROCESSES(&gpio_interrupt_process); @@ -66,16 +63,6 @@ PROCESS_THREAD(gpio_interrupt_process, ev, data) { PROCESS_BEGIN(); - i2c_config.speed = QUARKX1000_I2C_SPEED_STANDARD; - i2c_config.addressing_mode = QUARKX1000_I2C_ADDR_MODE_7BIT; - - quarkX1000_i2c_init(); - quarkX1000_i2c_configure(&i2c_config); - - /* use default pinmux configuration */ - galileo_pinmux_initialize(); - - quarkX1000_gpio_init(); quarkX1000_gpio_config(PIN_OUTPUT, QUARKX1000_GPIO_OUT); quarkX1000_gpio_config(PIN_INTR, QUARKX1000_GPIO_INT | QUARKX1000_GPIO_ACTIVE_HIGH | QUARKX1000_GPIO_EDGE); diff --git a/examples/galileo/gpio-output.c b/examples/galileo/gpio-output.c index 39a92516f..4dad7d684 100644 --- a/examples/galileo/gpio-output.c +++ b/examples/galileo/gpio-output.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015, Intel Corporation. All rights reserved. + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,7 +35,7 @@ #include "gpio.h" -#define PIN 4 /* IO1 */ +#define PIN 5 /* IO2 */ static uint32_t value; static struct ctimer timer; @@ -57,7 +57,6 @@ PROCESS_THREAD(gpio_output_process, ev, data) { PROCESS_BEGIN(); - quarkX1000_gpio_init(); quarkX1000_gpio_config(PIN, QUARKX1000_GPIO_OUT); quarkX1000_gpio_clock_enable(); diff --git a/examples/galileo/i2c-LSM9DS0.c b/examples/galileo/i2c-LSM9DS0.c index e5a47c458..03d61a2a4 100644 --- a/examples/galileo/i2c-LSM9DS0.c +++ b/examples/galileo/i2c-LSM9DS0.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015, Intel Corporation. All rights reserved. + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -34,7 +34,6 @@ #include "contiki.h" #include "sys/ctimer.h" -#include "galileo-pinmux.h" #include "i2c.h" #define LSM9DS0_I2C_ADDR 0x6A @@ -44,7 +43,6 @@ static uint8_t tx_data = WHO_AM_I_ADDR; static uint8_t rx_data = 0; static struct ctimer timer; -static struct quarkX1000_i2c_config cfg; PROCESS(i2c_lsm9ds0_process, "I2C LSM9DS0 Who Am I Process"); AUTOSTART_PROCESSES(&i2c_lsm9ds0_process); @@ -84,19 +82,7 @@ PROCESS_THREAD(i2c_lsm9ds0_process, ev, data) { PROCESS_BEGIN(); - cfg.speed = QUARKX1000_I2C_SPEED_STANDARD; - cfg.addressing_mode = QUARKX1000_I2C_ADDR_MODE_7BIT; - - quarkX1000_i2c_init(); - quarkX1000_i2c_configure(&cfg); - - galileo_pinmux_initialize(); - - cfg.cb_rx = rx; - cfg.cb_tx = tx; - cfg.cb_err = err; - - quarkX1000_i2c_configure(&cfg); + quarkX1000_i2c_set_callbacks(rx, tx, err); ctimer_set(&timer, CLOCK_SECOND * 5, timeout, NULL); diff --git a/platform/galileo/README.md b/platform/galileo/README.md index b99ad7d65..815b09011 100644 --- a/platform/galileo/README.md +++ b/platform/galileo/README.md @@ -30,6 +30,9 @@ Device drivers: * Real-Time Clock (RTC) * UART * Ethernet + * I2C + * GPIO (default pinmux configuration is listed in + platform/galileo/drivers/galileo-pinmux.c) Contiki APIs: * Clock module diff --git a/platform/galileo/contiki-main.c b/platform/galileo/contiki-main.c index bb6d0c5cb..141ad2a51 100644 --- a/platform/galileo/contiki-main.c +++ b/platform/galileo/contiki-main.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015, Intel Corporation. All rights reserved. + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -34,6 +34,9 @@ #include "contiki-net.h" #include "cpu.h" #include "eth-conf.h" +#include "galileo-pinmux.h" +#include "gpio.h" +#include "i2c.h" #include "interrupt.h" #include "shared-isr.h" #include "uart.h" @@ -56,6 +59,15 @@ main(void) printf("Starting Contiki\n"); + quarkX1000_i2c_init(); + quarkX1000_i2c_configure(QUARKX1000_I2C_SPEED_STANDARD, + QUARKX1000_I2C_ADDR_MODE_7BIT); + /* use default pinmux configuration */ + if(galileo_pinmux_initialize() < 0) { + fprintf(stderr, "Failed to initialize pinmux\n"); + } + quarkX1000_gpio_init(); + ENABLE_IRQ(); process_init(); diff --git a/platform/galileo/drivers/galileo-pinmux.c b/platform/galileo/drivers/galileo-pinmux.c index c66036ea2..3059bdb36 100644 --- a/platform/galileo/drivers/galileo-pinmux.c +++ b/platform/galileo/drivers/galileo-pinmux.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015, Intel Corporation. All rights reserved. + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions From b82d92e3736b5635da0536deab628935bae9cecb Mon Sep 17 00:00:00 2001 From: Michael LeMay Date: Wed, 6 Jan 2016 17:25:55 -0800 Subject: [PATCH 033/374] galileo: Add I2C callbacks example This patch adds an example for I2C callbacks that is very similar to the i2c-LSM9DS0 example except that it uses a PWM device that is built into the platform. --- examples/galileo/Makefile | 2 +- examples/galileo/README.md | 12 +++++ examples/galileo/i2c-callbacks.c | 93 ++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 examples/galileo/i2c-callbacks.c diff --git a/examples/galileo/Makefile b/examples/galileo/Makefile index 19a29f78a..2954adc38 100644 --- a/examples/galileo/Makefile +++ b/examples/galileo/Makefile @@ -1,6 +1,6 @@ TARGET=galileo -KNOWN_EXAMPLES = gpio-input gpio-output gpio-interrupt i2c-LSM9DS0 +KNOWN_EXAMPLES = gpio-input gpio-output gpio-interrupt i2c-LSM9DS0 i2c-callbacks ifneq ($(filter $(EXAMPLE),$(KNOWN_EXAMPLES)),) CONTIKI_PROJECT = $(EXAMPLE) diff --git a/examples/galileo/README.md b/examples/galileo/README.md index 61e8ea713..b725ec867 100644 --- a/examples/galileo/README.md +++ b/examples/galileo/README.md @@ -71,6 +71,18 @@ The wiring setup is as follows (left column from Galileo and right column from L - SDA and SDA - SCL and SCL +### I2C Callbacks (EXAMPLE=i2c-callbacks) + +This application is very similar to the previous one in that it also +shows how to use I2C callback functionality, but it can be run without +attaching any additional sensors to the platform since it simply +communicates with a built-in PWM controller. + +Every five seconds, the application reads the current value of the +MODE1 register, which should have previously been initialized to the +value 0x20. The test verifies that this expected value is returned by +the read. + References ---------- diff --git a/examples/galileo/i2c-callbacks.c b/examples/galileo/i2c-callbacks.c new file mode 100644 index 000000000..d97c6b448 --- /dev/null +++ b/examples/galileo/i2c-callbacks.c @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +#include +#include + +#include "contiki.h" +#include "sys/ctimer.h" + +#include "i2c.h" + +#define PWM_PCA9685_0_I2C_ADDR 0x47 +#define MODE1_ADDR 0x00 + +static uint8_t tx_data = MODE1_ADDR; +static uint8_t rx_data = 0; +static struct ctimer timer; + +PROCESS(i2c_callbacks_process, "I2C Callbacks Example Process"); +AUTOSTART_PROCESSES(&i2c_callbacks_process); +/*---------------------------------------------------------------------------*/ +static void +rx(void) +{ + /* The value below is programmed into this register in pwm_pca9685_init(). */ + printf("%s expected value: %x\n", + (rx_data == (1 << 5)) ? "Received" : "Did not receive", + (unsigned)rx_data); +} +/*---------------------------------------------------------------------------*/ +static void +tx(void) +{ + rx_data = 0; + + quarkX1000_i2c_read(&rx_data, sizeof(rx_data), PWM_PCA9685_0_I2C_ADDR); +} +/*---------------------------------------------------------------------------*/ +static void +err(void) +{ + printf("Something went wrong. err() callback has been called.\n"); +} +/*---------------------------------------------------------------------------*/ +static void +timeout(void *data) +{ + quarkX1000_i2c_write(&tx_data, sizeof(tx_data), PWM_PCA9685_0_I2C_ADDR); + + ctimer_reset(&timer); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(i2c_callbacks_process, ev, data) +{ + PROCESS_BEGIN(); + + quarkX1000_i2c_set_callbacks(rx, tx, err); + + ctimer_set(&timer, CLOCK_SECOND * 5, timeout, NULL); + + printf("I2C callbacks example is running\n"); + + PROCESS_YIELD(); + + PROCESS_END(); +} From 1f445172ff06e30c8c0f82022817dd94417e6ec4 Mon Sep 17 00:00:00 2001 From: Michael LeMay Date: Wed, 6 Jan 2016 20:55:21 -0800 Subject: [PATCH 034/374] galileo: Fix build help message in examples This patch fixes examples/galileo/Makefile so that it actually displays the intended help message when an unrecognized EXAMPLE is selected. --- examples/galileo/Makefile | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/examples/galileo/Makefile b/examples/galileo/Makefile index 2954adc38..f925f565a 100644 --- a/examples/galileo/Makefile +++ b/examples/galileo/Makefile @@ -2,17 +2,15 @@ TARGET=galileo KNOWN_EXAMPLES = gpio-input gpio-output gpio-interrupt i2c-LSM9DS0 i2c-callbacks -ifneq ($(filter $(EXAMPLE),$(KNOWN_EXAMPLES)),) - CONTIKI_PROJECT = $(EXAMPLE) -else - CONTIKI_PROJECT = help +ifeq ($(filter $(EXAMPLE),$(KNOWN_EXAMPLES)),) + $(info Set the variable EXAMPLE to one of the following Galileo-specific examples:) + $(foreach EXAMPLE,$(KNOWN_EXAMPLES),$(info - $(EXAMPLE))) + $(error Unable to proceed) endif +CONTIKI_PROJECT = $(EXAMPLE) + all: $(CONTIKI_PROJECT) CONTIKI = ../.. include $(CONTIKI)/Makefile.include - -help: - @echo -e "\nSet the variable EXAMPLE to one of the following Galileo-specific examples:" - @for EXAMPLE in $(KNOWN_EXAMPLES); do echo $$EXAMPLE; done From 151f532225d4ccf1d5618d2112b2b6555d5d144a Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Mon, 22 Feb 2016 10:34:48 +0100 Subject: [PATCH 035/374] Adapted the TMP102 sensor to Contiki's sensor API --- examples/zolertia/z1/test-tmp102.c | 11 +-- platform/z1/dev/tmp102.c | 137 +++++++++++++++-------------- platform/z1/dev/tmp102.h | 65 ++++---------- 3 files changed, 95 insertions(+), 118 deletions(-) diff --git a/examples/zolertia/z1/test-tmp102.c b/examples/zolertia/z1/test-tmp102.c index 5d8be7a08..ab5e7aca8 100644 --- a/examples/zolertia/z1/test-tmp102.c +++ b/examples/zolertia/z1/test-tmp102.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Zolertia(TM) is a trademark of Advancare,SL + * Copyright (c) 2010-2016, Zolertia * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,9 +32,10 @@ /*---------------------------------------------------------------------------*/ /** * \file - * A quick program for testing the tmp102 driver in the Z1 platform + * A quick program for testing the tmp102 sensor in the Z1 platform * \author * Enric M. Calvo + * Antonio Lignan */ /*---------------------------------------------------------------------------*/ #include @@ -44,7 +45,7 @@ /*---------------------------------------------------------------------------*/ #define TMP102_READ_INTERVAL (CLOCK_SECOND / 2) /*---------------------------------------------------------------------------*/ -PROCESS(temp_process, "Test Temperature process"); +PROCESS(temp_process, "TMP102 Temperature sensor process"); AUTOSTART_PROCESSES(&temp_process); /*---------------------------------------------------------------------------*/ static struct etimer et; @@ -55,12 +56,12 @@ PROCESS_THREAD(temp_process, ev, data) int16_t temp; - tmp102_init(); + SENSORS_ACTIVATE(tmp102); while(1) { etimer_set(&et, TMP102_READ_INTERVAL); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - temp = tmp102_read_temp_x100(); + temp = tmp102.value(TMP102_READ); printf("Temp = %d\n", temp); } PROCESS_END(); diff --git a/platform/z1/dev/tmp102.c b/platform/z1/dev/tmp102.c index cc9394b7b..4bf267246 100644 --- a/platform/z1/dev/tmp102.c +++ b/platform/z1/dev/tmp102.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2010, Swedish Institute of Computer Science. + * Copyright (c) 2016, Zolertia * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,65 +30,55 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** * \file * Device drivers for tmp102 temperature sensor in Zolertia Z1. * \author * Enric M. Calvo, Zolertia * Marcus Lundén, SICS + * Antonio Lignan, Zolertia */ - +/*---------------------------------------------------------------------------*/ #include #include "contiki.h" #include "i2cmaster.h" #include "tmp102.h" - -/* Bitmasks and bit flag variable for keeping track of tmp102 status. */ -enum TMP102_STATUSTYPES { - /* must be a bit and not more, not using 0x00. */ - INITED = 0x01, - RUNNING = 0x02, - STOPPED = 0x04, - LOW_POWER = 0x08, - AAA = 0x10, /* available to extend this... */ - BBB = 0x20, /* available to extend this... */ - CCC = 0x40, /* available to extend this... */ - DDD = 0x80 /* available to extend this... */ -}; -static enum TMP102_STATUSTYPES _TMP102_STATUS = 0x00; - +#include "lib/sensors.h" /*---------------------------------------------------------------------------*/ -/* PROCESS(tmp102_process, "Temperature Sensor process"); */ - +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; /*---------------------------------------------------------------------------*/ -/* Init the temperature sensor: ports, pins, registers, interrupts (none enabled), I2C, - default threshold values etc. */ - void tmp102_init(void) { - if(!(_TMP102_STATUS & INITED)) { - PRINTFDEBUG("TMP102 init\n"); - _TMP102_STATUS |= INITED; - /* Power Up TMP102 via pin */ - TMP102_PWR_DIR |= TMP102_PWR_PIN; - TMP102_PWR_SEL &= ~TMP102_PWR_SEL; - TMP102_PWR_SEL2 &= ~TMP102_PWR_SEL; - TMP102_PWR_REN &= ~TMP102_PWR_SEL; - TMP102_PWR_OUT |= TMP102_PWR_PIN; + /* Power Up TMP102 via pin */ + TMP102_PWR_DIR |= TMP102_PWR_PIN; + TMP102_PWR_SEL &= ~TMP102_PWR_SEL; + TMP102_PWR_SEL2 &= ~TMP102_PWR_SEL; + TMP102_PWR_REN &= ~TMP102_PWR_SEL; + TMP102_PWR_OUT |= TMP102_PWR_PIN; - /* Set up ports and pins for I2C communication */ - i2c_enable(); - } + /* Set up ports and pins for I2C communication */ + i2c_enable(); + + enabled = 1; +} +/*---------------------------------------------------------------------------*/ +void +tmp102_stop(void) +{ + /* Power off */ + TMP102_PWR_OUT &= ~TMP102_PWR_PIN; + enabled = 0; } /*---------------------------------------------------------------------------*/ -/* Write to a 16-bit register. - args: - reg register to write to - val value to write - */ - void tmp102_write_reg(uint8_t reg, uint16_t val) { @@ -98,26 +89,20 @@ tmp102_write_reg(uint8_t reg, uint16_t val) i2c_transmitinit(TMP102_ADDR); while(i2c_busy()); - PRINTFDEBUG("I2C Ready to TX\n"); + PRINTF("I2C Ready to TX\n"); i2c_transmit_n(3, tx_buf); while(i2c_busy()); - PRINTFDEBUG("WRITE_REG 0x%04X @ reg 0x%02X\n", val, reg); + PRINTF("WRITE_REG 0x%04X @ reg 0x%02X\n", val, reg); } /*---------------------------------------------------------------------------*/ -/* Read register. - args: - reg what register to read - returns the value of the read register type uint16_t - */ - uint16_t tmp102_read_reg(uint8_t reg) { uint8_t buf[] = { 0x00, 0x00 }; uint16_t retVal = 0; uint8_t rtx = reg; - PRINTFDEBUG("READ_REG 0x%02X\n", reg); + PRINTF("READ_REG 0x%02X\n", reg); /* transmit the register to read */ i2c_transmitinit(TMP102_ADDR); @@ -136,19 +121,14 @@ tmp102_read_reg(uint8_t reg) return retVal; } /*---------------------------------------------------------------------------*/ -/* Read temperature in a raw format. Further processing will be needed - to make an interpretation of these 12 or 13-bit data, depending on configuration - */ - uint16_t tmp102_read_temp_raw(void) { uint16_t rd = 0; - rd = tmp102_read_reg(TMP102_TEMP); - return rd; } +/*---------------------------------------------------------------------------*/ int16_t tmp102_read_temp_x100(void) { @@ -167,24 +147,47 @@ tmp102_read_temp_x100(void) /* Integer part of the temperature value and percents*/ temp_int = (abstemp >> 8) * sign * 100; temp_int += ((abstemp & 0xff) * 100) / 0x100; - - /* See test-tmp102.c on how to print values of temperature with decimals - fractional part in 1/10000 of degree - temp_frac = ((abstemp >>4) % 16) * 625; - Data could be multiplied by 63 to have less bit-growth and 1/1000 precision - Data could be multiplied by 64 (<< 6) to trade-off precision for speed - */ - return temp_int; } /*---------------------------------------------------------------------------*/ -/* Simple Read temperature. Return is an integer with temperature in 1deg. precision - Return value is a signed 8 bit integer. - */ - int8_t tmp102_read_temp_simple(void) { /* Casted to int8_t: We don't expect temperatures outside -128 to 127 C */ return tmp102_read_temp_x100() / 100; } +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type != SENSORS_ACTIVE) { + return TMP102_ERROR; + } + if(value) { + tmp102_init(); + } else { + tmp102_stop(); + } + enabled = value; + return TMP102_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return TMP102_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + return (int)tmp102_read_temp_x100(); +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(tmp102, TMP102_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ diff --git a/platform/z1/dev/tmp102.h b/platform/z1/dev/tmp102.h index 777577747..cf7a71eb8 100644 --- a/platform/z1/dev/tmp102.h +++ b/platform/z1/dev/tmp102.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2010, Swedish Institute of Computer Science. + * Copyright (c) 2016, Zolertia * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,75 +33,47 @@ /** * \file - * Device drivers header file for tmp102 temperature sensor in Zolertia Z1 WSN Platform. + * Device drivers header file for tmp102 temperature sensor in Zolertia + * Z1 WSN Platform. * \author * Enric M. Calvo, Zolertia * Marcus Lundén, SICS + * Antonio Lignan, Zolertia */ - +/* -------------------------------------------------------------------------- */ #ifndef TMP102_H_ #define TMP102_H_ #include +#include "lib/sensors.h" #include "i2cmaster.h" - /* -------------------------------------------------------------------------- */ -/* Init the temperature sensor: ports, pins, I2C, interrupts (XXX none so far), -*/ -void tmp102_init(void); - -/* Write to a register. - args: - reg register to write to - val value to write -*/ -void tmp102_write_reg(uint8_t reg, uint16_t val); - -/* Read one register. - args: - reg what register to read - returns the value of the read register -*/ +void tmp102_init(void); +void tmp102_write_reg(uint8_t reg, uint16_t val); uint16_t tmp102_read_reg(uint8_t reg); - -/* Read temperature in raw format - no args needed -*/ uint16_t tmp102_read_temp_raw(); - -/* Read only integer part of the temperature in 1deg. precision. - no args needed -*/ int8_t tmp102_read_temp_simple(); - -/* Read only integer part of the temperature in 1deg. precision. - no args needed -*/ int16_t tmp102_read_temp_x100(); - /* -------------------------------------------------------------------------- */ -/* Reference definitions */ -/* TMP102 slave address */ #define TMP102_ADDR 0x48 - -/* TMP102 registers */ -#define TMP102_TEMP 0x00 // read only +#define TMP102_TEMP 0x00 #define TMP102_CONF 0x01 #define TMP102_TLOW 0x02 #define TMP102_THIGH 0x03 -/* TMP102 Ports */ -/* Accelerometer hardware ports, pins and registers on the msp430 µC */ +/* TMP102 pin-out */ #define TMP102_PWR_DIR P5DIR #define TMP102_PWR_SEL P5SEL #define TMP102_PWR_SEL2 P5SEL2 #define TMP102_PWR_REN P5REN #define TMP102_PWR_OUT P5OUT -#define TMP102_PWR_PIN (1<<0) // P5.0 -//#define TMP102_INT_PIN (1<<7) // P1.7 - - +#define TMP102_PWR_PIN (1<<0) /* P5.0 */ +/* -------------------------------------------------------------------------- */ +#define TMP102_SUCCESS 0 +#define TMP102_ERROR (-1) +#define TMP102_READ 0x01 +/* -------------------------------------------------------------------------- */ +#define TMP102_SENSOR "TMP102 sensor" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor tmp102; /* -------------------------------------------------------------------------- */ #endif /* ifndef TMP102_H_ */ - - - From 1be30d52dc5ee2d377dcfdfcb3e8bbd946c9aeac Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Mon, 22 Feb 2016 11:24:50 +0100 Subject: [PATCH 036/374] Removed unused blocks and made functions static --- examples/zolertia/z1/test-adxl345.c | 18 +- platform/z1/dev/adxl345.c | 240 ++++++++------------------ platform/z1/dev/adxl345.h | 259 +++++++++++----------------- 3 files changed, 182 insertions(+), 335 deletions(-) diff --git a/examples/zolertia/z1/test-adxl345.c b/examples/zolertia/z1/test-adxl345.c index 259c46fde..e33981f76 100644 --- a/examples/zolertia/z1/test-adxl345.c +++ b/examples/zolertia/z1/test-adxl345.c @@ -42,10 +42,7 @@ #include #include "contiki.h" -#include "serial-shell.h" -#include "shell-ps.h" -#include "shell-file.h" -#include "shell-text.h" +#include "dev/leds.h" #include "dev/adxl345.h" /*---------------------------------------------------------------------------*/ #define LED_INT_ONTIME (CLOCK_SECOND / 2) @@ -91,7 +88,7 @@ print_int(uint16_t reg) void accm_ff_cb(uint8_t reg) { - L_ON(LEDS_B); + leds_on(LEDS_BLUE); process_post(&led_process, led_off_event, NULL); printf("~~[%u] Freefall detected! (0x%02X) -- ", ((uint16_t)clock_time()) / 128, reg); @@ -105,11 +102,11 @@ accm_tap_cb(uint8_t reg) { process_post(&led_process, led_off_event, NULL); if(reg & ADXL345_INT_DOUBLETAP) { - L_ON(LEDS_G); + leds_on(LEDS_GREEN); printf("~~[%u] DoubleTap detected! (0x%02X) -- ", ((uint16_t)clock_time()) / 128, reg); } else { - L_ON(LEDS_R); + leds_on(LEDS_RED); printf("~~[%u] Tap detected! (0x%02X) -- ", ((uint16_t)clock_time()) / 128, reg); } @@ -122,7 +119,7 @@ PROCESS_THREAD(led_process, ev, data) { PROCESS_WAIT_EVENT_UNTIL(ev == led_off_event); etimer_set(&led_etimer, LED_INT_ONTIME); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&led_etimer)); - L_OFF(LEDS_R + LEDS_G + LEDS_B); + leds_off(LEDS_RED + LEDS_GREEN + LEDS_BLUE); } PROCESS_END(); } @@ -133,11 +130,6 @@ PROCESS_THREAD(accel_process, ev, data) { { int16_t x, y, z; - serial_shell_init(); - shell_ps_init(); - shell_file_init(); /* for printing out files */ - shell_text_init(); /* for binprint */ - /* Register the event used for lighting up an LED when interrupt strikes. */ led_off_event = process_alloc_event(); diff --git a/platform/z1/dev/adxl345.c b/platform/z1/dev/adxl345.c index df653d7f8..512881d59 100644 --- a/platform/z1/dev/adxl345.c +++ b/platform/z1/dev/adxl345.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2010, Swedish Institute of Computer Science. + * Copyright (c) 2016, Zolertia * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,59 +30,42 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** * \file * Device drivers for adxl345 accelerometer in Zolertia Z1. * \author * Marcus Lundén, SICS * Enric M. Calvo, Zolertia + * Antonio Lignan, Zolertia */ - - +/*---------------------------------------------------------------------------*/ #include #include "contiki.h" #include "adxl345.h" #include "cc2420.h" #include "i2cmaster.h" #include "isr_compat.h" - +/*---------------------------------------------------------------------------*/ /* Callback pointers when interrupt occurs */ void (*accm_int1_cb)(uint8_t reg); void (*accm_int2_cb)(uint8_t reg); - -process_event_t int1_event, int2_event; - +/*---------------------------------------------------------------------------*/ /* Bitmasks for the interrupts */ static uint16_t int1_mask = 0, int2_mask = 0; -/* Keep track of when the interrupt was last seen in order to reduce the amount - of interrupts. Kind of like button debouncing. This can't be per int-pin, as - there can be several very different int per pin (eg tap && freefall). */ -// XXX Not used now, only one global timer. -//static volatile clock_time_t ints_lasttime[] = {0, 0, 0, 0, 0, 0, 0, 0}; +/* Default values for adxl345 at startup. + * This will be sent to the adxl345 in a + * stream at init to set it up in a default state + */ -/* Bitmasks and bit flag variable for keeping track of adxl345 status. */ -enum ADXL345_STATUSTYPES { - /* must be a bit and not more, not using 0x00. */ - INITED = 0x01, - RUNNING = 0x02, - STOPPED = 0x04, - LOW_POWER = 0x08, - AAA = 0x10, // available to extend this... - BBB = 0x20, // available to extend this... - CCC = 0x40, // available to extend this... - DDD = 0x80, // available to extend this... -}; -static enum ADXL345_STATUSTYPES _ADXL345_STATUS = 0x00; - -/* Default values for adxl345 at startup. This will be sent to the adxl345 in a - stream at init to set it up in a default state */ static uint8_t adxl345_default_settings[] = { /* Note, as the two first two bulks are to be written in a stream, they contain - the register address as first byte in that section. */ - /* 0--14 are in one stream, start at ADXL345_THRESH_TAP */ - ADXL345_THRESH_TAP, // XXX NB Register address, not register value!! + * the register address as first byte in that section. + * 0--14 are in one stream, start at ADXL345_THRESH_TAP + */ + /* XXX NB Register address, not register value!! */ + ADXL345_THRESH_TAP, ADXL345_THRESH_TAP_DEFAULT, ADXL345_OFSX_DEFAULT, ADXL345_OFSY_DEFAULT, @@ -98,7 +82,8 @@ static uint8_t adxl345_default_settings[] = { ADXL345_TAP_AXES_DEFAULT, /* 15--19 start at ADXL345_BW_RATE */ - ADXL345_BW_RATE, // XXX NB Register address, not register value!! + /* XXX NB Register address, not register value!! */ + ADXL345_BW_RATE, ADXL345_BW_RATE_DEFAULT, ADXL345_POWER_CTL_DEFAULT, ADXL345_INT_ENABLE_DEFAULT, @@ -108,18 +93,10 @@ static uint8_t adxl345_default_settings[] = { ADXL345_DATA_FORMAT_DEFAULT, ADXL345_FIFO_CTL_DEFAULT }; - - /*---------------------------------------------------------------------------*/ PROCESS(accmeter_process, "Accelerometer process"); /*---------------------------------------------------------------------------*/ -/* Write to a register. - args: - reg register to write to - val value to write -*/ - -void +static void accm_write_reg(uint8_t reg, uint8_t val) { uint8_t tx_buf[] = {reg, val}; @@ -132,15 +109,10 @@ accm_write_reg(uint8_t reg, uint8_t val) { PRINTFDEBUG("WRITE_REG 0x%02X @ reg 0x%02X\n", val, reg); } /*---------------------------------------------------------------------------*/ -/* Write several registers from a stream. - args: - len number of bytes to read - data pointer to where the data is read from - - First byte in stream must be the register address to begin writing to. - The data is then written from second byte and increasing. */ - -void +/* First byte in stream must be the register address to begin writing to. + * The data is then written from second byte and increasing. + */ +static void accm_write_stream(uint8_t len, uint8_t *data) { i2c_transmitinit(ADXL345_ADDR); while (i2c_busy()); @@ -152,13 +124,7 @@ accm_write_stream(uint8_t len, uint8_t *data) { } /*---------------------------------------------------------------------------*/ -/* Read one register. - args: - reg what register to read - returns the value of the read register -*/ - -uint8_t +static uint8_t accm_read_reg(uint8_t reg) { uint8_t retVal = 0; uint8_t rtx = reg; @@ -178,16 +144,8 @@ accm_read_reg(uint8_t reg) { return retVal; } - /*---------------------------------------------------------------------------*/ -/* Read several registers in a stream. - args: - reg what register to start reading from - len number of bytes to read - whereto pointer to where the data is saved -*/ - -void +static void accm_read_stream(uint8_t reg, uint8_t len, uint8_t *whereto) { uint8_t rtx = reg; PRINTFDEBUG("READ_STR %u B from 0x%02X\n", len, reg); @@ -206,11 +164,12 @@ accm_read_stream(uint8_t reg, uint8_t len, uint8_t *whereto) { } /*---------------------------------------------------------------------------*/ -/* Read an axis of the accelerometer (x, y or z). Return value is a signed 10 bit int. - The resolution of the acceleration measurement can be increased up to 13 bit, but - will change the data format of this read out. Refer to the data sheet if so is - wanted/needed. */ - +/* Read an axis of the accelerometer (x, y or z). Return value is a signed + * 10 bit int. + * The resolution of the acceleration measurement can be increased up to 13 bit, + * but will change the data format of this read out. Refer to the data sheet if + * so is wanted/needed. + */ int16_t accm_read_axis(enum ADXL345_AXIS axis){ int16_t rd = 0; @@ -224,73 +183,54 @@ accm_read_axis(enum ADXL345_AXIS axis){ } /*---------------------------------------------------------------------------*/ -/* Sets the g-range, ie the range the accelerometer measures (ie 2g means -2 to +2 g - on every axis). Possible values: - ADXL345_RANGE_2G - ADXL345_RANGE_4G - ADXL345_RANGE_8G - ADXL345_RANGE_16G - Example: - accm_set_grange(ADXL345_RANGE_4G); - */ - void accm_set_grange(uint8_t grange){ if(grange > ADXL345_RANGE_16G) { - // invalid g-range. PRINTFDEBUG("ADXL grange invalid: %u\n", grange); return; } + uint8_t tempreg = 0; - /* preserve the previous contents of the register */ - tempreg = (accm_read_reg(ADXL345_DATA_FORMAT) & 0xFC); // zero out the last two bits (grange) - tempreg |= grange; // set new range + /* Keep the previous contents of the register, zero out the last two bits */ + tempreg = (accm_read_reg(ADXL345_DATA_FORMAT) & 0xFC); + tempreg |= grange; accm_write_reg(ADXL345_DATA_FORMAT, tempreg); } /*---------------------------------------------------------------------------*/ -/* Init the accelerometer: ports, pins, registers, interrupts (none enabled), I2C, - default threshold values etc. */ - void accm_init(void) { - if(!(_ADXL345_STATUS & INITED)){ - PRINTFDEBUG("ADXL345 init\n"); - _ADXL345_STATUS |= INITED; - accm_int1_cb = NULL; - accm_int2_cb = NULL; - int1_event = process_alloc_event(); - int2_event = process_alloc_event(); + PRINTFDEBUG("ADXL345 init\n"); + accm_int1_cb = NULL; + accm_int2_cb = NULL; - /* Set up ports and pins for interrups. */ - ADXL345_DIR &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN); - ADXL345_SEL &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN); - ADXL345_SEL2 &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN); + /* Set up ports and pins for interrups. */ + ADXL345_DIR &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN); + ADXL345_SEL &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN); + ADXL345_SEL2 &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN); - /* Set up ports and pins for I2C communication */ - i2c_enable(); + /* Set up ports and pins for I2C communication */ + i2c_enable(); - /* set default register values. */ - accm_write_stream(15, &adxl345_default_settings[0]); - accm_write_stream(5, &adxl345_default_settings[15]); - accm_write_reg(ADXL345_DATA_FORMAT, adxl345_default_settings[20]); - accm_write_reg(ADXL345_FIFO_CTL, adxl345_default_settings[21]); + /* set default register values. */ + accm_write_stream(15, &adxl345_default_settings[0]); + accm_write_stream(5, &adxl345_default_settings[15]); + accm_write_reg(ADXL345_DATA_FORMAT, adxl345_default_settings[20]); + accm_write_reg(ADXL345_FIFO_CTL, adxl345_default_settings[21]); - process_start(&accmeter_process, NULL); + process_start(&accmeter_process, NULL); - /* Enable msp430 interrupts on the two interrupt pins. */ - dint(); - ADXL345_IES &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN); // low to high transition interrupts - ADXL345_IE |= (ADXL345_INT1_PIN | ADXL345_INT2_PIN); // enable interrupts - eint(); - } + /* Enable msp430 interrupts on the two interrupt pins. */ + dint(); + /* low to high transition interrupts */ + ADXL345_IES &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN); + /* enable interrupts */ + ADXL345_IE |= (ADXL345_INT1_PIN | ADXL345_INT2_PIN); + eint(); } /*---------------------------------------------------------------------------*/ -/* Map interrupt (FF, tap, dbltap etc) to interrupt pin (IRQ_INT1, IRQ_INT2). - This must come after accm_init() as the registers will otherwise be overwritten. */ - void accm_set_irq(uint8_t int1, uint8_t int2){ /* Set the corresponding interrupt mapping to INT1 or INT2 */ @@ -302,44 +242,16 @@ accm_set_irq(uint8_t int1, uint8_t int2){ accm_write_reg(ADXL345_INT_ENABLE, (int1 | int2)); accm_write_reg(ADXL345_INT_MAP, int2); // int1 bits are zeroes in the map register so this is for both ints } - -/*---------------------------------------------------------------------------*/ -#if 0 -/* now unused code that is later supposed to be turned into keeping track of every - interrupt by themselves instead of only one per INT1/2 */ - -/* XXX MUST HAVE some way of resetting the time so that we are not suppressing - erronous due to clock overflow.... XXX XXX XXX */ -/* Table with back off time periods */ -static volatile clock_time_t ints_backoffs[] = {ADXL345_INT_OVERRUN_BACKOFF, ADXL345_INT_WATERMARK_BACKOFF, - ADXL345_INT_FREEFALL_BACKOFF, ADXL345_INT_INACTIVITY_BACKOFF, - ADXL345_INT_ACTIVITY_BACKOFF, ADXL345_INT_DOUBLETAP_BACKOFF, - ADXL345_INT_TAP_BACKOFF, ADXL345_INT_DATAREADY_BACKOFF}; - -/*---------------------------------------------------------------------------*/ -/* Checks to see if an event occurred after backoff period (returns time period - past since) or not (returns 0) */ - -static clocktime_t -backoff_passed(clocktime_t happenedAt, const clocktime_t backoff){ - if(timenow-lasttime >= backoff) { - return 0; - } else { - return (timenow-lasttime); - } -} -#endif /*---------------------------------------------------------------------------*/ /* Invoked after an interrupt happened. Reads the interrupt source reg at the - accelerometer, which resets the interrupts, and invokes the corresponding - callback. It passes the source register value so the callback can determine - what interrupt happened, if several interrupts are mapped to the same pin. */ - + * accelerometer, which resets the interrupts, and invokes the corresponding + * callback. It passes the source register value so the callback can determine + * what interrupt happened, if several interrupts are mapped to the same pin. + */ static void poll_handler(void){ uint8_t ireg = 0; ireg = accm_read_reg(ADXL345_INT_SOURCE); - //printf("0x%02X, 0x%02X, 0x%02X, 0x%02X\n", ireg, ireg2, int1_mask, int2_mask); /* Invoke callbacks for the corresponding interrupts */ if(ireg & int1_mask){ @@ -354,33 +266,32 @@ poll_handler(void){ } } } - /*---------------------------------------------------------------------------*/ -/* This process is sleeping until an interrupt from the accelerometer occurs, which - polls this process from the interrupt service routine. */ - +/* This process is sleeping until an interrupt from the accelerometer occurs, + * which polls this process from the interrupt service routine. */ PROCESS_THREAD(accmeter_process, ev, data) { PROCESS_POLLHANDLER(poll_handler()); PROCESS_EXITHANDLER(); PROCESS_BEGIN(); while(1){ - PROCESS_WAIT_EVENT_UNTIL(0); // should do nothing in while loop. + PROCESS_WAIT_EVENT_UNTIL(0); } PROCESS_END(); } - /*---------------------------------------------------------------------------*/ -/* XXX This interrupt vector is shared with the interrupts from CC2420, so that - was moved here but should find a better home. XXX */ - -#if 1 +/* This interrupt vector is shared with the interrupts from CC2420, so that + * was moved here + */ static struct timer suppressTimer1, suppressTimer2; ISR(PORT1, port1_isr) { ENERGEST_ON(ENERGEST_TYPE_IRQ); - /* ADXL345_IFG.x goes high when interrupt occurs, use to check what interrupted */ - if ((ADXL345_IFG & ADXL345_INT1_PIN) && !(ADXL345_IFG & BV(CC2420_FIFOP_PIN))){ + + /* ADXL345_IFG.x goes high when interrupt occurs, use to check what + * interrupted + */ + if((ADXL345_IFG & ADXL345_INT1_PIN) && !(ADXL345_IFG & BV(CC2420_FIFOP_PIN))){ /* Check if this should be suppressed or not */ if(timer_expired(&suppressTimer1)) { timer_set(&suppressTimer1, SUPPRESS_TIME_INT1); @@ -388,11 +299,13 @@ ISR(PORT1, port1_isr) process_poll(&accmeter_process); LPM4_EXIT; } - } else if ((ADXL345_IFG & ADXL345_INT2_PIN) && !(ADXL345_IFG & BV(CC2420_FIFOP_PIN))){ + } else if((ADXL345_IFG & ADXL345_INT2_PIN) && + !(ADXL345_IFG & BV(CC2420_FIFOP_PIN))){ /* Check if this should be suppressed or not */ if(timer_expired(&suppressTimer2)) { timer_set(&suppressTimer2, SUPPRESS_TIME_INT2); - ADXL345_IFG &= ~ADXL345_INT2_PIN; // clear interrupt flag + /* clear interrupt flag */ + ADXL345_IFG &= ~ADXL345_INT2_PIN; process_poll(&accmeter_process); LPM4_EXIT; } @@ -404,7 +317,4 @@ ISR(PORT1, port1_isr) } ENERGEST_OFF(ENERGEST_TYPE_IRQ); } - /*---------------------------------------------------------------------------*/ - -#endif diff --git a/platform/z1/dev/adxl345.h b/platform/z1/dev/adxl345.h index 082572715..29179b319 100644 --- a/platform/z1/dev/adxl345.h +++ b/platform/z1/dev/adxl345.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2010, Swedish Institute of Computer Science. + * Copyright (c) 2016, Zolertia * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,158 +30,105 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** * \file * Device drivers header file for adxl345 accelerometer in Zolertia Z1. * \author * Marcus Lundén, SICS * Enric Calvo, Zolertia + * Antonio Lignan, Zolertia */ - +/*---------------------------------------------------------------------------*/ #ifndef ADXL345_H_ #define ADXL345_H_ #include #include "dev/i2cmaster.h" - -#define DEBUGLEDS 0 -#if DEBUGLEDS - #undef LEDS_ON(x) - #undef LEDS_OFF(x) - #define LEDS_ON(x) (LEDS_PxOUT &= ~x) - #define LEDS_OFF(x) (LEDS_PxOUT |= x) -#else - #undef LEDS_ON - #undef LEDS_OFF - #define LEDS_ON(x) - #define LEDS_OFF(x) -#endif - -#define LEDS_R 0x10 -#define LEDS_G 0x40 -#define LEDS_B 0x20 -#define L_ON(x) (LEDS_PxOUT &= ~x) -#define L_OFF(x) (LEDS_PxOUT |= x) - -/* Used in accm_read_axis(), eg accm_read_axis(X_AXIS);*/ +/*---------------------------------------------------------------------------*/ +/* Used in accm_read_axis(), eg accm_read_axis(X_AXIS) */ enum ADXL345_AXIS { X_AXIS = 0, Y_AXIS = 2, Z_AXIS = 4, }; - /* -------------------------------------------------------------------------- */ -/* Init the accelerometer: ports, pins, registers, interrupts (none enabled), I2C, - default threshold values etc. */ -void accm_init(void); +/* Init the accelerometer: ports, pins, registers, interrupts (none enabled), + * I2C, default threshold values etc. + */ +void accm_init(void); -/* Write to a register. - args: - reg register to write to - val value to write -*/ -void accm_write_reg(uint8_t reg, uint8_t val); - -/* Write several registers from a stream. - args: - len number of bytes to read - data pointer to where the data is read from - First byte in stream must be the register address to begin writing to. - The data is then written from the second byte and increasing. The address byte - is not included in length len. */ -void accm_write_stream(uint8_t len, uint8_t *data); - -/* Read one register. - args: - reg what register to read - returns the value of the read register -*/ -uint8_t accm_read_reg(uint8_t reg); - -/* Read several registers in a stream. - args: - reg what register to start reading from - len number of bytes to read - whereto pointer to where the data is saved -*/ -void accm_read_stream(uint8_t reg, uint8_t len, uint8_t *whereto); - -/* Read an axis of the accelerometer (x, y or z). Return value is a signed 10 bit int. - The resolution of the acceleration measurement can be increased up to 13 bit, but - will change the data format of this read out. Refer to the data sheet if so is - wanted/needed. */ +/* Read an axis of the accelerometer (x, y or z). Return value is a signed 10 + * bit int. + * The resolution of the acceleration measurement can be increased up to 13 bit, + * but will change the data format of this read out. Refer to the data sheet if + * so is wanted/needed. + */ int16_t accm_read_axis(enum ADXL345_AXIS axis); -/* Sets the g-range, ie the range the accelerometer measures (ie 2g means -2 to +2 g - on every axis). Possible values: - ADXL345_RANGE_2G - ADXL345_RANGE_4G - ADXL345_RANGE_8G - ADXL345_RANGE_16G - Example: - accm_set_grange(ADXL345_RANGE_4G); - */ -void accm_set_grange(uint8_t grange); +/* Sets the g-range, ie the range the accelerometer measures (ie 2g means -2 to + * +2 g on every axis). Possible values: + * - ADXL345_RANGE_2G + * - ADXL345_RANGE_4G + * - ADXL345_RANGE_8G + * - ADXL345_RANGE_16G + */ +void accm_set_grange(uint8_t grange); /* Map interrupt (FF, tap, dbltap etc) to interrupt pin (IRQ_INT1, IRQ_INT2). - This must come after accm_init() as the registers will otherwise be overwritten. */ -void accm_set_irq(uint8_t int1, uint8_t int2); + * This must come after accm_init() as the registers will otherwise be + * overwritten. + */ +void accm_set_irq(uint8_t int1, uint8_t int2); /* Macros for setting the pointers to callback functions from the interrupts. - The function will be called with an uint8_t as parameter, containing the interrupt - flag register from the ADXL345. That way, several interrupts can be mapped to - the same pin and be read from the */ + * The function will be called with an uint8_t as parameter, containing the + * interrupt flag register from the ADXL345. That way, several interrupts can be + * mapped to the same pin and be read + */ #define ACCM_REGISTER_INT1_CB(ptr) accm_int1_cb = ptr; #define ACCM_REGISTER_INT2_CB(ptr) accm_int2_cb = ptr; /* -------------------------------------------------------------------------- */ /* Application definitions, change if required by application. */ -/* Interrupt suppress periods */ -/* -// XXX Not used yet. -#define ADXL345_INT_OVERRUN_BACKOFF CLOCK_SECOND/8 -#define ADXL345_INT_WATERMARK_BACKOFF CLOCK_SECOND/8 -#define ADXL345_INT_FREEFALL_BACKOFF CLOCK_SECOND/8 -#define ADXL345_INT_INACTIVITY_BACKOFF CLOCK_SECOND/8 -#define ADXL345_INT_ACTIVITY_BACKOFF CLOCK_SECOND/8 -#define ADXL345_INT_DOUBLETAP_BACKOFF CLOCK_SECOND/8 -#define ADXL345_INT_TAP_BACKOFF CLOCK_SECOND/8 -#define ADXL345_INT_DATAREADY_BACKOFF CLOCK_SECOND/8 -*/ -/* Time after an interrupt that subsequent interrupts are suppressed. Should later - be turned into one specific time per type of interrupt (tap, freefall etc) */ +/* Time after an interrupt that subsequent interrupts are suppressed. Should + * later be turned into one specific time per type of interrupt (tap, freefall. + * etc) + */ #define SUPPRESS_TIME_INT1 CLOCK_SECOND/4 #define SUPPRESS_TIME_INT2 CLOCK_SECOND/4 /* Suggested defaults according to the data sheet etc */ -#define ADXL345_THRESH_TAP_DEFAULT 0x48 // 4.5g (0x30 == 3.0g) (datasheet: 3g++) -#define ADXL345_OFSX_DEFAULT 0x00 // for individual units calibration purposes +#define ADXL345_THRESH_TAP_DEFAULT 0x48 /* 4.5g (0x30 == 3.0g) */ +#define ADXL345_OFSX_DEFAULT 0x00 /* for calibration only */ #define ADXL345_OFSY_DEFAULT 0x00 #define ADXL345_OFSZ_DEFAULT 0x00 -#define ADXL345_DUR_DEFAULT 0x20 // 20 ms (datasheet: 10ms++) -#define ADXL345_LATENT_DEFAULT 0x50 // 100 ms (datasheet: 20ms++) -#define ADXL345_WINDOW_DEFAULT 0xFF // 320 ms (datasheet: 80ms++) -#define ADXL345_THRESH_ACT_DEFAULT 0x15 // 1.3g (62.5 mg/LSB) -#define ADXL345_THRESH_INACT_DEFAULT 0x08 // 0.5g (62.5 mg/LSB) -#define ADXL345_TIME_INACT_DEFAULT 0x02 // 2 s (1 s/LSB) -#define ADXL345_ACT_INACT_CTL_DEFAULT 0xFF // all axis involved, ac-coupled -#define ADXL345_THRESH_FF_DEFAULT 0x09 // 563 mg -#define ADXL345_TIME_FF_DEFAULT 0x20 // 160 ms -#define ADXL345_TAP_AXES_DEFAULT 0x07 // all axis, no suppression +#define ADXL345_DUR_DEFAULT 0x20 /* 20 ms (datasheet: 10ms++) */ +#define ADXL345_LATENT_DEFAULT 0x50 /* 100 ms (datasheet: 20ms++) */ +#define ADXL345_WINDOW_DEFAULT 0xFF /* 320 ms (datasheet: 80ms++) */ +#define ADXL345_THRESH_ACT_DEFAULT 0x15 /* 1.3g (62.5 mg/LSB) */ +#define ADXL345_THRESH_INACT_DEFAULT 0x08 /* 0.5g (62.5 mg/LSB) */ +#define ADXL345_TIME_INACT_DEFAULT 0x02 /* 2 s (1 s/LSB) */ +#define ADXL345_ACT_INACT_CTL_DEFAULT 0xFF /* all axis, ac-coupled */ +#define ADXL345_THRESH_FF_DEFAULT 0x09 /* 563 mg */ +#define ADXL345_TIME_FF_DEFAULT 0x20 /* 60 ms */ +#define ADXL345_TAP_AXES_DEFAULT 0x07 /* all axis, no suppression */ -#define ADXL345_BW_RATE_DEFAULT (0x00|ADXL345_SRATE_100) // 100 Hz, normal operation -#define ADXL345_POWER_CTL_DEFAULT 0x28 // link bit set, no autosleep, start normal measuring -#define ADXL345_INT_ENABLE_DEFAULT 0x00 // no interrupts enabled -#define ADXL345_INT_MAP_DEFAULT 0x00 // all mapped to int_1 +#define ADXL345_BW_RATE_DEFAULT (0x00 | ADXL345_SRATE_100) /* 100 Hz */ +/* link bit set, no autosleep, start normal measuring */ +#define ADXL345_POWER_CTL_DEFAULT 0x28 +#define ADXL345_INT_ENABLE_DEFAULT 0x00 /* no interrupts enabled */ +#define ADXL345_INT_MAP_DEFAULT 0x00 /* all mapped to int_1 */ /* XXX NB: In the data format register, data format of axis readings is chosen - between left or right justify. This affects the position of the MSB/LSB and is - different depending on g-range and resolution. If changed, make sure this is - reflected in the _read_axis() function. Also, the resolution can be increased - from 10 bit to at most 13 bit, but this also changes position of MSB etc on data - format so check this in read_axis() too. */ -#define ADXL345_DATA_FORMAT_DEFAULT (0x00|ADXL345_RANGE_2G) // right-justify, 2g, 10-bit mode, int is active high -#define ADXL345_FIFO_CTL_DEFAULT 0x00 // FIFO bypass mode + * between left or right justify. This affects the position of the MSB/LSB and is + * different depending on g-range and resolution. If changed, make sure this is + * reflected in the _read_axis() function. Also, the resolution can be increased + * from 10 bit to at most 13 bit, but this also changes position of MSB etc on data + * format so check this in read_axis() too. + */ +/* right-justify, 2g, 10-bit mode, int is active high */ +#define ADXL345_DATA_FORMAT_DEFAULT (0x00 | ADXL345_RANGE_2G) +#define ADXL345_FIFO_CTL_DEFAULT 0x00 /* FIFO bypass mode */ /* -------------------------------------------------------------------------- */ /* Reference definitions, should not be changed */ @@ -188,7 +136,7 @@ void accm_set_irq(uint8_t int1, uint8_t int2); #define ADXL345_ADDR 0x53 /* ADXL345 registers */ -#define ADXL345_DEVID 0x00 // read only +#define ADXL345_DEVID 0x00 /* registers 0x01 to 0x1C are reserved, do not access */ #define ADXL345_THRESH_TAP 0x1D #define ADXL345_OFSX 0x1E @@ -204,24 +152,24 @@ void accm_set_irq(uint8_t int1, uint8_t int2); #define ADXL345_THRESH_FF 0x28 #define ADXL345_TIME_FF 0x29 #define ADXL345_TAP_AXES 0x2A -#define ADXL345_ACT_TAP_STATUS 0x2B // read only +#define ADXL345_ACT_TAP_STATUS 0x2B #define ADXL345_BW_RATE 0x2C #define ADXL345_POWER_CTL 0x2D #define ADXL345_INT_ENABLE 0x2E #define ADXL345_INT_MAP 0x2F -#define ADXL345_INT_SOURCE 0x30 // read only +#define ADXL345_INT_SOURCE 0x30 #define ADXL345_DATA_FORMAT 0x31 -#define ADXL345_DATAX0 0x32 // read only, LSByte X, two's complement -#define ADXL345_DATAX1 0x33 // read only, MSByte X -#define ADXL345_DATAY0 0x34 // read only, LSByte Y -#define ADXL345_DATAY1 0x35 // read only, MSByte X -#define ADXL345_DATAZ0 0x36 // read only, LSByte Z -#define ADXL345_DATAZ1 0x37 // read only, MSByte X +#define ADXL345_DATAX0 0x32 /* read only, LSByte X, two's complement */ +#define ADXL345_DATAX1 0x33 /* read only, MSByte X */ +#define ADXL345_DATAY0 0x34 /* read only, LSByte Y */ +#define ADXL345_DATAY1 0x35 /* read only, MSByte X */ +#define ADXL345_DATAZ0 0x36 /* read only, LSByte Z */ +#define ADXL345_DATAZ1 0x37 /* read only, MSByte X */ #define ADXL345_FIFO_CTL 0x38 -#define ADXL345_FIFO_STATUS 0x39 // read only +#define ADXL345_FIFO_STATUS 0x39 /* read only */ /* ADXL345 interrupts */ -#define ADXL345_INT_DISABLE 0X00 // used for disabling interrupts +#define ADXL345_INT_DISABLE 0X00 /* used for disabling interrupts */ #define ADXL345_INT_OVERRUN 0X01 #define ADXL345_INT_WATERMARK 0X02 #define ADXL345_INT_FREEFALL 0X04 @@ -237,8 +185,8 @@ void accm_set_irq(uint8_t int1, uint8_t int2); #define ADXL345_REN P1REN #define ADXL345_SEL P1SEL #define ADXL345_SEL2 P1SEL2 -#define ADXL345_INT1_PIN (1<<6) // P1.6 -#define ADXL345_INT2_PIN (1<<7) // P1.7 +#define ADXL345_INT1_PIN (1<<6) /* P1.6 */ +#define ADXL345_INT2_PIN (1<<7) /* P1.7 */ #define ADXL345_IES P1IES #define ADXL345_IE P1IE #define ADXL345_IFG P1IFG @@ -251,43 +199,40 @@ void accm_set_irq(uint8_t int1, uint8_t int2); #define ADXL345_RANGE_16G 0x03 -/* The adxl345 has programmable sample rates, but unexpected results may occur if the wrong - rate and I2C bus speed is used (see datasheet p 17). Sample rates in Hz. This - setting does not change the internal sampling rate, just how often it is piped - to the output registers (ie the interrupt features use the full sample rate - internally). +/* The adxl345 has programmable sample rates, but unexpected results may occur + * if the wrong rate and I2C bus speed is used (see datasheet p 17). Sample + * rates in Hz. This setting does not change the internal sampling rate, just + * how often it is piped to the output registers (ie the interrupt features use + * the full sample rate internally). + * Example use: + * adxl345_set_reg(ADXL345_BW_RATE, ((_ADXL345_STATUS & LOW_POWER) + * | ADXL345_SRATE_50)); + */ - Example use: - adxl345_set_reg(ADXL345_BW_RATE, ((_ADXL345_STATUS & LOW_POWER) | ADXL345_SRATE_50)); - */ -#define ADXL345_SRATE_3200 0x0F // XXX NB don't use at all as I2C data rate<= 400kHz (see datasheet) -#define ADXL345_SRATE_1600 0x0E // XXX NB don't use at all as I2C data rate<= 400kHz (see datasheet) -#define ADXL345_SRATE_800 0x0D // when I2C data rate == 400 kHz -#define ADXL345_SRATE_400 0x0C // when I2C data rate == 400 kHz -#define ADXL345_SRATE_200 0x0B // when I2C data rate >= 100 kHz -#define ADXL345_SRATE_100 0x0A // when I2C data rate >= 100 kHz -#define ADXL345_SRATE_50 0x09 // when I2C data rate >= 100 kHz -#define ADXL345_SRATE_25 0x08 // when I2C data rate >= 100 kHz -#define ADXL345_SRATE_12_5 0x07 // 12.5 Hz, when I2C data rate >= 100 kHz -#define ADXL345_SRATE_6_25 0x06 // when I2C data rate >= 100 kHz -#define ADXL345_SRATE_3_13 0x05 // when I2C data rate >= 100 kHz -#define ADXL345_SRATE_1_56 0x04 // when I2C data rate >= 100 kHz -#define ADXL345_SRATE_0_78 0x03 // when I2C data rate >= 100 kHz -#define ADXL345_SRATE_0_39 0x02 // when I2C data rate >= 100 kHz -#define ADXL345_SRATE_0_20 0x01 // when I2C data rate >= 100 kHz -#define ADXL345_SRATE_0_10 0x00 // 0.10 Hz, when I2C data rate >= 100 kHz +/* XXX NB don't use at all as I2C data rate<= 400kHz */ +#define ADXL345_SRATE_3200 0x0F +/* XXX NB don't use at all as I2C data rate<= 400kHz */ +#define ADXL345_SRATE_1600 0x0E +#define ADXL345_SRATE_800 0x0D /* when I2C data rate == 400 kHz */ +#define ADXL345_SRATE_400 0x0C /* when I2C data rate == 400 kHz */ +#define ADXL345_SRATE_200 0x0B /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_100 0x0A /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_50 0x09 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_25 0x08 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_12_5 0x07 /* 12.5 Hz, when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_6_25 0x06 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_3_13 0x05 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_1_56 0x04 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_0_78 0x03 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_0_39 0x02 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_0_20 0x01 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_0_10 0x00 /* 0.10 Hz, when I2C data rate >= 100 kHz */ /* Callback pointers for the interrupts */ extern void (*accm_int1_cb)(uint8_t reg); extern void (*accm_int2_cb)(uint8_t reg); -/* Interrupt 1 and 2 events; ADXL345 signals interrupt on INT1 or INT2 pins, - ISR is invoked and polls the accelerometer process which invokes the callbacks. */ -extern process_event_t int1_event, int2_event; // static ? - #define ACCM_INT1 0x01 #define ACCM_INT2 0x02 - - /* -------------------------------------------------------------------------- */ #endif /* ifndef ADXL345_H_ */ From 934cdbacca841e89535090a6c7fcf8c12efac921 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Mon, 22 Feb 2016 12:06:38 +0100 Subject: [PATCH 037/374] Adapted the ADXL345 sensor to Contiki's sensor API --- examples/zolertia/z1/test-adxl345.c | 47 +++++---- platform/z1/dev/adxl345.c | 148 +++++++++++++++++++++++----- platform/z1/dev/adxl345.h | 20 ++-- 3 files changed, 161 insertions(+), 54 deletions(-) diff --git a/examples/zolertia/z1/test-adxl345.c b/examples/zolertia/z1/test-adxl345.c index e33981f76..a5e199bef 100644 --- a/examples/zolertia/z1/test-adxl345.c +++ b/examples/zolertia/z1/test-adxl345.c @@ -125,35 +125,40 @@ PROCESS_THREAD(led_process, ev, data) { } /*---------------------------------------------------------------------------*/ /* Main process, setups */ -PROCESS_THREAD(accel_process, ev, data) { +PROCESS_THREAD(accel_process, ev, data) +{ PROCESS_BEGIN(); - { - int16_t x, y, z; - /* Register the event used for lighting up an LED when interrupt strikes. */ - led_off_event = process_alloc_event(); + int16_t x, y, z; - /* Start and setup the accelerometer with default values, eg no interrupts enabled. */ - accm_init(); + /* Register the event used for lighting up an LED when interrupt strikes. */ + led_off_event = process_alloc_event(); - /* Register the callback functions for each interrupt */ - ACCM_REGISTER_INT1_CB(accm_ff_cb); - ACCM_REGISTER_INT2_CB(accm_tap_cb); + /* Start and setup the accelerometer with default values, eg no interrupts + * enabled. + */ + SENSORS_ACTIVATE(adxl345); - /* Set what strikes the corresponding interrupts. Several interrupts per pin is - possible. For the eight possible interrupts, see adxl345.h and adxl345 datasheet. */ - accm_set_irq(ADXL345_INT_FREEFALL, ADXL345_INT_TAP + ADXL345_INT_DOUBLETAP); + /* Register the callback functions for each interrupt */ + ACCM_REGISTER_INT1_CB(accm_ff_cb); + ACCM_REGISTER_INT2_CB(accm_tap_cb); - while(1) { - x = accm_read_axis(X_AXIS); - y = accm_read_axis(Y_AXIS); - z = accm_read_axis(Z_AXIS); - printf("x: %d y: %d z: %d\n", x, y, z); + /* Set what strikes the corresponding interrupts. Several interrupts per + * pin is possible. For the eight possible interrupts, see adxl345.h and + * adxl345 datasheet. + */ + accm_set_irq(ADXL345_INT_FREEFALL, ADXL345_INT_TAP + ADXL345_INT_DOUBLETAP); - etimer_set(&et, ACCM_READ_INTERVAL); - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - } + while(1) { + x = adxl345.value(X_AXIS); + y = adxl345.value(Y_AXIS); + z = adxl345.value(Z_AXIS); + printf("x: %d y: %d z: %d\n", x, y, z); + + etimer_set(&et, ACCM_READ_INTERVAL); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); } + PROCESS_END(); } /*---------------------------------------------------------------------------*/ diff --git a/platform/z1/dev/adxl345.c b/platform/z1/dev/adxl345.c index 512881d59..49bf9b6e6 100644 --- a/platform/z1/dev/adxl345.c +++ b/platform/z1/dev/adxl345.c @@ -46,6 +46,16 @@ #include "cc2420.h" #include "i2cmaster.h" #include "isr_compat.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; /*---------------------------------------------------------------------------*/ /* Callback pointers when interrupt occurs */ void (*accm_int1_cb)(uint8_t reg); @@ -97,38 +107,41 @@ static uint8_t adxl345_default_settings[] = { PROCESS(accmeter_process, "Accelerometer process"); /*---------------------------------------------------------------------------*/ static void -accm_write_reg(uint8_t reg, uint8_t val) { +accm_write_reg(uint8_t reg, uint8_t val) +{ uint8_t tx_buf[] = {reg, val}; i2c_transmitinit(ADXL345_ADDR); while (i2c_busy()); - PRINTFDEBUG("I2C Ready to TX\n"); + PRINTF("ADXL345: I2C Ready to TX\n"); i2c_transmit_n(2, tx_buf); while (i2c_busy()); - PRINTFDEBUG("WRITE_REG 0x%02X @ reg 0x%02X\n", val, reg); + PRINTF("ADXL345: WRITE_REG 0x%02X @ reg 0x%02X\n", val, reg); } /*---------------------------------------------------------------------------*/ /* First byte in stream must be the register address to begin writing to. * The data is then written from second byte and increasing. */ static void -accm_write_stream(uint8_t len, uint8_t *data) { +accm_write_stream(uint8_t len, uint8_t *data) +{ i2c_transmitinit(ADXL345_ADDR); while (i2c_busy()); - PRINTFDEBUG("I2C Ready to TX(stream)\n"); + PRINTF("ADXL345: I2C Ready to TX(stream)\n"); i2c_transmit_n(len, data); // start tx and send conf reg while (i2c_busy()); - PRINTFDEBUG("WRITE_STR %u B to 0x%02X\n", len, data[0]); + PRINTF("ADXL345: WRITE_STR %u B to 0x%02X\n", len, data[0]); } /*---------------------------------------------------------------------------*/ static uint8_t -accm_read_reg(uint8_t reg) { +accm_read_reg(uint8_t reg) +{ uint8_t retVal = 0; uint8_t rtx = reg; - PRINTFDEBUG("READ_REG 0x%02X\n", reg); + PRINTF("ADXL345: READ_REG 0x%02X\n", reg); /* transmit the register to read */ i2c_transmitinit(ADXL345_ADDR); @@ -146,9 +159,10 @@ accm_read_reg(uint8_t reg) { } /*---------------------------------------------------------------------------*/ static void -accm_read_stream(uint8_t reg, uint8_t len, uint8_t *whereto) { +accm_read_stream(uint8_t reg, uint8_t len, uint8_t *whereto) +{ uint8_t rtx = reg; - PRINTFDEBUG("READ_STR %u B from 0x%02X\n", len, reg); + PRINTF("ADXL345: READ_STR %u B from 0x%02X\n", len, reg); /* transmit the register to start reading from */ i2c_transmitinit(ADXL345_ADDR); @@ -171,7 +185,8 @@ accm_read_stream(uint8_t reg, uint8_t len, uint8_t *whereto) { * so is wanted/needed. */ int16_t -accm_read_axis(enum ADXL345_AXIS axis){ +accm_read_axis(enum ADXL345_AXIS axis) +{ int16_t rd = 0; uint8_t tmp[2]; if(axis > Z_AXIS){ @@ -181,27 +196,33 @@ accm_read_axis(enum ADXL345_AXIS axis){ rd = (int16_t)(tmp[0] | (tmp[1]<<8)); return rd; } - /*---------------------------------------------------------------------------*/ -void -accm_set_grange(uint8_t grange){ +int +accm_set_grange(uint8_t grange) +{ + uint8_t tempreg = 0; + if(grange > ADXL345_RANGE_16G) { - PRINTFDEBUG("ADXL grange invalid: %u\n", grange); - return; + PRINTF("ADXL345: grange invalid: %u\n", grange); + return ADXL345_ERROR; } - uint8_t tempreg = 0; + if(!enabled) { + return ADXL345_ERROR; + } /* Keep the previous contents of the register, zero out the last two bits */ tempreg = (accm_read_reg(ADXL345_DATA_FORMAT) & 0xFC); tempreg |= grange; accm_write_reg(ADXL345_DATA_FORMAT, tempreg); + return ADXL345_SUCCESS; } /*---------------------------------------------------------------------------*/ void -accm_init(void) { - PRINTFDEBUG("ADXL345 init\n"); +accm_init(void) +{ + PRINTF("ADXL345: init\n"); accm_int1_cb = NULL; accm_int2_cb = NULL; @@ -228,19 +249,38 @@ accm_init(void) { /* enable interrupts */ ADXL345_IE |= (ADXL345_INT1_PIN | ADXL345_INT2_PIN); eint(); -} + enabled = 1; +} /*---------------------------------------------------------------------------*/ void -accm_set_irq(uint8_t int1, uint8_t int2){ +accm_stop(void) +{ + dint(); + ADXL345_IE &= ~(ADXL345_INT1_PIN | ADXL345_INT2_PIN); + accm_write_reg(ADXL345_INT_ENABLE, ~(int1_mask | int2_mask)); + accm_write_reg(ADXL345_INT_MAP, ~int2_mask); + eint(); + enabled = 0; +} +/*---------------------------------------------------------------------------*/ +int +accm_set_irq(uint8_t int1, uint8_t int2) +{ + if(!enabled) { + return ADXL345_ERROR; + } + /* Set the corresponding interrupt mapping to INT1 or INT2 */ - PRINTFDEBUG("IRQs set to INT1: 0x%02X IRQ2: 0x%02X\n", int1, int2); + PRINTF("ADXL345: IRQs set to INT1: 0x%02X IRQ2: 0x%02X\n", int1, int2); int1_mask = int1; int2_mask = int2; accm_write_reg(ADXL345_INT_ENABLE, (int1 | int2)); - accm_write_reg(ADXL345_INT_MAP, int2); // int1 bits are zeroes in the map register so this is for both ints + /* int1 bits are zeroes in the map register so this is for both ints */ + accm_write_reg(ADXL345_INT_MAP, int2); + return ADXL345_SUCCESS; } /*---------------------------------------------------------------------------*/ /* Invoked after an interrupt happened. Reads the interrupt source reg at the @@ -249,19 +289,20 @@ accm_set_irq(uint8_t int1, uint8_t int2){ * what interrupt happened, if several interrupts are mapped to the same pin. */ static void -poll_handler(void){ +poll_handler(void) +{ uint8_t ireg = 0; ireg = accm_read_reg(ADXL345_INT_SOURCE); /* Invoke callbacks for the corresponding interrupts */ if(ireg & int1_mask){ if(accm_int1_cb != NULL){ - PRINTFDEBUG("INT1 cb invoked\n"); + PRINTF("ADXL345: INT1 cb invoked\n"); accm_int1_cb(ireg); } } else if(ireg & int2_mask){ if(accm_int2_cb != NULL){ - PRINTFDEBUG("INT2 cb invoked\n"); + PRINTF("ADXL345: INT2 cb invoked\n"); accm_int2_cb(ireg); } } @@ -269,7 +310,8 @@ poll_handler(void){ /*---------------------------------------------------------------------------*/ /* This process is sleeping until an interrupt from the accelerometer occurs, * which polls this process from the interrupt service routine. */ -PROCESS_THREAD(accmeter_process, ev, data) { +PROCESS_THREAD(accmeter_process, ev, data) +{ PROCESS_POLLHANDLER(poll_handler()); PROCESS_EXITHANDLER(); PROCESS_BEGIN(); @@ -318,3 +360,55 @@ ISR(PORT1, port1_isr) ENERGEST_OFF(ENERGEST_TYPE_IRQ); } /*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type != SENSORS_ACTIVE) { + return ADXL345_ERROR; + } + + if(value) { + accm_init(); + } else { + accm_stop(); + } + enabled = value; + return ADXL345_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return ADXL345_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + if(!enabled) { + return ADXL345_ERROR; + } + + if((type != X_AXIS) && (type != Y_AXIS) && (type != Z_AXIS)) { + return ADXL345_ERROR; + } + + switch(type) { + case X_AXIS: + return accm_read_axis(X_AXIS); + case Y_AXIS: + return accm_read_axis(Y_AXIS); + case Z_AXIS: + return accm_read_axis(Z_AXIS); + default: + return ADXL345_ERROR; + } +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(adxl345, ADXL345_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ diff --git a/platform/z1/dev/adxl345.h b/platform/z1/dev/adxl345.h index 29179b319..a8d4789d8 100644 --- a/platform/z1/dev/adxl345.h +++ b/platform/z1/dev/adxl345.h @@ -44,6 +44,7 @@ #define ADXL345_H_ #include #include "dev/i2cmaster.h" +#include "lib/sensors.h" /*---------------------------------------------------------------------------*/ /* Used in accm_read_axis(), eg accm_read_axis(X_AXIS) */ enum ADXL345_AXIS { @@ -72,13 +73,13 @@ int16_t accm_read_axis(enum ADXL345_AXIS axis); * - ADXL345_RANGE_8G * - ADXL345_RANGE_16G */ -void accm_set_grange(uint8_t grange); +int accm_set_grange(uint8_t grange); /* Map interrupt (FF, tap, dbltap etc) to interrupt pin (IRQ_INT1, IRQ_INT2). * This must come after accm_init() as the registers will otherwise be * overwritten. */ -void accm_set_irq(uint8_t int1, uint8_t int2); +int accm_set_irq(uint8_t int1, uint8_t int2); /* Macros for setting the pointers to callback functions from the interrupts. * The function will be called with an uint8_t as parameter, containing the @@ -227,12 +228,19 @@ void accm_set_irq(uint8_t int1, uint8_t int2); #define ADXL345_SRATE_0_39 0x02 /* when I2C data rate >= 100 kHz */ #define ADXL345_SRATE_0_20 0x01 /* when I2C data rate >= 100 kHz */ #define ADXL345_SRATE_0_10 0x00 /* 0.10 Hz, when I2C data rate >= 100 kHz */ - +/* -------------------------------------------------------------------------- */ /* Callback pointers for the interrupts */ extern void (*accm_int1_cb)(uint8_t reg); extern void (*accm_int2_cb)(uint8_t reg); - -#define ACCM_INT1 0x01 -#define ACCM_INT2 0x02 +/* -------------------------------------------------------------------------- */ +#define ACCM_INT1 0x01 +#define ACCM_INT2 0x02 +#define ADXL345_SUCCESS 0x00 +#define ADXL345_ERROR (-1) +/* -------------------------------------------------------------------------- */ +#define ADXL345_SENSOR "ADXL345 sensor" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor adxl345; +/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ #endif /* ifndef ADXL345_H_ */ From 4d4930921ea0c92a2da11a6669cc2d424b5d4e7f Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Mon, 22 Feb 2016 16:02:06 +0100 Subject: [PATCH 038/374] Fixes error when processes name are not used --- apps/shell/shell-exec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/shell/shell-exec.c b/apps/shell/shell-exec.c index 1f5bbf383..8442f22ef 100644 --- a/apps/shell/shell-exec.c +++ b/apps/shell/shell-exec.c @@ -116,11 +116,13 @@ PROCESS_THREAD(shell_exec_process, ev, data) shell_output_str(&exec_command, print, symbol); if(ret == ELFLOADER_OK) { +#if !PROCESS_CONF_NO_PROCESS_NAMES int i; for(i = 0; elfloader_autostart_processes[i] != NULL; ++i) { shell_output_str(&exec_command, "exec: starting process ", elfloader_autostart_processes[i]->name); } +#endif autostart_start(elfloader_autostart_processes); } From 56aeb7cd7e91f7f343e178b44c91f818054656b0 Mon Sep 17 00:00:00 2001 From: Aitor Mejias Date: Thu, 28 Jan 2016 10:12:19 +0100 Subject: [PATCH 039/374] Added Zolertia Zonik sound sensor test and drivers --- examples/zolertia/zoul/Makefile | 3 +- examples/zolertia/zoul/test-zonik.c | 123 +++++++++++++++++++ platform/zoul/dev/zonik.c | 184 ++++++++++++++++++++++++++++ platform/zoul/dev/zonik.h | 113 +++++++++++++++++ 4 files changed, 422 insertions(+), 1 deletion(-) create mode 100644 examples/zolertia/zoul/test-zonik.c create mode 100644 platform/zoul/dev/zonik.c create mode 100644 platform/zoul/dev/zonik.h diff --git a/examples/zolertia/zoul/Makefile b/examples/zolertia/zoul/Makefile index c4ad2affb..2b70773d9 100644 --- a/examples/zolertia/zoul/Makefile +++ b/examples/zolertia/zoul/Makefile @@ -5,10 +5,11 @@ CONTIKI_PROJECT += test-bmp085-bmp180 test-motion test-rotation-sensor CONTIKI_PROJECT += test-grove-light-sensor test-grove-loudness-sensor CONTIKI_PROJECT += test-weather-meter test-grove-gyro test-lcd test-iaq CONTIKI_PROJECT += test-pm10-sensor test-vac-sensor test-aac-sensor +CONTIKI_PROJECT += test-zonik CONTIKI_TARGET_SOURCEFILES += tsl2563.c sht25.c bmpx8x.c motion-sensor.c CONTIKI_TARGET_SOURCEFILES += adc-sensors.c weather-meter.c grove-gyro.c -CONTIKI_TARGET_SOURCEFILES += rgb-bl-lcd.c pm10-sensor.c iaq.c +CONTIKI_TARGET_SOURCEFILES += rgb-bl-lcd.c pm10-sensor.c iaq.c zonik.c all: $(CONTIKI_PROJECT) diff --git a/examples/zolertia/zoul/test-zonik.c b/examples/zolertia/zoul/test-zonik.c new file mode 100644 index 000000000..622b73291 --- /dev/null +++ b/examples/zolertia/zoul/test-zonik.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup remote-examples + * @{ + * \defgroup remote-zonik-test Zolertia Zonik sonometer test application + * + * Example of Zonik board implementation and simple operation: Infinite loop + * enablinkg the sensor and rading few times, acquiring the dBA of sensor + * The first value acquired is invalid, because it's in hw init state awaiting + * a valid internal reading.Once the driver is initialized, posterior readings + * are valid.Finally in the loop disables the board with standard call and + * shows the error, and loop again enabling it. + * + * @{ + * \file + * RE-Mote test application of Zolertia Zonik sound sensor + * \author + * Aitor Mejias + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "zonik.h" +#include "dev/i2c.h" +#include "dev/leds.h" +#include +#include +/*---------------------------------------------------------------------------*/ +#define MAX_VALID_READINGS 10L +#define MAX_INVALID_READINGS 3L +/*---------------------------------------------------------------------------*/ +PROCESS(test_remote_zonik_process, "Test Zonik driver process"); +AUTOSTART_PROCESSES(&test_remote_zonik_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(test_remote_zonik_process, ev, data) +{ + static int16_t zonik_val; + static uint8_t i; + + PROCESS_BEGIN(); + + printf("Initial status of sensor is: 0x%04X\n", + zonik.status(SENSORS_ACTIVE)); + + while(1) { + /* Configure Zonik and activate the internal process readings */ + SENSORS_ACTIVATE(zonik); + + printf("Initialized. Sensor status: 0x%04X\n", + zonik.status(SENSORS_ACTIVE)); + + /* Read sensor value dBA multiple times */ + for(i=0; i + * 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup remote-zonik + * @{ + * Driver for the RE-Mote Zonik sonometer board + * @{ + * \file + * Driver for the RE-Mote Zonik sound sensor (ZONIK) + * \author + * Aitor Mejias + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/gpio.h" +#include "dev/i2c.h" +#include "zonik.h" +#include "sys/timer.h" +#include "sys/etimer.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +#define ZONIK_INT1_PORT_BASE GPIO_PORT_TO_BASE(ZONIK_INT_PORT) +#define ZONIK_INT1_PIN_MASK GPIO_PIN_MASK(ZONIK_INT_PIN) +/*---------------------------------------------------------------------------*/ +static uint8_t zonik_buffer[ZONIK_FRAME_SIZE+1]; +static uint16_t zonik_status = ZONIK_DISABLED; +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS(zonik_stm_process, "Zonik process process handler"); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(zonik_stm_process, ev, data) +{ + #if DEBUG + static int i; + #endif + PROCESS_EXITHANDLER(); + PROCESS_BEGIN(); + + while(1) { + /* Wait a process */ + etimer_set(&et, ZONIK_SECOND_INTERVAL); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + /* Control the interrupt for activate the sensor */ + GPIO_SET_OUTPUT(ZONIK_INT1_PORT_BASE, ZONIK_INT1_PIN_MASK); + GPIO_CLR_PIN(ZONIK_INT1_PORT_BASE, ZONIK_INT1_PIN_MASK); + clock_delay_usec(ZONIK_INITIAL_WAIT_DELAY); + i2c_master_enable(); + if(i2c_single_send(ZONIK_ADDR, ZONIK_CMD_READ) != I2C_MASTER_ERR_NONE) { + zonik_status = ZONIK_ERROR; + PRINTF("Zonik: Error in I2C Communication\n"); + } + GPIO_SET_PIN(ZONIK_INT1_PORT_BASE, ZONIK_INT1_PIN_MASK); + GPIO_SET_INPUT(ZONIK_INT1_PORT_BASE, ZONIK_INT1_PIN_MASK); + if(zonik_status != ZONIK_ERROR) { + etimer_set(&et, ZONIK_WAIT_ACQ); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + clock_delay_usec(ZONIK_FINAL_WAIT_DELAY); + i2c_master_enable(); + if(i2c_burst_receive(ZONIK_ADDR, &zonik_buffer[0], ZONIK_FRAME_SIZE) != + I2C_MASTER_ERR_NONE) { + zonik_status = ZONIK_ERROR; + PRINTF("Zonik: Error in I2C Burst Mode Receive"); + } + #if DEBUG + PRINTF("\nZonik: "); + for(i=0; i + * 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. + * + */ +/* -------------------------------------------------------------------------- */ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup remote-zonik Zonik sound sensor + * @{ + * + * \file + * Header file for the Zolertia Zonik sound sensor + */ +/* -------------------------------------------------------------------------- */ +#ifndef ZONIK_H_ +#define ZONIK_H_ +/* -------------------------------------------------------------------------- */ +#include +#include "lib/sensors.h" +#include "dev/zoul-sensors.h" +#include "i2c.h" +#include "sys/rtimer.h" +/* -------------------------------------------------------------------------- */ +/** \name ZONIK address and definitions + * @{ + */ +#define ZONIK_ADDR 0x68 +#define ZONIK_SENSOR "Zonik Sound Sensor" + +#define ZONIK_INITIAL_WAIT_DELAY 11000L +#define ZONIK_FINAL_WAIT_DELAY 22000L + +#ifndef ZONIK_INT_CONF_PORT +#define ZONIK_INT_PORT I2C_INT_PORT +#else +#define ZONIK_INT_PORT ZONIK_INT_CONF_PORT +#endif + +#ifndef ZONIK_INT_CONF_PIN +#define ZONIK_INT_PIN I2C_INT_PIN +#else +#define ZONIK_INT_PIN ZONIK_INT_CONF_PIN +#endif + +#define ZONIK_FRAME_SIZE 4 + +#define ZONIK_WAIT_ACQ (CLOCK_SECOND / 5) + +/* Zonik wait sensor delay: ~800ms */ +#define ZONIK_SECOND_INTERVAL 106 + +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name ZONIK error values and definitions + * @{ + */ +#define ZONIK_ACTIVE SENSORS_ACTIVE +#define ZONIK_HW_INIT SENSORS_HW_INIT +#define ZONIK_ENABLED 1 +#define ZONIK_VALUE_DEACTIVATE 0 +#define ZONIK_DISABLED 0xD1ED +#define ZONIK_ERROR (-1) +#define ZONIK_DBA_LEQ_VALUE 0x00 +#define ZONIK_COUNT_VALUE 0x01 +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name ZONIK command definitions + * @{ + */ +#define ZONIK_CMD_READ 0x01 +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name ZONIK sensor type + * @{ + */ +extern const struct sensors_sensor zonik; +/** @} */ +/* -------------------------------------------------------------------------- */ +#endif +/* -------------------------------------------------------------------------- */ +/** + * @} + * @} + */ From d3980668eedfbb695e0b0fc772677161977cf40c Mon Sep 17 00:00:00 2001 From: Robert Olsson Date: Mon, 22 Feb 2016 20:14:06 +0100 Subject: [PATCH 040/374] Adding support for AtMega128RFR2 and AtMega256RFR2 --- cpu/avr/dev/clock-avr.h | 2 +- cpu/avr/dev/rs232.c | 2 +- cpu/avr/dev/rs232.h | 4 + .../radio/rf230bb/atmega256rfr2_registermap.h | 398 ++++++++++++++++++ cpu/avr/radio/rf230bb/hal.h | 12 +- cpu/avr/radio/rf230bb/halbb.c | 33 +- cpu/avr/radio/rf230bb/rf230bb.c | 49 ++- cpu/avr/radio/rf230bb/rf230bb.h | 6 +- cpu/avr/rtimer-arch.c | 2 +- 9 files changed, 478 insertions(+), 30 deletions(-) create mode 100644 cpu/avr/radio/rf230bb/atmega256rfr2_registermap.h diff --git a/cpu/avr/dev/clock-avr.h b/cpu/avr/dev/clock-avr.h index 97a79ee23..662bd21d3 100644 --- a/cpu/avr/dev/clock-avr.h +++ b/cpu/avr/dev/clock-avr.h @@ -73,7 +73,7 @@ TIMSK0 = _BV (OCIE0A); -#elif defined (__AVR_ATmega1284P__) || (__AVR_AT90USB1287__) || (__AVR_ATmega1281__) || defined (__AVR_ATmega128RFA1__) +#elif defined (__AVR_ATmega1284P__) || (__AVR_AT90USB1287__) || (__AVR_ATmega1281__) || defined (__AVR_ATmega128RFA1__) || defined (__AVR_ATmega128RFR2__) || defined (__AVR_ATmega256RFR2__) /* The Raven has a 32768Hz watch crystal that can be used to clock the timer while the 1284p is sleeping. The Jackdaw has pads for a crystal. The crystal diff --git a/cpu/avr/dev/rs232.c b/cpu/avr/dev/rs232.c index 94cf5035f..2df263491 100644 --- a/cpu/avr/dev/rs232.c +++ b/cpu/avr/dev/rs232.c @@ -83,7 +83,7 @@ #define NUMPORTS RS232_CONF_NUMPORTS #endif -#if defined (__AVR_ATmega128__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega128RFA1__) +#if defined (__AVR_ATmega128__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) #ifndef NUMPORTS #define NUMPORTS 2 #elif NUMPORTS > 2 diff --git a/cpu/avr/dev/rs232.h b/cpu/avr/dev/rs232.h index 08a3d4f9f..f7e962204 100644 --- a/cpu/avr/dev/rs232.h +++ b/cpu/avr/dev/rs232.h @@ -49,6 +49,10 @@ #include "dev/rs232_at90usb1287.h" #elif defined (__AVR_ATmega128RFA1__) #include "dev/rs232_atmega128rfa1.h" +#elif defined (__AVR_ATmega128RFR2__) +#include "dev/rs232_atmega128rfa1.h" +#elif defined (__AVR_ATmega256RFR2__) +#include "dev/rs232_atmega128rfa1.h" #elif defined (__AVR_ATmega644__) || defined (__AVR_ATmega328P__) #include "dev/rs232_atmega644.h" #elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega8515__) \ diff --git a/cpu/avr/radio/rf230bb/atmega256rfr2_registermap.h b/cpu/avr/radio/rf230bb/atmega256rfr2_registermap.h new file mode 100644 index 000000000..bc737de9a --- /dev/null +++ b/cpu/avr/radio/rf230bb/atmega256rfr2_registermap.h @@ -0,0 +1,398 @@ +/** + * @file + * @brief This file contains RF230-formatted register definitions for the atmega128rfa1 + */ +/* Copyright (c) 2008, 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: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. +*/ + +#ifndef PHY256RFR2_REGISTERMAP_EXTERNAL_H +#define PHY256RFR2_REGISTERMAP_EXTERNAL_H + +/* RF230 register access is through SPI which transfers 8 bits address/8 bits data. + * ATmega128rfa1 registers are defined in I/O space, e.g. in gcc /include/avr/iom128rfa1.h + * A typical definition is #define TRX_STATUS _SFR_MEM8(0x141) + * Registers can be read with a macro, but the args for subregisters don't expand properly so the actual address + * is used with explicit _SFR_MEM8 in the subregister read/write routines. + */ +#define RG_TRX_STATUS TRX_STATUS +#define SR_TRX_STATUS 0x141, 0x1f, 0 +#define SR_TRX_CMD 0x142, 0x1f, 0 +#define STATE_TRANSITION (31) +#define SR_TX_PWR 0x145, 0x0f, 0 +#define RG_VERSION_NUM VERSION_NUM +#define RG_MAN_ID_0 MAN_ID_0 +#define RG_IRQ_MASK IRQ_MASK +#define SR_MAX_FRAME_RETRIES 0x16C, 0xf0, 4 +#define SR_TX_AUTO_CRC_ON 0x144, 0x20, 5 +#define SR_TRAC_STATUS 0x142, 0xe0, 5 +#define SR_CHANNEL 0x148, 0x1f, 0 +#define SR_CCA_MODE 0x148, 0x60, 5 +#define SR_CCA_REQUEST 0x148, 0x80, 7 +#define RG_PAN_ID_0 PAN_ID_0 +#define RG_PAN_ID_1 PAN_ID_1 +#define RG_SHORT_ADDR_0 SHORT_ADDR_0 +#define RG_SHORT_ADDR_1 SHORT_ADDR_1 +#define RG_IEEE_ADDR_0 IEEE_ADDR_0 +#define RG_IEEE_ADDR_1 IEEE_ADDR_1 +#define RG_IEEE_ADDR_2 IEEE_ADDR_2 +#define RG_IEEE_ADDR_3 IEEE_ADDR_3 +#define RG_IEEE_ADDR_4 IEEE_ADDR_4 +#define RG_IEEE_ADDR_5 IEEE_ADDR_5 +#define RG_IEEE_ADDR_6 IEEE_ADDR_6 +#define RG_IEEE_ADDR_7 IEEE_ADDR_7 +//#define SR_ED_LEVEL 0x147, 0xff, 0 +#define RG_PHY_ED_LEVEL PHY_ED_LEVEL +#define RG_RX_SYN RX_SYN +#define SR_RSSI 0x146, 0x1f, 0 +#define SR_RX_SYN 0x155, 0xff, 0 +#define SR_TRX_RPC 0x156, 0xff, 0 +#define SR_XAH_CTRL_1 0x157, 0xf5, 2 +#define SR_PLL_CF_START 0x15a, 0x80, 7 +#define SR_PLL_DCU_START 0x15b, 0x80, 7 +#define SR_MAX_CSMA_RETRIES 0x16c, 0x0e, 1 +#define RG_CSMA_BE CSMA_BE +#define RG_CSMA_SEED_0 CSMA_SEED_0 +#define RG_PHY_RSSI PHY_RSSI +//#define SR_CCA_CS_THRES 0x149, 0xf0, 4 +#define SR_CCA_ED_THRES 0x149, 0x0f, 0 +#define SR_CCA_DONE 0x141, 0x80, 7 +#define SR_CCA_STATUS 0x141, 0x40, 6 +#define SR_AACK_SET_PD 0x16e, 0x20, 5 +#define SR_CSMA_SEED_1 0x16e, 0x10, 4 + +/* RF230 register assignments, for reference */ +#if 1 +//#define HAVE_REGISTER_MAP (1) +/** Offset for register TRX_STATUS */ +//#define RG_TRX_STATUS (0x01) +/** Access parameters for sub-register CCA_DONE in register @ref RG_TRX_STATUS */ +//#define SR_CCA_DONE 0x01, 0x80, 7 +/** Access parameters for sub-register CCA_STATUS in register @ref RG_TRX_STATUS */ +//#define SR_CCA_STATUS 0x01, 0x40, 6 +//#define SR_reserved_01_3 0x01, 0x20, 5 +/** Access parameters for sub-register TRX_STATUS in register @ref RG_TRX_STATUS */ +//#define SR_TRX_STATUS 0x01, 0x1f, 0 +/** Constant P_ON for sub-register @ref SR_TRX_STATUS */ +//#define P_ON (0) +/** Constant BUSY_RX for sub-register @ref SR_TRX_STATUS */ +#define BUSY_RX (1) +/** Constant BUSY_TX for sub-register @ref SR_TRX_STATUS */ +#define BUSY_TX (2) +/** Constant RX_ON for sub-register @ref SR_TRX_STATUS */ +#define RX_ON (6) +/** Constant TRX_OFF for sub-register @ref SR_TRX_STATUS */ +#define TRX_OFF (8) +/** Constant PLL_ON for sub-register @ref SR_TRX_STATUS */ +#define PLL_ON (9) +/** Constant SLEEP for sub-register @ref SR_TRX_STATUS */ +//#define SLEEP (15) +/** Constant BUSY_RX_AACK for sub-register @ref SR_TRX_STATUS */ +#define BUSY_RX_AACK (17) +/** Constant BUSY_TX_ARET for sub-register @ref SR_TRX_STATUS */ +#define BUSY_TX_ARET (18) +/** Constant RX_AACK_ON for sub-register @ref SR_TRX_STATUS */ +#define RX_AACK_ON (22) +/** Constant TX_ARET_ON for sub-register @ref SR_TRX_STATUS */ +#define TX_ARET_ON (25) +/** Constant RX_ON_NOCLK for sub-register @ref SR_TRX_STATUS */ +//#define RX_ON_NOCLK (28) +/** Constant RX_AACK_ON_NOCLK for sub-register @ref SR_TRX_STATUS */ +//#define RX_AACK_ON_NOCLK (29) +/** Constant BUSY_RX_AACK_NOCLK for sub-register @ref SR_TRX_STATUS */ +//#define BUSY_RX_AACK_NOCLK (30) +/** Constant STATE_TRANSITION for sub-register @ref SR_TRX_STATUS */ +//#define STATE_TRANSITION (31) + +/** Offset for register TRX_STATE */ +//#define RG_TRX_STATE (0x02) +/** Access parameters for sub-register TRAC_STATUS in register @ref RG_TRX_STATE */ +//#define SR_TRAC_STATUS 0x02, 0xe0, 5 +/** Access parameters for sub-register TRX_CMD in register @ref RG_TRX_STATE */ +//#define SR_TRX_CMD 0x02, 0x1f, 0 +/** Constant CMD_NOP for sub-register @ref SR_TRX_CMD */ +//#define CMD_NOP (0) +/** Constant CMD_TX_START for sub-register @ref SR_TRX_CMD */ +//#define CMD_TX_START (2) +/** Constant CMD_FORCE_TRX_OFF for sub-register @ref SR_TRX_CMD */ +#define CMD_FORCE_TRX_OFF (3) +///** Constant CMD_RX_ON for sub-register @ref SR_TRX_CMD */ +//#define CMD_RX_ON (6) +///** Constant CMD_TRX_OFF for sub-register @ref SR_TRX_CMD */ +//#define CMD_TRX_OFF (8) +///** Constant CMD_PLL_ON for sub-register @ref SR_TRX_CMD */ +//#define CMD_PLL_ON (9) +///** Constant CMD_RX_AACK_ON for sub-register @ref SR_TRX_CMD */ +//#define CMD_RX_AACK_ON (22) +///** Constant CMD_TX_ARET_ON for sub-register @ref SR_TRX_CMD */ +//#define CMD_TX_ARET_ON (25) +///** Offset for register TRX_CTRL_0 */ +//#define RG_TRX_CTRL_0 (0x03) +///** Offset for register TRX_CTRL_1 */ +//#define RG_TRX_CTRL_1 (0x04) +///** Access parameters for sub-register PAD_IO in register @ref RG_TRX_CTRL_0 */ +//#define SR_PAD_IO 0x03, 0xc0, 6 +///** Access parameters for sub-register PAD_IO_CLKM in register @ref RG_TRX_CTRL_0 */ +//#define SR_PAD_IO_CLKM 0x03, 0x30, 4 +///** Constant CLKM_2mA for sub-register @ref SR_PAD_IO_CLKM */ +//#define CLKM_2mA (0) +///** Constant CLKM_4mA for sub-register @ref SR_PAD_IO_CLKM */ +//#define CLKM_4mA (1) +///** Constant CLKM_6mA for sub-register @ref SR_PAD_IO_CLKM */ +//#define CLKM_6mA (2) +///** Constant CLKM_8mA for sub-register @ref SR_PAD_IO_CLKM */ +//#define CLKM_8mA (3) +///** Access parameters for sub-register CLKM_SHA_SEL in register @ref RG_TRX_CTRL_0 */ +//#define SR_CLKM_SHA_SEL 0x03, 0x08, 3 +///** Access parameters for sub-register CLKM_CTRL in register @ref RG_TRX_CTRL_0 */ +//#define SR_CLKM_CTRL 0x03, 0x07, 0 +///** Constant CLKM_no_clock for sub-register @ref SR_CLKM_CTRL */ +//#define CLKM_no_clock (0) +///** Constant CLKM_1MHz for sub-register @ref SR_CLKM_CTRL */ +//#define CLKM_1MHz (1) +///** Constant CLKM_2MHz for sub-register @ref SR_CLKM_CTRL */ +//#define CLKM_2MHz (2) +///** Constant CLKM_4MHz for sub-register @ref SR_CLKM_CTRL */ +//#define CLKM_4MHz (3) +///** Constant CLKM_8MHz for sub-register @ref SR_CLKM_CTRL */ +//#define CLKM_8MHz (4) +///** Constant CLKM_16MHz for sub-register @ref SR_CLKM_CTRL */ +//#define CLKM_16MHz (5) +///** Offset for register PHY_TX_PWR */ +//#define RG_PHY_TX_PWR (0x05) +///** Access parameters for sub-register TX_AUTO_CRC_ON in register @ref RG_PHY_TX_PWR */ +//#define SR_TX_AUTO_CRC_ON 0x05, 0x80, 7 +//#define SR_reserved_05_2 0x05, 0x70, 4 +///** Access parameters for sub-register TX_PWR in register @ref RG_PHY_TX_PWR */ +//#define SR_TX_PWR 0x05, 0x0f, 0 +///** Offset for register PHY_RSSI */ +//#define RG_PHY_RSSI (0x06) +//#define SR_reserved_06_1 0x06, 0xe0, 5 +///** Access parameters for sub-register RSSI in register @ref RG_PHY_RSSI */ +//#define SR_RSSI 0x06, 0x1f, 0 +///** Offset for register PHY_ED_LEVEL */ +//#define RG_PHY_ED_LEVEL (0x07) +///** Access parameters for sub-register ED_LEVEL in register @ref RG_PHY_ED_LEVEL */ +//#define SR_ED_LEVEL 0x07, 0xff, 0 +///** Offset for register PHY_CC_CCA */ +//#define RG_PHY_CC_CCA (0x08) +///** Access parameters for sub-register CCA_REQUEST in register @ref RG_PHY_CC_CCA */ +//#define SR_CCA_REQUEST 0x08, 0x80, 7 +///** Access parameters for sub-register CCA_MODE in register @ref RG_PHY_CC_CCA */ +//#define SR_CCA_MODE 0x08, 0x60, 5 +///** Access parameters for sub-register CHANNEL in register @ref RG_PHY_CC_CCA */ +//#define SR_CHANNEL 0x08, 0x1f, 0 +///** Offset for register CCA_THRES */ +//#define RG_CCA_THRES (0x09) +///** Access parameters for sub-register CCA_CS_THRES in register @ref RG_CCA_THRES */ +//#define SR_CCA_CS_THRES 0x09, 0xf0, 4 +///** Access parameters for sub-register CCA_ED_THRES in register @ref RG_CCA_THRES */ +//#define SR_CCA_ED_THRES 0x09, 0x0f, 0 +///** Offset for register IRQ_MASK */ +//#define RG_IRQ_MASK (0x0e) +///** Access parameters for sub-register IRQ_MASK in register @ref RG_IRQ_MASK */ +//#define SR_IRQ_MASK 0x0e, 0xff, 0 +///** Offset for register IRQ_STATUS */ +//#define RG_IRQ_STATUS (0x0f) +///** Access parameters for sub-register IRQ_7_BAT_LOW in register @ref RG_IRQ_STATUS */ +//#define SR_IRQ_7_BAT_LOW 0x0f, 0x80, 7 +///** Access parameters for sub-register IRQ_6_TRX_UR in register @ref RG_IRQ_STATUS */ +//#define SR_IRQ_6_TRX_UR 0x0f, 0x40, 6 +///** Access parameters for sub-register IRQ_5 in register @ref RG_IRQ_STATUS */ +//#define SR_IRQ_5 0x0f, 0x20, 5 +///** Access parameters for sub-register IRQ_4 in register @ref RG_IRQ_STATUS */ +//#define SR_IRQ_4 0x0f, 0x10, 4 +///** Access parameters for sub-register IRQ_3_TRX_END in register @ref RG_IRQ_STATUS */ +//#define SR_IRQ_3_TRX_END 0x0f, 0x08, 3 +///** Access parameters for sub-register IRQ_2_RX_START in register @ref RG_IRQ_STATUS */ +//#define SR_IRQ_2_RX_START 0x0f, 0x04, 2 +///** Access parameters for sub-register IRQ_1_PLL_UNLOCK in register @ref RG_IRQ_STATUS */ +//#define SR_IRQ_1_PLL_UNLOCK 0x0f, 0x02, 1 +///** Access parameters for sub-register IRQ_0_PLL_LOCK in register @ref RG_IRQ_STATUS */ +//#define SR_IRQ_0_PLL_LOCK 0x0f, 0x01, 0 +///** Offset for register VREG_CTRL */ +//#define RG_VREG_CTRL (0x10) +///** Access parameters for sub-register AVREG_EXT in register @ref RG_VREG_CTRL */ +//#define SR_AVREG_EXT 0x10, 0x80, 7 +///** Access parameters for sub-register AVDD_OK in register @ref RG_VREG_CTRL */ +//#define SR_AVDD_OK 0x10, 0x40, 6 +///** Access parameters for sub-register AVREG_TRIM in register @ref RG_VREG_CTRL */ +//#define SR_AVREG_TRIM 0x10, 0x30, 4 +///** Constant AVREG_1_80V for sub-register @ref SR_AVREG_TRIM */ +//#define AVREG_1_80V (0) +///** Constant AVREG_1_75V for sub-register @ref SR_AVREG_TRIM */ +//#define AVREG_1_75V (1) +///** Constant AVREG_1_84V for sub-register @ref SR_AVREG_TRIM */ +//#define AVREG_1_84V (2) +///** Constant AVREG_1_88V for sub-register @ref SR_AVREG_TRIM */ +//#define AVREG_1_88V (3) +///** Access parameters for sub-register DVREG_EXT in register @ref RG_VREG_CTRL */ +//#define SR_DVREG_EXT 0x10, 0x08, 3 +///** Access parameters for sub-register DVDD_OK in register @ref RG_VREG_CTRL */ +//#define SR_DVDD_OK 0x10, 0x04, 2 +///** Access parameters for sub-register DVREG_TRIM in register @ref RG_VREG_CTRL */ +//#define SR_DVREG_TRIM 0x10, 0x03, 0 +///** Constant DVREG_1_80V for sub-register @ref SR_DVREG_TRIM */ +//#define DVREG_1_80V (0) +///** Constant DVREG_1_75V for sub-register @ref SR_DVREG_TRIM */ +//#define DVREG_1_75V (1) +///** Constant DVREG_1_84V for sub-register @ref SR_DVREG_TRIM */ +//#define DVREG_1_84V (2) +///** Constant DVREG_1_88V for sub-register @ref SR_DVREG_TRIM */ +//#define DVREG_1_88V (3) +///** Offset for register BATMON */ +//#define RG_BATMON (0x11) +//#define SR_reserved_11_1 0x11, 0xc0, 6 +///** Access parameters for sub-register BATMON_OK in register @ref RG_BATMON */ +//#define SR_BATMON_OK 0x11, 0x20, 5 +///** Access parameters for sub-register BATMON_HR in register @ref RG_BATMON */ +//#define SR_BATMON_HR 0x11, 0x10, 4 +///** Access parameters for sub-register BATMON_VTH in register @ref RG_BATMON */ +//#define SR_BATMON_VTH 0x11, 0x0f, 0 +///** Offset for register XOSC_CTRL */ +//#define RG_XOSC_CTRL (0x12) +///** Offset for register RX_SYN */ +//#define RG_RX_SYN 0x15 +///** Offset for register XAH_CTRL_1 */ +//#define RG_XAH_CTRL_1 0x17 +///** Access parameters for sub-register XTAL_MODE in register @ref RG_XOSC_CTRL */ +//#define SR_XTAL_MODE 0x12, 0xf0, 4 +///** Access parameters for sub-register XTAL_TRIM in register @ref RG_XOSC_CTRL */ +//#define SR_XTAL_TRIM 0x12, 0x0f, 0 +///** Offset for register FTN_CTRL */ +//#define RG_FTN_CTRL (0x18) +///** Access parameters for sub-register FTN_START in register @ref RG_FTN_CTRL */ +//#define SR_FTN_START 0x18, 0x80, 7 +//#define SR_reserved_18_2 0x18, 0x40, 6 +///** Access parameters for sub-register FTNV in register @ref RG_FTN_CTRL */ +//#define SR_FTNV 0x18, 0x3f, 0 +///** Offset for register PLL_CF */ +//#define RG_PLL_CF (0x1a) +///** Access parameters for sub-register PLL_CF_START in register @ref RG_PLL_CF */ +//#define SR_PLL_CF_START 0x1a, 0x80, 7 +//#define SR_reserved_1a_2 0x1a, 0x70, 4 +///** Access parameters for sub-register PLL_CF in register @ref RG_PLL_CF */ +//#define SR_PLL_CF 0x1a, 0x0f, 0 +///** Offset for register PLL_DCU */ +//#define RG_PLL_DCU (0x1b) +///** Access parameters for sub-register PLL_DCU_START in register @ref RG_PLL_DCU */ +//#define SR_PLL_DCU_START 0x1b, 0x80, 7 +//#define SR_reserved_1b_2 0x1b, 0x40, 6 +///** Access parameters for sub-register PLL_DCUW in register @ref RG_PLL_DCU */ +//#define SR_PLL_DCUW 0x1b, 0x3f, 0 +///** Offset for register PART_NUM */ +//#define RG_PART_NUM (0x1c) +///** Access parameters for sub-register PART_NUM in register @ref RG_PART_NUM */ +//#define SR_PART_NUM 0x1c, 0xff, 0 +///** Constant RF230 for sub-register @ref SR_PART_NUM */ +//#define RF230 (2) +///** Offset for register VERSION_NUM */ +//#define RG_VERSION_NUM (0x1d) +///** Access parameters for sub-register VERSION_NUM in register @ref RG_VERSION_NUM */ +//#define SR_VERSION_NUM 0x1d, 0xff, 0 +///** Offset for register MAN_ID_0 */ +//#define RG_MAN_ID_0 (0x1e) +///** Access parameters for sub-register MAN_ID_0 in register @ref RG_MAN_ID_0 */ +//#define SR_MAN_ID_0 0x1e, 0xff, 0 +///** Offset for register MAN_ID_1 */ +//#define RG_MAN_ID_1 (0x1f) +///** Access parameters for sub-register MAN_ID_1 in register @ref RG_MAN_ID_1 */ +//#define SR_MAN_ID_1 0x1f, 0xff, 0 +///** Offset for register SHORT_ADDR_0 */ +//#define RG_SHORT_ADDR_0 (0x20) +///** Access parameters for sub-register SHORT_ADDR_0 in register @ref RG_SHORT_ADDR_0 */ +//#define SR_SHORT_ADDR_0 0x20, 0xff, 0 +///** Offset for register SHORT_ADDR_1 */ +//#define RG_SHORT_ADDR_1 (0x21) +///** Access parameters for sub-register SHORT_ADDR_1 in register @ref RG_SHORT_ADDR_1 */ +//#define SR_SHORT_ADDR_1 0x21, 0xff, 0 +///** Offset for register PAN_ID_0 */ +//#define RG_PAN_ID_0 (0x22) +///** Access parameters for sub-register PAN_ID_0 in register @ref RG_PAN_ID_0 */ +//#define SR_PAN_ID_0 0x22, 0xff, 0 +///** Offset for register PAN_ID_1 */ +//#define RG_PAN_ID_1 (0x23) +///** Access parameters for sub-register PAN_ID_1 in register @ref RG_PAN_ID_1 */ +//#define SR_PAN_ID_1 0x23, 0xff, 0 +///** Offset for register IEEE_ADDR_0 */ +//#define RG_IEEE_ADDR_0 (0x24) +///** Access parameters for sub-register IEEE_ADDR_0 in register @ref RG_IEEE_ADDR_0 */ +//#define SR_IEEE_ADDR_0 0x24, 0xff, 0 +///** Offset for register IEEE_ADDR_1 */ +//#define RG_IEEE_ADDR_1 (0x25) +///** Access parameters for sub-register IEEE_ADDR_1 in register @ref RG_IEEE_ADDR_1 */ +//#define SR_IEEE_ADDR_1 0x25, 0xff, 0 +///** Offset for register IEEE_ADDR_2 */ +//#define RG_IEEE_ADDR_2 (0x26) +///** Access parameters for sub-register IEEE_ADDR_2 in register @ref RG_IEEE_ADDR_2 */ +//#define SR_IEEE_ADDR_2 0x26, 0xff, 0 +///** Offset for register IEEE_ADDR_3 */ +//#define RG_IEEE_ADDR_3 (0x27) +///** Access parameters for sub-register IEEE_ADDR_3 in register @ref RG_IEEE_ADDR_3 */ +//#define SR_IEEE_ADDR_3 0x27, 0xff, 0 +///** Offset for register IEEE_ADDR_4 */ +//#define RG_IEEE_ADDR_4 (0x28) +///** Access parameters for sub-register IEEE_ADDR_4 in register @ref RG_IEEE_ADDR_4 */ +//#define SR_IEEE_ADDR_4 0x28, 0xff, 0 +///** Offset for register IEEE_ADDR_5 */ +//#define RG_IEEE_ADDR_5 (0x29) +///** Access parameters for sub-register IEEE_ADDR_5 in register @ref RG_IEEE_ADDR_5 */ +//#define SR_IEEE_ADDR_5 0x29, 0xff, 0 +///** Offset for register IEEE_ADDR_6 */ +//#define RG_IEEE_ADDR_6 (0x2a) +///** Access parameters for sub-register IEEE_ADDR_6 in register @ref RG_IEEE_ADDR_6 */ +//#define SR_IEEE_ADDR_6 0x2a, 0xff, 0 +///** Offset for register IEEE_ADDR_7 */ +//#define RG_IEEE_ADDR_7 (0x2b) +///** Access parameters for sub-register IEEE_ADDR_7 in register @ref RG_IEEE_ADDR_7 */ +//#define SR_IEEE_ADDR_7 0x2b, 0xff, 0 +///** Offset for register XAH_CTRL */ +//#define RG_XAH_CTRL_0 (0x2c) +///** Access parameters for sub-register MAX_FRAME_RETRIES in register @ref RG_XAH_CTRL_0 */ +//#define SR_MAX_FRAME_RETRIES 0x2c, 0xf0, 4 +///** Access parameters for sub-register MAX_CSMA_RETRIES in register @ref RG_XAH_CTRL_0 */ +//#define SR_MAX_CSMA_RETRIES 0x2c, 0x0e, 1 +//#define SR_reserved_2c_3 0x2c, 0x01, 0 +///** Offset for register CSMA_SEED_0 */ +//#define RG_CSMA_SEED_0 (0x2d) +///** Access parameters for sub-register CSMA_SEED_0 in register @ref RG_CSMA_SEED_0 */ +//#define SR_CSMA_SEED_0 0x2d, 0xff, 0 +///** Offset for register CSMA_SEED_1 */ +//#define RG_CSMA_SEED_1 (0x2e) +///** Offset for register CSMA_BE */ +//#define RG_CSMA_BE 0x2f +///** Access parameters for sub-register MIN_BE in register @ref RG_CSMA_SEED_1 */ +//#define SR_MIN_BE 0x2e, 0xc0, 6 +//#define SR_reserved_2e_2 0x2e, 0x30, 4 +///** Access parameters for sub-register I_AM_COORD in register @ref RG_CSMA_SEED_1 */ +//#define SR_I_AM_COORD 0x2e, 0x08, 3 +///** Access parameters for sub-register CSMA_SEED_1 in register @ref RG_CSMA_SEED_1 */ +//#define SR_CSMA_SEED_1 0x2e, 0x07, 0 +#endif +#endif /* PHY256RFR2y_REGISTERMAP_EXTERNAL_H */ diff --git a/cpu/avr/radio/rf230bb/hal.h b/cpu/avr/radio/rf230bb/hal.h index 737680d68..b28151a0c 100644 --- a/cpu/avr/radio/rf230bb/hal.h +++ b/cpu/avr/radio/rf230bb/hal.h @@ -78,6 +78,7 @@ #define ZIGBIT 4 #define IRIS 5 #define ATMEGA128RFA1 6 +#define ATMEGA256RFR2 7 #if PLATFORM_TYPE == RCB_B /* 1281 rcb */ @@ -145,6 +146,11 @@ # define SLPTRPORT TRXPR # define SLPTRPIN 1 +#elif PLATFORM_TYPE == ATMEGA256RFR2 +/* ATmega1281 with internal AT86RF231 radio */ +# define SLPTRPORT TRXPR +# define SLPTRPIN 1 + #elif CONTIKI_TARGET_MULLE /* mulle 5.2 (TODO: move to platform specific) */ # define SSPORT 3 @@ -233,7 +239,7 @@ * that the source code can directly use. * \{ */ -#if defined(__AVR_ATmega128RFA1__) +#if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) #define hal_set_rst_low( ) ( TRXPR &= ~( 1 << TRXRST ) ) /**< This macro pulls the RST pin low. */ #define hal_set_rst_high( ) ( TRXPR |= ( 1 << TRXRST ) ) /**< This macro pulls the RST pin high. */ @@ -274,7 +280,7 @@ #define HAL_DD_SCK SCKPIN /**< Data Direction bit for SCK. */ #define HAL_DD_MOSI MOSIPIN /**< Data Direction bit for MOSI. */ #define HAL_DD_MISO MISOPIN /**< Data Direction bit for MISO. */ -#endif /* defined(__AVR_ATmega128RFA1__) */ +#endif /* defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega256RFR2__) */ /** \} */ @@ -367,7 +373,7 @@ typedef struct{ void hal_init( void ); /* Hack for atmega128rfa1 with integrated radio. Access registers directly, not through SPI */ -#if defined(__AVR_ATmega128RFA1__) +#if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) //#define hal_register_read(address) _SFR_MEM8((uint16_t)address) #define hal_register_read(address) address uint8_t hal_subregister_read( uint16_t address, uint8_t mask, uint8_t position ); diff --git a/cpu/avr/radio/rf230bb/halbb.c b/cpu/avr/radio/rf230bb/halbb.c index 14ff57256..243e11c03 100644 --- a/cpu/avr/radio/rf230bb/halbb.c +++ b/cpu/avr/radio/rf230bb/halbb.c @@ -74,8 +74,9 @@ extern uint8_t debugflowsize,debugflow[DEBUGFLOWSIZE]; #include "hal.h" #if defined(__AVR_ATmega128RFA1__) -#include #include "atmega128rfa1_registermap.h" +#elif defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) +#include "atmega256rfr2_registermap.h" #else #include "at86rf230_registermap.h" #endif @@ -88,7 +89,7 @@ volatile extern signed char rf230_last_rssi; /*============================ IMPLEMENTATION ================================*/ -#if defined(__AVR_ATmega128RFA1__) +#if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) /* AVR1281 with internal RF231 radio */ #include @@ -158,8 +159,7 @@ inline uint8_t spiWrite(uint8_t byte) /** \brief This function initializes the Hardware Abstraction Layer. */ -#if defined(__AVR_ATmega128RFA1__) - +#if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) void hal_init(void) { @@ -241,8 +241,7 @@ hal_init(void) } #endif /* !__AVR__ */ - -#if defined(__AVR_ATmega128RFA1__) +#if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) /* Hack for internal radio registers. hal_register_read and hal_register_write are handled through defines, but the preprocesser can't parse a macro containing another #define with multiple arguments, e.g. using @@ -279,7 +278,7 @@ hal_subregister_write(uint16_t address, uint8_t mask, uint8_t position, HAL_LEAVE_CRITICAL_REGION(); } -#else /* defined(__AVR_ATmega128RFA1__) */ +#else /* defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) */ /*----------------------------------------------------------------------------*/ /** \brief This function reads data from one of the radio transceiver's registers. * @@ -383,7 +382,7 @@ hal_subregister_write(uint8_t address, uint8_t mask, uint8_t position, /* Write the modified register value. */ hal_register_write(address, value); } -#endif /* defined(__AVR_ATmega128RFA1__) */ +#endif /* defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) */ /*----------------------------------------------------------------------------*/ /** \brief Transfer a frame from the radio transceiver to a RAM buffer * @@ -399,7 +398,7 @@ hal_subregister_write(uint8_t address, uint8_t mask, uint8_t position, void hal_frame_read(hal_rx_frame_t *rx_frame) { -#if defined(__AVR_ATmega128RFA1__) +#if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) uint8_t frame_length,*rx_data,*rx_buffer; @@ -432,7 +431,7 @@ hal_frame_read(hal_rx_frame_t *rx_frame) */ rx_frame->crc = true; -#else /* defined(__AVR_ATmega128RFA1__) */ +#else /* */ uint8_t frame_length, *rx_data; @@ -487,7 +486,7 @@ hal_frame_read(hal_rx_frame_t *rx_frame) HAL_SPI_TRANSFER_CLOSE(); -#endif /* defined(__AVR_ATmega128RFA1__) */ +#endif /* defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) */ } /*----------------------------------------------------------------------------*/ @@ -500,7 +499,7 @@ hal_frame_read(hal_rx_frame_t *rx_frame) void hal_frame_write(uint8_t *write_buffer, uint8_t length) { -#if defined(__AVR_ATmega128RFA1__) +#if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) uint8_t *tx_buffer; tx_buffer=(uint8_t *)0x180; //start of fifo in i/o space /* Write frame length, including the two byte checksum */ @@ -518,7 +517,7 @@ hal_frame_write(uint8_t *write_buffer, uint8_t length) #endif do _SFR_MEM8(tx_buffer++)= *write_buffer++; while (--length); -#else /* defined(__AVR_ATmega128RFA1__) */ +#else /* defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) */ /* Optionally truncate length to maximum frame length. * Not doing this is a fast way to know when the application needs fixing! */ @@ -540,7 +539,7 @@ hal_frame_write(uint8_t *write_buffer, uint8_t length) do HAL_SPI_TRANSFER(*write_buffer++); while (--length); HAL_SPI_TRANSFER_CLOSE(); -#endif /* defined(__AVR_ATmega128RFA1__) */ +#endif /* defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) */ } /*----------------------------------------------------------------------------*/ @@ -632,7 +631,7 @@ volatile char rf230interruptflag; #define INTERRUPTDEBUG(arg) #endif -#if defined(__AVR_ATmega128RFA1__) +#if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) /* The atmega128rfa1 has individual interrupts for the integrated radio' * Whichever are enabled by the RF230 driver must be present even if not used! */ @@ -713,7 +712,7 @@ ISR(TRX24_CCA_ED_DONE_vect) rf230_ccawait=0; } -#else /* defined(__AVR_ATmega128RFA1__) */ +#else /* defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) */ /* Separate RF230 has a single radio interrupt and the source must be read from the IRQ_STATUS register */ HAL_RF230_ISR() { @@ -803,7 +802,7 @@ HAL_RF230_ISR() ; } } -#endif /* defined(__AVR_ATmega128RFA1__) */ +#endif /* defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) */ # endif /* defined(DOXYGEN) */ /** @} */ diff --git a/cpu/avr/radio/rf230bb/rf230bb.c b/cpu/avr/radio/rf230bb/rf230bb.c index d00a24d72..cbe8160ef 100644 --- a/cpu/avr/radio/rf230bb/rf230bb.c +++ b/cpu/avr/radio/rf230bb/rf230bb.c @@ -212,7 +212,7 @@ static unsigned long total_time_for_transmission, total_transmission_len; static int num_transmissions; #endif -#if defined(__AVR_ATmega128RFA1__) +#if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) volatile uint8_t rf230_wakewait, rf230_txendwait, rf230_ccawait; #endif @@ -433,7 +433,21 @@ rf230_waitidle(void) } } -/*----------------------------------------------------------------------------*/ +/* Set reduced power consumption for AtMegaXXXRFR2 MCU's. See AT02594 */ + +static uint8_t rpc = 0xFF; /* Default max power save */ +void +rf230_set_rpc(uint8_t data) +{ + rpc = data; +} + +uint8_t +rf230_get_rpc(void) +{ + return rpc; +} + /** \brief This function will change the current state of the radio * transceiver's internal state machine. * @@ -507,6 +521,10 @@ radio_set_trx_state(uint8_t new_state) /* When the PLL is active most states can be reached in 1us. However, from */ /* TRX_OFF the PLL needs time to activate. */ if (current_state == TRX_OFF){ + +#if defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) + hal_subregister_write(SR_TRX_RPC, rpc); /* Enable RPC features */ +#endif delay_us(TIME_TRX_OFF_TO_PLL_ACTIVE); } else { delay_us(TIME_STATE_TRANSITION_PLL_ACTIVE); @@ -535,7 +553,7 @@ rf230_set_promiscuous_mode(bool isPromiscuous) { #if RF230_CONF_AUTOACK is_promiscuous = isPromiscuous; /* TODO: Figure out when to pass promisc state to 802.15.4 */ -// radio_set_trx_state(is_promiscuous?RX_ON:RX_AACK_ON); + radio_set_trx_state(is_promiscuous?RX_ON:RX_AACK_ON); #endif } @@ -585,7 +603,7 @@ radio_on(void) #if RF230BB_CONF_LEDONPORTE1 PORTE|=(1<1 { uint8_t i; @@ -1658,7 +1695,7 @@ rf230_cca(void) /* Start the CCA, wait till done, return result */ /* Note reading the TRX_STATUS register clears both CCA_STATUS and CCA_DONE bits */ -#if defined(__AVR_ATmega128RFA1__) +#if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) #if 1 //interrupt method /* Disable rx transitions to busy (RX_PDT_BIT) */ /* Note: for speed this resets rx threshold to the compiled default */ diff --git a/cpu/avr/radio/rf230bb/rf230bb.h b/cpu/avr/radio/rf230bb/rf230bb.h index 30de9a1e5..c441e09ab 100644 --- a/cpu/avr/radio/rf230bb/rf230bb.h +++ b/cpu/avr/radio/rf230bb/rf230bb.h @@ -57,6 +57,8 @@ #include "hal.h" #if defined(__AVR_ATmega128RFA1__) #include "atmega128rfa1_registermap.h" +#elif defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) +#include "atmega256rfr2_registermap.h" #else #include "at86rf230_registermap.h" #endif @@ -68,7 +70,7 @@ #define RF230_REVB ( 2 ) #define SUPPORTED_MANUFACTURER_ID ( 31 ) -#if defined(__AVR_ATmega128RFA1__) +#if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) #define RF230_SUPPORTED_INTERRUPT_MASK ( 0xFF ) #else /* RF230 does not support RX_START interrupts in extended mode, but it seems harmless to always enable it. */ @@ -215,6 +217,8 @@ uint8_t rf230_get_channel(void); void rf230_set_pan_addr(unsigned pan,unsigned addr,const uint8_t ieee_addr[8]); void rf230_set_txpower(uint8_t power); uint8_t rf230_get_txpower(void); +void rf230_set_rpc(uint8_t rpc); +uint8_t rf230_get_rpc(void); void rf230_set_promiscuous_mode(bool isPromiscuous); bool rf230_is_ready_to_send(); diff --git a/cpu/avr/rtimer-arch.c b/cpu/avr/rtimer-arch.c index d1d97af7e..3ef22377b 100644 --- a/cpu/avr/rtimer-arch.c +++ b/cpu/avr/rtimer-arch.c @@ -64,7 +64,7 @@ #define OCF3C OCF3B #endif -#if defined(__AVR_ATmega1281__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega128RFA1__) +#if defined(__AVR_ATmega1281__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) #define ETIMSK TIMSK3 #define ETIFR TIFR3 #define TICIE3 ICIE3 From ce8e87d60e32ea61f7a5b2de13d84a3d0b5136c7 Mon Sep 17 00:00:00 2001 From: Robert Olsson Date: Mon, 22 Feb 2016 20:46:07 +0100 Subject: [PATCH 041/374] Adding the avr-rss2 platform based on AtMega256RFR2 --- platform/avr-rss2/Makefile.avr-rss2 | 61 ++ platform/avr-rss2/README.md | 173 +++++ platform/avr-rss2/apps/sniffer/Makefile | 11 + platform/avr-rss2/apps/sniffer/README.md | 25 + platform/avr-rss2/apps/sniffer/host/Makefile | 17 + platform/avr-rss2/apps/sniffer/host/README.md | 38 ++ .../avr-rss2/apps/sniffer/host/wsbridge.c | 459 +++++++++++++ platform/avr-rss2/apps/sniffer/project-conf.h | 51 ++ .../avr-rss2/apps/sniffer/rf230-promisc.pat | 39 ++ .../apps/sniffer/sniffer-example-coap.pcapng | 0 platform/avr-rss2/apps/sniffer/sniffer.c | 67 ++ platform/avr-rss2/apps/sniffer/stub-rdc.c | 100 +++ platform/avr-rss2/contiki-conf.h | 350 ++++++++++ platform/avr-rss2/contiki-main.c | 635 ++++++++++++++++++ platform/avr-rss2/dev/adc.c | 76 +++ platform/avr-rss2/dev/adc.h | 16 + platform/avr-rss2/dev/battery-sensor.c | 87 +++ platform/avr-rss2/dev/button-sensor.c | 41 ++ platform/avr-rss2/dev/co2_sa_kxx-sensor.c | 131 ++++ platform/avr-rss2/dev/co2_sa_kxx-sensor.h | 51 ++ platform/avr-rss2/dev/ds18b20.c | 247 +++++++ platform/avr-rss2/dev/enc28j60_avr.c | 83 +++ platform/avr-rss2/dev/enc28j60_avr.h | 53 ++ platform/avr-rss2/dev/i2c.c | 228 +++++++ platform/avr-rss2/dev/i2c.h | 65 ++ platform/avr-rss2/dev/leds.c | 45 ++ platform/avr-rss2/dev/leds.h | 17 + platform/avr-rss2/dev/light-sensor.c | 64 ++ platform/avr-rss2/dev/light-sensor.h | 45 ++ platform/avr-rss2/dev/pulse-sensor.c | 120 ++++ platform/avr-rss2/dev/pulse-sensor.h | 43 ++ platform/avr-rss2/dev/temp-sensor.c | 292 ++++++++ platform/avr-rss2/dev/temp-sensor.h | 71 ++ platform/avr-rss2/dev/temp_mcu-sensor.c | 90 +++ platform/avr-rss2/dev/temp_mcu-sensor.h | 47 ++ .../AtMega256RFR2-summary-power.dat | 25 + .../examples/avr_radio_power/Makefile | 9 + .../examples/avr_radio_power/README.md | 79 +++ .../avr_radio_power/avr_radio_power.c | 164 +++++ .../examples/avr_radio_power/project-conf.h | 51 ++ .../avr-rss2/examples/hello-sensors/Makefile | 19 + .../avr-rss2/examples/hello-sensors/README.md | 11 + .../examples/hello-sensors/hello-sensors.c | 119 ++++ .../examples/hello-sensors/project-conf.h | 51 ++ .../examples/ipv6/dc-rpl-coap/Makefile | 49 ++ .../examples/ipv6/dc-rpl-coap/README.md | 67 ++ .../ipv6/dc-rpl-coap/coap-client.avr-rss2 | 0 .../examples/ipv6/dc-rpl-coap/coap-client.c | 413 ++++++++++++ .../ipv6/dc-rpl-coap/coap-server.avr-rss2 | 0 .../examples/ipv6/dc-rpl-coap/coap-server.c | 269 ++++++++ .../examples/ipv6/dc-rpl-coap/dc-rpl-coap.csc | 168 +++++ .../ipv6/dc-rpl-coap/dev/dc-hw-sensor.c | 93 +++ .../ipv6/dc-rpl-coap/dev/dc-hw-sensor.h | 46 ++ .../ipv6/dc-rpl-coap/dev/dc-status-sensor.c | 84 +++ .../ipv6/dc-rpl-coap/dev/dc-status-sensor.h | 46 ++ .../ipv6/dc-rpl-coap/dev/dc-vdc-sensor.c | 97 +++ .../ipv6/dc-rpl-coap/dev/dc-vdc-sensor.h | 46 ++ .../examples/ipv6/dc-rpl-coap/er-dc-test.h | 62 ++ .../examples/ipv6/dc-rpl-coap/project-conf.h | 61 ++ .../ipv6/dc-rpl-coap/resources/res-dc-co2.c | 83 +++ .../ipv6/dc-rpl-coap/resources/res-dc-hwcfg.c | 120 ++++ .../dc-rpl-coap/resources/res-dc-status-obs.c | 113 ++++ .../ipv6/dc-rpl-coap/resources/res-dc-vdc.c | 129 ++++ .../examples/ipv6/rpl-border-router/Makefile | 55 ++ .../ipv6/rpl-border-router/README.ETHERNET.md | 66 ++ .../examples/ipv6/rpl-border-router/README.md | 17 + .../ipv6/rpl-border-router/border-router.c | 388 +++++++++++ .../rpl-border-router/enc28j60-ip64-driver.c | 104 +++ .../rpl-border-router/enc28j60-ip64-driver.h | 38 ++ .../ipv6/rpl-border-router/eth-bridge.c | 33 + .../ipv6/rpl-border-router/httpd-simple.c | 261 +++++++ .../ipv6/rpl-border-router/httpd-simple.h | 74 ++ .../ipv6/rpl-border-router/project-conf.h | 57 ++ .../examples/ipv6/rpl-udp-report/Makefile | 21 + .../examples/ipv6/rpl-udp-report/README.md | 17 + .../ipv6/rpl-udp-report/project-conf.h | 51 ++ .../ipv6/rpl-udp-report/report.avr-rss2 | 0 .../examples/ipv6/rpl-udp-report/report.c | 240 +++++++ .../ipv6/rpl-udp-report/rss2-rpl-udp.csc | 167 +++++ .../ipv6/rpl-udp-report/sink.avr-rss2 | 0 .../examples/ipv6/rpl-udp-report/sink.c | 184 +++++ .../examples/ipv6/sensd_client/Makefile | 12 + .../examples/ipv6/sensd_client/README.md | 222 ++++++ .../examples/ipv6/sensd_client/project-conf.h | 51 ++ .../examples/ipv6/sensd_client/sensd_client.c | 188 ++++++ .../examples/ipv6/sensd_client/server.c | 128 ++++ platform/avr-rss2/ip64-conf.h | 42 ++ platform/avr-rss2/params.c | 284 ++++++++ platform/avr-rss2/params.h | 108 +++ platform/avr-rss2/rss2.h | 36 + platform/avr-rss2/slip_uart0.c | 93 +++ 91 files changed, 9349 insertions(+) create mode 100644 platform/avr-rss2/Makefile.avr-rss2 create mode 100644 platform/avr-rss2/README.md create mode 100644 platform/avr-rss2/apps/sniffer/Makefile create mode 100644 platform/avr-rss2/apps/sniffer/README.md create mode 100644 platform/avr-rss2/apps/sniffer/host/Makefile create mode 100644 platform/avr-rss2/apps/sniffer/host/README.md create mode 100644 platform/avr-rss2/apps/sniffer/host/wsbridge.c create mode 100644 platform/avr-rss2/apps/sniffer/project-conf.h create mode 100644 platform/avr-rss2/apps/sniffer/rf230-promisc.pat create mode 100644 platform/avr-rss2/apps/sniffer/sniffer-example-coap.pcapng create mode 100644 platform/avr-rss2/apps/sniffer/sniffer.c create mode 100644 platform/avr-rss2/apps/sniffer/stub-rdc.c create mode 100644 platform/avr-rss2/contiki-conf.h create mode 100644 platform/avr-rss2/contiki-main.c create mode 100644 platform/avr-rss2/dev/adc.c create mode 100644 platform/avr-rss2/dev/adc.h create mode 100644 platform/avr-rss2/dev/battery-sensor.c create mode 100644 platform/avr-rss2/dev/button-sensor.c create mode 100644 platform/avr-rss2/dev/co2_sa_kxx-sensor.c create mode 100644 platform/avr-rss2/dev/co2_sa_kxx-sensor.h create mode 100644 platform/avr-rss2/dev/ds18b20.c create mode 100644 platform/avr-rss2/dev/enc28j60_avr.c create mode 100644 platform/avr-rss2/dev/enc28j60_avr.h create mode 100644 platform/avr-rss2/dev/i2c.c create mode 100644 platform/avr-rss2/dev/i2c.h create mode 100644 platform/avr-rss2/dev/leds.c create mode 100644 platform/avr-rss2/dev/leds.h create mode 100644 platform/avr-rss2/dev/light-sensor.c create mode 100644 platform/avr-rss2/dev/light-sensor.h create mode 100644 platform/avr-rss2/dev/pulse-sensor.c create mode 100644 platform/avr-rss2/dev/pulse-sensor.h create mode 100644 platform/avr-rss2/dev/temp-sensor.c create mode 100644 platform/avr-rss2/dev/temp-sensor.h create mode 100644 platform/avr-rss2/dev/temp_mcu-sensor.c create mode 100644 platform/avr-rss2/dev/temp_mcu-sensor.h create mode 100644 platform/avr-rss2/examples/avr_radio_power/AtMega256RFR2-summary-power.dat create mode 100644 platform/avr-rss2/examples/avr_radio_power/Makefile create mode 100644 platform/avr-rss2/examples/avr_radio_power/README.md create mode 100644 platform/avr-rss2/examples/avr_radio_power/avr_radio_power.c create mode 100644 platform/avr-rss2/examples/avr_radio_power/project-conf.h create mode 100644 platform/avr-rss2/examples/hello-sensors/Makefile create mode 100644 platform/avr-rss2/examples/hello-sensors/README.md create mode 100644 platform/avr-rss2/examples/hello-sensors/hello-sensors.c create mode 100644 platform/avr-rss2/examples/hello-sensors/project-conf.h create mode 100644 platform/avr-rss2/examples/ipv6/dc-rpl-coap/Makefile create mode 100644 platform/avr-rss2/examples/ipv6/dc-rpl-coap/README.md create mode 100644 platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-client.avr-rss2 create mode 100644 platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-client.c create mode 100644 platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-server.avr-rss2 create mode 100644 platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-server.c create mode 100644 platform/avr-rss2/examples/ipv6/dc-rpl-coap/dc-rpl-coap.csc create mode 100644 platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-hw-sensor.c create mode 100644 platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-hw-sensor.h create mode 100644 platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-status-sensor.c create mode 100644 platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-status-sensor.h create mode 100644 platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-vdc-sensor.c create mode 100644 platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-vdc-sensor.h create mode 100644 platform/avr-rss2/examples/ipv6/dc-rpl-coap/er-dc-test.h create mode 100644 platform/avr-rss2/examples/ipv6/dc-rpl-coap/project-conf.h create mode 100644 platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-co2.c create mode 100644 platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-hwcfg.c create mode 100644 platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-status-obs.c create mode 100644 platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-vdc.c create mode 100644 platform/avr-rss2/examples/ipv6/rpl-border-router/Makefile create mode 100644 platform/avr-rss2/examples/ipv6/rpl-border-router/README.ETHERNET.md create mode 100644 platform/avr-rss2/examples/ipv6/rpl-border-router/README.md create mode 100644 platform/avr-rss2/examples/ipv6/rpl-border-router/border-router.c create mode 100644 platform/avr-rss2/examples/ipv6/rpl-border-router/enc28j60-ip64-driver.c create mode 100644 platform/avr-rss2/examples/ipv6/rpl-border-router/enc28j60-ip64-driver.h create mode 100644 platform/avr-rss2/examples/ipv6/rpl-border-router/eth-bridge.c create mode 100644 platform/avr-rss2/examples/ipv6/rpl-border-router/httpd-simple.c create mode 100644 platform/avr-rss2/examples/ipv6/rpl-border-router/httpd-simple.h create mode 100644 platform/avr-rss2/examples/ipv6/rpl-border-router/project-conf.h create mode 100644 platform/avr-rss2/examples/ipv6/rpl-udp-report/Makefile create mode 100644 platform/avr-rss2/examples/ipv6/rpl-udp-report/README.md create mode 100644 platform/avr-rss2/examples/ipv6/rpl-udp-report/project-conf.h create mode 100644 platform/avr-rss2/examples/ipv6/rpl-udp-report/report.avr-rss2 create mode 100644 platform/avr-rss2/examples/ipv6/rpl-udp-report/report.c create mode 100644 platform/avr-rss2/examples/ipv6/rpl-udp-report/rss2-rpl-udp.csc create mode 100644 platform/avr-rss2/examples/ipv6/rpl-udp-report/sink.avr-rss2 create mode 100644 platform/avr-rss2/examples/ipv6/rpl-udp-report/sink.c create mode 100644 platform/avr-rss2/examples/ipv6/sensd_client/Makefile create mode 100644 platform/avr-rss2/examples/ipv6/sensd_client/README.md create mode 100644 platform/avr-rss2/examples/ipv6/sensd_client/project-conf.h create mode 100644 platform/avr-rss2/examples/ipv6/sensd_client/sensd_client.c create mode 100644 platform/avr-rss2/examples/ipv6/sensd_client/server.c create mode 100644 platform/avr-rss2/ip64-conf.h create mode 100644 platform/avr-rss2/params.c create mode 100644 platform/avr-rss2/params.h create mode 100644 platform/avr-rss2/rss2.h create mode 100644 platform/avr-rss2/slip_uart0.c diff --git a/platform/avr-rss2/Makefile.avr-rss2 b/platform/avr-rss2/Makefile.avr-rss2 new file mode 100644 index 000000000..2655b8b4a --- /dev/null +++ b/platform/avr-rss2/Makefile.avr-rss2 @@ -0,0 +1,61 @@ +CONTIKI_TARGET_DIRS = . apps net loader dev + +CONTIKI_CORE=contiki-main +CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.o +CONTIKI_TARGET_SOURCEFILES += contiki-main.c params.c battery-sensor.c i2c.c + +CONTIKI_TARGET_SOURCEFILES += sensors.c button-sensor.c slip_uart0.c slip.c leds.c temp_mcu-sensor.c light-sensor.c adc.c cfs-eeprom.c eeprom.c pulse-sensor.c + +CONTIKI_TARGET_SOURCEFILES += temp-sensor.c + +CONTIKI_TARGET_SOURCEFILES += enc28j60_avr.c +CONTIKI_TARGET_SOURCEFILES += co2_sa_kxx-sensor.c + +CONTIKIAVR=$(CONTIKI)/cpu/avr +CONTIKIBOARD=. + + +ifdef $(MCU) +MCU=$(MCU) +else +MCU=atmega256rfr2 +endif + +ifeq ($(MCU),atmega128rfa1) +CONTIKI_PLAT_DEFS = -DF_CPU=8000000UL -DAUTO_CRC_PADDING=2 +BOOTLOADER_START = 0x1E000 +endif + +ifeq ($(MCU),atmega128rfr2) +CONTIKI_PLAT_DEFS = -DF_CPU=8000000UL -DAUTO_CRC_PADDING=2 +BOOTLOADER_START = 0x1E000 +endif + +ifeq ($(MCU),atmega256rfr2) +CONTIKI_PLAT_DEFS = -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 +BOOTLOADER_START = 0x3E000 +endif + +AVRDUDE_PROGRAMMER=jtag2 + +# For usb devices, you may either use PORT=usb, or (e.g. if you have more than one +# programmer connected) you can use the following trick to find out the serial number: +# +# The example is for an JTAGICE mkII used to program an ATmega128: +# avrdude -v -P usb:xxxx -c jtag2 -p atmega128 +AVRDUDE_PORT=usb:00B000000D79 + +# Additional avrdude options +# Verify off +AVRDUDE_OPTIONS=-V +AVRDUDE_MCU=m256rfr2 + +include $(CONTIKIAVR)/Makefile.avr +include $(CONTIKIAVR)/radio/Makefile.radio + +#MODULES += core/net/mac core/net core/net/mac/sicslowmac core/net/mac/contikimac core/net/llsec core/net/rime + +MODULES += core/net/mac core/net core/net/mac/sicslowmac core/net/mac/contikimac core/net/llsec + + + diff --git a/platform/avr-rss2/README.md b/platform/avr-rss2/README.md new file mode 100644 index 000000000..260a7d4bb --- /dev/null +++ b/platform/avr-rss2/README.md @@ -0,0 +1,173 @@ +Getting Started with Contiki using avr-rss2 +=========================================== +This guide's aim is to help you start using Contiki for RSS2 boards +The platform supports different AtMega-RF boards: + +* Based on MCU AtMega128RFR2 +* Based on MCU AtMega256RFR2 +* Based on MCU AtMega128RFA1 + +Boards looks the same. "Made in EU" labeled on the AtMega256RFR2 boards +The platform and CPU code, are common for both boards, can be found under +`$(CONTIKI)/platfrom/avr-rssa. The port was developed and tested with RSS2. +This guide assumes that you have basic understanding of how to use the +command line and perform basic admin tasks on UNIX family OSs. You should' +also have understanding about the Contiki OS design as well have C +programming skills. + +Boards Features +---------------- +* Chip Antenna. Supercardiod. +* Robust radio performance. Up to 300 meter line-of-sight. +* Unique EUI64 address via chip combined with EEPROM +* Onboard temp sensor DS18B20, +* Light Sensor. +* 32kHz RTC xtal +* Comparator chip and input. +* SW FET, (relay) for power on/off of sensors. +* DC input via LDO up to 25V. +* Standard. 6-pin TTL-USB header for FTDI cable for UART. +* PCB formfactor for cheap project box G.40X IP54 +* Power/current: + ** RX ~10mA (Full RPC AtMegaXXRFR2). + ** Sleep ~45uA @ 16MHz XTAL + ** Sleep ~15uA @ 8MHz using internal oscillator + +* Preprogammed bootloader. +* CE certified by test institute. + +UART +---- +The board has one UART via the 6-pin TTL-USB adapter, The recommended +baudrate is 38400 bps. This speed gives the lowest error with respect +of the used clock frequency used internally. A possible hi-speed is +250000 bps wich gives 0% Error with 16MHz clock. + +Port Features +-------------- +The platform has the following key features: +* Standard, E64 address from built-in chip. +* First hooks for RPC (Reduced Power Consumption) for AtMegaXXXRFR2. + +Toolchain needs +--------------- +The Atmel toolcahin is available in most operating system. +Note. The native OS packages does not yet support the new +AtMega256RfR2 MCU. + +We'll use toolchain from Atmels web-site. You might also consider +Instant Contiki + + +* For Linux. +See http://www.atmel.com/tools/ATMELAVRTOOLCHAINFORLINUX.aspx +Download the proper 8-bit platform 32 or 64 bit. +Unpack unpack under /usr/local +Also add to your search PATH. For example .bashrc add: +export PATH=$PATH:/usr/local/avr8-gnu-toolchain-linux_x86/bin +or +export PATH=$PATH:/usr/local/avr8-gnu-toolchain-linux_x86_64/bin + +For flash programming you'll need avrdude. For OS using apt-get +apt-get install avrdude + +* For Windows. +Goes here + +Contiki build TARGET +-------------------- +make TARGET=avr-rss2 + +For AtMega128RFR2 boards: +make TARGET=avr-rss2 MCU=atmega128rfr2 + +For AtMega128RFA1 boards: +make TARGET=avr-rss2 MCU=atmega128rfa1 + +Flashing +-------- +Programming using avrdude using serial bootloader. (TTL-USB cable) +Press the RESET button. The bootloader with wait for boot commands +for 3 seconds. + +Flashing commnad line example 256k MCU: +avrdude -p m256rfr2 -c stk500v2 -P /dev/ttyUSB0 -b 38400 -e -U flash:w:hello-world.avr-rss2 + +Flashing commnad line example 128k MCU: +avrdude -p m128rfa1 -c avr109 -P /dev/ttyUSB0 -b 38400 -e -U flash:w:hello-world.avr-rss2 + +Older boards may use the avr109 boot loader. The stk500v2 uses the yellow +lED while the avr109 uses the red LED. + +Tested applications and examples +--------------------------------- +hello-world +ipv6/rpl-udp +ipv6/simple-udp-rpl +rime +ipv6/multicast +example-shell Needs symbol.c to be added to project also seems like +in core/dev/serial-line.c process_poll must be replaced with +process_post. + + /* Wake up consumer process */ +- process_poll(&serial_line_process); ++ process_post(&serial_line_process, 0, 0); + +examples/powertrace + +Platform tutorial applications +.----------------------------- +Example to read out various sensors leds serial numbers etc. +platform/avr-rss2/examples/hello-sensors/ + +This example shows the sensd data encoding. But UDP using 6lowpan. +platform/avr-rss2/examles/ipv6/rpl-udp-report/ + +NAT ip64 ethernet GW based on Contiki core/net/ip64 code +platform/avr-rss2/examples/ipv6/rpl-border-router/ + +Regressions tests +----------------- +Travis compile regression for platform: +regression-tests/23-compile-avr + +Port adds newer version of avr-gcc compiler (4.9.2), to support +testing of newwr Atmel MCU as Atmega256RFR2. Work by Atis Elsts + + +Board approvals +--------------- +Summary: +* R&TTE 73/23/EEC, 89/336/EEC and 99/5/EC +* Safety: EN 60950-1:2006 + A12: 2011 +* RF: ETSI EN 300 328 V1.7.1 (2006-10) +* EMC: ETSI EN 301 489-1 V1.9.2 (2011-09), ETSI EN 301 489-17 V2.2.1 (2012-09) +* EMF: EN 62479:2010 +* Human exposure to electromagnetic fields: EN 62479:2010 + +Commercial availability +------------------------ +Through vendor and though resellers. Note board is will only available +were CE approval is covered. This may be further restricted by WEEE. +Contact vendor. For research legislation is more relaxed in most +countries. + +References +---------- +AtMega64/128/256/RFR2 chip documentation available via Atmel. +Schematics and boards description. Available via Radio-Senors +Smart Reduced Power Consumption Techniques. AT02594 available via Atmel. + +ToDo +----- +API for radio power saving settings introduced Atmels app note AT02594. +Also function for the desensitizing RPC resister. + +Vendor info +----------- +http://radio-sensors.com/ + +Maintainer +---------- +Robert Olsson diff --git a/platform/avr-rss2/apps/sniffer/Makefile b/platform/avr-rss2/apps/sniffer/Makefile new file mode 100644 index 000000000..63412a817 --- /dev/null +++ b/platform/avr-rss2/apps/sniffer/Makefile @@ -0,0 +1,11 @@ +DEFINES+=PROJECT_CONF_H=\"project-conf.h\" +PROJECT_SOURCEFILES += stub-rdc.c + +CONTIKI_PROJECT = sniffer + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../../.. + +CONTIKI_WITH_RIME = 1 +include $(CONTIKI)/Makefile.include diff --git a/platform/avr-rss2/apps/sniffer/README.md b/platform/avr-rss2/apps/sniffer/README.md new file mode 100644 index 000000000..fa139878b --- /dev/null +++ b/platform/avr-rss2/apps/sniffer/README.md @@ -0,0 +1,25 @@ +Sniffer application mote side +============================= +This put the radio in sniff mode and should capure all traffic used +on the set channel. + +Default channel +--------------- +26 + +Bulld +----- +make TARGET=avr-rss2 + +Default serial port speed +------------------------- +38400 bps + +More info & uasage +------------------ +Look in the host directory + +Contiki support +--------------- +The code promisc for support is needed. This also adds the sensniff +format. See rf230-promisc.pat for the rf230bb radions. diff --git a/platform/avr-rss2/apps/sniffer/host/Makefile b/platform/avr-rss2/apps/sniffer/host/Makefile new file mode 100644 index 000000000..7308f66a5 --- /dev/null +++ b/platform/avr-rss2/apps/sniffer/host/Makefile @@ -0,0 +1,17 @@ + +CC = gcc +CFLAGS = -c +SOURCES = wsbridge.c +OBJECTS = $(SOURCES:.c=.o) +EXE = wsbridge + +all: $(SOURCES) $(EXE) + +$(EXE): $(OBJECTS) + $(CC) $(OBJECTS) -o $@ + +%.o:%.c + $(CC) $(CFLAGS) $< -o $@ + +clean: + rm *.o diff --git a/platform/avr-rss2/apps/sniffer/host/README.md b/platform/avr-rss2/apps/sniffer/host/README.md new file mode 100644 index 000000000..cb7960d50 --- /dev/null +++ b/platform/avr-rss2/apps/sniffer/host/README.md @@ -0,0 +1,38 @@ +Sniffer application host side +============================= +This a Unix application to link between the serial port having the +sensor node connected and Wireshark or tcpdump. Enclosed is a modified +wsbridge (See copyright i file) code to use the format used by sensniff. + +You can also use sensniff which is a Python script. Author of senssniff +is George Oikonomou (oikonomou@users.sf.net) + +See: +https://github.com/g-oikonomou/sensniff + + +Function +-------- +The mote captures WSN data and formats according sensniff format sends +over the serial line. The data is binary. The wsbridge reads reads serial +line (typically /dev/ttyUSB) on Linux systems decodes the sensnaiff and +create timestamp and adds the the PCAP farming and writes the result to +a FIFO or named pipe. /tmp/wireshark or /tmp/sensniff. + +Bulld +----- +Just use the Makefile. Put binary for convince in your path. + +Usage +----- +* wsbridge /dev/ttYUSB +* wireshart -k -i /tmp/wireshark + +Default serial port speed +------------------------- +38400 bps + +References +---------- +http://www.freaklabs.org/index.php/wsbridge.html +https://github.com/g-oikonomou/sensniff diff --git a/platform/avr-rss2/apps/sniffer/host/wsbridge.c b/platform/avr-rss2/apps/sniffer/host/wsbridge.c new file mode 100644 index 000000000..6809f36a8 --- /dev/null +++ b/platform/avr-rss2/apps/sniffer/host/wsbridge.c @@ -0,0 +1,459 @@ +/******************************************************************* + Copyright (C) 2009 FreakLabs + 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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. + + Originally written by Christopher Wang aka Akiba. + Please post support questions to the FreakLabs forum. + + *******************************************************************/ +/*! + FreakLabs Freakduino/Wireshark Bridge + + This program allows data from the Freakduino to be piped into wireshark. + When the sniffer firmware is loaded into the Freakduino, then the Freakduino + will be in promiscuous mode and will just dump any frames it sees. This + program takes the frame dump and sends it into Wireshark for analysis. The + global header is already set up to inform wireshark that the link layer for + all frames will be in IEEE 802.15.4 format. After that, it is up to the user + to choose any higher layer protocols to decode above 802.15.4 via the + wireshark "enable protocols" menu. + */ + +/* + + Modified for sensniff format. Magic[4] + Vers[1] + CMD[1] + len[1] + Robert Olsson 2015-11-10 + + */ + +/**************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PORTBUFSIZE 32 +#define BUFSIZE 1024 +#define PACKET_FCS 2 +#define DEBUG 1 +#define PIPENAME "/tmp/wireshark" +#define BAUDRATE B38400 + +enum FSM { + START_CAPTURE, + PACKET_CAPTURE +}; + +static int FD_pipe = -1; +static int FD_com = -1; +static uint8_t port_buf[PORTBUFSIZE]; +static uint8_t circ_buf[BUFSIZE]; +static uint16_t rd_idx = 0; +static uint16_t wr_idx = 0; +static uint8_t len; +static uint8_t state = START_CAPTURE; +static uint8_t file_write = 0; +static fd_set fds; +static const uint8_t magic[] = { 0xC1, 0x1F, 0xFE, 0x72 }; + +/**************************************************************************/ +/*! + Open the serial port that we'll be communicating with the Freakduino (sniffer) + through. + */ +/**************************************************************************/ + +int +serial_open(char *portname) +{ + int baud = B38400; + int fd; /* file descriptor for the serial port */ + struct termios tc, tp; + + fd = open(portname, O_RDONLY | O_NOCTTY | O_NDELAY); + + if(fd == -1) { /* if open is unsucessful */ + printf("serial_open: Unable to open %s.\n", portname); + exit(-1); + } + + fcntl(fd, F_GETFL); + fcntl(fd, F_SETFL, O_RDWR); + + tp.c_cflag = baud | CS8 | CLOCAL | CREAD; + tp.c_oflag = 0; /* Raw Input */ + tp.c_lflag = 0; /* No conoical */ + tp.c_oflag &= ~(OLCUC | OCRNL | ONOCR | ONLRET | OFILL | OFDEL | NLDLY | CRDLY); + + /* ignore CR, ignore parity */ + tp.c_iflag = ~(IGNBRK | PARMRK | INPCK | INLCR | IUCLC | IXOFF) | + BRKINT | IGNPAR | ICRNL | IXON | ISIG | ICANON; + + tp.c_lflag &= ~(ECHO | ECHONL); + tp.c_oflag = 0; /* Raw Input */ + tp.c_iflag &= ~ISTRIP; + + tcflush(fd, TCIFLUSH); + + cfsetospeed(&tp, baud); + cfsetispeed(&tp, baud); + + if(tcsetattr(fd, TCSANOW, &tp) < 0) { + perror("Couldn't set term attributes"); + return -1; + } + return fd; +} +/**************************************************************************/ +/*! + Create the named pipe that we will be communicating with wireshark through. + */ +/**************************************************************************/ +static void +named_pipe_create(char *name) +{ + int rv = 0; + rv = mkfifo(name, 0666); + if((rv == -1) && (errno != EEXIST)) { + perror("Error creating named pipe"); + exit(1); + } + + FD_pipe = open(name, O_WRONLY); + + if(FD_pipe == -1) { + perror("Error connecting to named pipe"); + exit(1); + } +} +/**************************************************************************/ +/*! + Write data to the pipe + */ +/**************************************************************************/ +size_t +data_write(const void *ptr, size_t size) +{ + ssize_t bytes = 0; + if(FD_pipe != -1) { + bytes = write(FD_pipe, ptr, size); + } +} +/**************************************************************************/ +/*! + Write the global header to wireshark. This is only done once at the + beginning of the capture. + */ +/**************************************************************************/ +static void +write_global_hdr() +{ + uint32_t magic_number = 0xa1b2c3d4; /* magic number */ + uint16_t version_major = 2; /* major version number */ + uint16_t version_minor = 4; /* minor version number */ + int32_t thiszone = 0; /* GMT to local correction */ + uint32_t sigfigs = 0; /* accuracy of timestamps */ + uint32_t snaplen = 65535; /* max length of captured packets, in octets */ + uint32_t network = 195; /* data link type (DLT) - IEEE 802.15.4 */ + + data_write(&magic_number, sizeof(magic_number)); + data_write(&version_major, sizeof(version_major)); + data_write(&version_minor, sizeof(version_minor)); + data_write(&thiszone, sizeof(thiszone)); + data_write(&sigfigs, sizeof(sigfigs)); + data_write(&snaplen, sizeof(snaplen)); + data_write(&network, sizeof(network)); +} +/**************************************************************************/ +/*! + Write the frame header into wireshark. This is required for the libpcap + format and informs wireshark that a new frame is coming. + */ +/**************************************************************************/ +static void +write_frame_hdr(uint8_t len) +{ + uint32_t ts_sec; /* timestamp seconds */ + uint32_t ts_usec; /* timestamp microseconds */ + uint32_t incl_len; /* number of octets of packet saved in file */ + uint32_t orig_len; /* actual length of packet */ + struct timeval tv; + + gettimeofday(&tv, NULL); + ts_sec = tv.tv_sec; + ts_usec = tv.tv_usec; + incl_len = len; + orig_len = len + PACKET_FCS; + + data_write(&ts_sec, sizeof(ts_sec)); + data_write(&ts_usec, sizeof(ts_usec)); + data_write(&incl_len, sizeof(incl_len)); + data_write(&orig_len, sizeof(orig_len)); +} +/**************************************************************************/ +/*! + Write one frame into wireshark (via the pipe). + */ +/**************************************************************************/ +static void +write_frame(uint8_t frame_len) +{ + uint8_t i; + + /* actual frame length for wireshark should not include FCS */ + frame_len -= PACKET_FCS; + + /* write header to inform WS that new frame has arrived */ + write_frame_hdr(frame_len); + + /* bump rd_idx. we don't want to write the length byte */ + rd_idx = (rd_idx + 1) % BUFSIZE; + + /* write frame into wireshark */ + for(i = 0; i < frame_len; i++) { + data_write(&circ_buf[rd_idx], 1); + rd_idx = (rd_idx + 1) % BUFSIZE; + } + + /* bump rd_idx. we're not using the trailing FCS value */ + rd_idx = (rd_idx + 1) % BUFSIZE; +} +/**************************************************************************/ +/*! + Calculate total number of bytes in buffer. + */ +/**************************************************************************/ +static uint16_t +calc_bytes_in_buf() +{ + if(rd_idx > wr_idx) { + /* read index is greater than write. we must have wrapped around */ + return BUFSIZE - (rd_idx - wr_idx); + } else { + return wr_idx - rd_idx; + } +} +/**************************************************************************/ +/*! + Deal with any received signals. This includes ctrl-C to stop the program. + */ +/**************************************************************************/ +static void +sig_int(int signo) +{ + (void)signo; + if(FD_pipe != -1) { + printf("\nClosing pipe.\n"); + close(FD_pipe); + } + + if(FD_com != -1) { + printf("\nClosing serial port.\n"); + close(FD_com); + } + + printf("\nSignal captured and devices shut down.\n"); + + exit(0); +} +/**************************************************************************/ +/*! + Init the signals we'll be checking for. + */ +/**************************************************************************/ +static void +signal_init(void) +{ + signal(SIGINT, sig_int); + signal(SIGHUP, sig_int); + signal(SIGTERM, sig_int); +} +int got; +int debug; + +/**************************************************************************/ +/*! + Here's the meat of the code. + */ +/**************************************************************************/ +int +main(int argc, char *argv[]) +{ + int nbytes; + uint8_t i; + + got = 0; + + /* capture any signals that will terminate program */ + signal_init(); + + /* make sure the COM port is specified */ + if(argc == 2) { + /* open the COM port */ + if((FD_com = serial_open(argv[1])) == -1) { + printf("Serial port not opened.\n"); + return 0; + } else { + /* set up the select statement for the COM port. */ + FD_ZERO(&fds); + FD_SET(FD_com, &fds); + + printf("Serial port connected. Waiting for wireshark connection.\n"); + printf("Open wireshark and connect to local interface: %s\n", PIPENAME); + } + } else { + printf("Usage: wsbridge .\n"); + return 0; + } + + /* create and open pipe for wireshark */ + named_pipe_create(PIPENAME); + + /* wait for wireshark to connect to pipe. Once wireshark */ + /* connects, then the global header will be written to it. */ + if(FD_pipe != -1) { + write_global_hdr(); + printf("Client connected to pipe.\n"); + } + + for(;;) { + uint16_t bytes_in_buf; + uint8_t frame_len, byte_ctr; + + /* block until there is data in the serial port */ + select(FD_com + 1, &fds, NULL, NULL, NULL); + if(FD_ISSET(FD_com, &fds)) { + int ii; + /* wait for data to come in on the serial port */ + if((nbytes = read(FD_com, port_buf, PORTBUFSIZE)) > 0) { + + if(debug) { + uint8_t p; + printf("read nbytes=%d\n", nbytes); + for(i = 0; i < nbytes; i++) { + printf(" %02X", port_buf[i]); + } + printf("\n"); + } + /* write data to circular buffer. loop through all received bytes */ + for(i = 0; i < nbytes; i++) { + switch(state) { + case START_CAPTURE: + /* new frame starting */ + if((got == 0) && (port_buf[i] == magic[0])) { + got = 1; + } else if((got == 1) && (port_buf[i] == magic[1])) { + got = 2; + } else if((got == 2) && (port_buf[i] == magic[2])) { + got = 3; + } else if((got == 3) && (port_buf[i] == magic[3])) { + got = 4; + if(debug) { + printf("GOT MAGIC i=%d\n", i); + } + } else if((got == 4) && (port_buf[i] == 1)) { + got = 5; + if(debug) { + printf("GOT VERSION i=%d\n", port_buf[i]); + } + } else if((got == 5) && (port_buf[i] == 0)) { + got = 6; + if(debug) { + printf("GOT COMMAND i=%d\n", port_buf[i]); + } + } else if(got == 6) { + len = port_buf[i]; + byte_ctr = 0; + if(debug) { + printf("Len = %02X.\n", len); + } + circ_buf[wr_idx] = len; + wr_idx = (wr_idx + 1) % BUFSIZE; + state = PACKET_CAPTURE; + } else { + got = 0; + } + break; + + case PACKET_CAPTURE: + /* continue capturing bytes until end of frame */ + /* write data to circular buffer and increment index */ + + circ_buf[wr_idx] = port_buf[i]; + /* ////printf("%02X ", circ_buf[wr_idx]); */ + + wr_idx = (wr_idx + 1) % BUFSIZE; + /* track number of received bytes. when received bytes */ + /* equals frame length, then restart state machine and */ + /* write bytes to wireshark */ + byte_ctr++; + if(byte_ctr == (len - 1)) { + state = START_CAPTURE; + file_write = 1; + /* printf("\n"); */ + got = 0; + } + break; + } + fflush(stdout); + } + /* at least one frame has been written. loop through circular buffer */ + /* and write out all completed frames */ + while(file_write) { + /* capture frame length and check buffer to see if one or more frames */ + /* are available. */ + frame_len = circ_buf[rd_idx]; + bytes_in_buf = calc_bytes_in_buf(); + + if(bytes_in_buf > frame_len) { + /* if more than one frame is available, then write one frame to */ + /* wireshark and then see if any more are available. */ + write_frame(frame_len); + } else if(bytes_in_buf == frame_len) { + /* only one frame is available. write to wireshark and then quit */ + /* the loop */ + write_frame(frame_len); + file_write = 0; + } else { + /* less than one frame is available. quit the loop and collect more */ + /* bytes. we normally should not get here. */ + file_write = 0; + } + } + } + } + } +} diff --git a/platform/avr-rss2/apps/sniffer/project-conf.h b/platform/avr-rss2/apps/sniffer/project-conf.h new file mode 100644 index 000000000..d56b19e7d --- /dev/null +++ b/platform/avr-rss2/apps/sniffer/project-conf.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2010, Loughborough University - 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. + */ + +/** + * \file + * Project specific configuration defines for the sniffer example. + * + * \author + * George Oikonomou - + * Robert Olsson - + */ + +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + + +#define NETSTACK_CONF_MAC nullmac_driver +/* Can see other channels. Interesting. */ +/* #define NETSTACK_CONF_MAC csma_driver */ +#define NETSTACK_CONF_RDC stub_rdc_driver + + +#endif /* PROJECT_CONF_H_ */ diff --git a/platform/avr-rss2/apps/sniffer/rf230-promisc.pat b/platform/avr-rss2/apps/sniffer/rf230-promisc.pat new file mode 100644 index 000000000..3e2c98e6f --- /dev/null +++ b/platform/avr-rss2/apps/sniffer/rf230-promisc.pat @@ -0,0 +1,39 @@ +diff --git a/cpu/avr/radio/rf230bb/rf230bb.c b/cpu/avr/radio/rf230bb/rf230bb.c +index 53959d1..b9f2262 100644 +--- a/cpu/avr/radio/rf230bb/rf230bb.c ++++ b/cpu/avr/radio/rf230bb/rf230bb.c +@@ -544,7 +544,7 @@ rf230_set_promiscuous_mode(bool isPromiscuous) { + #if RF230_CONF_AUTOACK + is_promiscuous = isPromiscuous; + /* TODO: Figure out when to pass promisc state to 802.15.4 */ +-// radio_set_trx_state(is_promiscuous?RX_ON:RX_AACK_ON); ++ radio_set_trx_state(is_promiscuous?RX_ON:RX_AACK_ON); + #endif + } + +@@ -1392,6 +1392,25 @@ PROCESS_THREAD(rf230_process, ev, data) + /* Restore interrupts. */ + HAL_LEAVE_CRITICAL_REGION(); + PRINTF("rf230_read: %u bytes lqi %u\n",len,rf230_last_correlation); ++ ++ if(is_promiscuous) { ++ uint8_t i; ++ unsigned const char * rxdata = packetbuf_dataptr(); ++ /* Print magic */ ++ putchar(0xC1); ++ putchar(0x1F); ++ putchar(0xFE); ++ putchar(0x72); ++ /* Print version */ ++ putchar(0x01); ++ /* Print CMD == frame */ ++ putchar(0x00); ++ putchar(len+3); ++ ++ for (i=0;i1 + { + uint8_t i; diff --git a/platform/avr-rss2/apps/sniffer/sniffer-example-coap.pcapng b/platform/avr-rss2/apps/sniffer/sniffer-example-coap.pcapng new file mode 100644 index 000000000..e69de29bb diff --git a/platform/avr-rss2/apps/sniffer/sniffer.c b/platform/avr-rss2/apps/sniffer/sniffer.c new file mode 100644 index 000000000..be572bce1 --- /dev/null +++ b/platform/avr-rss2/apps/sniffer/sniffer.c @@ -0,0 +1,67 @@ +/* + * 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. + * + */ + +/* + Author: Robert Olsson +*/ + +#include "contiki.h" +#include "net/rime/rime.h" +#include "random.h" +#include "dev/button-sensor.h" +#include "dev/leds.h" +#include +/*---------------------------------------------------------------------------*/ + +PROCESS(sniffer_process, "Sniffer process"); +AUTOSTART_PROCESSES(&sniffer_process); + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(sniffer_process, ev, data) +{ + PROCESS_BEGIN(); + + /* + To get rf230bb radio in sniff mode we need to have radio in RX_ON. + The promisc commands fixes this for us. No need to set PAN and + address or MAC to zero is this case. Se Atmel datasheet. There is + a chance other radios works the same way. + */ + + rf230_set_promiscuous_mode(1); + + printf("Sniffer started\n"); + + while(1) { + PROCESS_YIELD(); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/avr-rss2/apps/sniffer/stub-rdc.c b/platform/avr-rss2/apps/sniffer/stub-rdc.c new file mode 100644 index 000000000..a4db0710d --- /dev/null +++ b/platform/avr-rss2/apps/sniffer/stub-rdc.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2010, Loughborough University - 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. + */ + +/** + * \file + * Definition of a fake RDC driver to be used with passive + * examples. The sniffer will never send packets and it will never + * push incoming packets up the stack. We do this by defining this + * driver as our RDC. We then drop everything + * + * \author + * George Oikonomou - + */ + +#include "net/mac/mac.h" +#include "net/mac/rdc.h" +/*---------------------------------------------------------------------------*/ +static void +send(mac_callback_t sent, void *ptr) +{ + if(sent) { + sent(ptr, MAC_TX_OK, 1); + } +} +/*---------------------------------------------------------------------------*/ +static void +send_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *list) +{ + if(sent) { + sent(ptr, MAC_TX_OK, 1); + } +} +/*---------------------------------------------------------------------------*/ +static void +input(void) +{ +} +/*---------------------------------------------------------------------------*/ +static int +on(void) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +off(int keep_radio_on) +{ + return keep_radio_on; +} +/*---------------------------------------------------------------------------*/ +static unsigned short +cca(void) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ +} +/*---------------------------------------------------------------------------*/ +const struct rdc_driver stub_rdc_driver = { + "stub-rdc", + init, + send, + send_list, + input, + on, + off, + cca, +}; +/*---------------------------------------------------------------------------*/ diff --git a/platform/avr-rss2/contiki-conf.h b/platform/avr-rss2/contiki-conf.h new file mode 100644 index 000000000..3e1f5dfc2 --- /dev/null +++ b/platform/avr-rss2/contiki-conf.h @@ -0,0 +1,350 @@ +/* + * Copyright (c) 2006, Technical University of Munich + * 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. + * + * @(#)$$ + */ + +/** + * \file + * Configuration for RSS2 (radio-sensors.com) platform + */ + +#ifndef CONTIKI_CONF_H_ +#define CONTIKI_CONF_H_ + +/* include the project config */ +/* PROJECT_CONF_H might be defined in the project Makefile */ +#ifdef PROJECT_CONF_H +#include PROJECT_CONF_H +#endif + +/* Platform name, type, and MCU clock rate */ +#define PLATFORM_NAME "rss2" +#define PLATFORM_TYPE ATMEGA256RFR2 +#ifndef F_CPU +#define F_CPU 8000000UL +#endif + +#include + +#ifndef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC csma_driver +#endif + +#ifndef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC contikimac_driver +#endif + +#ifndef NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE +#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 +#endif + +#ifndef NETSTACK_CONF_FRAMER +#if NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_FRAMER contikimac_framer +#else +#define NETSTACK_CONF_FRAMER framer_802154 +#endif +#endif + +#ifndef NETSTACK_CONF_RADIO +#define NETSTACK_CONF_RADIO rf230_driver +#endif + +#ifndef CHANNEL_802_15_4 +#define CHANNEL_802_15_4 26 +#endif + +/* AUTOACK receive mode gives better rssi measurements, even if ACK is never requested */ +#ifndef RF230_CONF_AUTOACK +#define RF230_CONF_AUTOACK 1 +#endif + +#define MCUCSR MCUSR + +/* The AVR tick interrupt usually is done with an 8 bit counter around 128 Hz. + * 125 Hz needs slightly more overhead during the interrupt, as does a 32 bit + * clock_time_t. + */ +/* Clock ticks per second */ + +#define CLOCK_CONF_SECOND 128 +typedef unsigned long clock_time_t; +#define CLOCK_LT(a, b) ((signed long)((a) - (b)) < 0) +#define INFINITE_TIME 0xffffffff +/* These routines are not part of the contiki core but can be enabled in cpu/avr/clock.c */ +void clock_delay_msec(uint16_t howlong); +void clock_adjust_ticks(clock_time_t howmany); + +/* The radio needs to interrupt during an rtimer interrupt */ +#define RTIMER_CONF_NESTED_INTERRUPTS 1 + +/* RSS2 boards has a 32768Hz on TIMER2 */ +#define AVR_CONF_USE32KCRYSTAL 1 +#define SLIP_PORT RS232_PORT_0 + +/* Pre-allocated memory for loadable modules heap space (in bytes)*/ +/* Default is 4096. Currently used only when elfloader is present. Not tested on Raven */ +/* #define MMEM_CONF_SIZE 256 */ + +/* Starting address for code received via the codeprop facility. Not tested. */ +typedef unsigned long off_t; +/* #define EEPROMFS_ADDR_CODEPROP 0x8000 */ + +/* Logging adds 200 bytes to program size. RS232 output slows down webserver. */ +/* #define LOG_CONF_ENABLED 1 */ + +/* RADIOSTATS is used in rf230bb, clock.c and the webserver cgi to report radio usage */ +/* It has less overhead than ENERGEST */ +#define RADIOSTATS 1 + +/* More extensive stats, via main loop printfs or webserver status pages */ +#define ENERGEST_CONF_ON 1 + +/* Packet statistics */ +typedef unsigned short uip_stats_t; +#define UIP_STATISTICS 0 + +/* Available watchdog timeouts depend on mcu. Default is WDTO_2S. -1 Disables the watchdog. */ +/* AVR Studio simulator tends to reboot due to clocking the WD 8 times too fast */ +/* #define WATCHDOG_CONF_TIMEOUT -1 */ + +/* Debugflow macro, useful for tracing path through mac and radio interrupts */ +/* #define DEBUGFLOWSIZE 128 */ + +/* Define MAX_*X_POWER to reduce tx power and ignore weak rx packets for testing a miniature multihop network. + * Leave undefined for full power and sensitivity. + * tx=0 (3dbm, default) to 15 (-17.2dbm) + * RF230_CONF_AUTOACK sets the extended mode using the energy-detect register with rx=0 (-91dBm) to 84 (-7dBm) + * else the rssi register is used having range 0 (91dBm) to 28 (-10dBm) + * For simplicity RF230_MIN_RX_POWER is based on the energy-detect value and divided by 3 when autoack is not set. + * On the RF230 a reduced rx power threshold will not prevent autoack if enabled and requested. + * These numbers applied to both Raven and Jackdaw give a maximum communication distance of about 15 cm + * and a 10 meter range to a full-sensitivity RF230 sniffer. + *#define RF230_MAX_TX_POWER 15 + *#define RF230_MIN_RX_POWER 30 + */ +/* The rf231 and atmega128rfa1 can use an rssi threshold for triggering rx_busy that saves 0.5ma in rx mode */ +/* 1 - 15 maps into -90 to -48 dBm; the register is written with RF230_MIN_RX_POWER/6 + 1. Undefine for -100dBm sensitivity */ +/* #define RF230_MIN_RX_POWER 0 */ + +/* Network setup */ +/* TX routine passes the cca/ack result in the return parameter */ +#define RDC_CONF_HARDWARE_ACK 1 +/* TX routine does automatic cca and optional backoffs */ +#define RDC_CONF_HARDWARE_CSMA 1 +/* Allow MCU sleeping between channel checks */ +#define RDC_CONF_MCU_SLEEP 1 + +#if NETSTACK_CONF_WITH_IPV6 +#define LINKADDR_CONF_SIZE 8 +#define UIP_CONF_ICMP6 1 +#define UIP_CONF_UDP 1 +#ifndef UIP_CONF_TCP +#define UIP_CONF_TCP 1 +#endif +#define NETSTACK_CONF_NETWORK sicslowpan_driver +#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 +#else +/* ip4 should build but is largely untested */ +#define LINKADDR_CONF_SIZE 2 +#define NETSTACK_CONF_NETWORK rime_driver +#endif + +#define UIP_CONF_LL_802154 1 +#define UIP_CONF_LLH_LEN 0 + +/* 10 bytes per stateful address context - see sicslowpan.c */ +/* Default is 1 context with prefix aaaa::/64 */ +/* These must agree with all the other nodes or there will be a failure to communicate! */ +#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 1 +#define SICSLOWPAN_CONF_ADDR_CONTEXT_0 { addr_contexts[0].prefix[0] = 0xaa; addr_contexts[0].prefix[1] = 0xaa; } +#define SICSLOWPAN_CONF_ADDR_CONTEXT_1 { addr_contexts[1].prefix[0] = 0xbb; addr_contexts[1].prefix[1] = 0xbb; } +#define SICSLOWPAN_CONF_ADDR_CONTEXT_2 { addr_contexts[2].prefix[0] = 0x20; addr_contexts[2].prefix[1] = 0x01; addr_contexts[2].prefix[2] = 0x49; addr_contexts[2].prefix[3] = 0x78, addr_contexts[2].prefix[4] = 0x1d; addr_contexts[2].prefix[5] = 0xb1; } + +/* Take the default TCP maximum segment size for efficiency and simpler wireshark captures */ +/* Use this to prevent 6LowPAN fragmentation (whether or not fragmentation is enabled) */ +/* #define UIP_CONF_TCP_MSS 48 */ + +#define UIP_CONF_IP_FORWARD 0 +#define UIP_CONF_FWCACHE_SIZE 0 + +#define UIP_CONF_IPV6_CHECKS 1 +#define UIP_CONF_IPV6_QUEUE_PKT 1 +#define UIP_CONF_IPV6_REASSEMBLY 0 + +#define UIP_CONF_UDP_CHECKSUMS 1 +#define UIP_CONF_TCP_SPLIT 1 +#define UIP_CONF_DHCP_LIGHT 1 + +#if 0 /* No radio cycling */ + +#define NETSTACK_CONF_MAC nullmac_driver +#define NETSTACK_CONF_RDC sicslowmac_driver +#define NETSTACK_CONF_FRAMER framer_802154 +/* 1 + Number of auto retry attempts 0-15 (0 implies don't use extended TX_ARET_ON mode) */ +#define RF230_CONF_FRAME_RETRIES 2 +/* Number of csma retry attempts 0-5 in extended tx mode (7 does immediate tx with no csma) */ +#define RF230_CONF_CSMA_RETRIES 5 +/* Default is one RAM buffer for received packets. More than one may benefit multiple TCP connections or ports */ +#define RF230_CONF_RX_BUFFERS 3 +#define SICSLOWPAN_CONF_FRAG 1 +/* Most browsers reissue GETs after 3 seconds which stops fragment reassembly so a longer MAXAGE does no good */ +#define SICSLOWPAN_CONF_MAXAGE 3 +/* How long to wait before terminating an idle TCP connection. Smaller to allow faster sleep. Default is 120 seconds */ +/* If wait is too short the connection can be reset as a result of multiple fragment reassembly timeouts */ +#define UIP_CONF_WAIT_TIMEOUT 20 +/* 54 bytes per queue ref buffer */ +#define QUEUEBUF_CONF_REF_NUM 2 +/* Allocate remaining RAM as desired */ +/* 30 bytes per TCP connection */ +/* 6LoWPAN does not do well with concurrent TCP streams, as new browser GETs collide with packets coming */ +/* from previous GETs, causing decreased throughput, retransmissions, and timeouts. Increase to study this. */ +/* ACKs to other ports become interleaved with computation-intensive GETs, so ACKs are particularly missed. */ +/* Increasing the number of packet receive buffers in RAM helps to keep ACKs from being lost */ +#define UIP_CONF_MAX_CONNECTIONS 4 +/* 2 bytes per TCP listening port */ +#define UIP_CONF_MAX_LISTENPORTS 4 +/* 25 bytes per UDP connection */ +#define UIP_CONF_UDP_CONNS 10 +/* See uip-ds6.h */ +#define NBR_TABLE_CONF_MAX_NEIGHBORS 20 +#define UIP_CONF_DS6_DEFRT_NBU 2 +#define UIP_CONF_DS6_PREFIX_NBU 3 +#define UIP_CONF_MAX_ROUTES 20 +#define UIP_CONF_DS6_ADDR_NBU 3 +#define UIP_CONF_DS6_MADDR_NBU 0 +#define UIP_CONF_DS6_AADDR_NBU 0 + +#elif 1 /* Contiki-mac radio cycling */ +/* #define NETSTACK_CONF_MAC nullmac_driver */ +/* csma needed for burst mode at present. Webserver won't work without it */ +/* #define NETSTACK_CONF_MAC csma_driver */ +/* #define NETSTACK_CONF_RDC contikimac_driver */ +/* Default is two CCA separated by 500 usec */ + +/* So without the header this needed for RPL mesh to form */ +#define CONTIKIMAC_FRAMER_CONF_SHORTEST_PACKET_SIZE (43 - 18) /* multicast RPL DIS length */ +/* Not tested much yet */ +#define CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION 0 +#define CONTIKIMAC_CONF_COMPOWER 1 +#define RIMESTATS_CONF_ENABLED 0 + +/* A 0 here means non-extended mode; 1 means extended mode with no retry, >1 for retrys */ +/* Contikimac strobes on its own, but hardware retries are faster */ +#define RF230_CONF_FRAME_RETRIES 1 +/* Long csma backoffs will compromise radio cycling; set to 0 for 1 csma */ +#define RF230_CONF_CSMA_RETRIES 0 +#define SICSLOWPAN_CONF_FRAG 1 +#define SICSLOWPAN_CONF_MAXAGE 3 +/* 54 bytes per queue ref buffer */ +#define QUEUEBUF_CONF_REF_NUM 2 +/* Allocate remaining RAM. Not much left due to queuebuf increase */ +#define UIP_CONF_MAX_CONNECTIONS 2 +#define UIP_CONF_MAX_LISTENPORTS 4 +#define UIP_CONF_UDP_CONNS 5 +#define NBR_TABLE_CONF_MAX_NEIGHBORS 20 +#define UIP_CONF_DS6_DEFRT_NBU 2 +#define UIP_CONF_DS6_PREFIX_NBU 3 +#define UIP_CONF_MAX_ROUTES 4 +#define UIP_CONF_DS6_ADDR_NBU 3 +#define UIP_CONF_DS6_MADDR_NBU 0 +#define UIP_CONF_DS6_AADDR_NBU 0 + +#elif 0 /* cx-mac radio cycling */ +/* RF230 does clear-channel assessment in extended mode (autoretries>0) */ +/* These values are guesses */ +#define RF230_CONF_FRAME_RETRIES 10 +#define RF230_CONF_CSMA_RETRIES 2 +#if RF230_CONF_CSMA_RETRIES +#define NETSTACK_CONF_MAC nullmac_driver +#else +#define NETSTACK_CONF_MAC csma_driver +#endif +#define NETSTACK_CONF_RDC cxmac_driver +#define NETSTACK_CONF_FRAMER framer_802154 +#define SICSLOWPAN_CONF_FRAG 1 +#define SICSLOWPAN_CONF_MAXAGE 3 +#define CXMAC_CONF_ANNOUNCEMENTS 0 +/* 54 bytes per queue ref buffer */ +#define QUEUEBUF_CONF_REF_NUM 2 +/* Allocate remaining RAM. Not much left due to queuebuf increase */ +#define UIP_CONF_MAX_CONNECTIONS 2 +#define UIP_CONF_MAX_LISTENPORTS 4 +#define UIP_CONF_UDP_CONNS 5 +#define NBR_TABLE_CONF_MAX_NEIGHBORS 4 +#define UIP_CONF_DS6_DEFRT_NBU 2 +#define UIP_CONF_DS6_PREFIX_NBU 3 +#define UIP_CONF_MAX_ROUTES 4 +#define UIP_CONF_DS6_ADDR_NBU 3 +#define UIP_CONF_DS6_MADDR_NBU 0 +#define UIP_CONF_DS6_AADDR_NBU 0 +/* Below gives 10% duty cycle, undef for default 5% */ +/* #define CXMAC_CONF_ON_TIME (RTIMER_ARCH_SECOND / 80) */ +/* Below gives 50% duty cycle */ +/* #define CXMAC_CONF_ON_TIME (RTIMER_ARCH_SECOND / 16) */ + +#else +/* #error Network configuration not specified! */ +#endif /* Network setup */ + +#ifndef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 15 +#endif + +/* ************************************************************************** */ +/* #pragma mark RPL Settings */ +/* ************************************************************************** */ +#if UIP_CONF_IPV6_RPL + +#define UIP_CONF_ROUTER 1 +#define UIP_CONF_ND6_SEND_RA 0 +#define UIP_CONF_ND6_REACHABLE_TIME 600000 +#define UIP_CONF_ND6_RETRANS_TIMER 10000 + +/* For slow slip connections, to prevent buffer overruns */ +/* #define UIP_CONF_RECEIVE_WINDOW 300 */ +#undef UIP_CONF_FWCACHE_SIZE +#define UIP_CONF_BUFFER_SIZE 600 /* DHCPv4 packets by ip64 module */ +#define UIP_CONF_FWCACHE_SIZE 30 +#define UIP_CONF_BROADCAST 1 +#define UIP_ARCH_IPCHKSUM 1 +#define UIP_CONF_PINGADDRCONF 0 +#define UIP_CONF_LOGGING 0 + +#endif /* RPL */ + +#define CCIF +#define CLIF +#ifndef CC_CONF_INLINE +#define CC_CONF_INLINE inline +#endif + +#endif /* CONTIKI_CONF_H_ */ diff --git a/platform/avr-rss2/contiki-main.c b/platform/avr-rss2/contiki-main.c new file mode 100644 index 000000000..172c6139f --- /dev/null +++ b/platform/avr-rss2/contiki-main.c @@ -0,0 +1,635 @@ +/* + * Copyright (c) 2006, Technical University of Munich + * 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. + * + * Reworked for avr-rss2 platform. Robert Olsson + */ + +#define PRINTF(FORMAT, args ...) printf_P(PSTR(FORMAT),##args) + +#define ANNOUNCE_BOOT 1 /* adds about 600 bytes to program size */ +#if ANNOUNCE_BOOT +#define PRINTA(FORMAT, args ...) printf_P(PSTR(FORMAT),##args) +#else +#define PRINTA(...) +#endif + +#define DEBUG 0 +#if DEBUG +#define PRINTD(FORMAT, args ...) printf_P(PSTR(FORMAT),##args) +#else +#define PRINTD(...) +#endif + +#include +#include +#include +#include +#include +#include + +#include "loader/symbols-def.h" +#include "loader/symtab.h" + +#include "params.h" +#include "rss2.h" +#include "leds.h" +#include "i2c.h" +#include "radio/rf230bb/rf230bb.h" +#include "net/mac/frame802154.h" +#include "net/mac/framer-802154.h" +#include "net/ipv6/sicslowpan.h" + +#include "contiki.h" +#include "contiki-net.h" +#include "contiki-lib.h" + +#include "dev/rs232.h" +#include "dev/serial-line.h" +#include "dev/slip.h" + +#if AVR_WEBSERVER +#include "httpd-fs.h" +#include "httpd-cgi.h" +#endif + +#ifdef COFFEE_FILES +#include "cfs/cfs.h" +#include "cfs/cfs-coffee.h" +#endif + +#if UIP_CONF_ROUTER && 0 +#include "net/routing/rimeroute.h" +#include "net/rime/rime-udp.h" +#endif + +#include "net/rime/rime.h" + +/* Track interrupt flow through mac, rdc and radio driver */ +/* #define DEBUGFLOWSIZE 32 */ +#if DEBUGFLOWSIZE +uint8_t debugflowsize, debugflow[DEBUGFLOWSIZE]; +#define DEBUGFLOW(c) if(debugflowsize < (DEBUGFLOWSIZE - 1)) debugflow[debugflowsize++] = c +#else +#define DEBUGFLOW(c) +#endif + +/* Get periodic prints from idle loop, from clock seconds or rtimer interrupts */ +/* Use of rtimer will conflict with other rtimer interrupts such as contikimac radio cycling */ +/* STAMPS will print ENERGEST outputs if that is enabled. */ +#define PERIODICPRINTS 1 +#if PERIODICPRINTS +/* #define PINGS 64 */ +#define ROUTES 600 +#define STAMPS 60 +#define STACKMONITOR 1024 +uint32_t clocktime; +#define TESTRTIMER 0 +#if TESTRTIMER +uint8_t rtimerflag = 1; +struct rtimer rt; +void +rtimercycle(void) +{ + rtimerflag = 1; +} +#endif +#endif + +uint16_t node_id; /* Can be set by cooja */ + +uint16_t ledtimer_red, ledtimer_yellow; +uint16_t i2c_probed; /* i2c devices we have probed */ + + +/*-------------------------------------------------------------------------*/ +/*----------------------Configuration of the .elf file---------------------*/ +#if 1 +/* The proper way to set the signature is */ +#include +#else +/* Older avr-gcc's may not define the needed SIGNATURE bytes. Do it manually if you get an error */ +typedef struct {const unsigned char B2; + const unsigned char B1; + const unsigned char B0; +} __signature_t; +#define SIGNATURE __signature_t __signature __attribute__((section(".signature"))) +SIGNATURE = { + .B2 = 0x01, /* SIGNATURE_2, //ATMEGA128rfa1 */ + .B1 = 0xA7, /* SIGNATURE_1, //128KB flash */ + .B0 = 0x1E, /* SIGNATURE_0, //Atmel */ +}; +#endif + +#if 1 +/* JTAG, SPI enabled, Internal RC osc, Boot flash size 4K, 6CK+65msec delay, brownout disabled */ +FUSES = { .low = 0xe2, .high = 0x99, .extended = 0xff, }; +#else +/* JTAG+SPI, Boot 4096 words @ $F000, Internal oscillator, startup 6 CK +0 ms, Brownout 1.8 volts */ +FUSES = { .low = 0xC2, .high = 0x99, .extended = 0xfe, }; +#endif + +uint8_t +rng_get_uint8(void) +{ +#if 1 + /* Upper two RSSI reg bits (RND_VALUE) are random in rf231 */ + uint8_t j; + j = (PHY_RSSI & 0xc0) + ((PHY_RSSI >> 2) & 0x30) + ((PHY_RSSI >> 4) & 0x0c) + ((PHY_RSSI >> 6) & 0x03); +#else +/* Get a pseudo random number using the ADC */ + uint8_t i, j; + ADCSRA = 1 << ADEN; /* Enable ADC, not free running, interrupt disabled, fastest clock */ + for(i = 0; i < 4; i++) { + ADMUX = 0; /* toggle reference to increase noise */ + ADMUX = 0x1E; /* Select AREF as reference, measure 1.1 volt bandgap reference. */ + ADCSRA |= 1 << ADSC; /* Start conversion */ + while(ADCSRA & (1 << ADSC)) ; /* Wait till done */ + j = (j << 2) + ADC; + } + ADCSRA = 0; /* Disable ADC */ +#endif + PRINTD("rng issues %d\n", j); + return j; +} +/*-------------------------Low level initialization------------------------*/ +/*------Done in a subroutine to keep main routine stack usage small--------*/ +void +initialize(void) +{ + watchdog_init(); + watchdog_start(); + leds_init(); + serial_line_init(); + + rs232_init(RS232_PORT_0, USART_BAUD_38400, USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8); + rs232_redirect_stdout(RS232_PORT_0); + +#if 0 + /* Do it my way... */ + UBRR0L = 25; + UBRR0H = 0; + UCSR0A = (1 << U2X0); /*Double */ +#endif + + rs232_set_input(RS232_PORT_0, serial_line_input_byte); + + clock_init(); + + if(MCUSR & (1 << PORF)) { + PRINTD("Power-on reset.\n"); + } + if(MCUSR & (1 << EXTRF)) { + PRINTD("External reset!\n"); + } + if(MCUSR & (1 << BORF)) { + PRINTD("Brownout reset!\n"); + } + if(MCUSR & (1 << WDRF)) { + PRINTD("Watchdog reset!\n"); + } + if(MCUSR & (1 << JTRF)) { + PRINTD("JTAG reset!\n"); + } + + i2c_init(100000); /* 100 bit/s */ + +#if STACKMONITOR + /* Simple stack pointer highwater monitor. Checks for magic numbers in the main + * loop. In conjuction with PERIODICPRINTS, never-used stack will be printed + * every STACKMONITOR seconds. + */ + { + extern uint16_t __bss_end; + uint16_t p = (uint16_t)&__bss_end; + do { + *(uint16_t *)p = 0x4242; + p += 10; + } while(p < SP - 10); /* don't overwrite our own stack */ + } +#endif + +#define CONF_CALIBRATE_OSCCAL 0 +#if CONF_CALIBRATE_OSCCAL + void calibrate_rc_osc_32k(); + { + extern uint8_t osccal_calibrated; + uint8_t i; + PRINTD("\nBefore calibration OSCCAL=%x\n", OSCCAL); + for(i = 0; i < 10; i++) { + calibrate_rc_osc_32k(); + PRINTD("Calibrated=%x\n", osccal_calibrated); +/* #include */ +/* #define delay_us( us ) ( _delay_loop_2(1+(us*F_CPU)/4000000UL) ) */ +/* delay_us(50000); */ + } + clock_init(); + } +#endif + + PRINTA("\n*******Booting %s*******\n", CONTIKI_VERSION_STRING); + +/* rtimers needed for radio cycling */ + rtimer_init(); + + /* Initialize process subsystem */ + process_init(); + + /* etimers must be started before ctimer_init */ + process_start(&etimer_process, NULL); + ctimer_init(); + + /* Start radio and radio receive process */ + NETSTACK_RADIO.init(); + +/* Get a random seed for the 802.15.4 packet sequence number. + * Some layers will ignore duplicates found in a history (e.g. Contikimac) + * causing the initial packets to be ignored after a short-cycle restart. + */ + random_init(rng_get_uint8()); + + /* Set addresses BEFORE starting tcpip process */ + + linkaddr_t addr; + + printf("I2C: "); + i2c_probed = i2c_probe(); + printf("\n"); + + if( i2c_probed & I2C_AT24MAC ) { + i2c_at24mac_read((char *)&addr.u8, 1); + linkaddr_set_node_addr(&addr); + } + else { + char eui64[8]; + printf("Random EUI64 address generated\n"); + eui64[0] = 0xfc; /* Atmels OUI */ + eui64[1] = 0xc2; + eui64[2] = 0x3d; + eui64[3] = 0; + eui64[4] = 0; + eui64[5] = 0; + eui64[6] = node_id >> 8; + eui64[7] = node_id & 0xff; + linkaddr_set_node_addr(&eui64); + } + + /* memcpy(&uip_lladdr.addr, &addr.u8, sizeof(linkaddr_t)); */ + +#if NETSTACK_CONF_WITH_IPV6 + memcpy(&uip_lladdr.addr, &addr.u8, sizeof(linkaddr_t)); +#endif + + rf230_set_pan_addr(params_get_panid(), params_get_panaddr(), (uint8_t *)&addr.u8); + rf230_set_channel(params_get_channel()); + rf230_set_txpower(params_get_txpower()); + +#if NETSTACK_CONF_WITH_IPV6 + PRINTA("EUI-64 MAC: %x-%x-%x-%x-%x-%x-%x-%x\n", addr.u8[0], addr.u8[1], addr.u8[2], addr.u8[3], addr.u8[4], addr.u8[5], addr.u8[6], addr.u8[7]); +#else + PRINTA("MAC address "); + uint8_t i; + for(i = sizeof(linkaddr_t); i > 0; i--) { + PRINTA("%x:", addr.u8[i - 1]); + } + PRINTA("\n"); +#endif + + /* Initialize stack protocols */ + queuebuf_init(); + NETSTACK_RDC.init(); + NETSTACK_MAC.init(); + NETSTACK_NETWORK.init(); + +#if ANNOUNCE_BOOT + PRINTA("MAC=%s, RDC=%s, NETWORK=%s, channel=%-u, check-rate-Hz=%-u, tx-power=%-u\n", NETSTACK_MAC.name, + NETSTACK_RDC.name, NETSTACK_NETWORK.name, rf230_get_channel(), + CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1 : NETSTACK_RDC.channel_check_interval()), + rf230_get_txpower()); +#if UIP_CONF_IPV6_RPL + PRINTA("RPL Enabled\n"); +#endif +#if UIP_CONF_ROUTER + PRINTA("Routing Enabled\n"); +#endif + +#endif /* ANNOUNCE_BOOT */ + +#if NETSTACK_CONF_WITH_IPV6 || NETSTACK_CONF_WITH_IPV4 + process_start(&tcpip_process, NULL); +#endif + + /* Autostart other processes */ + autostart_start(autostart_processes); + + /*---If using coffee file system create initial web content if necessary---*/ +#if COFFEE_FILES + int fa = cfs_open("/index.html", CFS_READ); + if(fa < 0) { /* Make some default web content */ + PRINTA("No index.html file found, creating upload.html!\n"); + PRINTA("Formatting FLASH file system for coffee..."); + cfs_coffee_format(); + PRINTA("Done!\n"); + fa = cfs_open("/index.html", CFS_WRITE); + int r = cfs_write(fa, &"It works!", 9); + if(r < 0) { + PRINTA("Can''t create /index.html!\n"); + } + cfs_close(fa); +/* fa = cfs_open("upload.html"), CFW_WRITE); */ +/*
*/ + } +#endif /* COFFEE_FILES */ + +/* Add addresses for testing */ +#if 0 + { + uip_ip6addr_t ipaddr; + uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); +/* uip_ds6_prefix_add(&ipaddr,64,0); */ + } +#endif +/*--------------------------Announce the configuration---------------------*/ +#if ANNOUNCE_BOOT +#if AVR_WEBSERVER + { uint8_t i; + char buf[80]; + unsigned int size; + + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + if(uip_ds6_if.addr_list[i].isused) { + httpd_cgi_sprint_ip6(uip_ds6_if.addr_list[i].ipaddr, buf); + PRINTA("IPv6 Address: %s\n", buf); + } + } + cli(); + eeprom_read_block(buf, eemem_server_name, sizeof(eemem_server_name)); + sei(); + buf[sizeof(eemem_server_name)] = 0; + PRINTA("%s", buf); + cli(); + eeprom_read_block(buf, eemem_domain_name, sizeof(eemem_domain_name)); + sei(); + buf[sizeof(eemem_domain_name)] = 0; + size = httpd_fs_get_size(); +#ifndef COFFEE_FILES + PRINTA(".%s online with fixed %u byte web content\n", buf, size); +#elif COFFEE_FILES == 1 + PRINTA(".%s online with static %u byte EEPROM file system\n", buf, size); +#elif COFFEE_FILES == 2 + PRINTA(".%s online with dynamic %u KB EEPROM file system\n", buf, size >> 10); +#elif COFFEE_FILES == 3 + PRINTA(".%s online with static %u byte program memory file system\n", buf, size); +#elif COFFEE_FILES == 4 + PRINTA(".%s online with dynamic %u KB program memory file system\n", buf, size >> 10); +#endif /* COFFEE_FILES */ + } +#else + PRINTA("Online\n"); +#endif +#endif /* ANNOUNCE_BOOT */ + + ledtimer_red = 1000; + leds_on(LEDS_RED); +} + + +#if ROUTES && NETSTACK_CONF_WITH_IPV6 +static void +ipaddr_add(const uip_ipaddr_t *addr) +{ + uint16_t a; + int8_t i, f; + for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { + a = (addr->u8[i] << 8) + addr->u8[i + 1]; + if(a == 0 && f >= 0) { + if(f++ == 0) { + PRINTF("::"); + } + } else { + if(f > 0) { + f = -1; + } else if(i > 0) { + PRINTF(":"); + } + PRINTF("%x", a); + } + } +} +#endif +/*-------------------------------------------------------------------------*/ +/*------------------------- Main Scheduler loop----------------------------*/ +/*-------------------------------------------------------------------------*/ +int +main(void) +{ +#if NETSTACK_CONF_WITH_IPV6 + uip_ds6_nbr_t *nbr; +#endif /* NETSTACK_CONF_WITH_IPV6 */ + initialize(); + + while(1) { + process_run(); + watchdog_periodic(); + + /* Turn off LED's */ + if(ledtimer_red) { + if(--ledtimer_red == 0) { + leds_off(LEDS_RED); + } + } + if(ledtimer_yellow) { + if(--ledtimer_yellow == 0) { + leds_off(LEDS_YELLOW); + } + } + leds_off(LEDS_RED); + leds_off(LEDS_YELLOW); + +#if 0 +/* Various entry points for debugging in the AVR Studio simulator. + * Set as next statement and step into the routine. + */ + NETSTACK_RADIO.send(packetbuf_hdrptr(), 42); + process_poll(&rf230_process); + packetbuf_clear(); + len = rf230_read(packetbuf_dataptr(), PACKETBUF_SIZE); + packetbuf_set_datalen(42); + NETSTACK_RDC.input(); +#endif + +#if 0 +/* Clock.c can trigger a periodic PLL calibration in the RF230BB driver. + * This can show when that happens. + */ + extern uint8_t rf230_calibrated; + if(rf230_calibrated) { + PRINTD("\nRF230 calibrated!\n"); + rf230_calibrated = 0; + } +#endif + +/* Set DEBUGFLOWSIZE in contiki-conf.h to track path through MAC, RDC, and RADIO */ +#if DEBUGFLOWSIZE + if(debugflowsize) { + debugflow[debugflowsize] = 0; + PRINTF("%s", debugflow); + debugflowsize = 0; + } +#endif + +#if PERIODICPRINTS +#if TESTRTIMER +/* Timeout can be increased up to 8 seconds maximum. + * A one second cycle is convenient for triggering the various debug printouts. + * The triggers are staggered to avoid printing everything at once. + */ + if(rtimerflag) { + rtimer_set(&rt, RTIMER_NOW() + RTIMER_ARCH_SECOND * 1UL, 1, (void *)rtimercycle, NULL); + rtimerflag = 0; +#else + if(clocktime != clock_seconds()) { + clocktime = clock_seconds(); +#endif + +#if STAMPS + if((clocktime % STAMPS) == 0) { +#if ENERGEST_CONF_ON +#include "lib/print-stats.h" + print_stats(); +#elif RADIOSTATS + extern volatile unsigned long radioontime; + PRINTF("%u(%u)s\n", clocktime, radioontime); +#else + PRINTF("%us\n", clocktime); +#endif + } +#endif +#if TESTRTIMER + clocktime += 1; +#endif + +#if PINGS && NETSTACK_CONF_WITH_IPV6 + extern void raven_ping6(void); + if((clocktime % PINGS) == 1) { + PRINTF("**Ping\n"); + raven_ping6(); + } +#endif + +#if ROUTES && NETSTACK_CONF_WITH_IPV6 + if((clocktime % ROUTES) == 2) { + + extern uip_ds6_netif_t uip_ds6_if; + + uint8_t i, j; + PRINTF("\nAddresses [%u max]\n", UIP_DS6_ADDR_NB); + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + if(uip_ds6_if.addr_list[i].isused) { + ipaddr_add(&uip_ds6_if.addr_list[i].ipaddr); + PRINTF("\n"); + } + } + PRINTF("\nNeighbors [%u max]\n", NBR_TABLE_MAX_NEIGHBORS); + j = 0; + for(nbr = nbr_table_head(ds6_neighbors); + nbr != NULL; + nbr = nbr_table_next(ds6_neighbors, nbr)) { + ipaddr_add(&nbr->ipaddr); + PRINTF("\n"); + j++; + } + if(!j) { + PRINTF(" "); + } + PRINTF("\nRoutes [%u max]\n", UIP_DS6_ROUTE_NB); + { + uip_ds6_route_t *r; + j = 0; + for(r = uip_ds6_route_head(); + r != NULL; + r = uip_ds6_route_next(r)) { + ipaddr_add(&r->ipaddr); + PRINTF("/%u (via ", r->length); + ipaddr_add(uip_ds6_route_nexthop(r)); + PRINTF(") %lus\n", r->state.lifetime); + j++; + } + } + if(!j) { + PRINTF(" "); + } + PRINTF("\n---------\n"); + } +#endif + +#if STACKMONITOR + if((clocktime % STACKMONITOR) == 3) { + extern uint16_t __bss_end; + uint16_t p = (uint16_t)&__bss_end; + do { + if(*(uint16_t *)p != 0x4242) { + PRINTF("Never-used stack > %d bytes\n", p - (uint16_t)&__bss_end); + break; + } + p += 10; + } while(p < RAMEND - 10); + } +#endif + } +#endif /* PERIODICPRINTS */ + +#if RF230BB && 0 + extern uint8_t rf230processflag; + if(rf230processflag) { + PRINTF("rf230p%d", rf230processflag); + rf230processflag = 0; + } +#endif + +#if RF230BB && 0 + extern uint8_t rf230_interrupt_flag; + if(rf230_interrupt_flag) { + /* if (rf230_interrupt_flag!=11) { */ + PRINTF("**RI%u", rf230_interrupt_flag); + /* } */ + rf230_interrupt_flag = 0; + } +#endif + } + return 0; +} +/*---------------------------------------------------------------------------*/ + +void +log_message(char *m1, char *m2) +{ + PRINTF("%s%s\n", m1, m2); +} diff --git a/platform/avr-rss2/dev/adc.c b/platform/avr-rss2/dev/adc.c new file mode 100644 index 000000000..cb82d16b7 --- /dev/null +++ b/platform/avr-rss2/dev/adc.c @@ -0,0 +1,76 @@ +/* Copyright Robert Olsson */ + +#include +#include +#include +#include +#include +#include +#include "params.h" +#include "rss2.h" +#include "contiki.h" +#include "adc.h" +#include "rss2.h" + +uint16_t +adc_read(uint8_t pin) +{ + uint16_t volt = 0; + int i; + + ADMUX = pin; /* ADC pin PA0-PA7 -> 0-7 */ + ADCSRB &= ~(1 << MUX5); /* Needs to write before ADMUX pp 418 */ + ADMUX |= (1 << REFS1) | (1 << REFS0); /* 1.6 */ + + /* Maximal Track and Hold time */ + + ADCSRA = (1 << ADPS2) | (0 << ADPS1) | (1 << ADPS0); /* Prescaler /32 */ + ADCSRA |= (1 << ADEN); /* Enable the ADC */ + + while(!(ADCSRB & (1 << AVDDOK))) ; /* Wait for AVDD ok */ + while(!(ADCSRB & (1 << REFOK))) ; /* Wait for ref ok */ + + /* Ignore first result */ + + ADCSRA |= (1 << ADSC); + while(ADCSRA & _BV(ADSC)) { + } + + ADCW = 0; +#define RES 4 + + for(i = 0; i < RES; i++) { + + /* Start the conversion */ + ADCSRA |= (1 << ADSC); + + /* Wait for conversion */ + while(ADCSRA & (1 << ADSC)) { + } + + volt += ADCW; + } + ADMUX = 0; /* turn off internal vref */ + volt = volt / RES; + + /* Disable the ADC to save power */ + ADCSRA &= ~_BV(ADEN); + + return volt; +} +double +adc_read_v_in(void) +{ + /* Special treatment for v_in. Schottky voltage drop add */ + return ((double)adc_read(AV_IN)) * V_IN_FACTOR_SCHOTTKY + SCHOTTKY_DROP; +} +double +adc_read_a1(void) +{ + return ((double)adc_read(A1)) * V_IN_FACTOR; +} +double +adc_read_a2(void) +{ + return ((double)adc_read(A2)) * V_IN_FACTOR; +} diff --git a/platform/avr-rss2/dev/adc.h b/platform/avr-rss2/dev/adc.h new file mode 100644 index 000000000..9e9473e31 --- /dev/null +++ b/platform/avr-rss2/dev/adc.h @@ -0,0 +1,16 @@ +/* Copyright Robert Olsson */ + +#define V_IN_FACTOR 0.006256 /* 6.4/1023 */ +#define V_IN_FACTOR_NONE 0.001564 /* 1.6/1023 */ +#define SCHOTTKY_DROP 0.29 +#define V_IN_FACTOR_SCHOTTKY 0.0292 /* 30.19-SCHOTTKY_DROP/1023 schottky corr */ + +uint16_t +adc_read(uint8_t pin); +double +adc_read_v_in(void); +double +adc_read_a1(void); +double +adc_read_a2(void); + diff --git a/platform/avr-rss2/dev/battery-sensor.c b/platform/avr-rss2/dev/battery-sensor.c new file mode 100644 index 000000000..b81db95f6 --- /dev/null +++ b/platform/avr-rss2/dev/battery-sensor.c @@ -0,0 +1,87 @@ +/* + * 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 ADVISE OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * + * ----------------------------------------------------------------- + * + * Author : Dag Björklund, Robert Olsson + * Created : 2005-11-01 + * Updated : $Date: 2010/08/25 19:30:52 $ + * $Revision: 1.11 $ + */ + +#include "contiki.h" +#include "dev/battery-sensor.h" +#include +#define delay_us(us) (_delay_loop_2(1 + (us * F_CPU) / 4000000UL)) + +const struct sensors_sensor battery_sensor; + +/* Returns the MCU voltage in mV read from the BATMON MCU register + * See AtMega chip docs for BATMON details. + */ + +static int +value(int type) +{ + uint16_t mv; + int i; + /* Resolution is 75mV if V>=2.55V; and 50mV if V<=2.45V */ + mv = 3675; + + for(i = 0x1f; 1; i--) { + + BATMON = i; + delay_us(100); + if(BATMON & 0x20) { + break; + } + + if(i == 0x10) { /* Range hi or lo */ + mv = 2500; + } + if(i > 0x10) { + mv -= 75; + } else { + mv -= 50; + } + } + return (int)((float)mv); +} +static int +configure(int type, int c) +{ + return 0; +} +static int +status(int type) +{ + return 1; +} +SENSORS_SENSOR(battery_sensor, BATTERY_SENSOR, value, configure, status); + diff --git a/platform/avr-rss2/dev/button-sensor.c b/platform/avr-rss2/dev/button-sensor.c new file mode 100644 index 000000000..664278993 --- /dev/null +++ b/platform/avr-rss2/dev/button-sensor.c @@ -0,0 +1,41 @@ +/* Dummy sensor routine */ + +#include "lib/sensors.h" +#include "dev/button-sensor.h" +const struct sensors_sensor button_sensor; +static int status(int type); +struct sensors_sensor *sensors[1]; +unsigned char sensors_flags[1]; + +static int +value(int type) +{ + return 0; +} +static int +configure(int type, int c) +{ + switch(type) { + case SENSORS_ACTIVE: + if(c) { + if(!status(SENSORS_ACTIVE)) { + } + } else { + } + return 1; + } + return 0; +} +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return 1; + } + return 0; +} +SENSORS_SENSOR(button_sensor, BUTTON_SENSOR, + value, configure, status); + diff --git a/platform/avr-rss2/dev/co2_sa_kxx-sensor.c b/platform/avr-rss2/dev/co2_sa_kxx-sensor.c new file mode 100644 index 000000000..1866c0f2f --- /dev/null +++ b/platform/avr-rss2/dev/co2_sa_kxx-sensor.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2015, Copyright Markus Hidell, Robert Olsson + * 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. + * + * + * Authors : Markus Hidell, Robert Olsson {mahidell, roolss} @kth.se + * Created : 2015-10-27 + * Updated : $Date: 2010/01/14 20:23:02 $ + * $Revision: 1.2 $ + */ + +#include "contiki.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dev/watchdog.h" +#include "lib/list.h" +#include "lib/memb.h" +#include "co2_sa_kxx-sensor.h" + +static int +status(int type) +{ + return 0; +} +static int +configure(int type, int c) +{ + return 0; +} +static int +value(int var) +{ + int val, status; + uint8_t buf[2], csum; + int16_t res; + (void) status; + (void) csum; + + res = 0; + i2c_start_wait(I2C_CO2SA_ADDR | I2C_WRITE); + if(res) { + goto err; + } + + i2c_write(0x22); + i2c_write(0x00); + + if(var == CO2_SA_KXX_CO2) { + i2c_write(0x08); + i2c_write(0x2A); + } + + if(var == CO2_SA_KXX_TEMP) { + i2c_write(0x12); + i2c_write(0x34); + } + + if(var == CO2_SA_KXX_RH) { + i2c_write(0x14); + i2c_write(0x36); + } + + i2c_stop(); + + if(res) { + goto err; + } + + clock_delay_msec(20); + + res = 0; + i2c_start(I2C_CO2SA_ADDR | I2C_READ); + + if(res) { + goto err; + } + + + status = i2c_readAck(); + + if(status & 0x01 == 0) + goto err; + + buf[0] = i2c_readAck(); + buf[1] = i2c_readAck(); + csum = i2c_readNak(); + i2c_stop(); + + val = ((int16_t)(buf[0] << 8)) | buf[1]; + + return val; + +err: + i2c_stop(); + return 0; +} +SENSORS_SENSOR(co2_sa_kxx_sensor, "CO2", value, configure, status); diff --git a/platform/avr-rss2/dev/co2_sa_kxx-sensor.h b/platform/avr-rss2/dev/co2_sa_kxx-sensor.h new file mode 100644 index 000000000..bdb366fea --- /dev/null +++ b/platform/avr-rss2/dev/co2_sa_kxx-sensor.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2015, Copyright Markus Hidell, Robert Olsson + * 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. + * + * + * Authors : Markus Hidell, Robert Olsson {mahidell, roolss} @kth.se + * Created : 2015-10-27 + * Updated : $Date: 2010/01/14 20:23:02 $ + * $Revision: 1.2 $ + */ + +#ifndef CO2_SA_KXX_SENSOR_H_ +#define CO2_SA_KXX_SENSOR_H_ + +#define CO2_SA_KXX_CO2 0 +#define CO2_SA_KXX_TEMP 1 +#define CO2_SA_KXX_RH 3 + +#include "lib/sensors.h" + +extern const struct sensors_sensor co2_sa_kxx_sensor; + +#define I2C_CO2SA_ADDR (0x68 << 1) + +#endif /* CO2_SA_KXX-SENSOR_H_ */ diff --git a/platform/avr-rss2/dev/ds18b20.c b/platform/avr-rss2/dev/ds18b20.c new file mode 100644 index 000000000..6044ad91e --- /dev/null +++ b/platform/avr-rss2/dev/ds18b20.c @@ -0,0 +1,247 @@ +/* + + Contiki library for DS18B20 temperature sensor - + For more details see http://xxx + + Author - + Author - + + License - GPLv3 + + */ + +#include "ds18b20.h" + +/* probe_for_ds18b20 probes for the sensor. Returns 0 on failure, 1 on success */ +/* Assumptions: only one sensor on the "1-wire bus", on port WSN_DS18B20_PORT */ +/* BUG: THIS CODE DOES NOT WORK AS INTENDED! IT RETURNS "1" EVEN WHEN THERE IS NO */ +/* SENSOR CONNECTED. */ + +uint8_t +ds18b20_probe(void) +{ + uint8_t result = 0; + + /* Reset 1W-bus */ + + /* Pull PIN low for 480 microseconds (us) */ + /* Start with setting bit DS18B20_1_PIN to 0 */ + OW_SET_PIN_LOW(); + /* then set direction to OUT by setting DS18B20_1_DDR bit to 1 */ + OW_SET_OUTPUT(); + /* Delay 480 us */ + clock_delay_usec(480); + /* See if sensor responds. First release the bus and switch to INput mode */ + /* by setting DS18B20_1_DDR bit to 0 */ + OW_SET_INPUT(); + /* Activate internal pull-up by setting pin to HIGH (when in INput mode) */ + /* OW_SET_PIN_HIGH(); */ + /* Wait for the pin to go HIGH for 64 us */ + clock_delay_usec(64); + /* Now the sensor, if present, pulls the pin LOW for 60-240 us */ + /* Detect 0 on PIND bit DS18B20_1_PIN. Invert the result so a presence (aka a 0) */ + /* sets "result" to 1 (for success) */ + result = !OW_GET_PIN_STATE(); + + /* The sensor releases the pin so it goes HIGH after 240 us, add some */ + /* for the signal to stabilize, say 300 usecs to be on the safe side? */ + if(result) { + clock_delay_usec(300); + /* Now the bus should be HIGH again */ + result = OW_GET_PIN_STATE(); + } + + return result; +} +/* Write 1 or 0 on the bus */ + +void +write_bit(uint8_t bit) +{ + /* Set pin to 0 */ + OW_SET_OUTPUT(); + OW_SET_PIN_LOW(); + + /* Pin should be 0 for at least 1 us */ + clock_delay_usec(2); + + /* If we're writing a 1, let interna pull-up pull the bus high */ + /* within 15 us of setting the bus to low */ + if(bit) { + /* Internal pull-up is activated by setting direction to IN and the */ + /* setting the pin to HIGH */ + OW_SET_INPUT(); + OW_SET_PIN_HIGH(); + } + /* OK, now the bus is either LOW, or pulled HIGH by the internal pull-up */ + /* Let this state remain for 60 us, then release the bus */ + clock_delay_usec(60); + + /* Release the bus */ + OW_SET_PIN_HIGH(); + OW_SET_INPUT(); + + /* Allow > 1 us between read/write operations */ + clock_delay_usec(2); +} +/* */ +/* Read one bit of information from the bus, and return it as 1 or 0 */ +/* */ + +uint8_t +read_bit(void) +{ + uint8_t bit = 0; + + /* Set pin to 0 */ + OW_SET_OUTPUT(); + OW_SET_PIN_LOW(); + + /* Pin should be 0 for at least 1 us */ + clock_delay_usec(2); + + /* Now read the bus, start by setting in/out direction and activating internal */ + /* pull-up resistor */ + OW_SET_INPUT(); + OW_SET_PIN_HIGH(); + + /* ds18b20 either keeps the pin down or releases the bus and the */ + /* bus then goes high because of the interna pull-up resistor */ + /* Check whichever happens before 15 us has passed */ + clock_delay_usec(15 - 2 - 1); + bit = OW_GET_PIN_STATE(); + + /* The complete read cycle must last at least 60 us. We have now spent */ + /* about 14-15 us in delays, so add another delay to reach >= 60 us */ + clock_delay_usec(50); + + /* Release bus */ + OW_SET_PIN_HIGH(); + OW_SET_INPUT(); + + /* Allow > 1 us between read/write operations */ + clock_delay_usec(2); + + return bit ? 1 : 0; +} +/* */ +/* Read one byte of information. A byte is read least significant bit first */ +/* */ + +uint8_t +read_byte(void) +{ + uint8_t result = 0; + uint8_t bit; + int i; + + for(i = 0; i < 8; i++) { + bit = read_bit(); + result += (bit << i); + } + return result; +} +/* */ +/* Write one byte of information. A byte is written least significant bit first */ +/* */ + +void +write_byte(uint8_t byte) +{ + int i; + + for(i = 0; i < 8; i++) { + write_bit((byte >> i) & 1); + } +} +/* */ +/* ds18b20_get_temp returns the temperature in "temp" (in degrees celsius) */ +/* Returns 0 on failure (and then "temp" is left unchanged */ +/* Returns 1 on success, and sets temp */ +/* */ + +uint8_t +ds18b20_get_temp(float *temp) +{ + uint8_t result = 0; + + /* Reset bus by probing. Probe returns 1 on success/presence of sensor */ + if(ds18b20_probe()) { + /* write command "skip rom" since we only have one sensor on the wire! */ + write_byte(DS18B20_COMMAND_SKIP_ROM); + + /* write command to start measurement */ + write_byte(DS18B20_COMMAND_START_CONVERSION); + + /* Wait for conversion to complete */ + /* Conversion is 12-bit by default. */ + /* Since we have external power to the sensor (ie not in "parasitic power" mode) */ + /* the bus is held LOW by the sensor while the conversion is going on, and then HIGH */ + /* when conversion is finished. */ + OW_SET_INPUT(); + int count = 0; + while(!OW_GET_PIN_STATE()) { + clock_delay_msec(10); + count++; + /* Longest conversion time is 750 ms (12-bit resolution) */ + /* So if count > 80 (for a little margin!), we return -274.0 */ + /* which indicates failure to read the temperature. */ + if(count > 80) { + return 0; + } + } + + /* The result is stored in the "scratch pad", a 9 byte memory block. */ + /* The first two bytes are the conversion result. Reading the scratch pad */ + /* can be terminated by sending a reset signal (but we read all 9 bytes) */ + (void)ds18b20_probe(); + write_byte(DS18B20_COMMAND_SKIP_ROM); + write_byte(DS18B20_COMMAND_READ_SCRATCH_PAD); + uint8_t i, sp_arr[9]; + for(i = 0; i < 9; i++) { + sp_arr[i] = read_byte(); + } + + /* Check CRC, if mismatch, return 0 (failure to read temperature) */ + uint8_t crc_cal = crc8_ds18b20(sp_arr, 8); + + if(crc_cal != sp_arr[8]) { + return 0; + } + + /* OK, now decode what the temperature reading is. This code assumes 12-bit resolution, */ + /* so this must be modified if the code is modified to use any other resolution! */ + int16_t temp_res; + uint8_t temp_lsb = sp_arr[0]; + uint8_t temp_msb = sp_arr[1]; + + temp_res = (int16_t)temp_msb << 8 | temp_lsb; + *temp = (float)temp_res * 0.0625; + + result = 1; + } + return result; +} +/* */ +/* crc8 algorithm for ds18b20 */ +/* http://www.miscel.dk/MiscEl/CRCcalculations.html */ +/* */ + +uint8_t +crc8_ds18b20(uint8_t *buf, uint8_t buf_len) +{ + uint8_t result = 0; + uint8_t i, b; + + for(i = 0; i < buf_len; i++) { + result = result ^ buf[i]; + for(b = 1; b < 9; b++) { + if(result & 0x1) { + result = (result >> 1) ^ 0x8C; + } else { + result = result >> 1; + } + } + } + return result; +} diff --git a/platform/avr-rss2/dev/enc28j60_avr.c b/platform/avr-rss2/dev/enc28j60_avr.c new file mode 100644 index 000000000..2bfb49562 --- /dev/null +++ b/platform/avr-rss2/dev/enc28j60_avr.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2012-2013, Robert Olsson + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + * + */ + +#include +#include +#include +#include "dev/watchdog.h" +#include "contiki.h" +#include "i2c.h" +#include +#include +#include +#include "enc28j60_avr.h" + +#include +#define delay_us(us) (_delay_loop_2(1 + (us * F_CPU) / 4000000UL)) + +void +enc28j60_arch_spi_init(void) +{ + CS_SPI_DDR |= (1 << SPI_CS); + CS_SPI_PORT |= (1 << SPI_CS); + + SPI_DDR |= (1 << SPI_MOSI) | (1 << SPI_SCK); + SPI_DDR &= ~(1 << SPI_MISO); + SPI_PORT &= ~(1 << SPI_MOSI); + SPI_PORT &= ~(1 << SPI_SCK); + SPCR = (1 << SPE) | (1 << MSTR); + /* SPSR |= (1< + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + * + */ + +#ifndef ENC28J60_AVR_H +#define ENC28J60_AVR_H + +#define SPI_DDR DDRB /* Data Direction Register: Port B */ +#define SPI_PORT PORTB /* Serial Peripheral Interface */ +#define SPI_MOSI 2 /* PB2: Master Out Slave In */ +#define SPI_MISO 3 /* PB3: Master In Slave out */ +#define SPI_SCK 1 /* PB1: Serial Clock */ + +#define CS_SPI_DDR DDRD /* Data Direction Register: Port B */ +#define CS_SPI_PORT PORTD /* Serial Peripheral Interface */ +#define SPI_CS 6 /* PD6: OW2_PIN, Chip Select */ + +/* AVR specific's for enc28j60 */ + +void enc28j60_arch_spi_init(void); +uint8_t enc28j60_arch_spi_write(uint8_t data); +uint8_t enc28j60_arch_spi_read(void); +void enc28j60_arch_spi_select(void); +void enc28j60_arch_spi_deselect(void); + +#endif /* ENC28J60_AVR_H */ diff --git a/platform/avr-rss2/dev/i2c.c b/platform/avr-rss2/dev/i2c.c new file mode 100644 index 000000000..2668aad58 --- /dev/null +++ b/platform/avr-rss2/dev/i2c.c @@ -0,0 +1,228 @@ +/* + * 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. + * + */ + +/** + * \file + * i2c core functions + * \author + * Robert Olsson + */ + +#include +#include +#include +#include +#include "dev/watchdog.h" +#include "contiki.h" +#include "i2c.h" +#include +#include +#include +#include "dev/co2_sa_kxx-sensor.h" + +void +i2c_init(uint32_t speed) +{ + /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */ + + TWSR = 0; /* no prescaler */ + TWBR = ((F_CPU / speed) - 16) / 2; /* must be > 10 for stable operation */ +} +uint8_t +i2c_start(uint8_t addr) +{ + uint8_t twst; + uint32_t n; + + /* Send START condition */ + TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); + + /* Wait until transmission completed */ + for(n = 0; n < 100000 && !(TWCR & (1 << TWINT)); n++) { + } + if(n >= 100000) { + return 1; + } + + /* check value of TWI Status Register. Mask prescaler bits. */ + twst = TW_STATUS & 0xF8; + if((twst != TW_START) && (twst != TW_REP_START)) { + return 1; + } + + /* send device address */ + TWDR = addr; + TWCR = (1 << TWINT) | (1 << TWEN); + + /* wail until transmission completed and ACK/NACK has been received */ + for(n = 0; n < 100000 && !(TWCR & (1 << TWINT)); n++) { + } + if(n >= 100000) { + return 1; + } + + /* check value of TWI Status Register. Mask prescaler bits. */ + twst = TW_STATUS & 0xF8; + if((twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK)) { + return 1; + } + + return 0; +} +void +i2c_start_wait(uint8_t addr) +{ + uint8_t twst; + while ( 1 ) + { + // send START condition + TWCR = (1< + */ + +#include "contiki.h" + +/* Here we define the i2c address for dev we support */ +#define I2C_AT24MAC_ADDR 0xB0 /* EUI64 ADDR */ +#define I2C_SHT2X_ADDR (0x40 << 1) /* SHT2X ADDR */ + + +/* Here we define a enumration for devices */ +#define I2C_AT24MAC (1<<0) +#define I2C_SHT2X (1<<1) +#define I2C_CO2SA (1<<2) /* Sense-Air CO2 */ + +#define I2C_READ 1 +#define I2C_WRITE 0 + +void i2c_init(uint32_t speed); +uint8_t i2c_start(uint8_t addr); +void i2c_start_wait(uint8_t addr); +void i2c_stop(void); +void i2c_write(uint8_t u8data); +uint8_t i2c_readAck(void); +uint8_t i2c_readNak(void); +uint8_t i2c_getstatus(void); +uint16_t i2c_probe(void); +void i2c_read_mem(uint8_t addr, uint8_t reg, uint8_t buf[], uint8_t bytes); +void i2c_write_mem(uint8_t addr, uint8_t reg, uint8_t value); +void i2c_at24mac_read(char *buf, uint8_t eui64); +extern uint16_t i2c_probed; /* i2c devices we have probed */ diff --git a/platform/avr-rss2/dev/leds.c b/platform/avr-rss2/dev/leds.c new file mode 100644 index 000000000..c59f9d09f --- /dev/null +++ b/platform/avr-rss2/dev/leds.c @@ -0,0 +1,45 @@ +#include +#include "rss2.h" +#include "leds.h" + +void +leds_init(void) +{ + DDRE |= (1 << LED_RED); + DDRE |= (1 << LED_YELLOW); + /* Off */ + leds_off(LEDS_ALL); +} +void +leds_on(unsigned char ledv) +{ + if(ledv & LEDS_YELLOW) { + PORTE &= ~(1 << LED_YELLOW); + } + if(ledv & LEDS_RED) { + PORTE &= ~(1 << LED_RED); + } +} +void +leds_off(unsigned char ledv) +{ + if(ledv & LEDS_YELLOW) { + PORTE |= (1 << LED_YELLOW); + } + if(ledv & LEDS_RED) { + PORTE |= (1 << LED_RED); + } +} +void +leds_toggle(unsigned char ledv) +{ +} +void +leds_invert(unsigned char ledv) +{ +} +unsigned char +leds_get(void) +{ + return 0; +} diff --git a/platform/avr-rss2/dev/leds.h b/platform/avr-rss2/dev/leds.h new file mode 100644 index 000000000..6dee358c8 --- /dev/null +++ b/platform/avr-rss2/dev/leds.h @@ -0,0 +1,17 @@ + +#ifndef CONTIKI_LED_H_ +#define CONTIKI_LED_H_ + +#define LEDS_GREEN 1 +#define LEDS_YELLOW 2 +#define LEDS_RED 4 +#define LEDS_ALL 7 + +void leds_init(void); /* Initialize the LEDs driver. */ +unsigned char leds_get(void); /* Get the status of a LED. */ +void leds_on(unsigned char ledv); /* Turn on a set of LEDs. */ +void leds_off(unsigned char ledv); /* Turn off a set of LEDs. */ +void leds_toggle(unsigned char ledv); /* Toggle a set of LEDs. */ +void leds_invert(unsigned char ledv); /* Toggle a set of LEDs. */ + +#endif /* CONTIKI_LED_H_ */ diff --git a/platform/avr-rss2/dev/light-sensor.c b/platform/avr-rss2/dev/light-sensor.c new file mode 100644 index 000000000..cbb0a93f7 --- /dev/null +++ b/platform/avr-rss2/dev/light-sensor.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2015, Copyright Robert Olsson + * 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. + * + */ + +#include "contiki.h" +#include "lib/sensors.h" +#include "dev/light-sensor.h" +#include "rss2.h" +#include "adc.h" + +const struct sensors_sensor light_sensor; + +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + return adc_read(A3); +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + DDRF &= ~(1 << A3); /* Light sensor */ + DDRF &= ~(1 << A3_PWR); + + PORTF |= (1 << A3_PWR); /* Light sensor */ + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(light_sensor, "Light", value, configure, status); diff --git a/platform/avr-rss2/dev/light-sensor.h b/platform/avr-rss2/dev/light-sensor.h new file mode 100644 index 000000000..da26c724e --- /dev/null +++ b/platform/avr-rss2/dev/light-sensor.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2015, Copyright Robert Olsson + * 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. + * + * + * Author : Robert Olsson + * Created : 2015-10-27 + * Updated : $Date: 2010/01/14 20:23:02 $ + * $Revision: 1.2 $ + */ + +#ifndef LIGHT_SENSOR_H_ +#define LIGHT_SENSOR_H_ + +#include "lib/sensors.h" + +extern const struct sensors_sensor light_sensor; + +#endif /* LIGHT-SENSOR_H_ */ diff --git a/platform/avr-rss2/dev/pulse-sensor.c b/platform/avr-rss2/dev/pulse-sensor.c new file mode 100644 index 000000000..eb0f3a842 --- /dev/null +++ b/platform/avr-rss2/dev/pulse-sensor.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2015, Copyright Robert Olsson / Radio Sensors AB + * 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. + * + * + * Author : Robert Olsson robert@radio-sensors.com + * Created : 2015-11-22 + */ + +#include "contiki.h" +#include "lib/sensors.h" +#include "dev/pulse-sensor.h" +#include "rss2.h" + +const struct sensors_sensor pulse_sensor; + +#define NP 2 + +uint32_t volatile pc[NP]; + +/* + * Note interrupt sources can be woken up from sleep mode PWR_SAVE + * Two interrupt ports, #0 green terminal block. #1 pin header via + * a comparator. + */ + +static void +port_irq_ctrl(uint8_t on) +{ + if(on) { + + DDRD &= ~(1 << PD2); + PORTD &= ~(1 << PD2); + EIMSK = 0; + EICRA |= 0x20; /* Falling edge INT2 */ + EIMSK |= (1 << PD2); /* Enable interrupt for pin */ + + /* p1 port */ + DDRD &= ~(1 << PD3); + PORTD &= ~(1 << PD3); + EIMSK |= (1 << PD3); /* Enable interrupt for pin */ + EICRA |= 0x80; /* Falling edge */ + PCICR |= (1 << PCIE0); /* And enable irq PCINT 7:0 */ + } else { + EICRA = 0; + PORTD |= (1 << PD2); + EIMSK &= ~(1 << PD2); /* Disable interrupt for pin */ + + PORTD |= (1 << PD3); + EIMSK &= ~(1 << PD3); /* Disable interrupt for pin */ + } +} +ISR(INT2_vect) +{ + if(!(PCICR & (1 << PCIE0))) { + return; + } + pc[0]++; +} + +ISR(INT3_vect) +{ + if(!(PCICR & (1 << PCIE0))) { + return; + } + pc[1]++; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + if(type == 0) { + return (int)pc[0]; + } + if(type == 1) { + return (int)pc[1]; + } + return -1; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + port_irq_ctrl(1); /* Enable pulse counts */ + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(pulse_sensor, "Pulse", value, configure, status); diff --git a/platform/avr-rss2/dev/pulse-sensor.h b/platform/avr-rss2/dev/pulse-sensor.h new file mode 100644 index 000000000..03a09cd1b --- /dev/null +++ b/platform/avr-rss2/dev/pulse-sensor.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015, Copyright Robert Olsson / Radio Sensors AB + * 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. + * + * + * Author : Robert Olsson robert@radio-sensors.com + * Created : 2015-11-22 + */ + +#ifndef PULSE_SENSOR_H_ +#define PULSE_SENSOR_H_ + +#include "lib/sensors.h" + +extern const struct sensors_sensor pulse_sensor; + +#endif /* PULSE-SENSOR_H_ */ diff --git a/platform/avr-rss2/dev/temp-sensor.c b/platform/avr-rss2/dev/temp-sensor.c new file mode 100644 index 000000000..5bc108c7e --- /dev/null +++ b/platform/avr-rss2/dev/temp-sensor.c @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2015, Copyright Per Lindgren + * 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. + * + * + * Author : Per Lindgren + * Hacked by: Robert Olsson robert@radio-sensors.com + * Created : 2015-11-22 + */ + +#include "contiki.h" +#include "dev/temp-sensor.h" +#include +#define delay_us(us) (_delay_loop_2(1 + (us * F_CPU) / 4000000UL)) + +const struct sensors_sensor temp_mcu_sensor; + +/* probe_for_ds18b20 probes for the sensor. Returns 0 on failure, 1 on success + * Assumptions: only one sensor on the "1-wire bus", on port WSN_DS18B20_PORT + * BUG: THIS CODE DOES NOT WORK AS INTENDED! IT RETURNS "1" EVEN WHEN THERE + * IS NO SENSOR CONNECTED. + */ + +uint8_t +ds18b20_probe(void) +{ + uint8_t result = 0; + + /* Reset 1W-bus */ + + /* Pull PIN low for 480 microseconds (us) + * Start with setting bit DS18B20_1_PIN to 0 */ + OW_SET_PIN_LOW(); + /* then set direction to OUT by setting DS18B20_1_DDR bit to 1 */ + OW_SET_OUTPUT(); + /* Delay 480 us */ + clock_delay_usec(480); + /* See if sensor responds. First release the bus and switch to INput mode + * by setting DS18B20_1_DDR bit to 0 */ + OW_SET_INPUT(); + /* Activate internal pull-up by setting pin to HIGH (when in INput mode) + * OW_SET_PIN_HIGH(); + * Wait for the pin to go HIGH for 64 us */ + clock_delay_usec(64); + /* Now the sensor, if present, pulls the pin LOW for 60-240 us + * Detect 0 on PIND bit DS18B20_1_PIN. Invert the result so a presence + * (aka * a 0) sets "result" to 1 (for success) */ + result = !OW_GET_PIN_STATE(); + + /* The sensor releases the pin so it goes HIGH after 240 us, add some + for the signal to stabilize, say 300 usecs to be on the safe side? */ + if(result) { + clock_delay_usec(300); + /* Now the bus should be HIGH again */ + result = OW_GET_PIN_STATE(); + } + return result; +} +/* Write 1 or 0 on the bus */ + +void +write_bit(uint8_t bit) +{ + /* Set pin to 0 */ + OW_SET_OUTPUT(); + OW_SET_PIN_LOW(); + + /* Pin should be 0 for at least 1 us */ + clock_delay_usec(2); + + /* If we're writing a 1, let interna pull-up pull the bus high + * within 15 us of setting the bus to low */ + if(bit) { + /* Internal pull-up is activated by setting direction to IN and the + * setting the pin to HIGH */ + OW_SET_INPUT(); + OW_SET_PIN_HIGH(); + } + /* OK, now the bus is either LOW, or pulled HIGH by the internal pull-up + * Let this state remain for 60 us, then release the bus */ + clock_delay_usec(60); + + /* Release the bus */ + OW_SET_PIN_HIGH(); + OW_SET_INPUT(); + + /* Allow > 1 us between read/write operations */ + clock_delay_usec(2); +} +/* Read one bit of information from the bus, and return it as 1 or 0 */ + +uint8_t +read_bit(void) +{ + uint8_t bit = 0; + + /* Set pin to 0 */ + OW_SET_OUTPUT(); + OW_SET_PIN_LOW(); + + /* Pin should be 0 for at least 1 us */ + clock_delay_usec(2); + + /* Now read the bus, start by setting in/out direction and activating + * internal pull-up resistor */ + OW_SET_INPUT(); + OW_SET_PIN_HIGH(); + + /* ds18b20 either keeps the pin down or releases the bus and the + * bus then goes high because of the interna pull-up resistor + * Check whichever happens before 15 us has passed */ + clock_delay_usec(15 - 2 - 1); + bit = OW_GET_PIN_STATE(); + + /* The complete read cycle must last at least 60 us. We have now spent + * about 14-15 us in delays, so add another delay to reach >= 60 us */ + clock_delay_usec(50); + + /* Release bus */ + OW_SET_PIN_HIGH(); + OW_SET_INPUT(); + + /* Allow > 1 us between read/write operations */ + clock_delay_usec(2); + + return bit ? 1 : 0; +} +/* Read one byte of information. A byte is read least significant bit first */ + +uint8_t +read_byte(void) +{ + uint8_t result = 0; + uint8_t bit; + int i; + + for(i = 0; i < 8; i++) { + bit = read_bit(); + result += (bit << i); + } + return result; +} +/* Write one byte of information. A byte is written least significant bit first */ + +void +write_byte(uint8_t byte) +{ + int i; + + for(i = 0; i < 8; i++) { + write_bit((byte >> i) & 1); + } +} +/* ds18b20_get_temp returns the temperature in "temp" (in degrees celsius) + * Returns 0 on failure (and then "temp" is left unchanged + * Returns 1 on success, and sets temp */ + +uint8_t +ds18b20_get_temp(double *temp) +{ + uint8_t result = 0; + + /* Reset bus by probing. Probe returns 1 on success/presence of sensor */ + if(ds18b20_probe()) { + /* write command "skip rom" since we only have one sensor on the wire! */ + write_byte(DS18B20_COMMAND_SKIP_ROM); + + /* write command to start measurement */ + write_byte(DS18B20_COMMAND_START_CONVERSION); + + /* Wait for conversion to complete. Conversion is 12-bit by default. + * Since we have external power to the sensor (ie not in "parasitic power" + * mode) the bus is held LOW by the sensor while the conversion is going + * on, and then HIGH when conversion is finished. */ + OW_SET_INPUT(); + int count = 0; + while(!OW_GET_PIN_STATE()) { + clock_delay_msec(10); + count++; + /* Longest conversion time is 750 ms (12-bit resolution) + * So if count > 80 (for a little margin!), we return -274.0 + * which indicates failure to read the temperature. */ + if(count > 80) { + return 0; + } + } + + /* The result is stored in the "scratch pad", a 9 byte memory block. + * The first two bytes are the conversion result. Reading the scratch pad + * can be terminated by sending a reset signal (but we read all 9 bytes) */ + (void)ds18b20_probe(); + write_byte(DS18B20_COMMAND_SKIP_ROM); + write_byte(DS18B20_COMMAND_READ_SCRATCH_PAD); + uint8_t i, sp_arr[9]; + for(i = 0; i < 9; i++) { + sp_arr[i] = read_byte(); + } + + /* Check CRC, if mismatch, return 0 (failure to read temperature) */ + uint8_t crc_cal = crc8_ds18b20(sp_arr, 8); + + if(crc_cal != sp_arr[8]) { + return 0; + } + + /* OK, now decode what the temperature reading is. This code assumes + * 12-bit resolution, so this must be modified if the code is modified + * to use any other resolution! */ + int16_t temp_res; + uint8_t temp_lsb = sp_arr[0]; + uint8_t temp_msb = sp_arr[1]; + + temp_res = (int16_t)temp_msb << 8 | temp_lsb; + *temp = (double)temp_res * 0.0625; + + result = 1; + } + return result; +} +/* crc8 algorithm for ds18b20 */ +/* http://www.miscel.dk/MiscEl/CRCcalculations.html */ + +uint8_t +crc8_ds18b20(uint8_t *buf, uint8_t buf_len) +{ + uint8_t result = 0; + uint8_t i, b; + + for(i = 0; i < buf_len; i++) { + result = result ^ buf[i]; + for(b = 1; b < 9; b++) { + if(result & 0x1) { + result = (result >> 1) ^ 0x8C; + } else { + result = result >> 1; + } + } + } + return result; +} +static int +value(int type) +{ + double t; + int ret; + ret = ds18b20_get_temp(&t); + + /* Return temp multiplied by 100 for two decimals */ + if(ret) + return (int) (t * 100); + + /* Error return largest negative value */ + return 0x8000; +} +static int +configure(int type, int c) +{ + ds18b20_probe(); + return 0; +} +static int +status(int type) +{ + return 1; +} +SENSORS_SENSOR(temp_sensor, TEMP_SENSOR, value, configure, status); diff --git a/platform/avr-rss2/dev/temp-sensor.h b/platform/avr-rss2/dev/temp-sensor.h new file mode 100644 index 000000000..b5ab53659 --- /dev/null +++ b/platform/avr-rss2/dev/temp-sensor.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2015, Copyright Per Lindgren + * 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. + * + * + * Author : Per Lindgren + * Hacked by: Robert Olsson robert@radio-sensors.com + * Created : 2015-11-22 + */ + +#ifndef TEMP_SENSOR_H_ +#define TEMP_SENSOR_H_ + +#include "lib/sensors.h" +#include +#include "contiki.h" +#include "rss2.h" + +#define DS18B20_1_PIN OW_BUS_0 +#define DS18B20_1_IN PIND +#define DS18B20_1_OUT PORTD +#define DS18B20_1_DDR DDRD + +#define OW_SET_PIN_LOW() (DS18B20_1_OUT &= ~(1 << DS18B20_1_PIN)) +#define OW_SET_PIN_HIGH() (DS18B20_1_OUT |= (1 << DS18B20_1_PIN)) +#define OW_SET_OUTPUT() (DS18B20_1_DDR |= (1 << DS18B20_1_PIN)) +#define OW_SET_INPUT() (DS18B20_1_DDR &= ~(1 << DS18B20_1_PIN)) +#define OW_GET_PIN_STATE() ((DS18B20_1_IN & (1 << DS18B20_1_PIN)) ? 1 : 0) + +#define DS18B20_COMMAND_READ_SCRATCH_PAD 0xBE +#define DS18B20_COMMAND_START_CONVERSION 0x44 +#define DS18B20_COMMAND_SKIP_ROM 0xCC + +/* probe_for_ds18b20 probes for the sensor. Returns 0 on failure, 1 on success + * Assumption: only one sensor on the "1-wire bus", on port DS18B20_1_PIN */ + +extern uint8_t ds18b20_probe(void); +extern uint8_t ds18b20_get_temp(double *temp); +extern uint8_t crc8_ds18b20(uint8_t *buf, uint8_t buf_len); + +extern const struct sensors_sensor temp_sensor; + +#define TEMP_SENSOR "temp" + +#endif /* TEMP_SENSOR_H_ */ diff --git a/platform/avr-rss2/dev/temp_mcu-sensor.c b/platform/avr-rss2/dev/temp_mcu-sensor.c new file mode 100644 index 000000000..cfa21707d --- /dev/null +++ b/platform/avr-rss2/dev/temp_mcu-sensor.c @@ -0,0 +1,90 @@ +/* + * 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 ADVISE OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * + * ----------------------------------------------------------------- + * + * Author : Robert Olsson + * Created : 2015-10-27 + * Updated : $Date: 2010/08/25 19:30:52 $ + * $Revision: 1.11 $ + */ + +#include "contiki.h" +#include "dev/temp_mcu-sensor.h" +#include +#define delay_us(us) (_delay_loop_2(1 + (us * F_CPU) / 4000000UL)) + +const struct sensors_sensor temp_mcu_sensor; + +/* Returns the MCU temp in C*10 read from the BATMON MCU register + * See AtMega chip docs for BATMON details. + */ + +static int +value(int type) +{ + uint16_t v; + + ADCSRB |= (1 << MUX5); /* this bit buffered till ADMUX written to! */ + ADMUX = 0xc9; + + /* ADC on /32 ADC start */ + ADCSRA = (1 << ADPS2) | (0 << ADPS1) | (1 << ADPS0); + ADCSRA |= (1 << ADEN); /* Enable the ADC */ + + while(!(ADCSRB & (1 << AVDDOK))) ; /* Wait for AVDD ok */ + while(!(ADCSRB & (1 << REFOK))) ; /* Wait for ref ok */ + + ADCSRA |= (1 << ADSC); /* Throwaway conversion */ + while + (ADCSRA & (1 << ADSC)) ; + + ADCSRA |= (1 << ADSC); /* Start conversion */ + while + (ADCSRA & (1 << ADSC)) ; + + v = ADC; + + /* Disable the ADC to save power */ + ADCSRA &= ~_BV(ADEN); + /* ADMUX = 0; //turn off internal vref */ + return (int)((double)(v * 1.13 - 272.8) * 10); +} +static int +configure(int type, int c) +{ + return 0; +} +static int +status(int type) +{ + return 1; +} +SENSORS_SENSOR(temp_mcu_sensor, TEMP_MCU_SENSOR, value, configure, status); + diff --git a/platform/avr-rss2/dev/temp_mcu-sensor.h b/platform/avr-rss2/dev/temp_mcu-sensor.h new file mode 100644 index 000000000..c311fdb16 --- /dev/null +++ b/platform/avr-rss2/dev/temp_mcu-sensor.h @@ -0,0 +1,47 @@ +/* + * 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. + * + * + * ----------------------------------------------------------------- + * + * Author : Robert Olsson + * Created : 2015-10-27 + * Updated : $Date: 2007/11/13 20:36:40 $ + * $Revision: 1.1 $ + */ + +#ifndef TEMP_MCU_SENSOR_H_ +#define TEMP_MCU_SENSOR_H_ + +#include "lib/sensors.h" + +extern const struct sensors_sensor temp_mcu_sensor; + +#define TEMP_MCU_SENSOR "temp_mcu" + +#endif /* TEMP_MCU_SENSOR_H_ */ diff --git a/platform/avr-rss2/examples/avr_radio_power/AtMega256RFR2-summary-power.dat b/platform/avr-rss2/examples/avr_radio_power/AtMega256RFR2-summary-power.dat new file mode 100644 index 000000000..bc4e1f0cc --- /dev/null +++ b/platform/avr-rss2/examples/avr_radio_power/AtMega256RFR2-summary-power.dat @@ -0,0 +1,25 @@ + +# Atmega256RFR2 @ 20C, UNT-61E, RSS2 Mote 2015-12-30 +# TX-PWR RPC=0x0 vs RPC=0xFF. Current mA +# +15 14.6 11.8 +14 15.0 12.1 +13 15.3 12.5 +12 15.6 12.8 +11 15.9 13.1 +10 16.1 13.4 + 9 16.3 13.7 + 8 16.5 13.8 + 7 16.7 13.9 + 6 16.9 14.0 + 5 17.0 14.2 + 4 17.2 14.3 + 3 17.2 14.5 + 2 17.2 14.6 + 1 17.3 14.6 + 0 17.4 14.5 +RX 13.7 7.3 +IDLE 0 0 + + + diff --git a/platform/avr-rss2/examples/avr_radio_power/Makefile b/platform/avr-rss2/examples/avr_radio_power/Makefile new file mode 100644 index 000000000..fb9b062a1 --- /dev/null +++ b/platform/avr-rss2/examples/avr_radio_power/Makefile @@ -0,0 +1,9 @@ +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +CONTIKI_PROJECT = avr_radio_power +APPS+=powertrace +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../../.. +CONTIKI_WITH_RIME = 1 +include $(CONTIKI)/Makefile.include diff --git a/platform/avr-rss2/examples/avr_radio_power/README.md b/platform/avr-rss2/examples/avr_radio_power/README.md new file mode 100644 index 000000000..745a31790 --- /dev/null +++ b/platform/avr-rss2/examples/avr_radio_power/README.md @@ -0,0 +1,79 @@ +avr_radio_power +=============== + +Motivation +----------- +Spins over different radio seting for the Atmel radio. The motivation is to +get understanding and also to get correct data for avrora and Contiki + simulations. Program loops over different TX-power setting and measures +RX consumption also radio off and idle power use in SLEEP_MODE_PWR_SAVE is +measured. Program disables radio duty cycling (RDC) and sets MCU in deep +sleep mode to only get radio consumption. + +Usage +----- +The different setting is printed on the terminal. You need a way to measure +the current consumption and relate to the tests. + +Example +------- +Program printout with added measurements. The used board was RSS2 mote +with a AtMega256RFR2 CPU. Max is when 0xFF is written to the RPC register. + + +Run/setup Current use +------------------------------------------------ +TX with PWR=0 RPC=0x00 17.80 mA (MAX TX-pwr) +TX with PWR=1 RPC=0x00 17.74 +TX with PWR=2 RPC=0x00 +TX with PWR=3 RPC=0x00 +TX with PWR=4 RPC=0x00 +TX with PWR=5 RPC=0x00 17.43 +TX with PWR=6 RPC=0x00 +TX with PWR=7 RPC=0x00 +TX with PWR=8 RPC=0x00 +TX with PWR=9 RPC=0x00 17.68 +TX with PWR=10 RPC=0x00 +TX with PWR=11 RPC=0x00 +TX with PWR=12 RPC=0x00 +TX with PWR=13 RPC=0x00 +TX with PWR=14 RPC=0x00 +TX with PWR=15 RPC=0x00 +RX with RPC=0x00 -------------------- 13.43 (RX) + +------------------------------------------------- +TX with PWR=0 RPC=0xff 14.63 mA (MAX TX-pwr) +TX with PWR=1 RPC=0xff +TX with PWR=2 RPC=0xff +TX with PWR=3 RPC=0xff +TX with PWR=4 RPC=0xff +TX with PWR=5 RPC=0xff +TX with PWR=6 RPC=0xff 14.45 +TX with PWR=7 RPC=0xff +TX with PWR=8 RPC=0xff +TX with PWR=9 RPC=0xff +TX with PWR=10 RPC=0xff +TX with PWR=11 RPC=0xff +TX with PWR=12 RPC=0xff +TX with PWR=13 RPC=0xff +TX with PWR=14 RPC=0xff +TX with PWR=15 RPC=0xff +RX with RPC=0xFF -------------------- 7.11 (RX) + +RX radio off 0.001 mA + + +Comments +-------- +We see TX consumption decreases from 17.80 to 14.63 mA using Max RPC (0xFF). +NOTE! For RX 13.43 to 7.11 mA. Nice. This actual measurements. +The avr-rss2 port adds support for the AtMegaXXXRFR2 including the new RPC +function. + + +References +---------- +Atmel application note. AT02594: Smart Reduced Power Consumption Techniques +[Here] (http://www.atmel.com/images/atmel-42356-smart-reduced-power-consumption-techniques_applicationnote_at02594.pdf) + +Multimeter UNI-T UT61E with USB-logging. \ No newline at end of file diff --git a/platform/avr-rss2/examples/avr_radio_power/avr_radio_power.c b/platform/avr-rss2/examples/avr_radio_power/avr_radio_power.c new file mode 100644 index 000000000..5be61d8bd --- /dev/null +++ b/platform/avr-rss2/examples/avr_radio_power/avr_radio_power.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2015, Copyright Robert Olsson / Radio Sensors AB + * 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. + * + * + * Author : Robert Olsson robert@radio-sensors.com + * Created : 2015-12-30 + */ + +/** + * \file + * An application for monitoring current use on Atmel + * radios also supporting the RPC function on RFR2 chips. + * Current needs to be measured with amp-meter. + */ + +#include "contiki.h" +#include "net/rime/rime.h" +#include "powertrace.h" +#include +#include "dev/leds.h" +#include "rf230bb.h" +#include "net/packetbuf.h" +#include "net/rime/rimestats.h" +#include "net/netstack.h" +#include +#include + +#define TEST_PERIOD 6 + +static int ps = 0; /* Power-save false */ +static char buf[110]; +static struct etimer et; + +PROCESS(power_use_process, "Power use test"); +PROCESS(sleep_process, "Sleep process"); +AUTOSTART_PROCESSES(&power_use_process, &sleep_process); + +static void +broadcast_recv(struct broadcast_conn *c, const linkaddr_t *from) +{ + printf("broadcast message received from %d.%d: '%s'\n", + from->u8[0], from->u8[1], (char *)packetbuf_dataptr()); +} + +static const struct broadcast_callbacks broadcast_call = {broadcast_recv}; +static struct broadcast_conn broadcast; + + +PROCESS_THREAD(power_use_process, ev, data) +{ + static int i, j; + PROCESS_EXITHANDLER(broadcast_close(&broadcast);) + PROCESS_BEGIN(); + + /* powertrace_start(CLOCK_SECOND * 2); */ + broadcast_open(&broadcast, 129, &broadcast_call); + leds_init(); + rf230_set_channel(25); + + for(i=0; i < 2; i++) { /* Loop over min and max rpc settings */ + + NETSTACK_RADIO.off(); /* Radio off for rpc change */ + NETSTACK_RADIO.off(); + etimer_set(&et, CLOCK_SECOND * 8); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + if(i == 0) + rf230_set_rpc(0x0); /* Disbable all RPC features */ + else + rf230_set_rpc(0xFF); /* Enable all RPC features. Only XRFR2 radios */ + NETSTACK_RADIO.on(); + + /* Loop over the different TX power settings 0-15 */ + + for(j=15; j >= 0; j--) { + NETSTACK_RADIO.on(); + rf230_set_txpower(j); + ps = 0; + printf("TX with PWR=%d RPC=0x%02x\n", rf230_get_txpower(), rf230_get_rpc()); + ps = 1; + + etimer_set(&et, CLOCK_SECOND * TEST_PERIOD); + + while(1) { + if(etimer_expired(&et)) + break; + packetbuf_copyfrom(buf, sizeof(buf)); /* Dummy data */ + broadcast_send(&broadcast); + PROCESS_PAUSE(); + //leds_on(LEDS_RED); + } + /* Barrier so we can see next run */ + NETSTACK_RADIO.off(); + etimer_set(&et, CLOCK_SECOND * TEST_PERIOD); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + } + + /* RX */ + NETSTACK_RADIO.on(); + ps = 0; + printf("RX radio on RPC=0x%02x\n", rf230_get_rpc()); + ps = 1; + etimer_set(&et, CLOCK_SECOND * TEST_PERIOD); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + NETSTACK_RADIO.off(); + } + + /* Last just RX OFF*/ + ps = 0; + printf("RX radio off\n"); + ps = 1; + etimer_set(&et, CLOCK_SECOND * TEST_PERIOD); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + PROCESS_END(); +} + +/* Sleep process is just put MCU in sleep so we minimiza MCU impact */ +PROCESS_THREAD(sleep_process, ev, data) +{ + PROCESS_BEGIN(); + while(1) { + watchdog_periodic(); + if(ps) + set_sleep_mode(SLEEP_MODE_PWR_SAVE); + else + set_sleep_mode(SLEEP_MODE_IDLE); + cli(); + sleep_enable(); + sei(); + sleep_cpu(); + sleep_disable(); + sei(); + PROCESS_PAUSE(); + } + PROCESS_END(); +} + diff --git a/platform/avr-rss2/examples/avr_radio_power/project-conf.h b/platform/avr-rss2/examples/avr_radio_power/project-conf.h new file mode 100644 index 000000000..8d1bc434f --- /dev/null +++ b/platform/avr-rss2/examples/avr_radio_power/project-conf.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2015, Copyright Robert Olsson / Radio Sensors AB + * 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. + * + * + * Author : Robert Olsson robert@radio-sensors.com + * Created : 2015-11-22 + */ + +/** + * \file + * Project specific configuration defines for example + * + */ + +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +#define NETSTACK_CONF_RDC nullrdc_driver +#define NETSTACK_CONF_MAC nullmac_driver + +//#define NETSTACK_CONF_MAC csma_driver +//#define NETSTACK_CONF_RDC contikimac_driver + +#endif /* PROJECT_CONF_H_ */ diff --git a/platform/avr-rss2/examples/hello-sensors/Makefile b/platform/avr-rss2/examples/hello-sensors/Makefile new file mode 100644 index 000000000..c6e0da805 --- /dev/null +++ b/platform/avr-rss2/examples/hello-sensors/Makefile @@ -0,0 +1,19 @@ +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +CONTIKI_PROJECT = hello-sensors +all: $(CONTIKI_PROJECT) + +# We use floating vars. Add library. +PRINTF_LIB_FLT = -Wl,-u,vfprintf -lprintf_flt -lm +PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min +PRINTF_LIB = $(PRINTF_LIB_FLT) +CLIBS = $(PRINTF_LIB) + + +CUSTOM_RULE_LINK = 1 +%.$(TARGET): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a + $(LD) $(LDFLAGS) $(TARGET_STARTFILES) ${filter-out %.a,$^} ${filter %.a,$^} $(TARGET_LIBFILES) -o $@ $(CLIBS) + + + +CONTIKI = ../../../.. +include $(CONTIKI)/Makefile.include diff --git a/platform/avr-rss2/examples/hello-sensors/README.md b/platform/avr-rss2/examples/hello-sensors/README.md new file mode 100644 index 000000000..9b204a2a6 --- /dev/null +++ b/platform/avr-rss2/examples/hello-sensors/README.md @@ -0,0 +1,11 @@ +Hello-sensors +============= + +Simple demo to read out sensors from the RSS2 mote. + +Demo uses double which has the same size as float on Atmel. We sacrifice +some bytes for this. + +Build +----- +make TARGET=avr-rss2 diff --git a/platform/avr-rss2/examples/hello-sensors/hello-sensors.c b/platform/avr-rss2/examples/hello-sensors/hello-sensors.c new file mode 100644 index 000000000..42be6109e --- /dev/null +++ b/platform/avr-rss2/examples/hello-sensors/hello-sensors.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2015, Copyright Robert Olsson / Radio Sensors AB + * 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. + * + * + * Author : Robert Olsson robert@radio-sensors.com + * Created : 2015-11-22 + */ + +/** + * \file + * A simple application showing sensor reading on RSS2 mote + */ + +#include "contiki.h" +#include "sys/etimer.h" +#include +#include "adc.h" +#include "i2c.h" +#include "dev/leds.h" +#include "dev/battery-sensor.h" +#include "dev/temp-sensor.h" +#include "dev/temp_mcu-sensor.h" +#include "dev/light-sensor.h" +#include "dev/pulse-sensor.h" +#ifdef CO2 +#include "dev/co2_sa_kxx-sensor.h" +#endif +/*---------------------------------------------------------------------------*/ +PROCESS(hello_sensors_process, "Hello sensor process"); +AUTOSTART_PROCESSES(&hello_sensors_process); + +static struct etimer et; + +static void +read_values(void) +{ + char serial[16]; + + int i; + + /* Read out mote unique 128 bit ID */ + i2c_at24mac_read((char *) &serial, 0); + printf("128_bit_ID="); + for(i=0; i < 15; i++) + printf("%02x", serial[i]); + printf("%02x\n", serial[15]); + printf("T=%-5.2f", ((double) temp_sensor.value(0)/100.)); + printf(" V_MCU=%-3.1f", ((double) battery_sensor.value(0))/1000.); + printf(" V_IN=%-4.2f", adc_read_v_in()); + printf(" V_AD1=%-4.2f", adc_read_a1()); + printf(" V_AD2=%-4.2f", adc_read_a2()); + printf(" T_MCU=%-4.1f", ((double) temp_mcu_sensor.value(0)/10.)); + printf(" LIGHT=%-d", light_sensor.value(0)); + printf(" PULSE_0=%-d", pulse_sensor.value(0)); + printf(" PULSE_1=%-d", pulse_sensor.value(1)); +#ifdef CO2 + printf(" CO2=%-d", co2_sa_kxx_sensor.value( CO2_SA_KXX_CO2)); +#endif + printf("\n"); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(hello_sensors_process, ev, data) +{ + PROCESS_BEGIN(); + + SENSORS_ACTIVATE(temp_sensor); + SENSORS_ACTIVATE(battery_sensor); + SENSORS_ACTIVATE(temp_mcu_sensor); + SENSORS_ACTIVATE(light_sensor); + SENSORS_ACTIVATE(pulse_sensor); +#ifdef CO2 + SENSORS_ACTIVATE(co2_sa_kxx_sensor); +#endif + leds_init(); + leds_on(LEDS_RED); + leds_on(LEDS_YELLOW); + + /* + * Delay 5 sec + * Gives a chance to trigger some pulses + */ + + etimer_set(&et, CLOCK_SECOND * 5); + while(1) { + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + read_values(); + etimer_reset(&et); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/avr-rss2/examples/hello-sensors/project-conf.h b/platform/avr-rss2/examples/hello-sensors/project-conf.h new file mode 100644 index 000000000..8d1bc434f --- /dev/null +++ b/platform/avr-rss2/examples/hello-sensors/project-conf.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2015, Copyright Robert Olsson / Radio Sensors AB + * 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. + * + * + * Author : Robert Olsson robert@radio-sensors.com + * Created : 2015-11-22 + */ + +/** + * \file + * Project specific configuration defines for example + * + */ + +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +#define NETSTACK_CONF_RDC nullrdc_driver +#define NETSTACK_CONF_MAC nullmac_driver + +//#define NETSTACK_CONF_MAC csma_driver +//#define NETSTACK_CONF_RDC contikimac_driver + +#endif /* PROJECT_CONF_H_ */ diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/Makefile b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/Makefile new file mode 100644 index 000000000..9d8bccece --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/Makefile @@ -0,0 +1,49 @@ +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +all: coap-client coap-server +APPS=servreg-hack +CONTIKI=../../../../.. + +ifdef WITH_COMPOWER +APPS+=powertrace +CFLAGS+= -DCONTIKIMAC_CONF_COMPOWER=1 -DWITH_COMPOWER=1 -DQUEUEBUF_CONF_NUM=4 +endif + +ifdef SERVER_REPLY +CFLAGS+=-DSERVER_REPLY=$(SERVER_REPLY) +endif +ifdef PERIOD +CFLAGS+=-DPERIOD=$(PERIOD) +endif + +### -------------------------------------------------------- ### + +#CONTIKI_TARGET_SOURCEFILES += control.c vdc.c + +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_FILES = $(notdir $(shell find $(REST_RESOURCES_DIR) -name '*.c')) + +DC_SENSOR_DIR = ./dev +DC_SENSOR_FILES = $(notdir $(shell find $(DC_SENSOR_DIR) -name '*.c')) + +PROJECTDIRS += $(REST_RESOURCES_DIR) $(DC_SENSOR_DIR) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) $(DC_SENSOR_FILES) + +# linker optimizations +SMALL=1 + +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine + +#CFLAGS += -DUIP_CONF_BUFFER_SIZE=384 +CFLAGS += -DREST_MAX_CHUNK_SIZE=128 +CFLAGS += -DCOAP_MAX_HEADER_SIZE=64 + +CFLAGS += -DUIP_CONF_TCP=0 + +### -------------------------------------------------------- ### + +CONTIKI_WITH_IPV6 = 1 +include $(CONTIKI)/Makefile.include diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/README.md b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/README.md new file mode 100644 index 000000000..ba14cb756 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/README.md @@ -0,0 +1,67 @@ +Example: mockup of DC converter functionality for IoT-grid. +=========================================== +This example imitates DC converter functionality for IoT-grid. +We use standard IoT protocol stack with CoAP application-level protocol. +The settings are as follows. + +* APPLICATION: CoAP +* TRANSPORT: UDP +* NETWORK: IPv6/RPL +* ADAPTATION: 6LoWPAN +* MAC: nullmac_driver +* RADIO DUTY CYCLE: nullrdc_driver +* PHYSICAL: IEEE 802.15.4 + +CoAP resources +---------------- +We define a CoAP resource for each functionality of DC converter. +Since each functionality may have several parameters, we define each resource +as a vector of parameters as follows. + +* /dcdc/status read-only parameters for power monitoring. +It also support periodic monitoring through CoAP observe option. + ** 0 VOUT Output voltage + ** 1 VIN Input voltage + ** 2 IOUT Output current + ** 3 IIN Input current + +* /dcdc/vdc configurable parameters for voltage droop control function. + ** 0 VGRID Desired grid output voltage + ** 1 SLOPE Slope of voltage droop control function + ** 2 PMAX Maximum output power allowed + +* /dcdc/hwcfg configurable parameters for DC converter hardware. + ** 0 VMAX Maximum output voltage allowed + ** 1 IMAX Maximum output current allowed + +Each functionality is implemented as a sensor type device. +They are located in "dev" folder. +* dc-status-sensor for /dcdc/status +* dc-vdc-sensor for /dcdc/vdc +* dc-hw-sensor for /dcdc/hwcfg + +The corresponding CoAP handler for each resource is defined in "resources" folder. +* res-dc-status-obs for /dcdc/status +* res-dc-vdc for /dcdc/vdc +* res-dc-hwcfg for /dcdc/hwcfg + +coap-server.c +---------------- +The server acts as the RPL root node. +It has 3 CoAP resources as described above. + +coap-client.c +---------------- +The client periodically send a CoAP command (either GET or PUT) to monitor/update +values of parameters of a resource. + +project-conf.h +---------------- +This file contains definitions needed for this IoT-grid example as follows. +* Enable IPv6 network stack +* Set nullrdc_driver +* Set nullmac_driver +* Activate CoAP observe client library (COAP_OBSERVE_CLIENT = 1) +* Increase the maximum number of observee and maximum number of open transaction to 10 +(COAP_MAX_OPEN_TRANSACTIONS and COAP_MAX_OBSERVEES = 10) + diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-client.avr-rss2 b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-client.avr-rss2 new file mode 100644 index 000000000..e69de29bb diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-client.c b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-client.c new file mode 100644 index 000000000..691b48e40 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-client.c @@ -0,0 +1,413 @@ +/* + * 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. + * + */ + +#include "contiki.h" +#include "contiki-net.h" +#include "lib/random.h" +#include "sys/ctimer.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "net/ip/uip-udp-packet.h" +#ifdef WITH_COMPOWER +#include "powertrace.h" +#endif +#include +#include + +/**************************************************************************/ +/* from er-rest-example/er-rexample-client.c */ +#include +#include "er-coap-engine.h" +#include "er-coap.h" +#include "er-coap-observe-client.h" +/* #include "dev/button-sensor.h" */ + +#if PLATFORM_HAS_LEDS +#include "dev/leds.h" +#endif + +#define DEBUG 1 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +/* FIXME: This server address is hard-coded for Cooja and link-local for unconnected border router. */ +/* #define SERVER_NODE(ipaddr) uip_ip6addr(ipaddr, 0xfe80, 0, 0, 0, 0x0212, 0x7402, 0x0002, 0x0202) / * cooja2 * / */ +/* #define SERVER_NODE(ipaddr) uip_ip6addr(ipaddr, 0xbbbb, 0, 0, 0, 0, 0, 0, 0x1) */ + +/* #define SERVER_NODE(ipaddr) uip_ip6addr(ipaddr, 0x2000, 0, 0, 0, 0, 0, 0, 0x0001) */ +#define LOCAL_PORT UIP_HTONS(COAP_DEFAULT_PORT + 1) +#define REMOTE_PORT UIP_HTONS(COAP_DEFAULT_PORT) + +#define GET_INTERVAL 10 +/* #define OBSERVE_INTERVAL 10 */ + +/**************************************************************************/ + +#define UDP_CLIENT_PORT 8765 +#define UDP_SERVER_PORT 5678 + +#define UDP_EXAMPLE_ID 190 + +/* #define DEBUG DEBUG_PRINT */ +/* #include "net/ip/uip-debug.h" */ + +#ifndef PERIOD +/* #define PERIOD 60 */ +#define PERIOD 10 +#endif + +#define START_INTERVAL (15 * CLOCK_SECOND) +#define SEND_INTERVAL (PERIOD * CLOCK_SECOND) +#define SEND_TIME (random_rand() % (SEND_INTERVAL)) + +/* static struct uip_udp_conn *client_conn; */ +static uip_ipaddr_t server_ipaddr; +static coap_observee_t *obs; +static int count_notify = 0; + +/**************************************************************************/ +static struct etimer et; + +/* Example URIs that can be queried. */ +#define NUMBER_OF_URLS 4 +/* leading and ending slashes only for demo purposes, get cropped automatically when setting the Uri-Path */ +char *service_urls[NUMBER_OF_URLS] = +{ ".well-known/core", "/dcdc/status", "/dcdc/vdc", "/dcdc/hwcfg" }; +/* + #if PLATFORM_HAS_BUTTON + static int uri_switch = 0; + #endif + */ +/* This function is will be passed to COAP_BLOCKING_REQUEST() to handle responses. */ +void +client_chunk_handler(void *response) +{ + const uint8_t *chunk; + + int len = coap_get_payload(response, &chunk); + +#if PLATFORM_HAS_LEDS + /* set red led when receiving a packet */ + leds_on(LEDS_RED); +#endif + +/* printf("|%.*s", len, (char *)chunk); */ + printf("RX: %d\n%s\n", len, (char *)chunk); +} +/**************************************************************************/ + +/*---------------------------------------------------------------------------*/ +PROCESS(coap_client_process, "CoAP client process"); +AUTOSTART_PROCESSES(&coap_client_process); +/*---------------------------------------------------------------------------*/ +static void +tcpip_handler(void) +{ + char *str; + + if(uip_newdata()) { + str = uip_appdata; + str[uip_datalen()] = '\0'; + printf("DATA recv '%s'\n", str); + } +} +/*---------------------------------------------------------------------------*/ +static void +print_local_addresses(void) +{ + int i; + uint8_t state; + + PRINTF("Client 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)) { + PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); + PRINTF("\n"); + /* hack to make address "final" */ + if(state == ADDR_TENTATIVE) { + uip_ds6_if.addr_list[i].state = ADDR_PREFERRED; + } + } + } +} +/*---------------------------------------------------------------------------*/ +static void +set_global_address(void) +{ + uip_ipaddr_t ipaddr; + + 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); + +/* The choice of server address determines its 6LoPAN header compression. + * (Our address will be compressed Mode 3 since it is derived from our link-local address) + * Obviously the choice made here must also be selected in udp-server.c. + * + * For correct Wireshark decoding using a sniffer, add the /64 prefix to the 6LowPAN protocol preferences, + * e.g. set Context 0 to aaaa::. At present Wireshark copies Context/128 and then overwrites it. + * (Setting Context 0 to aaaa::1111:2222:3333:4444 will report a 16 bit compressed address of aaaa::1111:22ff:fe33:xxxx) + * + * Note the IPCMV6 checksum verification depends on the correct uncompressed addresses. + */ + +#if 0 +/* Mode 1 - 64 bits inline */ + uip_ip6addr(&server_ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1); +#elif 1 +/* Mode 2 - 16 bits inline */ + uip_ip6addr(&server_ipaddr, 0xaaaa, 0, 0, 0, 0, 0x00ff, 0xfe00, 1); +#else +/* Mode 3 - derived from server link-local (MAC) address */ + uip_ip6addr(&server_ipaddr, 0xaaaa, 0, 0, 0, 0x0250, 0xc2ff, 0xfea8, 0xcd1a); /* redbee-econotag */ +#endif +/* Voravit Added */ +/* PRINTF("VORAVIT CLIENT: SERVER IPv6 addresses: \n"); */ +/* PRINT6ADDR(&server_ipaddr); */ +} +/*---------------------------------------------------------------------------*/ + +static void +generate_random_payload(int type, char *msg) +{ + if(type == 2) { /* /dcdc/vdc */ + snprintf((char *)msg, 64, "&VG=%d&SL=%d&PMX=%d", (random_rand() % 25) + 1, (random_rand() % 10) + 1, (random_rand() % 100) + 1); + } else if(type == 3) { /* /dcdc/hwcfg */ + snprintf((char *)msg, 64, "&VMX=%d&IMX=%d", (random_rand() % 25) + 1, (random_rand() % 6) + 1); + } +} +/*----------------------------------------------------------------------------*/ +/* + * Handle the response to the observe request and the following notifications + */ +static void +notification_callback(coap_observee_t *obs, void *notification, coap_notification_flag_t flag) +{ + int len = 0; + const uint8_t *payload = NULL; + +/* printf("Notification handler\n"); */ +/* printf("Observee URI: %s\n", obs->url); */ + if(notification) { + len = coap_get_payload(notification, &payload); + } + switch(flag) { + case NOTIFICATION_OK: + count_notify++; + printf("NOTIFICATION OK: %d\n%*s\n", count_notify, len, (char *)payload); + break; + case OBSERVE_OK: /* server accepeted observation request */ + printf("OBSERVE_OK: \n%*s\n", len, (char *)payload); + break; + case OBSERVE_NOT_SUPPORTED: + printf("OBSERVE_NOT_SUPPORTED: \n%*s\n", len, (char *)payload); + obs = NULL; + break; + case ERROR_RESPONSE_CODE: + printf("ERROR_RESPONSE_CODE: \n%*s\n", len, (char *)payload); + obs = NULL; + break; + case NO_REPLY_FROM_SERVER: + printf("NO_REPLY_FROM_SERVER: " + "removing observe registration with token %x%x\n", + obs->token[0], obs->token[1]); + obs = NULL; + break; + } +} +/*---------------------------------------------------------------------------*/ +/* + * Toggle the observation of the remote resource + */ +void +toggle_observation(void) +{ + if(obs) { + printf("Stopping observation\n"); + coap_obs_remove_observee(obs); + obs = NULL; + } else { + printf("Starting observation\n"); + obs = coap_obs_request_registration(&server_ipaddr, REMOTE_PORT, service_urls[1], notification_callback, NULL); + } +} +/*---------------------------------------------------------------------------*/ +static int count_get = 0; +static int count_put = 0; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(coap_client_process, ev, data) +{ +/* + #if WITH_COMPOWER + static int print = 0; + #endif + */ + PROCESS_BEGIN(); + + PROCESS_PAUSE(); + + set_global_address(); + + PRINTF("CoAP client process started\n"); + + print_local_addresses(); + +/**************************************************************************/ + static coap_packet_t request[1]; /* This way the packet can be treated as pointer as usual. */ + + /* receives all CoAP messages */ + coap_init_engine(); + + etimer_set(&et, GET_INTERVAL * CLOCK_SECOND); + + while(1) { + PROCESS_YIELD(); + + if(ev == tcpip_event) { + printf("TCPIP_HANDLER\n"); + tcpip_handler(); + } + + if(etimer_expired(&et)) { + count_get++; + +/*---------------------------------------------------------------------------*/ + if(count_get < 10) { /* we do normal GET 3 times for each resource */ + /* TEST GET: looping through the 3 resources: status, vdc, hwcfg */ + /* Also CoAP GET doesn't need to have a payload */ + coap_init_message(request, COAP_TYPE_CON, COAP_GET, 0); + if(count_get % 3 == 1) { + coap_set_header_uri_path(request, service_urls[1]); + PRINTF("GET %d: %s\n", count_get, service_urls[1]); + } else if(count_get % 3 == 2) { + coap_set_header_uri_path(request, service_urls[2]); + PRINTF("GET %d: %s\n", count_get, service_urls[2]); + } else { + coap_set_header_uri_path(request, service_urls[3]); + PRINTF("GET %d: %s\n", count_get, service_urls[3]); + } + +#if PLATFORM_HAS_LEDS + /* set yellow led when sending packet */ + leds_on(LEDS_YELLOW); +#endif + COAP_BLOCKING_REQUEST(&server_ipaddr, REMOTE_PORT, request, + client_chunk_handler); + } /* if (count_get < 10) */ +/*---------------------------------------------------------------------------*/ + /* test PUT: vdc and hwcfg on odd and even packet */ + /* every 10th timer we PUT a resource: vdc and hwcfg alternately */ + if(count_get % 10 == 0) { + /* static char msg[64] = ""; */ + char msg[64] = ""; + + /*---------------------------------------------------------------------------*/ + /* We read CO2 sensor if it is enable */ + #ifdef CO2 + coap_init_message(request, COAP_TYPE_CON, COAP_GET, 0); + coap_set_header_uri_path(request, "/dcdc/co2"); + PRINTF("GET %d: %s\n", count_get, "/dcdc/co2"); + #if PLATFORM_HAS_LEDS + leds_on(LEDS_YELLOW); + #endif + COAP_BLOCKING_REQUEST(&server_ipaddr, REMOTE_PORT, request, + client_chunk_handler); + #endif + /*---------------------------------------------------------------------------*/ + + count_put++; + coap_init_message(request, COAP_TYPE_CON, COAP_PUT, 0); + + if(count_put % 2 == 0) { + coap_set_header_uri_path(request, service_urls[3]); + generate_random_payload(3, msg); + coap_set_payload(request, (uint8_t *)msg, sizeof(msg) - 1); + PRINTF("PUT %d: %s PAYLOAD: %s\n", count_get, service_urls[3], msg); + } else { + coap_set_header_uri_path(request, service_urls[2]); + generate_random_payload(2, msg); + coap_set_payload(request, (uint8_t *)msg, sizeof(msg) - 1); + PRINTF("PUT %d: %s PAYLOAD: %s\n", count_get, service_urls[2], msg); + } + +#if PLATFORM_HAS_LEDS + /* set yellow led when sending packet */ + leds_on(LEDS_YELLOW); +#endif + COAP_BLOCKING_REQUEST(&server_ipaddr, REMOTE_PORT, request, + client_chunk_handler); + + + } + + /* after 2 more timeout we do GET to check the resource new value */ + if((count_get > 10) && ((count_get - 2) % 10 == 0)) { + coap_init_message(request, COAP_TYPE_CON, COAP_GET, 0); + + if(count_put % 2 == 0) { + coap_set_header_uri_path(request, service_urls[3]); + PRINTF("GET %d: %s\n", count_get, service_urls[3]); + } else { + coap_set_header_uri_path(request, service_urls[2]); + PRINTF("GET %d: %s\n", count_get, service_urls[2]); + } + +#if PLATFORM_HAS_LEDS + /* set yellow led when sending packet */ + leds_on(LEDS_YELLOW); +#endif + COAP_BLOCKING_REQUEST(&server_ipaddr, REMOTE_PORT, request, + client_chunk_handler); + } + +/*---------------------------------------------------------------------------*/ + + /* test GET with observe option when timer expires the 15th time */ + if(count_get == 15) { + /* PRINTF("GET %d: OBSERVE: %s\n", count_get, service_urls[2]); */ + toggle_observation(); + } + + etimer_reset(&et); + } + } /* END_WHILE(1) */ + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-server.avr-rss2 b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-server.avr-rss2 new file mode 100644 index 000000000..e69de29bb diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-server.c b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-server.c new file mode 100644 index 000000000..8e1ee552d --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-server.c @@ -0,0 +1,269 @@ +/* + * 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. + * + */ + +#include "contiki.h" +#include "contiki-lib.h" +#include "contiki-net.h" +#include "net/ip/uip.h" +#include "net/rpl/rpl.h" + +#include "net/netstack.h" +/* #include "dev/leds.h" */ +#include +#include +#include +#include + +/* + #define DEBUG DEBUG_PRINT + #include "net/ip/uip-debug.h" + */ +/**************************************************************************/ +/* add mock-up code for DC-DC converter */ +/* #include "control.h" */ +/* #include "vdc.h" */ +#ifdef CO2 +#include "dev/co2_sa_kxx-sensor.h" +#endif +#include "dev/dc-status-sensor.h" +#include "dev/dc-vdc-sensor.h" +#include "dev/dc-hw-sensor.h" + +/* from er-rest-example/er-rexample-server.c */ +#include "rest-engine.h" +/* #include "er-coap.h" */ + +#if PLATFORM_HAS_LEDS +#include "dev/leds.h" +#endif + +/* + #if PLATFORM_HAS_BUTTON + #include "dev/button-sensor.h" + #endif + */ +#define DEBUG 1 +#if DEBUG +/* #include */ +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +/* #define TOGGLE_INTERVAL 10 */ +/* #define OBSERVE_INTERVAL 10 */ + +/* + * Resources to be activated need to be imported through the extern keyword. + * The build system automatically compiles the resources in the corresponding sub-directory. + */ +extern resource_t +/* res_hello, */ +/* res_push, */ +/* res_event, */ +/* res_sub; */ +/* res_dc_status_obs; */ +/* res_dc_status, */ +#ifdef CO2 + res_dc_co2, +#endif + res_dc_status_obs, + res_dc_vdc, + res_dc_hwcfg; +/* + #if PLATFORM_HAS_LEDS + extern resource_t + // res_leds, + res_toggle; + #endif + */ +/* #if PLATFORM_HAS_LIGHT */ +/* #include "dev/light-sensor.h" */ +/* extern resource_t res_light; */ +/* #endif */ + +/**************************************************************************/ + +PROCESS(coap_server_process, "CoAP server process"); +AUTOSTART_PROCESSES(&coap_server_process); +/*---------------------------------------------------------------------------*/ +static void +print_local_addresses(void) +{ + int i; + uint8_t state; + + PRINTF("Server IPv6 addresses: "); + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(state == ADDR_TENTATIVE || state == ADDR_PREFERRED) { + PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); + PRINTF("\n"); + /* hack to make address "final" */ + if(state == ADDR_TENTATIVE) { + uip_ds6_if.addr_list[i].state = ADDR_PREFERRED; + } + } + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(coap_server_process, ev, data) +{ + uip_ipaddr_t ipaddr; + struct uip_ds6_addr *root_if; + + PROCESS_BEGIN(); + + PROCESS_PAUSE(); + +/* SENSORS_ACTIVATE(button_sensor); */ +#ifdef CO2 + SENSORS_ACTIVATE(co2_sa_kxx_sensor); +#endif + SENSORS_ACTIVATE(dc_status_sensor); + SENSORS_ACTIVATE(dc_vdc_sensor); + SENSORS_ACTIVATE(dc_hw_sensor); + +/**************************************************************************/ + +#if PLATFORM_HAS_LEDS +/* initialize leds */ + leds_init(); + leds_on(LEDS_RED); + leds_on(LEDS_YELLOW); +#endif + +/* Initilize DC-DC converter parameters */ +/* ValueInit(); */ +/* VDCInit(); */ +/* + #ifdef PARAMS_CHANNEL + PRINTF("PARAMs channel: %u\n", PARAMS_CHANNEL); + #endif + */ +#ifdef RF_CHANNEL + PRINTF("RF channel: %u\n", RF_CHANNEL); +#endif +#ifdef IEEE802154_PANID + PRINTF("PAN ID: 0x%04X\n", IEEE802154_PANID); +#endif + + PRINTF("uIP buffer: %u\n", UIP_BUFSIZE); + PRINTF("LL header: %u\n", UIP_LLH_LEN); + PRINTF("IP+UDP header: %u\n", UIP_IPUDPH_LEN); + PRINTF("REST max chunk: %u\n", REST_MAX_CHUNK_SIZE); + + /* Initialize the REST engine. */ + rest_init_engine(); + + /* + * Bind the resources to their Uri-Path. + * WARNING: Activating twice only means alternate path, not two instances! + * All static variables are the same for each URI path. + */ +/* rest_activate_resource(&res_hello, "test/hello"); */ +/* rest_activate_resource(&res_mirror, "debug/mirror"); */ +/* rest_activate_resource(&res_chunks, "test/chunks"); */ +/* rest_activate_resource(&res_separate, "test/separate"); */ +/* rest_activate_resource(&res_push, "test/push"); */ +/* rest_activate_resource(&res_event, "sensors/button"); */ +/* rest_activate_resource(&res_sub, "test/sub"); */ +/* rest_activate_resource(&res_b1_sep_b2, "test/b1sepb2"); */ +#ifdef CO2 + rest_activate_resource(&res_dc_co2, "dcdc/co2"); +#endif + rest_activate_resource(&res_dc_status_obs, "dcdc/status"); +/* rest_activate_resource(&res_dc_status, "dcdc/status"); */ + rest_activate_resource(&res_dc_vdc, "dcdc/vdc"); + rest_activate_resource(&res_dc_hwcfg, "dcdc/hwcfg"); +/* #if PLATFORM_HAS_LEDS */ +/* / * rest_activate_resource(&res_leds, "actuators/leds"); * / */ +/* rest_activate_resource(&res_toggle, "actuators/toggle"); */ +/* #endif */ +/* #if PLATFORM_HAS_LIGHT */ +/* rest_activate_resource(&res_light, "sensors/light"); */ +/* SENSORS_ACTIVATE(light_sensor); */ +/* #endif */ + +/**************************************************************************/ + + PRINTF("CoAP server started\n"); + +#if UIP_CONF_ROUTER +/* The choice of server address determines its 6LoPAN header compression. + * Obviously the choice made here must also be selected in udp-client.c. + * + * For correct Wireshark decoding using a sniffer, add the /64 prefix to the 6LowPAN protocol preferences, + * e.g. set Context 0 to aaaa::. At present Wireshark copies Context/128 and then overwrites it. + * (Setting Context 0 to aaaa::1111:2222:3333:4444 will report a 16 bit compressed address of aaaa::1111:22ff:fe33:xxxx) + * Note Wireshark's IPCMV6 checksum verification depends on the correct uncompressed addresses. + */ + +#if 0 +/* Mode 1 - 64 bits inline */ + uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1); +#elif 1 +/* Mode 2 - 16 bits inline */ + uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0x00ff, 0xfe00, 1); +#else +/* Mode 3 - derived from link local (MAC) address */ + uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); +#endif + + uip_ds6_addr_add(&ipaddr, 0, ADDR_MANUAL); + root_if = uip_ds6_addr_lookup(&ipaddr); + if(root_if != NULL) { + rpl_dag_t *dag; + dag = rpl_set_root(RPL_DEFAULT_INSTANCE, (uip_ip6addr_t *)&ipaddr); + uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + rpl_set_prefix(dag, &ipaddr, 64); + PRINTF("created a new RPL dag\n"); + } else { + PRINTF("failed to create a new RPL DAG\n"); + } +#endif /* UIP_CONF_ROUTER */ + + print_local_addresses(); + + /* The data sink runs with a 100% duty cycle in order to ensure high + packet reception rates. */ + NETSTACK_MAC.off(1); + + while(1) { + PROCESS_WAIT_EVENT(); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dc-rpl-coap.csc b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dc-rpl-coap.csc new file mode 100644 index 000000000..40faff223 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dc-rpl-coap.csc @@ -0,0 +1,168 @@ + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/native_gateway + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + /home/user/contikiprojects/sics.se/mobility + [CONTIKI_DIR]/tools/cooja/apps/collect-view + /home/user/contikiprojects/sics.se/powertracker + + My simulation + 123456 + 1000000 + + se.sics.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.avrmote.RSS2MoteType + mote1 + Mote1 + [CONTIKI_DIR]/platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-server.c + make coap-server.avr-rss2 TARGET=avr-rss2 MCU=atmega128rfr2 + [CONTIKI_DIR]/platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-server.avr-rss2 + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.avrmote.interfaces.AvroraClock + se.sics.cooja.avrmote.interfaces.AvroraMoteID + se.sics.cooja.avrmote.interfaces.AvroraUsart0 + se.sics.cooja.avrmote.interfaces.AvroraUsart1 + se.sics.cooja.avrmote.interfaces.RFR2Radio + se.sics.cooja.avrmote.interfaces.AvroraADC + se.sics.cooja.avrmote.interfaces.AvroraLED + + + se.sics.cooja.avrmote.RSS2MoteType + mote2 + Mote2 + [CONTIKI_DIR]/platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-client.c + make coap-client.avr-rss2 TARGET=avr-rss2 MCU=atmega128rfr2 + [CONTIKI_DIR]/platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-client.avr-rss2 + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.avrmote.interfaces.AvroraClock + se.sics.cooja.avrmote.interfaces.AvroraMoteID + se.sics.cooja.avrmote.interfaces.AvroraUsart0 + se.sics.cooja.avrmote.interfaces.AvroraUsart1 + se.sics.cooja.avrmote.interfaces.RFR2Radio + se.sics.cooja.avrmote.interfaces.AvroraADC + se.sics.cooja.avrmote.interfaces.AvroraLED + + + + + se.sics.cooja.interfaces.Position + 100.0 + 100.0 + 0.0 + + + se.sics.cooja.avrmote.interfaces.AvroraMoteID + 1 + + mote1 + + + + + se.sics.cooja.interfaces.Position + 110.0 + 100.0 + 0.0 + + + se.sics.cooja.avrmote.interfaces.AvroraMoteID + 2 + + mote2 + + + + se.sics.cooja.plugins.SimControl + 280 + 9 + 160 + 400 + 0 + + + se.sics.cooja.plugins.Visualizer + + true + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.GridVisualizerSkin + 3.908924509090908 0.0 0.0 3.908924509090908 -216.43707345454544 -217.89245090909074 + + 400 + 5 + 400 + 1 + 1 + + + se.sics.cooja.plugins.LogListener + + + + + + 1269 + 8 + 240 + 400 + 160 + + + se.sics.cooja.plugins.Notes + + Enter notes here + true + + 989 + 6 + 160 + 680 + 0 + + + se.sics.cooja.plugins.MoteInterfaceViewer + 0 + + Serial port + 0,0 + + 508 + 4 + 389 + 13 + 413 + + + se.sics.cooja.plugins.MoteInterfaceViewer + 1 + + Serial port + 0,0 + + 545 + 3 + 392 + 531 + 413 + + + diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-hw-sensor.c b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-hw-sensor.c new file mode 100644 index 000000000..d5715b820 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-hw-sensor.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2015, ICT/COS/NSLab, KTH Royal Institute of Technology + * 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. + */ + +/** + * \file + * dcdc/hwcfg for DC-DC converter hardware configuration + * \author + * Voravit Tanyingyong + */ + +#include "contiki.h" +/* #include "lib/sensors.h" */ +#include "dev/dc-hw-sensor.h" + +const struct sensors_sensor dc_hw_sensor; + +/* + * hw contains 2 parameters + * hw[0] VMAX + * hw[1] IMAX + */ + +uint32_t volatile hw[2] = { 25, 6 }; + +static int +value(int type) +{ + switch(type) { + case 0: + return hw[0]; + + case 1: + return hw[1]; + } + return -1; +} +static int +configure(int type, int c) +{ + switch(type) { + case 0: + if((c >= 0) && (c <= 25)) { + hw[0] = c; + return 0; + } else { + return 1; + } + + case 1: + if((c >= 0) && (c <= 6)) { + hw[1] = c; + return 0; + } else { + return 0; + } + } + return 1; +} +static int +status(int type) +{ + return 1; +} +SENSORS_SENSOR(dc_hw_sensor, "hw sensors", value, configure, status); + diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-hw-sensor.h b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-hw-sensor.h new file mode 100644 index 000000000..538dd2be3 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-hw-sensor.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2015, ICT/COS/NSLab, KTH Royal Institute of Technology + * 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. + */ + +/** + * \file + * dcdc/hwcfg header file + * \author + * Voravit Tanyingyong + */ + +#ifndef DC_HW_SENSOR_H +#define DC_HW_SENSOR_H + +#include "lib/sensors.h" + +extern const struct sensors_sensor dc_hw_sensor; + +#endif /* DC_HW_SENSOR_H */ diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-status-sensor.c b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-status-sensor.c new file mode 100644 index 000000000..c4998e61c --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-status-sensor.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2015, ICT/COS/NSLab, KTH Royal Institute of Technology + * 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. + */ + +/** + * \file + * dcdc/status read-only parameters for power monitoring + * \author + * Voravit Tanyingyong + */ + +#include "contiki.h" +/* #include "lib/sensors.h" */ +#include "dev/dc-status-sensor.h" + +const struct sensors_sensor dc_status_sensor; + +/* + * Status contains 4 parameters + * status[0] VOUT + * status[1] VIN + * status[2] IOUT + * status[3] IIN + */ + +uint32_t volatile s[4] = { 18, 20, 1, 2 }; + +static int +value(int type) +{ + switch(type) { + case 0: + return s[0]; + + case 1: + return s[1]; + + case 2: + return s[2]; + + case 3: + return s[3]; + } + return -1; +} +static int +configure(int type, int c) +{ + return 0; +} +static int +status(int type) +{ + return 1; +} +SENSORS_SENSOR(dc_status_sensor, "DC status sensors", value, configure, status); + diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-status-sensor.h b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-status-sensor.h new file mode 100644 index 000000000..97bb7c0c2 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-status-sensor.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2015, ICT/COS/NSLab, KTH Royal Institute of Technology + * 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. + */ + +/** + * \file + * dcdc/status header file + * \author + * Voravit Tanyingyong + */ + +#ifndef DC_STATUS_SENSOR_H +#define DC_STATUS_SENSOR_H + +#include "lib/sensors.h" + +extern const struct sensors_sensor dc_status_sensor; + +#endif /* DC_STATUS_SENSOR_H */ diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-vdc-sensor.c b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-vdc-sensor.c new file mode 100644 index 000000000..bdec4df70 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-vdc-sensor.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2015, ICT/COS/NSLab, KTH Royal Institute of Technology + * 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. + */ + +/** + * \file + * dcdc/vdc for voltage droop control function + * \author + * Voravit Tanyingyong + */ + +#include "contiki.h" +/* #include "lib/sensors.h" */ +#include "dev/dc-vdc-sensor.h" + +const struct sensors_sensor dc_vdc_sensor; + +/* + * vdc contains 3 parameters + * vdc[0] VGRID + * vdc[1] SLOPE + * vdc[2] PMAX + */ + +uint32_t volatile vdc[3] = { 18, 1, 100 }; + +static int +value(int type) +{ + switch(type) { + case 0: + return vdc[0]; + + case 1: + return vdc[1]; + + case 2: + return vdc[2]; + } + return -1; +} +static int +configure(int type, int c) +{ + switch(type) { + case 0: + if((c >= 0) && (c <= 25)) { + vdc[0] = c; + return 0; + } else { + return 1; + } + + case 1: + vdc[1] = c; + return 0; + + case 2: + vdc[2] = c; + return 0; + } + return 1; +} +static int +status(int type) +{ + return 1; +} +SENSORS_SENSOR(dc_vdc_sensor, "vdc sensors", value, configure, status); + diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-vdc-sensor.h b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-vdc-sensor.h new file mode 100644 index 000000000..72749c1c6 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-vdc-sensor.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2015, ICT/COS/NSLab, KTH Royal Institute of Technology + * 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. + */ + +/** + * \file + * dcdc/vdc sensor header file + * \author + * Voravit Tanyingyong + */ + +#ifndef DC_VDC_SENSOR_H +#define DC_VDC_SENSOR_H + +#include "lib/sensors.h" + +extern const struct sensors_sensor dc_vdc_sensor; + +#endif /* DC_VDC_SENSOR_H */ diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/er-dc-test.h b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/er-dc-test.h new file mode 100644 index 000000000..5c34cb847 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/er-dc-test.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015, ICT/COS/NSLab, KTH Royal Institute of Technology + * 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. + */ + +/** + * \file + * header file for resources + * \author + * Voravit Tanyingyong + */ + +#ifndef __ER_DC_TEST_H__ +#define __ER_DC_TEST_H__ + +#define DEBUG 1 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +/* double expansion */ +#define TO_STRING2(x) # x +#define TO_STRING(x) TO_STRING2(x) + +#define MAX_COAP_PAYLOAD 64 + 1 /* +1 for the terminating zero, which is not transmitted */ +/* #define MAX_PLUGFEST_BODY 2048 */ +/* #define CHUNKS_TOTAL 2012 */ + +#endif /* __ER_DC_TEST_H__ */ diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/project-conf.h b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/project-conf.h new file mode 100644 index 000000000..8193c1ee0 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/project-conf.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2015, ICT/COS/NSLab, KTH Royal Institute of Technology + * 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. + */ + +/** + * \file + * test rpl configuration. + * \author + * Voravit Tanyingyong + */ + +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +/* enable IPv6 */ +/* #ifndef NETSTACK_CONF_WITH_IPV6 */ +#define NETSTACK_CONF_WITH_IPV6 1 +/* #endif / * NETSTACK_CONF_WITH_IPV6 * / */ + +#define NETSTACK_CONF_RDC nullrdc_driver +#define NETSTACK_CONF_MAC nullmac_driver + +#define COAP_OBSERVE_CLIENT 1 +#define COAP_MAX_OBSERVEES 10 +#define COAP_MAX_OPEN_TRANSACTIONS 10 + +/* enable debug to activate PRINT6ADDR macro */ +/* #undef DEBUG_PRINT */ +/* #define DEBUG_PRINT 1 */ + +/* #define PRINTF(...) printf(__VA_ARGS__) */ +/* #define PRINT6ADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) */ + +#endif /* PROJECT_CONF_H_ */ diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-co2.c b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-co2.c new file mode 100644 index 000000000..45860653a --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-co2.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2015, ICT/COS/NSLab, KTH Royal Institute of Technology + * 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. + */ + +/** + * \file + * dcdc/co2 testing coap with CO2 sensor from SenseAir + * \author + * Voravit Tanyingyong + */ + +/* #include */ +#include +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-dc-test.h" +#if PLATFORM_HAS_LEDS +#include "dev/leds.h" +#endif +#include "dev/co2_sa_kxx-sensor.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_dc_co2, "title=\"co2 reading\"", res_get_handler, NULL, NULL, NULL); + +/*---------------------------------------------------------------------------*/ +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + int co2 = co2_sa_kxx_sensor.value(CO2_SA_KXX_CO2); // 0 is CO2_SA_KXX_CO2 + +#if PLATFORM_HAS_LEDS + /* set red led when receiving a packet */ + leds_on(LEDS_RED); +#endif + + PRINTF("dcdc/co2 GET (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + + /* Code 2.05 CONTENT is default. */ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + /* REST.set_header_max_age(response, 30); */ + REST.set_response_payload( + response, + buffer, +/* snprintf((char *)buffer, MAX_COAP_PAYLOAD, "VMX\t%d.000\nIMX\t%d.000\nINT\t%d\n", v_max, i_max, interval)); */ + snprintf((char *)buffer, MAX_COAP_PAYLOAD, "CO2\t%d\n", co2)); + +#if PLATFORM_HAS_LEDS + /* set yellow led when sending packet */ + leds_on(LEDS_YELLOW); +#endif +} + diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-hwcfg.c b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-hwcfg.c new file mode 100644 index 000000000..6c8091774 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-hwcfg.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2015, ICT/COS/NSLab, KTH Royal Institute of Technology + * 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. + */ + +/** + * \file + * dcdc/vdc configurable parameters for voltage droop control function + * \author + * Voravit Tanyingyong + */ + +/* #include */ +#include +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-dc-test.h" +#if PLATFORM_HAS_LEDS +#include "dev/leds.h" +#endif +#include "dev/dc-hw-sensor.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_post_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_dc_hwcfg, "title=\"hwcfg parameters\"", res_get_handler, res_post_put_handler, res_post_put_handler, NULL); + +/*---------------------------------------------------------------------------*/ +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + int v_max = dc_hw_sensor.value(0); + int i_max = dc_hw_sensor.value(1); + +#if PLATFORM_HAS_LEDS + /* set red led when receiving a packet */ + leds_on(LEDS_RED); +#endif + + PRINTF("dcdc/hwcfg GET (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + + /* Code 2.05 CONTENT is default. */ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + /* REST.set_header_max_age(response, 30); */ + REST.set_response_payload( + response, + buffer, +/* snprintf((char *)buffer, MAX_COAP_PAYLOAD, "VMX\t%d.000\nIMX\t%d.000\nINT\t%d\n", v_max, i_max, interval)); */ + snprintf((char *)buffer, MAX_COAP_PAYLOAD, "VMX\t%d.000\nIMX\t%d.000\n", v_max, i_max)); + +#if PLATFORM_HAS_LEDS + /* set yellow led when sending packet */ + leds_on(LEDS_YELLOW); +#endif +} +/*---------------------------------------------------------------------------*/ +static void +res_post_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + +#if PLATFORM_HAS_LEDS + /* set red led when receiving a packet */ + leds_on(LEDS_RED); +#endif + + PRINTF("dcdc/hwcfg PUT (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + + const char *variable = NULL; + + if(REST.get_post_variable(request, "VMX", &variable) > 0) { + int v_max = atoi(variable); + if(dc_hw_sensor.configure(0, v_max)) { + PRINTF("Value out of range: must be 0 <= VMX <= 30"); + } + } + + if(REST.get_post_variable(request, "IMX", &variable) > 0) { + int i_max = atoi(variable); + if(dc_hw_sensor.configure(1, i_max)) { + PRINTF("Value out of range: must be 0 <= Imax <= 6"); + } + } + + REST.set_response_status(response, REST.status.CHANGED); + +#if PLATFORM_HAS_LEDS + /* set yellow led when sending packet */ + leds_on(LEDS_YELLOW); +#endif +} diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-status-obs.c b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-status-obs.c new file mode 100644 index 000000000..75d992fe2 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-status-obs.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2015, ICT/COS/NSLab, KTH Royal Institute of Technology + * 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. + */ + +/** + * \file + * dcdc/status read-only parameters for power monitoring + * \author + * Voravit Tanyingyong + */ + +#include +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-coap-observe.h" +#include "../er-dc-test.h" +#if PLATFORM_HAS_LEDS +#include "dev/leds.h" +#endif +#include "dev/dc-status-sensor.h" + +static void res_dc_status_obs_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_dc_status_obs_periodic_handler(void); + +PERIODIC_RESOURCE(res_dc_status_obs, "title=\"status parameters\"", res_dc_status_obs_get_handler, NULL, NULL, NULL, 10 * CLOCK_SECOND, res_dc_status_obs_periodic_handler); + +static uint32_t observe = 0; +static count = 0; +/*---------------------------------------------------------------------------*/ +static void +res_dc_status_obs_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + int vout_value = dc_status_sensor.value(0); + int vin_value = dc_status_sensor.value(1); + int iout_value = dc_status_sensor.value(2); + int iin_value = dc_status_sensor.value(3); + + /* a request comes from a remote host */ + if(request != NULL) { + +#if PLATFORM_HAS_LEDS + /* set red led when receiving a packet */ + leds_on(LEDS_RED); +#endif + + coap_packet_t *const coap_req = (coap_packet_t *)request; + + PRINTF("dcdc/status GET (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + + /* if comes with observe then register it */ + if(coap_get_header_observe(request, &observe)) { +/* PRINTF("OBSERVE set\n"); */ + /* respond with empty ack */ + REST.set_header_content_type(response, observe); + REST.set_response_payload(response, 0, 0); + } else { /* if no observe option, then answer to GET request as normal */ +/* PRINTF("OBSERVE NOT set\n"); */ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload( + response, + buffer, + snprintf((char *)buffer, MAX_COAP_PAYLOAD, "ST\tON\nVO\t%d.000\nIO\t%d.000\nVI\t%d.000\nII\t%d.000\n", vout_value, iout_value, vin_value, iin_value)); + } + } else { /* this is a notification: need to set payload */ +/* PRINTF("NULL REQUEST = PERIODIC\n"); */ + REST.set_response_payload( + response, + buffer, + snprintf((char *)buffer, MAX_COAP_PAYLOAD, "ST\tON\nVO\t%d.000\nIO\t%d.000\nVI\t%d.000\nII\t%d.000\n", vout_value, iout_value, vin_value, iin_value)); + } + count++; + printf("PERIODIC %d: ST:ON VO:%d IO:%d VI:%d II:%d\n", count, vout_value, iout_value, vin_value, iin_value); +#if PLATFORM_HAS_LEDS + /* set yellow led when sending packet */ + leds_on(LEDS_YELLOW); +#endif +} +/*---------------------------------------------------------------------------*/ +static void +res_dc_status_obs_periodic_handler() +{ + /* send periodic notification to the observers */ + REST.notify_subscribers(&res_dc_status_obs); +} diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-vdc.c b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-vdc.c new file mode 100644 index 000000000..8157fbf90 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-vdc.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2015, ICT/COS/NSLab, KTH Royal Institute of Technology + * 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. + */ + +/** + * \file + * dcdc/vdc configurable parameters for voltage droop control function + * \author + * Voravit Tanyingyong + */ + +/* #include */ +#include +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-dc-test.h" +#if PLATFORM_HAS_LEDS +#include "dev/leds.h" +#endif +#include "dev/dc-vdc-sensor.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_post_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_dc_vdc, "title=\"vdc parameters\"", res_get_handler, res_post_put_handler, res_post_put_handler, NULL); + +/*---------------------------------------------------------------------------*/ +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + int vdc_grid = dc_vdc_sensor.value(0); + int vdc_slope = dc_vdc_sensor.value(1); + int vdc_pmax = dc_vdc_sensor.value(2); + +#if PLATFORM_HAS_LEDS + /* set red led when receiving a packet */ + leds_on(LEDS_RED); +#endif + + PRINTF("dcdc/vdc GET (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + + /* Code 2.05 CONTENT is default. */ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + /* REST.set_header_max_age(response, 30); */ + REST.set_response_payload( + response, + buffer, + snprintf((char *)buffer, MAX_COAP_PAYLOAD, "VG\t%d.000\nSL\t%d.000\nPMAX\t%d.000\n", vdc_grid, vdc_slope, vdc_pmax)); + +#if PLATFORM_HAS_LEDS + /* set yellow led when sending packet */ + leds_on(LEDS_YELLOW); +#endif +} +/*---------------------------------------------------------------------------*/ +static void +res_post_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + +#if PLATFORM_HAS_LEDS + /* set red led when receiving a packet */ + leds_on(LEDS_RED); +#endif + + PRINTF("dcdc/vdc PUT (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + + const char *variable = NULL; + + if(REST.get_post_variable(request, "VG", &variable) > 0) { + int vdc_grid = atoi(variable); + /* PRINTF("VG: %d\n",vdc_grid); */ + if(dc_vdc_sensor.configure(0, vdc_grid)) { + PRINTF("Value out of range: must be 0 <= Vgrid <= Vmax"); + } + } + + if(REST.get_post_variable(request, "SL", &variable) > 0) { + int vdc_slope = atoi(variable); + /* PRINTF("SL: %d\n",vdc_slope); */ + if(dc_vdc_sensor.configure(1, vdc_slope)) { + PRINTF("Error: SLOPE is not set!"); + } + } + + if(REST.get_post_variable(request, "PMX", &variable) > 0) { + int vdc_pmax = atoi(variable); + /* PRINTF("PMAX: %d\n",vdc_pmax); */ + if(dc_vdc_sensor.configure(2, vdc_pmax)) { + PRINTF("Error: PMAX is not set!"); + } + } + + REST.set_response_status(response, REST.status.CHANGED); +#if PLATFORM_HAS_LEDS + /* set yellow led when sending packet */ + leds_on(LEDS_YELLOW); +#endif +} diff --git a/platform/avr-rss2/examples/ipv6/rpl-border-router/Makefile b/platform/avr-rss2/examples/ipv6/rpl-border-router/Makefile new file mode 100644 index 000000000..ba3f16af6 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/rpl-border-router/Makefile @@ -0,0 +1,55 @@ +CONTIKI_PROJECT=border-router +all: $(CONTIKI_PROJECT) + +CONTIKI=../../../../.. + +#linker optimizations +SMALL=1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +PROJECT_SOURCEFILES += eth-bridge.c +#PROJECT_SOURCEFILES += enc28j60.c +PROJECT_SOURCEFILES += enc28j60-ip64-driver.c + +APPS += ping6 + +MODULES += dev/enc28j60 core/net/ip64 + +#Simple built-in webserver is the default. +#Override with make WITH_WEBSERVER=0 for no webserver. +#WITH_WEBSERVER=webserver-name will use /apps/webserver-name if it can be +#found in the /apps, /platform/$(TARGET)/apps/, or current directory (in that order). +# WITH_WEBSERVER=webserver for /apps/webserver +# WITH_WEBSERVER=raven-webserver for /platform/avr-raven/apps/raven-webserver/ +#make clean before changing webservers! + +#Note /apps/webserver contains a 2500 byte style sheet which is a severe test +#of the slip connection. Large MSS together with low baud rates without flow +#control will overrun the transmit buffer when the style sheet is requested. + +WITH_WEBSERVER=1 +ifeq ($(WITH_WEBSERVER),1) +CFLAGS += -DUIP_CONF_TCP=1 +CFLAGS += -DWEBSERVER=1 +PROJECT_SOURCEFILES += httpd-simple.c +else ifneq ($(WITH_WEBSERVER), 0) +APPS += $(WITH_WEBSERVER) +CFLAGS += -DUIP_CONF_TCP=1 +CFLAGS += -DWEBSERVER=2 +endif + +ifeq ($(PREFIX),) + PREFIX = aaaa::1/64 +endif + +CONTIKI_WITH_IPV6 = 1 +include $(CONTIKI)/Makefile.include + +$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c + (cd $(CONTIKI)/tools && $(MAKE) tunslip6) + +connect-router: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 $(PREFIX) + +connect-router-cooja: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 $(PREFIX) diff --git a/platform/avr-rss2/examples/ipv6/rpl-border-router/README.ETHERNET.md b/platform/avr-rss2/examples/ipv6/rpl-border-router/README.ETHERNET.md new file mode 100644 index 000000000..ab63e9ae3 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/rpl-border-router/README.ETHERNET.md @@ -0,0 +1,66 @@ +Document version: 2015-12-29 + +HOWTO connect the Microchip enc28j60 module +=========================================== + +It's possible to to add Ethernet to most microcontrollers having a SPI inter- +face. In the Atmel world the SPI pins are used for the ISP programming. Usually +a 6-pin header. Named MOSI, MISO, SCK, CS (Chup Select), Vcc, GND + +One popular Ethernet chip is Microchip ENC28J60. It been used for quite some +time and is easy to program and are also supported by many platforms and +projects. Contiki has files under: + +Most focus fon AVR platforms. The SPI is used by Atmel ISP-progammings +interface. In addition to those pins you to selects a pin for chip +select (CS). + +dev/enc28j60/ +The low-level SPI drives is platform or rather CPU-specific. The avr-rss2 +platform adds the low-level drivers for Atmel. + +platform/avr-rss2/enc28j60_avr.[ch] +This should be usable on most 8-bit avr platforms. + +The power consumption might be a problem. The enc28j60 consumes 160mA at 3.3V +when transmitting. The LDO (voltage reg. LP2950) on the mote can only handle +100mA. So external power is needed. Below is a description of a prototype. + +Used components: +---------------- +Externel power supply 5V. +Small breadboard +DC-jack +Voltage Reg. LCP1700 3.3V +Capacitor 4.7uF +enc28j60 (From Ebay) +Pin-headers +Cables 2x5 (enc28j60) 2x3 SPI (AtMega node) + +Used colors: +Black GND +Red VCC 3.3V +Yellow SCK +Green MISO +White MOSI +Blue CS (Chip select) + +SPI (Connector view) +-------------------- +GREEN YELLOW NC +RED WHITE BLACK + +CS is connected to external temp sensor middle pin. Consequently the +external temp sensor can not be used in this application. + +Pictures +-------- +![Module] ( http://www.radio-sensors.com/pictures/enc28j60.jpg) +![Connector] (http://www.radio-sensors.com/pictures/enc28c60-cable.jpg) + + +References +----------- + + + diff --git a/platform/avr-rss2/examples/ipv6/rpl-border-router/README.md b/platform/avr-rss2/examples/ipv6/rpl-border-router/README.md new file mode 100644 index 000000000..fa3019c2d --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/rpl-border-router/README.md @@ -0,0 +1,17 @@ +Document version: 2016-02-22 + +An ethernet-to-802.15.4 NAT/GW IP64 +=================================== + +This project is heavily based on the rpl-border-router in the example directory +using the IP64 framework. This work is done Contiki/Thingsquare as the driver +for enc28j60. + +But rather than using slip as in the original example an ethernet interface +the Microchip enc28j60 is used. The needed SPI-glue for AtMega's is added by +this platform. (avr-rss2) + +See the README.ETHERNET.md for ethernet module info. + + + diff --git a/platform/avr-rss2/examples/ipv6/rpl-border-router/border-router.c b/platform/avr-rss2/examples/ipv6/rpl-border-router/border-router.c new file mode 100644 index 000000000..6a992982f --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/rpl-border-router/border-router.c @@ -0,0 +1,388 @@ +/* + * 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. + * + */ +/** + * \file + * border-router + * \author + * Niclas Finne + * Joakim Eriksson + * Nicolas Tsiftes + */ + +#include "contiki.h" +#include "contiki-lib.h" +#include "contiki-net.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "ip64.h" +#include "net/rpl/rpl.h" +#include "enc28j60.h" +#include "enc28j60-ip64-driver.h" +#include "net/netstack.h" +#include "dev/button-sensor.h" +#include "dev/slip.h" +#include "dev/leds.h" + +#include +#include +#include +#include + +#define DEBUG DEBUG_PRINT +#include "net/ip/uip-debug.h" + +static uip_ipaddr_t prefix; +static uint8_t prefix_set; + +PROCESS(border_router_process, "Border router process"); + +#if WEBSERVER==0 +/* No webserver */ +AUTOSTART_PROCESSES(&border_router_process); +#elif WEBSERVER>1 +/* Use an external webserver application */ +#include "webserver-nogui.h" +AUTOSTART_PROCESSES(&border_router_process,&webserver_nogui_process); +#else +/* Use simple webserver with only one page for minimum footprint. + * Multiple connections can result in interleaved tcp segments since + * a single static buffer is used for all segments. + */ +#include "httpd-simple.h" +/* The internal webserver can provide additional information if + * enough program flash is available. + */ +#define WEBSERVER_CONF_LOADTIME 1 +#define WEBSERVER_CONF_FILESTATS 1 +#define WEBSERVER_CONF_NEIGHBOR_STATUS 1 +/* Adding links requires a larger RAM buffer. To avoid static allocation + * the stack can be used for formatting; however tcp retransmissions + * and multiple connections can result in garbled segments. + * TODO:use PSOCk_GENERATOR_SEND and tcp state storage to fix this. + */ +#define WEBSERVER_CONF_ROUTE_LINKS 1 +#if WEBSERVER_CONF_ROUTE_LINKS +#define BUF_USES_STACK 1 +#endif + +PROCESS(webserver_nogui_process, "Web server"); +PROCESS_THREAD(webserver_nogui_process, ev, data) +{ + PROCESS_BEGIN(); + + httpd_init(); + + while(1) { + PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event); + httpd_appcall(data); + } + + PROCESS_END(); +} +AUTOSTART_PROCESSES(&border_router_process,&webserver_nogui_process); + +static const char *TOP = "ContikiRPL\n"; +static const char *BOTTOM = "\n"; +#if BUF_USES_STACK +static char *bufptr, *bufend; +#define ADD(...) do { \ + bufptr += snprintf(bufptr, bufend - bufptr, __VA_ARGS__); \ + } while(0) +#else +static char buf[256]; +static int blen; +#define ADD(...) do { \ + blen += snprintf(&buf[blen], sizeof(buf) - blen, __VA_ARGS__); \ + } while(0) +#endif + +/*---------------------------------------------------------------------------*/ +static void +ipaddr_add(const uip_ipaddr_t *addr) +{ + uint16_t a; + int i, f; + for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { + a = (addr->u8[i] << 8) + addr->u8[i + 1]; + if(a == 0 && f >= 0) { + if(f++ == 0) ADD("::"); + } else { + if(f > 0) { + f = -1; + } else if(i > 0) { + ADD(":"); + } + ADD("%x", a); + } + } +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(generate_routes(struct httpd_state *s)) +{ + static uip_ds6_route_t *r; + static uip_ds6_nbr_t *nbr; +#if BUF_USES_STACK + char buf[256]; +#endif +#if WEBSERVER_CONF_LOADTIME + static clock_time_t numticks; + numticks = clock_time(); +#endif + + PSOCK_BEGIN(&s->sout); + + SEND_STRING(&s->sout, TOP); +#if BUF_USES_STACK + bufptr = buf;bufend=bufptr+sizeof(buf); +#else + blen = 0; +#endif + ADD("Neighbors
");
+
+  for(nbr = nbr_table_head(ds6_neighbors);
+      nbr != NULL;
+      nbr = nbr_table_next(ds6_neighbors, nbr)) {
+
+#if WEBSERVER_CONF_NEIGHBOR_STATUS
+#if BUF_USES_STACK
+{char* j=bufptr+25;
+      ipaddr_add(&nbr->ipaddr);
+      while (bufptr < j) ADD(" ");
+      switch (nbr->state) {
+      case NBR_INCOMPLETE: ADD(" INCOMPLETE");break;
+      case NBR_REACHABLE: ADD(" REACHABLE");break;
+      case NBR_STALE: ADD(" STALE");break;
+      case NBR_DELAY: ADD(" DELAY");break;
+      case NBR_PROBE: ADD(" NBR_PROBE");break;
+      }
+}
+#else
+{uint8_t j=blen+25;
+      ipaddr_add(&nbr->ipaddr);
+      while (blen < j) ADD(" ");
+      switch (nbr->state) {
+      case NBR_INCOMPLETE: ADD(" INCOMPLETE");break;
+      case NBR_REACHABLE: ADD(" REACHABLE");break;
+      case NBR_STALE: ADD(" STALE");break;
+      case NBR_DELAY: ADD(" DELAY");break;
+      case NBR_PROBE: ADD(" NBR_PROBE");break;
+      }
+}
+#endif
+#else
+      ipaddr_add(&nbr->ipaddr);
+#endif
+
+      ADD("\n");
+#if BUF_USES_STACK
+      if(bufptr > bufend - 45) {
+        SEND_STRING(&s->sout, buf);
+        bufptr = buf; bufend = bufptr + sizeof(buf);
+      }
+#else
+      if(blen > sizeof(buf) - 45) {
+        SEND_STRING(&s->sout, buf);
+        blen = 0;
+      }
+#endif
+  }
+  ADD("
Routes
");
+  SEND_STRING(&s->sout, buf);
+#if BUF_USES_STACK
+  bufptr = buf; bufend = bufptr + sizeof(buf);
+#else
+  blen = 0;
+#endif
+
+  for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) {
+
+#if BUF_USES_STACK
+#if WEBSERVER_CONF_ROUTE_LINKS
+    ADD("ipaddr);
+    ADD("]/status.shtml>");
+    ipaddr_add(&r->ipaddr);
+    ADD("");
+#else
+    ipaddr_add(&r->ipaddr);
+#endif
+#else
+#if WEBSERVER_CONF_ROUTE_LINKS
+    ADD("ipaddr);
+    ADD("]/status.shtml>");
+    SEND_STRING(&s->sout, buf); //TODO: why tunslip6 needs an output here, wpcapslip does not
+    blen = 0;
+    ipaddr_add(&r->ipaddr);
+    ADD("");
+#else
+    ipaddr_add(&r->ipaddr);
+#endif
+#endif
+    ADD("/%u (via ", r->length);
+    ipaddr_add(uip_ds6_route_nexthop(r));
+    if(1 || (r->state.lifetime < 600)) {
+      ADD(") %lus\n", (unsigned long)r->state.lifetime);
+    } else {
+      ADD(")\n");
+    }
+    SEND_STRING(&s->sout, buf);
+#if BUF_USES_STACK
+    bufptr = buf; bufend = bufptr + sizeof(buf);
+#else
+    blen = 0;
+#endif
+  }
+  ADD("
"); + +#if WEBSERVER_CONF_FILESTATS + static uint16_t numtimes; + ADD("
This page sent %u times",++numtimes); +#endif + +#if WEBSERVER_CONF_LOADTIME + numticks = clock_time() - numticks + 1; + ADD(" (%lu.%02lu sec)",numticks/CLOCK_SECOND,((100*(numticks%CLOCK_SECOND))/CLOCK_SECOND)); +#endif + + + SEND_STRING(&s->sout, buf); + SEND_STRING(&s->sout, BOTTOM); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +httpd_simple_script_t +httpd_simple_get_script(const char *name) +{ + return generate_routes; +} + +#endif /* WEBSERVER */ + +/*---------------------------------------------------------------------------*/ +static void +print_local_addresses(void) +{ + int i; + uint8_t state; + + PRINTA("Server IPv6 addresses:\n"); + 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)) { + PRINTA(" "); + uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr); + PRINTA("\n"); + } + } +} +/*---------------------------------------------------------------------------*/ +void +request_prefix(void) +{ + /* mess up uip_buf with a dirty request... */ + uip_buf[0] = '?'; + uip_buf[1] = 'P'; + uip_len = 2; + //slip_send(); + uip_clear_buf(); +} +/*---------------------------------------------------------------------------*/ +void +set_prefix_64(uip_ipaddr_t *prefix_64) +{ + rpl_dag_t *dag; + uip_ipaddr_t ipaddr; + memcpy(&prefix, prefix_64, 16); + memcpy(&ipaddr, prefix_64, 16); + prefix_set = 1; + uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); + uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); + + dag = rpl_set_root(RPL_DEFAULT_INSTANCE, &ipaddr); + if(dag != NULL) { + rpl_set_prefix(dag, &prefix, 64); + PRINTF("created a new RPL dag\n"); + } +} + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(border_router_process, ev, data) +{ + PROCESS_BEGIN(); + uip_ipaddr_t ipaddr; + +/* While waiting for the prefix to be sent through the SLIP connection, the future + * border router can join an existing DAG as a parent or child, or acquire a default + * router that will later take precedence over the SLIP fallback interface. + * Prevent that by turning the radio off until we are initialized as a DAG root. + */ + prefix_set = 0; + NETSTACK_MAC.off(0); + + PROCESS_PAUSE(); + + SENSORS_ACTIVATE(button_sensor); + leds_init(); + ip64_init(); + + PRINTF("RPL-Border router started\n"); +#if 0 + /* The border router runs with a 100% duty cycle in order to ensure high + packet reception rates. + Note if the MAC RDC is not turned off now, aggressive power management of the + cpu will interfere with establishing the SLIP connection */ + NETSTACK_MAC.off(1); +#endif + + /* Now turn the radio on, but disable radio duty cycling. + * Since we are the DAG root, reception delays would constrain mesh throughbut. + */ + NETSTACK_MAC.off(1); + +/* Derived from link local (MAC) address */ + uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + set_prefix_64(&ipaddr); + print_local_addresses(); + + while(1) { + PROCESS_YIELD(); + leds_on(LEDS_YELLOW); + if (ev == sensors_event && data == &button_sensor) { + PRINTF("Initiating global repair\n"); + rpl_repair_root(RPL_DEFAULT_INSTANCE); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/avr-rss2/examples/ipv6/rpl-border-router/enc28j60-ip64-driver.c b/platform/avr-rss2/examples/ipv6/rpl-border-router/enc28j60-ip64-driver.c new file mode 100644 index 000000000..6bc4122a4 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/rpl-border-router/enc28j60-ip64-driver.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2012-2013, Thingsquare, http://www.thingsquare.com/. + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + * + */ + +#include "contiki.h" +#include "enc28j60.h" +#include "enc28j60-ip64-driver.h" +#include "net/linkaddr.h" + +#include "ip64.h" +#include "ip64-eth.h" + +#include +#include + +PROCESS(enc28j60_ip64_driver_process, "ENC28J60 IP64 driver"); + +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + uint8_t eui64[8]; + uint8_t macaddr[6]; + + /* Assume that linkaddr_node_addr holds the EUI64 of this device. */ + memcpy(eui64, &linkaddr_node_addr, sizeof(eui64)); + + /* Mangle the EUI64 into a 48-bit Ethernet address. */ + memcpy(&macaddr[0], &eui64[0], 3); + memcpy(&macaddr[3], &eui64[5], 3); + + /* In case the OUI happens to contain a broadcast bit, we mask that + out here. */ + macaddr[0] = (macaddr[0] & 0xfe); + + /* Set the U/L bit, in order to create a locally administered MAC address */ + macaddr[0] = (macaddr[0] | 0x02); + + memcpy(ip64_eth_addr.addr, macaddr, sizeof(macaddr)); + + printf("MAC addr %02x:%02x:%02x:%02x:%02x:%02x\n", + macaddr[0], macaddr[1], macaddr[2], + macaddr[3], macaddr[4], macaddr[5]); + enc28j60_init(macaddr); + process_start(&enc28j60_ip64_driver_process, NULL); +} +/*---------------------------------------------------------------------------*/ +static int +output(uint8_t *packet, uint16_t len) +{ + enc28j60_send(packet, len); + return len; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(enc28j60_ip64_driver_process, ev, data) +{ + static int len; + static struct etimer e; + PROCESS_BEGIN(); + + while(1) { + etimer_set(&e, 1); + PROCESS_WAIT_EVENT(); + len = enc28j60_read(ip64_packet_buffer, ip64_packet_buffer_maxlen); + if(len > 0) { + IP64_INPUT(ip64_packet_buffer, len); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +const struct ip64_driver enc28j60_ip64_driver = { + init, + output +}; +/*---------------------------------------------------------------------------*/ diff --git a/platform/avr-rss2/examples/ipv6/rpl-border-router/enc28j60-ip64-driver.h b/platform/avr-rss2/examples/ipv6/rpl-border-router/enc28j60-ip64-driver.h new file mode 100644 index 000000000..29d3ed5a4 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/rpl-border-router/enc28j60-ip64-driver.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2012-2013, Thingsquare, http://www.thingsquare.com/. + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + * + */ + +#ifndef ENC28J60_IP64_DRIVER_H +#define ENC28J60_IP64_DRIVER_H + +#include "ip64-driver.h" +extern const struct ip64_driver enc28j60_ip64_driver; + +#endif /* ENC28J60_IP64_DRIVER_H */ diff --git a/platform/avr-rss2/examples/ipv6/rpl-border-router/eth-bridge.c b/platform/avr-rss2/examples/ipv6/rpl-border-router/eth-bridge.c new file mode 100644 index 000000000..b5d9ec498 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/rpl-border-router/eth-bridge.c @@ -0,0 +1,33 @@ +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include +#include "ip64-eth-interface.h" + +#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" + +static void +init(void) +{ + PRINTF("eth-bridge: init\n"); + ip64_eth_interface.init(); +} +/*---------------------------------------------------------------------------*/ +static int +output() +{ + PRINTF("eth-bridge: src="); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF(" dst="); + PRINT6ADDR(&UIP_IP_BUF->destipaddr); + PRINTF("\n"); + ip64_eth_interface.output(); + return 0; +} +/*---------------------------------------------------------------------------*/ +const struct uip_fallback_interface rpl_interface = { + init, output +}; +/*---------------------------------------------------------------------------*/ diff --git a/platform/avr-rss2/examples/ipv6/rpl-border-router/httpd-simple.c b/platform/avr-rss2/examples/ipv6/rpl-border-router/httpd-simple.c new file mode 100644 index 000000000..115e54d45 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/rpl-border-router/httpd-simple.c @@ -0,0 +1,261 @@ +/* + * 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. + * + */ + +/** + * \file + * A simple web server forwarding page generation to a protothread + * \author + * Adam Dunkels + * Niclas Finne + * Joakim Eriksson + */ + +#include +#include + +#include "contiki-net.h" + +//#include "urlconv.h" + +#include "httpd-simple.h" +#define webserver_log_file(...) +#define webserver_log(...) + +#ifndef WEBSERVER_CONF_CFS_CONNS +#define CONNS UIP_CONNS +#else /* WEBSERVER_CONF_CFS_CONNS */ +#define CONNS WEBSERVER_CONF_CFS_CONNS +#endif /* WEBSERVER_CONF_CFS_CONNS */ + +#ifndef WEBSERVER_CONF_CFS_URLCONV +#define URLCONV 0 +#else /* WEBSERVER_CONF_CFS_URLCONV */ +#define URLCONV WEBSERVER_CONF_CFS_URLCONV +#endif /* WEBSERVER_CONF_CFS_URLCONV */ + +#define STATE_WAITING 0 +#define STATE_OUTPUT 1 + +MEMB(conns, struct httpd_state, CONNS); + +#define ISO_nl 0x0a +#define ISO_space 0x20 +#define ISO_period 0x2e +#define ISO_slash 0x2f + +/*---------------------------------------------------------------------------*/ +static const char *NOT_FOUND = "" +"
" +"

404 - file not found

" +"
" +"" +""; +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_string(struct httpd_state *s, const char *str)) +{ + PSOCK_BEGIN(&s->sout); + + SEND_STRING(&s->sout, str); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +const char http_content_type_html[] = "Content-type: text/html\r\n\r\n"; +static +PT_THREAD(send_headers(struct httpd_state *s, const char *statushdr)) +{ + /* char *ptr; */ + + PSOCK_BEGIN(&s->sout); + + SEND_STRING(&s->sout, statushdr); + + /* ptr = strrchr(s->filename, ISO_period); */ + /* if(ptr == NULL) { */ + /* s->ptr = http_content_type_plain; */ + /* } else if(strcmp(http_html, ptr) == 0) { */ + /* s->ptr = http_content_type_html; */ + /* } else if(strcmp(http_css, ptr) == 0) { */ + /* s->ptr = http_content_type_css; */ + /* } else if(strcmp(http_png, ptr) == 0) { */ + /* s->ptr = http_content_type_png; */ + /* } else if(strcmp(http_gif, ptr) == 0) { */ + /* s->ptr = http_content_type_gif; */ + /* } else if(strcmp(http_jpg, ptr) == 0) { */ + /* s->ptr = http_content_type_jpg; */ + /* } else { */ + /* s->ptr = http_content_type_binary; */ + /* } */ + /* SEND_STRING(&s->sout, s->ptr); */ + SEND_STRING(&s->sout, http_content_type_html); + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +const char http_header_200[] = "HTTP/1.0 200 OK\r\nServer: Contiki/2.4 http://www.sics.se/contiki/\r\nConnection: close\r\n"; +const char http_header_404[] = "HTTP/1.0 404 Not found\r\nServer: Contiki/2.4 http://www.sics.se/contiki/\r\nConnection: close\r\n"; +static +PT_THREAD(handle_output(struct httpd_state *s)) +{ + PT_BEGIN(&s->outputpt); + + s->script = NULL; + s->script = httpd_simple_get_script(&s->filename[1]); + if(s->script == NULL) { + strncpy(s->filename, "/notfound.html", sizeof(s->filename)); + PT_WAIT_THREAD(&s->outputpt, + send_headers(s, http_header_404)); + PT_WAIT_THREAD(&s->outputpt, + send_string(s, NOT_FOUND)); + uip_close(); + webserver_log_file(&uip_conn->ripaddr, "404 - not found"); + PT_EXIT(&s->outputpt); + } else { + PT_WAIT_THREAD(&s->outputpt, + send_headers(s, http_header_200)); + PT_WAIT_THREAD(&s->outputpt, s->script(s)); + } + s->script = NULL; + PSOCK_CLOSE(&s->sout); + PT_END(&s->outputpt); +} +/*---------------------------------------------------------------------------*/ +const char http_get[] = "GET "; +const char http_index_html[] = "/index.html"; +//const char http_referer[] = "Referer:" +static +PT_THREAD(handle_input(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sin); + + PSOCK_READTO(&s->sin, ISO_space); + + if(strncmp(s->inputbuf, http_get, 4) != 0) { + PSOCK_CLOSE_EXIT(&s->sin); + } + PSOCK_READTO(&s->sin, ISO_space); + + if(s->inputbuf[0] != ISO_slash) { + PSOCK_CLOSE_EXIT(&s->sin); + } + +#if URLCONV + s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0; + urlconv_tofilename(s->filename, s->inputbuf, sizeof(s->filename)); +#else /* URLCONV */ + if(s->inputbuf[1] == ISO_space) { + strncpy(s->filename, http_index_html, sizeof(s->filename)); + } else { + s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0; + strncpy(s->filename, s->inputbuf, sizeof(s->filename)); + } +#endif /* URLCONV */ + + webserver_log_file(&uip_conn->ripaddr, s->filename); + + s->state = STATE_OUTPUT; + + while(1) { + PSOCK_READTO(&s->sin, ISO_nl); +#if 0 + if(strncmp(s->inputbuf, http_referer, 8) == 0) { + s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0; + webserver_log(s->inputbuf); + } +#endif + } + + PSOCK_END(&s->sin); +} +/*---------------------------------------------------------------------------*/ +static void +handle_connection(struct httpd_state *s) +{ + handle_input(s); + if(s->state == STATE_OUTPUT) { + handle_output(s); + } +} + +/*---------------------------------------------------------------------------*/ +void +httpd_appcall(void *state) +{ + struct httpd_state *s = (struct httpd_state *)state; + + if(uip_closed() || uip_aborted() || uip_timedout()) { + if(s != NULL) { + s->script = NULL; + memb_free(&conns, s); + } + } else if(uip_connected()) { + s = (struct httpd_state *)memb_alloc(&conns); + if(s == NULL) { + uip_abort(); + webserver_log_file(&uip_conn->ripaddr, "reset (no memory block)"); + return; + } + tcp_markconn(uip_conn, s); + PSOCK_INIT(&s->sin, (uint8_t *)s->inputbuf, sizeof(s->inputbuf) - 1); + PSOCK_INIT(&s->sout, (uint8_t *)s->inputbuf, sizeof(s->inputbuf) - 1); + PT_INIT(&s->outputpt); + s->script = NULL; + s->state = STATE_WAITING; + timer_set(&s->timer, CLOCK_SECOND * 10); + handle_connection(s); + } else if(s != NULL) { + if(uip_poll()) { + if(timer_expired(&s->timer)) { + uip_abort(); + s->script = NULL; + memb_free(&conns, s); + webserver_log_file(&uip_conn->ripaddr, "reset (timeout)"); + } + } else { + timer_restart(&s->timer); + } + handle_connection(s); + } else { + uip_abort(); + } +} + +/*---------------------------------------------------------------------------*/ +void +httpd_init(void) +{ + + tcp_listen(UIP_HTONS(80)); + memb_init(&conns); +#if URLCONV + urlconv_init(); +#endif /* URLCONV */ +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/avr-rss2/examples/ipv6/rpl-border-router/httpd-simple.h b/platform/avr-rss2/examples/ipv6/rpl-border-router/httpd-simple.h new file mode 100644 index 000000000..a16dbd99e --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/rpl-border-router/httpd-simple.h @@ -0,0 +1,74 @@ +/* + * 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. + * + */ + +/** + * \file + * A simple webserver + * \author + * Adam Dunkels + * Niclas Finne + * Joakim Eriksson + */ + +#ifndef HTTPD_SIMPLE_H_ +#define HTTPD_SIMPLE_H_ + +#include "contiki-net.h" + +/* The current internal border router webserver ignores the requested file name */ +/* and needs no per-connection output buffer, so save some RAM */ +#ifndef WEBSERVER_CONF_CFS_PATHLEN +#define HTTPD_PATHLEN 2 +#else /* WEBSERVER_CONF_CFS_CONNS */ +#define HTTPD_PATHLEN WEBSERVER_CONF_CFS_PATHLEN +#endif /* WEBSERVER_CONF_CFS_CONNS */ + +struct httpd_state; +typedef char (* httpd_simple_script_t)(struct httpd_state *s); + +struct httpd_state { + struct timer timer; + struct psock sin, sout; + struct pt outputpt; + char inputbuf[HTTPD_PATHLEN + 24]; +/*char outputbuf[UIP_TCP_MSS]; */ + char filename[HTTPD_PATHLEN]; + httpd_simple_script_t script; + char state; +}; + +void httpd_init(void); +void httpd_appcall(void *state); + +httpd_simple_script_t httpd_simple_get_script(const char *name); + +#define SEND_STRING(s, str) PSOCK_SEND(s, (uint8_t *)str, strlen(str)) + +#endif /* HTTPD_SIMPLE_H_ */ diff --git a/platform/avr-rss2/examples/ipv6/rpl-border-router/project-conf.h b/platform/avr-rss2/examples/ipv6/rpl-border-router/project-conf.h new file mode 100644 index 000000000..f1d9e8cda --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/rpl-border-router/project-conf.h @@ -0,0 +1,57 @@ +/* + * 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. + * + */ + +#ifndef PROJECT_ROUTER_CONF_H_ +#define PROJECT_ROUTER_CONF_H_ + +#define NETSTACK_CONF_RDC nullrdc_driver +#define NETSTACK_CONF_MAC nullmac_driver + +#ifndef UIP_FALLBACK_INTERFACE +#define UIP_FALLBACK_INTERFACE rpl_interface +#endif + +#ifndef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 4 +#endif + +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 600 +#endif + +#ifndef UIP_CONF_RECEIVE_WINDOW +#define UIP_CONF_RECEIVE_WINDOW 60 +#endif + +#ifndef WEBSERVER_CONF_CFS_CONNS +#define WEBSERVER_CONF_CFS_CONNS 2 +#endif + +#endif /* PROJECT_ROUTER_CONF_H_ */ diff --git a/platform/avr-rss2/examples/ipv6/rpl-udp-report/Makefile b/platform/avr-rss2/examples/ipv6/rpl-udp-report/Makefile new file mode 100644 index 000000000..770ad3749 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/rpl-udp-report/Makefile @@ -0,0 +1,21 @@ + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +all: report sink +APPS=servreg-hack +CONTIKI=../../../../.. + +ifdef WITH_COMPOWER +APPS+=powertrace +CFLAGS+= -DCONTIKIMAC_CONF_COMPOWER=1 -DWITH_COMPOWER=1 -DQUEUEBUF_CONF_NUM=4 +endif + +ifdef SERVER_REPLY +CFLAGS+=-DSERVER_REPLY=$(SERVER_REPLY) +endif +ifdef PERIOD +CFLAGS+=-DPERIOD=$(PERIOD) +endif + +CONTIKI_WITH_IPV6 = 1 +include $(CONTIKI)/Makefile.include diff --git a/platform/avr-rss2/examples/ipv6/rpl-udp-report/README.md b/platform/avr-rss2/examples/ipv6/rpl-udp-report/README.md new file mode 100644 index 000000000..1f10ff7e5 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/rpl-udp-report/README.md @@ -0,0 +1,17 @@ + +This application is derived form rpl-udp. + +It's modified to show: + +* Reading out sensors from the avr-rss2 platform. Which should follow the + Contiki conventions. + +* Encode the data according to the sensd TAG format. In effect the sensd + GW and rest of "eco-system" as Mobile apps etc can be used for a simple + and flexible data collection, Sink mote will be connected to sensd GW. + +References and code: +https://github.com/herjulf/sensd +https://github.com/herjulf/Read-Sensors (Android app. Also at Google Play) + + diff --git a/platform/avr-rss2/examples/ipv6/rpl-udp-report/project-conf.h b/platform/avr-rss2/examples/ipv6/rpl-udp-report/project-conf.h new file mode 100644 index 000000000..b004c6335 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/rpl-udp-report/project-conf.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2015, RAdio Sensors AB, Uppsala Sweden + * 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. + */ + +/** + * \file + * Project specific configuration defines for example + * + * \author + * Robert Olsson + */ + +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +#define NETSTACK_CONF_RDC nullrdc_driver +#define NETSTACK_CONF_MAC nullmac_driver + +//#define NETSTACK_CONF_MAC csma_driver +//#define NETSTACK_CONF_RDC contikimac_driver +//#define NETSTACK_CONF_FRAMER framer_802154 +//#define NETSTACK_CONF_RADIO rf230_driver + +#endif /* PROJECT_CONF_H_ */ diff --git a/platform/avr-rss2/examples/ipv6/rpl-udp-report/report.avr-rss2 b/platform/avr-rss2/examples/ipv6/rpl-udp-report/report.avr-rss2 new file mode 100644 index 000000000..e69de29bb diff --git a/platform/avr-rss2/examples/ipv6/rpl-udp-report/report.c b/platform/avr-rss2/examples/ipv6/rpl-udp-report/report.c new file mode 100644 index 000000000..7915dff2f --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/rpl-udp-report/report.c @@ -0,0 +1,240 @@ +/* + * 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. + * + */ + +#include "contiki.h" +#include "lib/random.h" +#include "sys/ctimer.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "net/ip/uip-udp-packet.h" +#include "sys/ctimer.h" +#include "dev/leds.h" +#include "dev/battery-sensor.h" +#include "dev/temp_mcu-sensor.h" +#include "dev/light-sensor.h" +#ifdef CO2 +#include "dev/co2_sa_kxx-sensor.h" +#endif +#ifdef WITH_COMPOWER +#include "powertrace.h" +#endif +#include +#include + +#define UDP_CLIENT_PORT 8765 +#define UDP_SERVER_PORT 5678 + +#define UDP_EXAMPLE_ID 190 + +#define DEBUG DEBUG_PRINT +#include "net/ip/uip-debug.h" + +#ifndef PERIOD +#define PERIOD 10 +#endif + +#define START_INTERVAL (15 * CLOCK_SECOND) +#define SEND_INTERVAL (PERIOD * CLOCK_SECOND) +#define SEND_TIME (random_rand() % (SEND_INTERVAL)) +#define MAX_PAYLOAD_LEN 50 + +static struct uip_udp_conn *client_conn; +static uip_ipaddr_t server_ipaddr; + +extern uint16_t node_id; /* Can be set by cooja */ + +/*---------------------------------------------------------------------------*/ +PROCESS(udp_client_process, "UDP client process"); +AUTOSTART_PROCESSES(&udp_client_process); +/*---------------------------------------------------------------------------*/ +static void +tcpip_handler(void) +{ + char *str; + + if(uip_newdata()) { + str = uip_appdata; + str[uip_datalen()] = '\0'; + printf("DATA recv '%s'\n", str); + } +} +/*---------------------------------------------------------------------------*/ +static void +send_packet(void *ptr) +{ + static int seq_id; + char buf[MAX_PAYLOAD_LEN]; + int len = 0; + + seq_id++; + + len += snprintf((char *) &buf[len], sizeof(buf), "&: "); + len += snprintf((char *) &buf[len], sizeof(buf), "V_MCU=%-d ", battery_sensor.value(0)); + + /* + * Cooja needs to set a node_id. So we can skip sensor reading in case of simulation. + */ + + if(node_id == 0) { + len += snprintf((char *) &buf[len], sizeof(buf), "T_MCU=%-d ", temp_mcu_sensor.value(0)); + len += snprintf((char *) &buf[len], sizeof(buf), "LIGHT=%-d ", light_sensor.value(0)); +#ifdef CO2 + len += snprintf((char *) &buf[len], sizeof(buf), "CO2=%-d ", co2_sa_kxx_sensor.value(value)); +#endif + } + PRINTF("TX %d to %d %s\n", + server_ipaddr.u8[sizeof(server_ipaddr.u8) - 1], seq_id, buf); + + leds_on(LEDS_YELLOW); + + uip_udp_packet_sendto(client_conn, buf, strlen(buf), + &server_ipaddr, UIP_HTONS(UDP_SERVER_PORT)); +} +/*---------------------------------------------------------------------------*/ +static void +print_local_addresses(void) +{ + int i; + uint8_t state; + + PRINTF("Client 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)) { + PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); + PRINTF("\n"); + /* hack to make address "final" */ + if (state == ADDR_TENTATIVE) { + uip_ds6_if.addr_list[i].state = ADDR_PREFERRED; + } + } + } +} +/*---------------------------------------------------------------------------*/ +static void +set_global_address(void) +{ + uip_ipaddr_t ipaddr; + + 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); + +/* The choice of server address determines its 6LoPAN header compression. + * (Our address will be compressed Mode 3 since it is derived from our link-local address) + * Obviously the choice made here must also be selected in udp-server.c. + * + * For correct Wireshark decoding using a sniffer, add the /64 prefix to the 6LowPAN protocol preferences, + * e.g. set Context 0 to aaaa::. At present Wireshark copies Context/128 and then overwrites it. + * (Setting Context 0 to aaaa::1111:2222:3333:4444 will report a 16 bit compressed address of aaaa::1111:22ff:fe33:xxxx) + * + * Note the IPCMV6 checksum verification depends on the correct uncompressed addresses. + */ + +#if 0 +/* Mode 1 - 64 bits inline */ + uip_ip6addr(&server_ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1); +#elif 1 +/* Mode 2 - 16 bits inline */ + uip_ip6addr(&server_ipaddr, 0xaaaa, 0, 0, 0, 0, 0x00ff, 0xfe00, 1); +#else +/* Mode 3 - derived from server link-local (MAC) address */ + uip_ip6addr(&server_ipaddr, 0xaaaa, 0, 0, 0, 0x0250, 0xc2ff, 0xfea8, 0xcd1a); //redbee-econotag +#endif +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(udp_client_process, ev, data) +{ + static struct etimer periodic; + static struct ctimer backoff_timer; +#if WITH_COMPOWER + static int print = 0; +#endif + + PROCESS_BEGIN(); + + PROCESS_PAUSE(); + + SENSORS_ACTIVATE(battery_sensor); + SENSORS_ACTIVATE(temp_mcu_sensor); + SENSORS_ACTIVATE(light_sensor); +#ifdef CO2 + SENSORS_ACTIVATE(co2_sa_kxx_sensor); +#endif + set_global_address(); + leds_init(); + + PRINTF("UDP client process started\n"); + + print_local_addresses(); + + /* new connection with remote host */ + client_conn = udp_new(NULL, UIP_HTONS(UDP_SERVER_PORT), NULL); + if(client_conn == NULL) { + PRINTF("No UDP connection available, exiting the process!\n"); + PROCESS_EXIT(); + } + udp_bind(client_conn, UIP_HTONS(UDP_CLIENT_PORT)); + + PRINTF("Created a connection with the server "); + PRINT6ADDR(&client_conn->ripaddr); + PRINTF(" local/remote port %u/%u\n", + UIP_HTONS(client_conn->lport), UIP_HTONS(client_conn->rport)); + +#if WITH_COMPOWER + powertrace_sniff(POWERTRACE_ON); +#endif + + etimer_set(&periodic, SEND_INTERVAL); + while(1) { + PROCESS_YIELD(); + if(ev == tcpip_event) { + tcpip_handler(); + } + + if(etimer_expired(&periodic)) { + etimer_reset(&periodic); + ctimer_set(&backoff_timer, SEND_TIME, send_packet, NULL); + +#if WITH_COMPOWER + if (print == 0) { + powertrace_print("#P"); + } + if (++print == 3) { + print = 0; + } +#endif + + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/avr-rss2/examples/ipv6/rpl-udp-report/rss2-rpl-udp.csc b/platform/avr-rss2/examples/ipv6/rpl-udp-report/rss2-rpl-udp.csc new file mode 100644 index 000000000..b2d599577 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/rpl-udp-report/rss2-rpl-udp.csc @@ -0,0 +1,167 @@ + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/native_gateway + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + /home/user/contikiprojects/sics.se/mobility + [CONTIKI_DIR]/tools/cooja/apps/collect-view + /home/user/contikiprojects/sics.se/powertracker + + UDP sink/report simulation + 123456 + 1000000 + + se.sics.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.avrmote.RSS2MoteType + mote1 + Mote1 + [CONTIKI_DIR]/platform/avr-rss2/examples/ipv6/rpl-udp-report/report.c + make report.avr-rss2 TARGET=avr-rss2 MCU=atmega128rfr2 + [CONTIKI_DIR]/platform/avr-rss2/examples/ipv6/rpl-udp-report/report.avr-rss2 + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.avrmote.interfaces.AvroraClock + se.sics.cooja.avrmote.interfaces.AvroraMoteID + se.sics.cooja.avrmote.interfaces.AvroraUsart0 + se.sics.cooja.avrmote.interfaces.AvroraUsart1 + se.sics.cooja.avrmote.interfaces.RFR2Radio + se.sics.cooja.avrmote.interfaces.AvroraADC + se.sics.cooja.avrmote.interfaces.AvroraLED + + + se.sics.cooja.avrmote.RSS2MoteType + mote2 + Mote2 + [CONTIKI_DIR]/platform/avr-rss2/examples/ipv6/rpl-udp-report/sink.c + make sink.avr-rss2 TARGET=avr-rss2 MCU=atmega128rfr2 + [CONTIKI_DIR]/platform/avr-rss2/examples/ipv6/rpl-udp-report/sink.avr-rss2 + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.avrmote.interfaces.AvroraClock + se.sics.cooja.avrmote.interfaces.AvroraMoteID + se.sics.cooja.avrmote.interfaces.AvroraUsart0 + se.sics.cooja.avrmote.interfaces.AvroraUsart1 + se.sics.cooja.avrmote.interfaces.RFR2Radio + se.sics.cooja.avrmote.interfaces.AvroraADC + se.sics.cooja.avrmote.interfaces.AvroraLED + + + + + se.sics.cooja.interfaces.Position + 100.0 + 100.0 + 0.0 + + + se.sics.cooja.avrmote.interfaces.AvroraMoteID + 1 + + mote1 + + + + + se.sics.cooja.interfaces.Position + 110.0 + 100.0 + 0.0 + + + se.sics.cooja.avrmote.interfaces.AvroraMoteID + 2 + + mote2 + + + + se.sics.cooja.plugins.SimControl + 280 + 9 + 160 + 400 + 0 + + + se.sics.cooja.plugins.Visualizer + + true + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.GridVisualizerSkin + 3.908924509090908 0.0 0.0 3.908924509090908 -216.43707345454544 -217.89245090909074 + + 400 + 5 + 400 + 1 + 1 + + + se.sics.cooja.plugins.LogListener + + + + + + 1269 + 8 + 240 + 400 + 160 + + + se.sics.cooja.plugins.Notes + + Enter notes here + true + + 989 + 6 + 160 + 680 + 0 + + + se.sics.cooja.plugins.MoteInterfaceViewer + 0 + + Serial port + 0,0 + + 508 + 4 + 389 + 13 + 413 + + + se.sics.cooja.plugins.MoteInterfaceViewer + 1 + + Serial port + 0,0 + + 545 + 3 + 392 + 531 + 413 + + diff --git a/platform/avr-rss2/examples/ipv6/rpl-udp-report/sink.avr-rss2 b/platform/avr-rss2/examples/ipv6/rpl-udp-report/sink.avr-rss2 new file mode 100644 index 000000000..e69de29bb diff --git a/platform/avr-rss2/examples/ipv6/rpl-udp-report/sink.c b/platform/avr-rss2/examples/ipv6/rpl-udp-report/sink.c new file mode 100644 index 000000000..cb8421943 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/rpl-udp-report/sink.c @@ -0,0 +1,184 @@ +/* + * 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. + * + */ + +#include "contiki.h" +#include "contiki-lib.h" +#include "contiki-net.h" +#include "net/ip/uip.h" +#include "net/rpl/rpl.h" + +#include "net/netstack.h" +#include "dev/button-sensor.h" +#include "dev/leds.h" +#include +#include +#include +#include + +#define DEBUG DEBUG_PRINT +#include "net/ip/uip-debug.h" + +#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) + +#define UDP_CLIENT_PORT 8765 +#define UDP_SERVER_PORT 5678 + +#define UDP_EXAMPLE_ID 190 + +static struct uip_udp_conn *server_conn; + +PROCESS(udp_server_process, "UDP server process"); +AUTOSTART_PROCESSES(&udp_server_process); +/*---------------------------------------------------------------------------*/ +static void +tcpip_handler(void) +{ + char *appdata; + + if(uip_newdata()) { + + leds_on(LEDS_RED); + + appdata = (char *)uip_appdata; + appdata[uip_datalen()] = 0; + PRINTF("Report RX '%s' from ", appdata); + PRINTF("%d", + UIP_IP_BUF->srcipaddr.u8[sizeof(UIP_IP_BUF->srcipaddr.u8) - 1]); + PRINTF("\n"); +#if SERVER_REPLY + PRINTF("DATA sending reply\n"); + uip_ipaddr_copy(&server_conn->ripaddr, &UIP_IP_BUF->srcipaddr); + uip_udp_packet_send(server_conn, "Reply", sizeof("Reply")); + uip_create_unspecified(&server_conn->ripaddr); +#endif + } +} +/*---------------------------------------------------------------------------*/ +static void +print_local_addresses(void) +{ + int i; + uint8_t state; + + PRINTF("Server IPv6 addresses: "); + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(state == ADDR_TENTATIVE || state == ADDR_PREFERRED) { + PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); + PRINTF("\n"); + /* hack to make address "final" */ + if (state == ADDR_TENTATIVE) { + uip_ds6_if.addr_list[i].state = ADDR_PREFERRED; + } + } + } +} + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(udp_server_process, ev, data) +{ + uip_ipaddr_t ipaddr; + struct uip_ds6_addr *root_if; + + PROCESS_BEGIN(); + + PROCESS_PAUSE(); + + SENSORS_ACTIVATE(button_sensor); + + leds_init(); + PRINTF("UDP server started\n"); + + +#if UIP_CONF_ROUTER +/* The choice of server address determines its 6LoPAN header compression. + * Obviously the choice made here must also be selected in udp-client.c. + * + * For correct Wireshark decoding using a sniffer, add the /64 prefix to the 6LowPAN protocol preferences, + * e.g. set Context 0 to aaaa::. At present Wireshark copies Context/128 and then overwrites it. + * (Setting Context 0 to aaaa::1111:2222:3333:4444 will report a 16 bit compressed address of aaaa::1111:22ff:fe33:xxxx) + * Note Wireshark's IPCMV6 checksum verification depends on the correct uncompressed addresses. + */ + +#if 0 +/* Mode 1 - 64 bits inline */ + uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1); +#elif 1 +/* Mode 2 - 16 bits inline */ + uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0x00ff, 0xfe00, 1); +#else +/* Mode 3 - derived from link local (MAC) address */ + uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); +#endif + + uip_ds6_addr_add(&ipaddr, 0, ADDR_MANUAL); + root_if = uip_ds6_addr_lookup(&ipaddr); + if(root_if != NULL) { + rpl_dag_t *dag; + dag = rpl_set_root(RPL_DEFAULT_INSTANCE,(uip_ip6addr_t *)&ipaddr); + uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + rpl_set_prefix(dag, &ipaddr, 64); + PRINTF("created a new RPL dag\n"); + } else { + PRINTF("failed to create a new RPL DAG\n"); + } +#endif /* UIP_CONF_ROUTER */ + + print_local_addresses(); + + /* The data sink runs with a 100% duty cycle in order to ensure high + packet reception rates. */ + //NETSTACK_MAC.off(1); + + server_conn = udp_new(NULL, UIP_HTONS(UDP_CLIENT_PORT), NULL); + if(server_conn == NULL) { + PRINTF("No UDP connection available, exiting the process!\n"); + PROCESS_EXIT(); + } + udp_bind(server_conn, UIP_HTONS(UDP_SERVER_PORT)); + + PRINTF("Created a server connection with remote address "); + PRINT6ADDR(&server_conn->ripaddr); + PRINTF(" local/remote port %u/%u\n", UIP_HTONS(server_conn->lport), + UIP_HTONS(server_conn->rport)); + + while(1) { + PROCESS_YIELD(); + if(ev == tcpip_event) { + tcpip_handler(); + } else if (ev == sensors_event && data == &button_sensor) { + PRINTF("Initiaing global repair\n"); + rpl_repair_root(RPL_DEFAULT_INSTANCE); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/avr-rss2/examples/ipv6/sensd_client/Makefile b/platform/avr-rss2/examples/ipv6/sensd_client/Makefile new file mode 100644 index 000000000..c0eabf9b0 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/sensd_client/Makefile @@ -0,0 +1,12 @@ + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +all: sensd_client server +CONTIKI=../../../../.. + +ifdef PERIOD +CFLAGS+=-DPERIOD=$(PERIOD) +endif + +CONTIKI_WITH_IPV6 = 1 +include $(CONTIKI)/Makefile.include diff --git a/platform/avr-rss2/examples/ipv6/sensd_client/README.md b/platform/avr-rss2/examples/ipv6/sensd_client/README.md new file mode 100644 index 000000000..17beb02f3 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/sensd_client/README.md @@ -0,0 +1,222 @@ +Contiki client for sensd +======================== + +Sensd README describes the concept. sensd code is on github. + + +sensd - A WSN Internet GW, hub, agent, proxy & cloud +==================================================== + +Authors +-------- +Robert Olsson +Jens Laas + +Contributors +------------ + +Abstract +-------- +We've outlined, designed and implemented and very simple concept for WSN +data sharing, including data collection, storage and retrieval using +standard text tools. The concept restricts Internet access to WSN +motes and acts agent not to expose motes directly for robustness and +security reasons. Low level, physical or link WSN protocol can be used. +including 6lowpan, RIME etc and any type of Radio Duty Cycling (RDC). +sensd works on the application layer. A TCP connection initiates an +implicit "subscribe". The M2P model is currently supported. + +Key concepts +------------ + +* Agent. sensd works as an agent and does not allow direct Internet + access to motes. Recall motes are constrained in most aspects and + can not support many connections, has weak security etc. + +* Hub. Share the data from the root or sink node over TCP. In effect sensor + data can be sent over Internet to be shared over among TCP active listeners. + The TCP connection initiates an implicit "subscribe". + +* Proxy. The support proxy functions over ipv4 and well as ipv6. Sensd can + forward to a proxy on a public IP. The typical case is when GW is behind + a NAT. + +* WSN RP "rendez-vous point". A concepts where data from various WSN nets + are merged. This models a "cloud service" functionality for WSN networks. + sensd can be used both to forward data to RP. It can also work as the RP. + RP receiving WSN data and allowing multiple TCP listeners. + +* All programs are written C, script in Java and bash. Designed for small + footprint and with minimal dependencies. sensd runs on Raspberry Pi and + Openwrt. + +* This work introduces a simple tag format for sensor data. The overall + idea is that data tagging is an "agreement" between producers and consumer. + Tags are simple are description of the data. Example T=25.2. where T= + is the tag 25.2 the value. Most likely this a temperature. But we + can't be sure since we don't know since this is an agreement between + the producer and the consumer. Tags are also used for identification. + Example tags, E64= Where globally unique ID can used. Another more + relaxed example is TXT= a user description. See docs. + +* Geotagging and timestamping is supported via tags. + +* Ecosystem support. There are telphone apps to for data monitoring and + and plotting. Android app can act as WSN-agent and forward to proxy/RP. + +* The concept also includes a mapping to URI (Unified Resource Identifier) + to form a WSN caching server similar to CoAP using http-proxy. + +* Copyright. Open-Source via GPL. Projecet used github.com + + +Introduction +------------ + +This is collection of software to implement data monitoring and data collection +from WSN Wireless Sensor Networks. The goal is to have a very simple, +straight-forward and robust framework. + +The scenario: One or several motes is connected to USB or serial port to gather +received information from connected WSN motes. Data can be visualized in +several ways. + +* Sensor data report can be transmitted and propagated throughout the + Internet. sensd acts as server and sends incoming report to active + listeners. + +* Data is kept in ASCII with tagging and ID information. Data is conveniently + handled, copied and viewed with standard text utilities of your OS. + +* Last mote report is cached into the file system suitable for URI use. The + Format is SID/TAG. Typical tags are EUI64 and unique serial numbers. The + different TAGS are left for mote user to define. Although the TAGS used in + our example setup are included in this draft for example purposes. + + +Both formats can easily be stored or linked directly in web tree to form a +URI to format WSN logging/datafile or caching service. + +A daemon that reads WSN mote reports from USB/serial and stores data in a ASCII +data file. Default is located at _/var/log/sensors.dat_ + +Addtional components +-------------------- + +* seltag [More info] (https://github.com/herjulf/sensd/blob/master/seltag/README.md) + +* js A set of Java-scripts can plot, print and visualize sensor data from + sensd directly in your web-browser. + +* documentation and sample files. [More info] (https://github.com/herjulf/sensd/blob/master/seltag/README.md) + +* Read Sensors Android app. [Source Code] (https://github.com/herjulf/Read-Sensors) + + +Datafile logging +---------------- + +Below is and example of the anatomy of a sensors.dat file we are currently using in our WSN +data collection networks. + + 2012-05-22 14:07:46 UT=1337688466 ID=283c0cdd030000d7 PS=0 T=30.56 T_MCU=34.6 V_MCU=3.08 UP=2C15C V_IN=4.66 + + 2012-05-22 14:11:41 UT=1337688701 ID=28a9d5dc030000af PS=0 T=36.00 V_MCU=2.92 UP=12C8A0 RH=42.0 V_IN=4.13 V_A1=3.43 [ADDR=0.175 SEQ=33 RSSI=21 LQI=255 DRP=1.00] + +Each line is a mote report. They start with date and time and are followed by a set of +tags. The tags is different for different motes. In other words they can +send different data. Essential is the ID which should be unique for each mote. + +The information with brackets is information generated by the receiving mote +and is not a part the motes data. Typically RSSI (Receiver Signal Strength +Indicator) and LQI (Link Quality Indicator) + + +Internet sensor data +-------------------- + +Start sensd with the `-report` option. This enables reports to be transmitted +over IP to remote listeners. Default TCP port 1234. + +Server side example: + + sensd -report -p 1234 -D /dev/ttyUSB0 + +Client side. Example using netcat: + + nc server-ip 1234 + +URI format +---------- + +URI (Unified Resource Identifier) displays the node ID and the tags in a file tree. +It is easy to export this into a web tree to form a URI similar to a CoAP gateway. + +Example: In our case we have a unique sensor ID followed by the different data +fields represented by "tags". + + /tmp/WSN1-GW1/281a98d20200004a: + DRP ID LQI PS RH RSSI SEQ T V_IN V_MCU ADDR + + /tmp/WSN1-GW1/28be51ce02000031: + DRP ID LQI PS RH RSSI SEQ T UP V_IN V_MCU ADDR + +Read Temp from a sensor: + + cat /tmp/WSN1-GW1/281a98d20200004a/T + 19.44 + +And it's very easy to link this tree into a web-server. + +GPS support +----------- + +Positioning support has been added via GPS device connected to serial +or USB port. Tags added when enabled GWGPS_LON & GWGPS_LAT. +GPS code from. https://github.com/herjulf/gps_simple + +Getting the source and building +------------------------------- + +Code is stored in github. Typically procedure below is the very straight- +forward unix way: + + git clone http://github.com/herjulf/sensd + cd sensd + make + +Put your binaries after your preference: + +Pre-built binary versions +-------------------------- + +For x86: +Sensd and friends are available in Bifrost/Linux packages. Those packages are +statically linked and can be used on most x86 Linuxes. 32-bit compiled. + +http://ftp.sunet.se/pub/Linux/distributions/bifrost/download/opt/opt-sensd-2.3-1.tar.gz + + +Use +--- + +The WSN data logging and caching concept is in actual use with Contiki, RIME +broadcast application. + +Tips +---- + +One can use netcat to listen to reports: + +Example: + + nc radio-sensors.com 1235 + +To save in file use nohup: + + nohup nc radio-sensors.com 1235 > /var/log/sensors.dat + +As sensd used TCP and ASCII encoding. tetlnet and web-browsers can be used +as well. + + diff --git a/platform/avr-rss2/examples/ipv6/sensd_client/project-conf.h b/platform/avr-rss2/examples/ipv6/sensd_client/project-conf.h new file mode 100644 index 000000000..b004c6335 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/sensd_client/project-conf.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2015, RAdio Sensors AB, Uppsala Sweden + * 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. + */ + +/** + * \file + * Project specific configuration defines for example + * + * \author + * Robert Olsson + */ + +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +#define NETSTACK_CONF_RDC nullrdc_driver +#define NETSTACK_CONF_MAC nullmac_driver + +//#define NETSTACK_CONF_MAC csma_driver +//#define NETSTACK_CONF_RDC contikimac_driver +//#define NETSTACK_CONF_FRAMER framer_802154 +//#define NETSTACK_CONF_RADIO rf230_driver + +#endif /* PROJECT_CONF_H_ */ diff --git a/platform/avr-rss2/examples/ipv6/sensd_client/sensd_client.c b/platform/avr-rss2/examples/ipv6/sensd_client/sensd_client.c new file mode 100644 index 000000000..b523e87c4 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/sensd_client/sensd_client.c @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2015, Copyright Robert Olsson / Radio Sensors AB + * 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. + * + * + * Author : Robert Olsson robert@radio-sensors.com + * Created : 2015-12-28 + */ + +/** + * \file + * A simple application reporting sensor data. Can be sensd + */ + +#include +#include "contiki-net.h" +#include "leds.h" +#include "dev/leds.h" +#include "dev/battery-sensor.h" +#include "dev/temp_mcu-sensor.h" +#include "dev/light-sensor.h" +#ifdef CO2 +#include "dev/co2_sa_kxx-sensor.h" +#endif + +#ifndef PERIOD +#define PERIOD 10 +#endif + +#define REPORT_INTERVAL (PERIOD * CLOCK_SECOND) + +#define DEBUG DEBUG_PRINT +#include "uip-debug.h" + +#define PORT 1236 +#define MAX_PAYLOAD_LEN 80 + +static struct psock ps; +static uint8_t out_buf[MAX_PAYLOAD_LEN]; +static char in_buffer[MAX_PAYLOAD_LEN]; +static int i; +static int send_now; +static clock_time_t report_interval = REPORT_INTERVAL; +static uint8_t state; +static uip_ipaddr_t addr; +static struct timer t, t1; +static struct etimer et, et1; + +PROCESS(sensd_client_process, "sensd TCP client process"); +PROCESS(report_timer_process, "report pacemaker"); +AUTOSTART_PROCESSES +(&sensd_client_process,&report_timer_process); + +static int +do_report(void) +{ + static int seq_id; + int len = 0; + + seq_id++; + len += snprintf((char *) &out_buf[len], sizeof(out_buf), "&: "); + len += snprintf((char *) &out_buf[len], sizeof(out_buf), "TXT=6LOWPAN "); + len += snprintf((char *) &out_buf[len], sizeof(out_buf), "TARGET=avr-rss2 "); + len += snprintf((char *) &out_buf[len], sizeof(out_buf), "V_MCU=%-d ", battery_sensor.value(0)); + len += snprintf((char *) &out_buf[len], sizeof(out_buf), "T_MCU=%-d ", temp_mcu_sensor.value(0)); + len += snprintf((char *) &out_buf[len], sizeof(out_buf), "LIGHT=%-d ", light_sensor.value(0)); +#ifdef CO2 + len += snprintf((char *) &out_buf[len], sizeof(out_buf), "CO2=%-d ", co2_sa_kxx_sensor.value(value)); +#endif + len += snprintf((char *) &out_buf[len], sizeof(out_buf), "\n\r"); + + return len; +} + +static void +print_local_addresses(void) +{ + PRINTF("Server IPv6 addresses:\n\r"); + 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)) { + PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); + PRINTF("\n\r"); + } + } +} + +static void +set_global_address(void) +{ + uip_ipaddr_t ipaddr; + 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); +} + +static int handle_connection(struct psock *p, long ts) { + PSOCK_BEGIN(p); + if(send_now) { + do_report(); + leds_on(LEDS_YELLOW); + PSOCK_SEND(p, (const uint8_t *) out_buf, strlen((const char *) out_buf)); + send_now = 0; + } + PSOCK_END(p); +} + +PROCESS_THREAD(report_timer_process, ev, data) { + PROCESS_BEGIN(); + while(1) { + timer_set(&t1, report_interval); + etimer_set(&et1, timer_remaining(&t1)); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et1)); + send_now = 1; + leds_on(LEDS_RED); + } + PROCESS_END(); +} + +PROCESS_THREAD(sensd_client_process, ev, data) { + PROCESS_BEGIN(); + + set_global_address(); + leds_init(); + print_local_addresses(); + printf("Starting TCP client on port=%d\n", PORT); + + /* Set server address. typically sensd */ + //uip_ip6addr(&addr, 0xfe80, 0, 0, 0, 0xfec2, 0x3d00, 1, 0x63ae); + uip_ip6addr(&addr, 0x0000, 0, 0, 0, 0, 0xffff, 0xc0a8, 0x0201); + //uip_ip6addr(&addr, 0x0000, 0, 0, 0, 0, 0xffff, 0xc0a8, 0x0255); + + random_init(50); + + while(1) { + + /* Delay connection attempts */ + timer_set(&t, 2*CLOCK_SECOND); + etimer_set(&et, timer_remaining(&t)); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + /* Time out teh actual connection attempt */ + timer_set(&t, 10*CLOCK_SECOND); + printf("Connecting"); + tcp_connect(&addr, UIP_HTONS(PORT), NULL); + PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event); + + if(uip_aborted() || uip_timedout() || uip_closed()) { + printf(" Failed\n"); + } else if(uip_connected()) { + printf(" Success\n"); + PSOCK_INIT(&ps, (uint8_t *)in_buffer, sizeof(in_buffer)); + do { + handle_connection(&ps, clock_seconds()); + PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event); + } while(!(uip_closed() || uip_aborted() || uip_timedout())); + printf("Disconnected\n"); + } + } + PROCESS_END(); +} diff --git a/platform/avr-rss2/examples/ipv6/sensd_client/server.c b/platform/avr-rss2/examples/ipv6/sensd_client/server.c new file mode 100644 index 000000000..c2dea4514 --- /dev/null +++ b/platform/avr-rss2/examples/ipv6/sensd_client/server.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2015, Copyright Robert Olsson / Radio Sensors AB + * 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. + * + * + * Author : Robert Olsson robert@radio-sensors.com + * Created : 2015-12-28 + */ + +/** + * \file + * A simple TCP server for client app. + */ + +#include +#include "contiki-net.h" +#include "leds.h" + +#define DEBUG DEBUG_PRINT +#include "uip-debug.h" + +#define PORT 1236 + +static struct psock ps; +static uint8_t buf[120]; +static int i; +static uint8_t state; + +static void +print_local_addresses(void) +{ + PRINTF("Server IPv6 addresses:\n\r"); + 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)) { + PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); + PRINTF("\n\r"); + } + } +} + +static void +set_global_address(void) +{ + uip_ipaddr_t ipaddr; + 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); +} + +static +PT_THREAD(handle_connection(struct psock *p)) +{ + PSOCK_BEGIN(p); + //PSOCK_SEND_STR(p, "Type something!\n"); + leds_on(LEDS_RED); + PSOCK_READTO(p, '\n'); + printf("RX=%s", buf); + //PSOCK_SEND_STR(p, "Got: "); + //PSOCK_SEND(p, buf, PSOCK_DATALEN(p)); + //PSOCK_SEND_STR(p, "EOL\r\n"); + //PSOCK_CLOSE(p); + PSOCK_END(p); +} + +PROCESS(server_process, "Server"); +AUTOSTART_PROCESSES(&server_process); + +PROCESS_THREAD(server_process, ev, data) +{ + PROCESS_BEGIN(); + + set_global_address(); + leds_init(); + print_local_addresses(); + printf("Starting TCP server on port=%d\n", PORT); + tcp_listen(UIP_HTONS(PORT)); + + while(1) { + PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event); + + if(uip_aborted() ) + printf("TCP aborted\n"); + if(uip_timedout() ) + printf("TCP timeoutn\n"); + if(uip_closed() ) + printf("TCP closed\n"); + + if(uip_connected()) { + printf("TCP Connected\n\r"); + PSOCK_INIT(&ps, buf, sizeof(buf)); + + while(!(uip_aborted() || uip_closed() || uip_timedout())) { + PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event); + handle_connection(&ps); + } + } + } + PROCESS_END(); +} + diff --git a/platform/avr-rss2/ip64-conf.h b/platform/avr-rss2/ip64-conf.h new file mode 100644 index 000000000..26c51a55f --- /dev/null +++ b/platform/avr-rss2/ip64-conf.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + * + */ +#ifndef IP64_CONF_H +#define IP64_CONF_H + +#include "net/ip64/ip64-eth-interface.h" +#include "dev/enc28j60/enc28j60-ip64-driver.h" +#define IP64_CONF_UIP_FALLBACK_INTERFACE ip64_eth_interface +#define IP64_CONF_INPUT ip64_eth_interface_input +#define IP64_CONF_DHCP 1 +#define IP64_CONF_ETH_DRIVER enc28j60_ip64_driver + +#endif /* IP64_CONF_H */ diff --git a/platform/avr-rss2/params.c b/platform/avr-rss2/params.c new file mode 100644 index 000000000..f2ae2abfc --- /dev/null +++ b/platform/avr-rss2/params.c @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2011, 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. + * + */ +#define PRINTF(FORMAT, args ...) printf_P(PSTR(FORMAT),##args) + +#define DEBUG 1 +#if DEBUG +#define PRINTD(FORMAT, args ...) printf_P(PSTR(FORMAT),##args) +#else +#define PRINTD(...) +#endif + +#include "contiki.h" +#include +#include +#include +#include + +#if AVR_WEBSERVER +/* #include "httpd-fs.h" */ +/* #include "httpd-cgi.h" */ +#endif + +#include "contiki-net.h" +#include "params.h" + +#if CONTIKI_CONF_RANDOM_MAC +extern uint8_t rng_get_uint8(void); +static void +generate_new_eui64(uint8_t eui64[8]) +{ + eui64[0] = 0x02; + eui64[1] = rng_get_uint8(); + eui64[2] = rng_get_uint8(); + eui64[3] = 0xFF; + eui64[4] = 0xFE; + eui64[5] = rng_get_uint8(); + eui64[6] = rng_get_uint8(); + eui64[7] = rng_get_uint8(); +} +#endif + +#if AVR_WEBSERVER +/* Webserver builds can set these in httpd-fsdata.c via makefsdata.h */ +extern uint8_t default_mac_address[8]; +extern uint8_t default_server_name[16]; +extern uint8_t default_domain_name[30]; +#else +const uint8_t default_mac_address[8] PROGMEM = PARAMS_EUI64ADDR; +const uint8_t default_server_name[] PROGMEM = PARAMS_SERVERNAME; +const uint8_t default_domain_name[] PROGMEM = PARAMS_DOMAINNAME; +#endif + +#if PARAMETER_STORAGE == 0 +/* 0 Hard coded, minmal program and eeprom usage. */ +uint8_t +params_get_eui64(uint8_t *eui64) +{ +#if CONTIKI_CONF_RANDOM_MAC + PRINTD("Generating random EUI64 MAC\n"); + generate_new_eui64(eui64); + return 1; +#else + uint8_t i; + for(i = 0; i < sizeof(default_mac_address); i++) { + eui64[i] = pgm_read_byte_near(default_mac_address + i); + } + return 0; +#endif +} +#elif PARAMETER_STORAGE == 1 +/* 1 Stored in fixed eeprom locations, rewritten from flash if corrupt. + * They can be manually changed and kept over program reflash. + * The channel and bit complement are used to check EEMEM integrity, + * If corrupt all values will be rewritten with the default flash values. + * To make this work, get the channel before anything else. + */ +#if !AVR_WEBSERVER +uint8_t eemem_mac_address[] EEMEM = PARAMS_EUI64ADDR; +uint8_t eemem_server_name[] EEMEM = PARAMS_SERVERNAME; +uint8_t eemem_domain_name[] EEMEM = PARAMS_DOMAINNAME; +#endif /*AVR_WEBSERVER */ + +uint16_t eemem_nodeid EEMEM = PARAMS_NODEID; +uint8_t eemem_channel[2] EEMEM = { PARAMS_CHANNEL, ~PARAMS_CHANNEL }; +uint16_t eemem_panid EEMEM = PARAMS_PANID; +uint16_t eemem_panaddr EEMEM = PARAMS_PANADDR; +uint8_t eemem_txpower EEMEM = PARAMS_TXPOWER; + +#if CONTIKI_CONF_RANDOM_MAC +static uint8_t randomeui64; +#endif + +uint8_t +params_get_channel(void) +{ + uint8_t x[2]; + *(uint16_t *)x = eeprom_read_word((uint16_t *)&eemem_channel); +/* Don't return an invalid channel number */ + if((x[0] < 11) || (x[0] > 26)) { + x[1] = x[0]; + } +/* Do exclusive or test on the two values read */ + if((uint8_t)x[0] != (uint8_t) ~x[1]) { /* ~x[1] can promote comparison to 16 bit */ +/* Verification fails, rewrite everything */ + uint8_t i, buffer[32]; + PRINTD("EEPROM is corrupt, rewriting with defaults.\n"); +#if CONTIKI_CONF_RANDOM_MAC + PRINTD("Generating random EUI64 MAC\n"); + generate_new_eui64(&buffer); + randomeui64 = 1; +#else + for(i = 0; i < sizeof(default_mac_address); i++) { + buffer[i] = pgm_read_byte_near(default_mac_address + i); + } +#endif +/* eeprom_write_block should not be interrupted */ + cli(); + eeprom_write_block(&buffer, &eemem_mac_address, sizeof(eemem_mac_address)); + for(i = 0; i < sizeof(default_server_name); i++) { + buffer[i] = pgm_read_byte_near(default_server_name + i); + } + eeprom_write_block(&buffer, &eemem_server_name, sizeof(eemem_server_name)); + for(i = 0; i < sizeof(default_domain_name); i++) { + buffer[i] = pgm_read_byte_near(default_domain_name + i); + } + eeprom_write_block(&buffer, &eemem_domain_name, sizeof(eemem_domain_name)); + eeprom_write_word(&eemem_panid, PARAMS_PANID); + eeprom_write_word(&eemem_panaddr, PARAMS_PANADDR); + eeprom_write_byte(&eemem_txpower, PARAMS_TXPOWER); + eeprom_write_word(&eemem_nodeid, PARAMS_NODEID); + x[0] = PARAMS_CHANNEL; + x[1] = ~x[0]; + eeprom_write_word((uint16_t *)&eemem_channel, *(uint16_t *)x); + sei(); + } +/* Always returns a valid channel */ + return x[0]; +} +uint8_t +params_get_eui64(uint8_t *eui64) +{ + cli(); + eeprom_read_block((void *)eui64, &eemem_mac_address, sizeof(linkaddr_t)); + sei(); +#if CONTIKI_CONF_RANDOM_MAC + return randomeui64; +#else + return 0; +#endif +} +uint16_t +params_get_panid(void) +{ + return eeprom_read_word(&eemem_panid); +} +uint16_t +params_get_panaddr(void) +{ + return eeprom_read_word(&eemem_panaddr); +} +uint8_t +params_get_txpower(void) +{ + return eeprom_read_byte(&eemem_txpower); +} +#else /* CONTIKI_CONF_SETTINGS_MANAGER */ + +uint8_t +params_get_channel() +{ + uint8_t x; + size_t size = 1; + if(settings_get(SETTINGS_KEY_CHANNEL, 0, (unsigned char *)&x, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get RF channel %u\n", x); + } else { + x = PARAMS_CHANNEL; + if(settings_add_uint8(SETTINGS_KEY_CHANNEL, x) == SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM RF channel to %d\n", x); + } + } + return x; +} +uint8_t +params_get_eui64(uint8_t *eui64) +{ + size_t size = sizeof(linkaddr_t); + if(settings_get(SETTINGS_KEY_EUI64, 0, (unsigned char *)eui64, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get EUI64 MAC\n"); + return 0; + } +#if CONTIKI_CONF_RANDOM_MAC + PRINTD("Generating random EUI64 MAC\n"); + generate_new_eui64(eui64); +#else + { uint8_t i; + for(i = 0; i < 8; i++) { + eui64[i] = pgm_read_byte_near(default_mac_address + i); + } + } /* test this */ +#endif + if(settings_add(SETTINGS_KEY_EUI64, (unsigned char *)eui64, 8) == SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM MAC address\n"); + } +#if CONTIKI_CONF_RANDOM_MAC + return 1; +#else + return 0; +#endif +} +uint16_t +params_get_panid(void) +{ + uint16_t x; + size_t size = 2; + if(settings_get(SETTINGS_KEY_PAN_ID, 0, (unsigned char *)&x, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get PAN ID of %04x\n", x); + } else { + x = PARAMS_PANID; + if(settings_add_uint16(SETTINGS_KEY_PAN_ID, x) == SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM PAN ID to %04x\n", x); + } + } + return x; +} +uint16_t +params_get_panaddr(void) +{ + uint16_t x; + size_t size = 2; + if(settings_get(SETTINGS_KEY_PAN_ADDR, 0, (unsigned char *)&x, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get PAN address of %04x\n", x); + } else { + x = PARAMS_PANADDR; + if(settings_add_uint16(SETTINGS_KEY_PAN_ADDR, x) == SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM PAN address to %04x\n", x); + } + } + return x; +} +uint8_t +params_get_txpower(void) +{ + uint8_t x; + size_t size = 1; + if(settings_get(SETTINGS_KEY_TXPOWER, 0, (unsigned char *)&x, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get tx power of %d (0=max)\n", x); + } else { + x = PARAMS_TXPOWER; + if(settings_add_uint8(SETTINGS_KEY_TXPOWER, x) == SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM tx power of %d (0=max)\n", x); + } + } + return x; +} +#endif /* CONTIKI_CONF_SETTINGS_MANAGER */ diff --git a/platform/avr-rss2/params.h b/platform/avr-rss2/params.h new file mode 100644 index 000000000..95150333b --- /dev/null +++ b/platform/avr-rss2/params.h @@ -0,0 +1,108 @@ +#ifndef __PARAMS_H__ +#define __PARAMS_H__ +/* PARAMETER_STORAGE = + * 0 Hard coded, minmal program and eeprom usage. + * 1 Stored in fixed eeprom locations, rewritten from flash if corrupt. + * This allows parameter changes using a hardware programmer or custom application code. + * Corruption test is based on channel verify so get the channel before anything else! + * 2 Obtained from eeprom using the general settings manager and read from program flash if not present. + * Useful for for testing builds without wearing out flash memory. + * 3 Obtained from eeprom using the settings manager and rewritten from flash if not present. + * This ensures all parameters are present in upper eeprom flash. + * + * Note the parameters in this file can be changed without forcing a complete rebuild. + */ +#define CONTIKI_CONF_RANDOM_MAC 0 /* adds 78 bytes */ +#define CONTIKI_CONF_SETTINGS_MANAGER 0 /* adds 1696 bytes */ + +#if CONTIKI_CONF_SETTINGS_MANAGER +/* #define PARAMETER_STORAGE 2 */ +#define PARAMETER_STORAGE 2 +#else +#define PARAMETER_STORAGE 1 +#endif + +/* Include settings.h, then dummy out the write routines */ +#include "settings.h" +#if PARAMETER_STORAGE == 2 +#define settings_add(...) 0 +#define settings_add_uint8(...) 0 +#define settings_add_uint16(...) 0 +#endif + +#if AVR_WEBSERVER +/* Webserver builds can set some defaults in httpd-fsdata.c via makefsdata.h */ +extern uint8_t eemem_mac_address[8]; +extern uint8_t eemem_server_name[16]; +extern uint8_t eemem_domain_name[30]; +#endif + +#ifdef SERVER_NAME +#define PARAMS_SERVERNAME SERVER_NAME +#else +#define PARAMS_SERVERNAME "ATMEGA256rfr2" +#endif +#ifdef DOMAIN_NAME +#define PARAMS_DOMAINNAME DOMAIN_NAME +#else +#define PARAMS_DOMAINNAME "localhost" +#endif +#ifdef NODE_ID +#define PARAMS_NODEID NODE_ID +#else +#define PARAMS_NODEID 0 +#endif +#ifdef CHANNEL_802_15_4 +#define PARAMS_CHANNEL CHANNEL_802_15_4 +#else +#define PARAMS_CHANNEL 26 +#endif +#ifdef IEEE802154_PANID +#define PARAMS_PANID IEEE802154_PANID +#else +#define PARAMS_PANID 0xABCD +#endif +#ifdef IEEE802154_PANADDR +#define PARAMS_PANADDR IEEE802154_PANADDR +#else +#define PARAMS_PANADDR 0 +#endif +#ifdef RF230_MAX_TX_POWER +#define PARAMS_TXPOWER RF230_MAX_TX_POWER +#else +#define PARAMS_TXPOWER 0 +#endif +#ifdef EUI64_ADDRESS +#define PARAMS_EUI64ADDR EUI64_ADDRESS +#else +/* This form of of EUI64 mac allows full 6LoWPAN header compression from mac address */ +#if UIP_CONF_LL_802154 +/* #define PARAMS_EUI64ADDR {0x02, 0xNN, 0xNN, 0xNN, 0xNN, 0xNN, 0xNN, 0xNN} */ +#define PARAMS_EUI64ADDR { 0x02, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x01 } +#else +/* #define PARAMS_EUI64ADDR {0x02, 0xNN, 0xNN, 0xff, 0xfe, 0xNN, 0xNN, 0xNN} */ +#define PARAMS_EUI64ADDR { 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x01 } +#endif +/* This form of of EUI64 mac allows 16 bit 6LoWPAN header compression on multihops */ +/* #define PARAMS_EUI64ADDR {0x02, 0x00, 0x00, 0xff, 0xfe, 0x00, 0xNN, 0xNN} */ +#endif + +uint8_t params_get_eui64(uint8_t *eui64); +#if PARAMETER_STORAGE == 0 +/* Hard coded program flash parameters */ +#define params_get_servername(...) +#define params_get_nodeid(...) PARAMS_NODEID +#define params_get_channel(...) PARAMS_CHANNEL +#define params_get_panid(...) PARAMS_PANID +#define params_get_panaddr(...) PARAMS_PANADDR +#define params_get_txpower(...) PARAMS_TXPOWER +#else +/* Parameters stored in eeprom */ +uint16_t params_get_nodeid(void); +uint8_t params_get_channel(void); +uint16_t params_get_panid(void); +uint16_t params_get_panaddr(void); +uint8_t params_get_txpower(void); +#endif + +#endif /* __PARAMS_H__ */ diff --git a/platform/avr-rss2/rss2.h b/platform/avr-rss2/rss2.h new file mode 100644 index 000000000..46ade3822 --- /dev/null +++ b/platform/avr-rss2/rss2.h @@ -0,0 +1,36 @@ + +/* + Pin assigments for Radio Sensors board revision 2.3 + using MCU AtMega128rfa1 + */ + +#define ISP_1 PB1 /* SCK */ +#define ISP_2 PB2 /* MOSI */ +#define ISP_3 PB3 /* MISO */ + +#define LED_YELLOW PE3 /* 1k pullup to Vcc */ +#define LED_RED PE4 /* 1k pullup to Vcc */ +#define USB_PWR PB5 /* High if FTDI TTL-USB cable sources */ +#define P0 PD2 /* Pulse count input. Pullup via jumper */ +#define P1 PD3 /* Pulse count input via optional Comparator */ +#define PWR_1 PE7 /* Programmable power pin Vcc via P-FET */ + +#define AV_IN PF0 /* V_IN ADC input. 100k/1M volt. divider */ +#define A1 PF1 /* A1 ADC input. 100k/300k volt. divider */ +#define A2 PF2 /* A2 ADC input 100k/300k volt. divider */ +#define A3 PF3 /* Light sensor A3 ADC input 100k/100k volt. divider */ +#define A3_PWR PF4 /* Light sensor power A3_PWR */ + +#define RX0 PE0 /* RX UART0 -- FTDI TTL-USB cable */ +#define TX0 PE1 /* TX UART0 -- FTDI TTL-USB cable */ + +#define OW_BUS_0 PD7 /* One-Wire bus w temp/ID Pulled Up. Separate Vcc */ +#define OW_BUS_1 PD6 /* One-Wire bus extra Pulled Up. Separate Vcc */ + +/* AVR ISP standard connected */ +/* 16 MHz xtal */ +/* RTC 32.768 Hz xtal */ + +/*Optional HIH610 connected on SPI */ +#define HUM_PWR PE2 /* Power pin for HIH6130 also to ena. HIH 6130 Alarm mode */ + diff --git a/platform/avr-rss2/slip_uart0.c b/platform/avr-rss2/slip_uart0.c new file mode 100644 index 000000000..8f064f980 --- /dev/null +++ b/platform/avr-rss2/slip_uart0.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2010, University of Colombo School of Computing + * 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. + * + * @(#)$$ + */ + +/** + * \file + * Machine dependent AVR SLIP routines for UART0. + * \author + * Kasun Hewage + */ + +#include +#include "contiki.h" +#include "dev/rs232.h" +#include "slip.h" + +/*---------------------------------------------------------------------------*/ +static int +slip_putchar(char c, FILE *stream) +{ +#define SLIP_END 0300 + static char debug_frame = 0; + + if(!debug_frame) { /* Start of debug output */ + slip_arch_writeb(SLIP_END); + slip_arch_writeb('\r'); /* Type debug line == '\r' */ + debug_frame = 1; + } + + slip_arch_writeb((unsigned char)c); + + /* + * Line buffered output, a newline marks the end of debug output and + * implicitly flushes debug output. + */ + if(c == '\n') { + slip_arch_writeb(SLIP_END); + debug_frame = 0; + } + + return c; +} +/*---------------------------------------------------------------------------*/ +static FILE slip_stdout = FDEV_SETUP_STREAM(slip_putchar, NULL, + _FDEV_SETUP_WRITE); +/*---------------------------------------------------------------------------*/ +void +slip_arch_init(unsigned long ubr) +{ + rs232_set_input(SLIP_PORT, slip_input_byte); + stdout = &slip_stdout; +} +/*---------------------------------------------------------------------------*/ +/* + XXX: + Currently, the following function is in cpu/avr/dev/rs232.c file. this + should be moved to here from there hence this is a platform specific slip + related function. + void + slip_arch_writeb(unsigned char c) + { + rs232_send(RS232_PORT_0, c); + } + */ From 42e7a6a7e1f9427239e0916b9a8a021ccab4c663 Mon Sep 17 00:00:00 2001 From: Robert Olsson Date: Mon, 22 Feb 2016 20:50:49 +0100 Subject: [PATCH 042/374] Adding travis regression compile test for the avr-rss2 platform. --- .travis.yml | 7 ++++++- regression-tests/23-compile-avr/Makefile | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 regression-tests/23-compile-avr/Makefile diff --git a/.travis.yml b/.travis.yml index 3a035fd2e..f00dc2f9b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,11 @@ before_script: msp430-gcc --version ## Install avr toolchain - - sudo apt-get -qq install gcc-avr avr-libc + - $WGET http://atiselsts.github.io/resources/avr-gcc-4.9.2-compiled.tar.bz2 && + tar xjf avr-gcc*.tar.bz2 -C /tmp/ && + sudo cp -f -r /tmp/avr-gcc/* /usr/local/ && + rm -rf /tmp/avr-gcc avr-gcc*.tar.bz2 && + avr-gcc --version ## Install 32-bit compatibility libraries - sudo apt-get -qq install libc6:i386 libgcc1:i386 gcc-4.6-base:i386 @@ -140,3 +144,4 @@ env: - BUILD_TYPE='compile-nxp-ports' BUILD_CATEGORY='compile' BUILD_ARCH='jn516x' - BUILD_TYPE='slip-radio' MAKE_TARGETS='cooja' - BUILD_TYPE='llsec' MAKE_TARGETS='cooja' + - BUILD_TYPE='compile-avr' BUILD_CATEGORY='compile' BUILD_ARCH='avr-rss2' diff --git a/regression-tests/23-compile-avr/Makefile b/regression-tests/23-compile-avr/Makefile new file mode 100644 index 000000000..0904e2f37 --- /dev/null +++ b/regression-tests/23-compile-avr/Makefile @@ -0,0 +1,15 @@ +EXAMPLESDIR=../.. +TOOLSDIR=../../tools + +# build avr-rss2 examples, covering IPv6, RPL, Rime, Nullrdc, Contikimac + +EXAMPLES = \ +platform/avr-rss2/examples/hello-sensors/avr-rss2 \ +platform/avr-rss2/examples/ipv6/rpl-udp-report/avr-rss2 \ +platform/avr-rss2/examples/ipv6/rpl-border-router/avr-rss2 \ +examples/ipv6/rpl-udp/avr-rss2 \ +examples/powertrace/avr-rss2 \ +examples/rime/avr-rss2 +TOOLS= + +include ../Makefile.compile-test From d8f2129b17b0dbb7dbd184850b1565373f4ab44b Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Tue, 23 Feb 2016 11:28:50 +0200 Subject: [PATCH 043/374] avr-rss2 platform: Update README.md --- platform/avr-rss2/README.md | 100 ++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 49 deletions(-) diff --git a/platform/avr-rss2/README.md b/platform/avr-rss2/README.md index 260a7d4bb..05d448fc6 100644 --- a/platform/avr-rss2/README.md +++ b/platform/avr-rss2/README.md @@ -7,15 +7,15 @@ The platform supports different AtMega-RF boards: * Based on MCU AtMega256RFR2 * Based on MCU AtMega128RFA1 -Boards looks the same. "Made in EU" labeled on the AtMega256RFR2 boards +Boards all looks the same. AtMega256RFR2 boards are labeled with "Made in EU". The platform and CPU code, are common for both boards, can be found under -`$(CONTIKI)/platfrom/avr-rssa. The port was developed and tested with RSS2. +`$(CONTIKI)/platfrom/avr-rssa`. The port was developed and tested with RSS2. This guide assumes that you have basic understanding of how to use the -command line and perform basic admin tasks on UNIX family OSs. You should' +command line and perform basic admin tasks on UNIX family OSs. You should also have understanding about the Contiki OS design as well have C programming skills. -Boards Features +Board Features ---------------- * Chip Antenna. Supercardiod. * Robust radio performance. Up to 300 meter line-of-sight. @@ -29,10 +29,9 @@ Boards Features * Standard. 6-pin TTL-USB header for FTDI cable for UART. * PCB formfactor for cheap project box G.40X IP54 * Power/current: - ** RX ~10mA (Full RPC AtMegaXXRFR2). - ** Sleep ~45uA @ 16MHz XTAL - ** Sleep ~15uA @ 8MHz using internal oscillator - + * RX ~10mA (Full RPC AtMegaXXRFR2). + * Sleep ~45uA @ 16MHz XTAL + * Sleep ~15uA @ 8MHz using internal oscillator * Preprogammed bootloader. * CE certified by test institute. @@ -56,33 +55,33 @@ Note. The native OS packages does not yet support the new AtMega256RfR2 MCU. We'll use toolchain from Atmels web-site. You might also consider -Instant Contiki +Instant Contiki. -* For Linux. -See http://www.atmel.com/tools/ATMELAVRTOOLCHAINFORLINUX.aspx -Download the proper 8-bit platform 32 or 64 bit. -Unpack unpack under /usr/local -Also add to your search PATH. For example .bashrc add: -export PATH=$PATH:/usr/local/avr8-gnu-toolchain-linux_x86/bin -or -export PATH=$PATH:/usr/local/avr8-gnu-toolchain-linux_x86_64/bin +###### For Linux -For flash programming you'll need avrdude. For OS using apt-get -apt-get install avrdude +1. See http://www.atmel.com/tools/ATMELAVRTOOLCHAINFORLINUX.aspx +2. Download the proper 8-bit platform 32 or 64 bit. +3. Unpack under `/usr/local` +4. Add to your search PATH. For example add to `.bashrc`: `export PATH=$PATH:/usr/local/avr8-gnu-toolchain-linux_x86_64/bin` (for 64 bit systems) or `export PATH=$PATH:/usr/local/avr8-gnu-toolchain-linux_x86/bin` (for 32 birt systems). +5. For flash programming you'll need `avrdude`. It can be installed with the command +`apt-get install avrdude` + +###### For Windows -* For Windows. Goes here Contiki build TARGET -------------------- -make TARGET=avr-rss2 + make TARGET=avr-rss2 For AtMega128RFR2 boards: -make TARGET=avr-rss2 MCU=atmega128rfr2 + + make TARGET=avr-rss2 MCU=atmega128rfr2 For AtMega128RFA1 boards: -make TARGET=avr-rss2 MCU=atmega128rfa1 + + make TARGET=avr-rss2 MCU=atmega128rfa1 Flashing -------- @@ -91,49 +90,52 @@ Press the RESET button. The bootloader with wait for boot commands for 3 seconds. Flashing commnad line example 256k MCU: -avrdude -p m256rfr2 -c stk500v2 -P /dev/ttyUSB0 -b 38400 -e -U flash:w:hello-world.avr-rss2 + + avrdude -p m256rfr2 -c stk500v2 -P /dev/ttyUSB0 -b 38400 -e -U flash:w:hello-world.avr-rss2 Flashing commnad line example 128k MCU: -avrdude -p m128rfa1 -c avr109 -P /dev/ttyUSB0 -b 38400 -e -U flash:w:hello-world.avr-rss2 -Older boards may use the avr109 boot loader. The stk500v2 uses the yellow + avrdude -p m128rfa1 -c avr109 -P /dev/ttyUSB0 -b 38400 -e -U flash:w:hello-world.avr-rss2 + +Older boards may use the avr109 boot loader. The `stk500v2` uses the yellow lED while the avr109 uses the red LED. Tested applications and examples --------------------------------- -hello-world -ipv6/rpl-udp -ipv6/simple-udp-rpl -rime -ipv6/multicast -example-shell Needs symbol.c to be added to project also seems like -in core/dev/serial-line.c process_poll must be replaced with -process_post. +* `hello-world` +* `ipv6/rpl-udp` +* `ipv6/simple-udp-rpl` +* `rime` +* `ipv6/multicast` +* `examples/powertrace` +* `example-shell` - /* Wake up consumer process */ -- process_poll(&serial_line_process); -+ process_post(&serial_line_process, 0, 0); +Note that the shell example needs file `symbols.c` to be added to project also seems like +in `core/dev/serial-line.c` the function `process_poll` must be replaced with `process_post`: + + /* Wake up consumer process */ + - process_poll(&serial_line_process); + + process_post(&serial_line_process, 0, 0); -examples/powertrace Platform tutorial applications -.----------------------------- -Example to read out various sensors leds serial numbers etc. -platform/avr-rss2/examples/hello-sensors/ +----------------------------- +Example to read out various sensors, leds, serial numbers, and so on: +[platform/avr-rss2/examples/hello-sensors/](examples/hello-sensors/). -This example shows the sensd data encoding. But UDP using 6lowpan. -platform/avr-rss2/examles/ipv6/rpl-udp-report/ +The previous example uses the `sensd` data encoding. An example that uses UDP through 6lowpan is here: +[platform/avr-rss2/examples/ipv6/rpl-udp-report](examples/ipv6/rpl-udp-report). -NAT ip64 ethernet GW based on Contiki core/net/ip64 code -platform/avr-rss2/examples/ipv6/rpl-border-router/ +An Ethernet gateway with ip64 NAT, based on Contiki `core/net/ip64` code: +[platform/avr-rss2/examples/ipv6/rpl-border-router/](examples/ipv6/rpl-border-router/). Regressions tests ----------------- -Travis compile regression for platform: -regression-tests/23-compile-avr +Travis compile regression test for the platform: +[regression-tests/23-compile-avr](../../regression-tests/23-compile-avr). -Port adds newer version of avr-gcc compiler (4.9.2), to support -testing of newwr Atmel MCU as Atmega256RFR2. Work by Atis Elsts +This port adds newer version of `avr-gcc` compiler (4.9.2), to support +testing of newer Atmel MCU as Atmega256RFR2. Board approvals From 9f1fedfbc1ba122f3484abeeb6a634e6ce360877 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Tue, 23 Feb 2016 11:43:51 +0200 Subject: [PATCH 044/374] avr-rss2 platform examples: remove some binary files --- platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-client.avr-rss2 | 0 platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-server.avr-rss2 | 0 platform/avr-rss2/examples/ipv6/rpl-udp-report/report.avr-rss2 | 0 platform/avr-rss2/examples/ipv6/rpl-udp-report/sink.avr-rss2 | 0 4 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-client.avr-rss2 delete mode 100644 platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-server.avr-rss2 delete mode 100644 platform/avr-rss2/examples/ipv6/rpl-udp-report/report.avr-rss2 delete mode 100644 platform/avr-rss2/examples/ipv6/rpl-udp-report/sink.avr-rss2 diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-client.avr-rss2 b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-client.avr-rss2 deleted file mode 100644 index e69de29bb..000000000 diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-server.avr-rss2 b/platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-server.avr-rss2 deleted file mode 100644 index e69de29bb..000000000 diff --git a/platform/avr-rss2/examples/ipv6/rpl-udp-report/report.avr-rss2 b/platform/avr-rss2/examples/ipv6/rpl-udp-report/report.avr-rss2 deleted file mode 100644 index e69de29bb..000000000 diff --git a/platform/avr-rss2/examples/ipv6/rpl-udp-report/sink.avr-rss2 b/platform/avr-rss2/examples/ipv6/rpl-udp-report/sink.avr-rss2 deleted file mode 100644 index e69de29bb..000000000 From 786aa19cbd35918f41b78d73b8e4c75241b8a7b1 Mon Sep 17 00:00:00 2001 From: Billy Kozak Date: Tue, 23 Feb 2016 10:41:01 -0700 Subject: [PATCH 045/374] Fixed numeruous bus in CC26xx-CC13xx lpm Bug fixes include: - keep interrupts disabled during lpm_sleep() so that we don't miss any interrupts we may have been expecting - check that the pending etimer isn't already expired (and don't sleep at all if it is) - check that the about-to-be scheduled rtimer wakeup is neither too far into the future nor too close into the future (or even in the past) before actually setting the interrupt (should fix #1509); If the time is out of bounds we use a default min or max value instead. - Correctly handle LPM_MODE_MAX_SUPPORTED set to zero (and added a macro for the zero value) so that sleeping can be disabled altogether - If no etimer is set, we specify a wakeup time which is reasonably far into the future instead of setting none at all (this will save on power consumption whenever no etimers are set). Also did a bit of refactoring in that some long functions were broken into multiple functions. --- cpu/cc26xx-cc13xx/lpm.c | 364 +++++++++++++++++++++++----------------- cpu/cc26xx-cc13xx/lpm.h | 1 + 2 files changed, 213 insertions(+), 152 deletions(-) diff --git a/cpu/cc26xx-cc13xx/lpm.c b/cpu/cc26xx-cc13xx/lpm.c index 6af58e899..eec8ed66d 100644 --- a/cpu/cc26xx-cc13xx/lpm.c +++ b/cpu/cc26xx-cc13xx/lpm.c @@ -75,7 +75,12 @@ LIST(modules_list); * Don't consider standby mode if the next AON RTC event is scheduled to fire * in less than STANDBY_MIN_DURATION rtimer ticks */ -#define STANDBY_MIN_DURATION (RTIMER_SECOND >> 11) +#define STANDBY_MIN_DURATION (RTIMER_SECOND >> 11) +#define MINIMAL_SAFE_SCHEDUAL 8u +#define MAX_SLEEP_TIME RTIMER_SECOND +#define DEFAULT_SLEEP_TIME RTIMER_SECOND +/*---------------------------------------------------------------------------*/ +#define CLK_TO_RT(c) ((c) * (RTIMER_SECOND / CLOCK_SECOND)) /*---------------------------------------------------------------------------*/ /* Prototype of a function in clock.c. Called every time we come out of DS */ void clock_update(void); @@ -234,30 +239,195 @@ wake_up(void) } } /*---------------------------------------------------------------------------*/ -void -lpm_drop() +static void +deep_sleep(void) { - lpm_registered_module_t *module; - uint8_t max_pm = LPM_MODE_MAX_SUPPORTED; - uint8_t module_pm; - clock_time_t next_event; - uint32_t domains = LOCKABLE_DOMAINS; + lpm_registered_module_t *module; - /* Critical. Don't get interrupted! */ - ti_lib_int_master_disable(); + /* + * Notify all registered modules that we are dropping to mode X. We do not + * need to do this for simple sleep. + * + * This is a chance for modules to delay us a little bit until an ongoing + * operation has finished (e.g. uart TX) or to configure themselves for + * deep sleep. + * + * At this stage, we also collect power domain locks, if any. + * The argument to PRCMPowerDomainOff() is a bitwise OR, so every time + * we encounter a lock we just clear the respective bits in the 'domains' + * variable as required by the lock. In the end the domains variable will + * just hold whatever has not been cleared + */ + for(module = list_head(modules_list); module != NULL; + module = module->next) { + if(module->shutdown) { + module->shutdown(LPM_MODE_DEEP_SLEEP); + } - /* Check if any events fired before we turned interrupts off. If so, abort */ - if(process_nevents()) { - ti_lib_int_master_enable(); - return; + /* Clear the bits specified in the lock */ + domains &= ~module->domain_lock; } - if(RTIMER_CLOCK_LT(soc_rtc_get_next_trigger(), - RTIMER_NOW() + STANDBY_MIN_DURATION)) { - ti_lib_int_master_enable(); - lpm_sleep(); - return; + /* Pat the dog: We don't want it to shout right after we wake up */ + watchdog_periodic(); + + /* Clear unacceptable bits, just in case a lock provided a bad value */ + domains &= LOCKABLE_DOMAINS; + + /* + * Freeze the IOs on the boundary between MCU and AON. We only do this if + * PERIPH is not needed + */ + if(domains & PRCM_DOMAIN_PERIPH) { + ti_lib_aon_ioc_freeze_enable(); + } + + /* + * Among LOCKABLE_DOMAINS, turn off those that are not locked + * + * If domains is != 0, pass it as-is + */ + if(domains) { + ti_lib_prcm_power_domain_off(domains); + } + + /* + * Before entering Deep Sleep, we must switch off the HF XOSC. The HF XOSC + * is predominantly controlled by the RF driver. In a build with radio + * cycling (e.g. ContikiMAC), the RF driver will request the XOSC before + * using the Freq. Synth, and switch back to the RC when it is about to + * turn back off. + * + * If the radio is on, we won't even reach here, and if it's off the HF + * clock source should already be the HF RC. + * + * Nevertheless, request the switch to the HF RC explicitly here. + */ + oscillators_switch_to_hf_rc(); + + /* Configure clock sources for MCU and AUX: No clock */ + ti_lib_aon_wuc_mcu_power_down_config(AONWUC_NO_CLOCK); + ti_lib_aon_wuc_aux_power_down_config(AONWUC_NO_CLOCK); + + /* Full RAM retention. */ + ti_lib_aon_wuc_mcu_sram_config(MCU_RAM0_RETENTION | MCU_RAM1_RETENTION | + MCU_RAM2_RETENTION | MCU_RAM3_RETENTION); + + /* Disable retention of AUX RAM */ + ti_lib_aon_wuc_aux_sram_config(false); + + /* + * Always turn off RFCORE, CPU, SYSBUS and VIMS. RFCORE should be off + * already + */ + ti_lib_prcm_power_domain_off(PRCM_DOMAIN_RFCORE | PRCM_DOMAIN_CPU | + PRCM_DOMAIN_VIMS | PRCM_DOMAIN_SYSBUS); + + /* Request JTAG domain power off */ + ti_lib_aon_wuc_jtag_power_off(); + + /* Turn off AUX */ + ti_lib_aux_wuc_power_ctrl(AUX_WUC_POWER_OFF); + ti_lib_aon_wuc_domain_power_down_enable(); + while(ti_lib_aon_wuc_power_status_get() & AONWUC_AUX_POWER_ON); + + /* Configure the recharge controller */ + ti_lib_sys_ctrl_set_recharge_before_power_down(XOSC_IN_HIGH_POWER_MODE); + + /* + * If both PERIPH and SERIAL PDs are off, request the uLDO as the power + * source while in deep sleep. + */ + if(domains == LOCKABLE_DOMAINS) { + ti_lib_pwr_ctrl_source_set(PWRCTRL_PWRSRC_ULDO); + } + + /* We are only interested in IRQ energest while idle or in LPM */ + ENERGEST_IRQ_RESTORE(irq_energest); + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); + + /* Sync the AON interface to ensure all writes have gone through. */ + ti_lib_sys_ctrl_aon_sync(); + + /* + * Explicitly turn off VIMS cache, CRAM and TRAM. Needed because of + * retention mismatch between VIMS logic and cache. We wait to do this + * until right before deep sleep to be able to use the cache for as long + * as possible. + */ + ti_lib_prcm_cache_retention_disable(); + ti_lib_vims_mode_set(VIMS_BASE, VIMS_MODE_OFF); + + /* Deep Sleep */ + ti_lib_prcm_deep_sleep(); + + /* + * When we reach here, some interrupt woke us up. The global interrupt + * flag is off, hence we have a chance to run things here. We will wake up + * the chip properly, and then we will enable the global interrupt without + * unpending events so the handlers can fire + */ + wake_up(); +} +/*---------------------------------------------------------------------------*/ +static void +safe_schedule_rtimer(rtimer_clock_t time, rtimer_clock_t now, int pm) +{ + rtimer_clock_t min_sleep; + rtimer_clock_t max_sleep; + + min_sleep = now + MINIMAL_SAFE_SCHEDUAL; + max_sleep = now + MAX_SLEEP_TIME; + + if(RTIMER_CLOCK_LT(time, min_sleep)) { + /* ensure that we schedule sleep a minimal number of ticks into the + future */ + soc_rtc_schedule_one_shot(AON_RTC_CH1, min_sleep); + } else if((pm == LPM_MODE_SLEEP) && RTIMER_CLOCK_LT(max_sleep, time)) { + /* if max_pm is LPM_MODE_SLEEP, we could trigger the watchdog if we slept + for too long. */ + soc_rtc_schedule_one_shot(AON_RTC_CH1, max_sleep); + } else { + soc_rtc_schedule_one_shot(AON_RTC_CH1, time); + } +} +/*---------------------------------------------------------------------------*/ +static int +setup_sleep_mode(void) +{ + rtimer_clock_t et_distance = 0; + + lpm_registered_module_t *module; + int max_pm; + int module_pm; + int etimer_is_pending; + rtimer_clock_t now; + rtimer_clock_t et_time; + rtimer_clock_t next_trig; + + max_pm = LPM_MODE_MAX_SUPPORTED; + now = RTIMER_NOW(); + + if((LPM_MODE_MAX_SUPPORTED == LPM_MODE_AWAKE) || process_nevents()) { + return LPM_MODE_AWAKE; + } + + etimer_is_pending = etimer_pending(); + + if(etimer_is_pending) { + et_distance = CLK_TO_RT(etimer_next_expiration_time() - clock_time()); + + if(RTIMER_CLOCK_LT(et_distance, 1)) { + /* there is an etimer which is already expired; we shouldn't go to + sleep at all */ + return LPM_MODE_AWAKE; + } + } + + next_trig = soc_rtc_get_next_trigger(); + if(RTIMER_CLOCK_LT(next_trig, now + STANDBY_MIN_DURATION)) { + return LPM_MODE_SLEEP; } /* Collect max allowed PM permission from interested modules */ @@ -272,146 +442,36 @@ lpm_drop() } /* Reschedule AON RTC CH1 to fire just in time for the next etimer event */ - next_event = etimer_next_expiration_time(); + if(etimer_is_pending) { + et_time = soc_rtc_last_isr_time() + et_distance; - if(etimer_pending()) { - next_event = next_event - clock_time(); - soc_rtc_schedule_one_shot(AON_RTC_CH1, soc_rtc_last_isr_time() + - (next_event * (RTIMER_SECOND / CLOCK_SECOND))); + safe_schedule_rtimer(et_time, now, max_pm); + } else { + /* set a maximal sleep period if no etimers are queued */ + soc_rtc_schedule_one_shot(AON_RTC_CH1, now + DEFAULT_SLEEP_TIME); } + return max_pm; +} +/*---------------------------------------------------------------------------*/ +void +lpm_drop() +{ + uint8_t max_pm; + + /* Critical. Don't get interrupted! */ + ti_lib_int_master_disable(); + + max_pm = setup_sleep_mode(); + /* Drop */ if(max_pm == LPM_MODE_SLEEP) { - ti_lib_int_master_enable(); lpm_sleep(); - } else { - /* - * Notify all registered modules that we are dropping to mode X. We do not - * need to do this for simple sleep. - * - * This is a chance for modules to delay us a little bit until an ongoing - * operation has finished (e.g. uart TX) or to configure themselves for - * deep sleep. - * - * At this stage, we also collect power domain locks, if any. - * The argument to PRCMPowerDomainOff() is a bitwise OR, so every time - * we encounter a lock we just clear the respective bits in the 'domains' - * variable as required by the lock. In the end the domains variable will - * just hold whatever has not been cleared - */ - for(module = list_head(modules_list); module != NULL; - module = module->next) { - if(module->shutdown) { - module->shutdown(max_pm); - } - - /* Clear the bits specified in the lock */ - domains &= ~module->domain_lock; - } - - /* Pat the dog: We don't want it to shout right after we wake up */ - watchdog_periodic(); - - /* Clear unacceptable bits, just in case a lock provided a bad value */ - domains &= LOCKABLE_DOMAINS; - - /* - * Freeze the IOs on the boundary between MCU and AON. We only do this if - * PERIPH is not needed - */ - if(domains & PRCM_DOMAIN_PERIPH) { - ti_lib_aon_ioc_freeze_enable(); - } - - /* - * Among LOCKABLE_DOMAINS, turn off those that are not locked - * - * If domains is != 0, pass it as-is - */ - if(domains) { - ti_lib_prcm_power_domain_off(domains); - } - - /* - * Before entering Deep Sleep, we must switch off the HF XOSC. The HF XOSC - * is predominantly controlled by the RF driver. In a build with radio - * cycling (e.g. ContikiMAC), the RF driver will request the XOSC before - * using the Freq. Synth, and switch back to the RC when it is about to - * turn back off. - * - * If the radio is on, we won't even reach here, and if it's off the HF - * clock source should already be the HF RC. - * - * Nevertheless, request the switch to the HF RC explicitly here. - */ - oscillators_switch_to_hf_rc(); - - /* Configure clock sources for MCU and AUX: No clock */ - ti_lib_aon_wuc_mcu_power_down_config(AONWUC_NO_CLOCK); - ti_lib_aon_wuc_aux_power_down_config(AONWUC_NO_CLOCK); - - /* Full RAM retention. */ - ti_lib_aon_wuc_mcu_sram_config(MCU_RAM0_RETENTION | MCU_RAM1_RETENTION | - MCU_RAM2_RETENTION | MCU_RAM3_RETENTION); - - /* Disable retention of AUX RAM */ - ti_lib_aon_wuc_aux_sram_config(false); - - /* - * Always turn off RFCORE, CPU, SYSBUS and VIMS. RFCORE should be off - * already - */ - ti_lib_prcm_power_domain_off(PRCM_DOMAIN_RFCORE | PRCM_DOMAIN_CPU | - PRCM_DOMAIN_VIMS | PRCM_DOMAIN_SYSBUS); - - /* Request JTAG domain power off */ - ti_lib_aon_wuc_jtag_power_off(); - - /* Turn off AUX */ - ti_lib_aux_wuc_power_ctrl(AUX_WUC_POWER_OFF); - ti_lib_aon_wuc_domain_power_down_enable(); - while(ti_lib_aon_wuc_power_status_get() & AONWUC_AUX_POWER_ON); - - /* Configure the recharge controller */ - ti_lib_sys_ctrl_set_recharge_before_power_down(XOSC_IN_HIGH_POWER_MODE); - - /* - * If both PERIPH and SERIAL PDs are off, request the uLDO as the power - * source while in deep sleep. - */ - if(domains == LOCKABLE_DOMAINS) { - ti_lib_pwr_ctrl_source_set(PWRCTRL_PWRSRC_ULDO); - } - - /* We are only interested in IRQ energest while idle or in LPM */ - ENERGEST_IRQ_RESTORE(irq_energest); - ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); - - /* Sync the AON interface to ensure all writes have gone through. */ - ti_lib_sys_ctrl_aon_sync(); - - /* - * Explicitly turn off VIMS cache, CRAM and TRAM. Needed because of - * retention mismatch between VIMS logic and cache. We wait to do this - * until right before deep sleep to be able to use the cache for as long - * as possible. - */ - ti_lib_prcm_cache_retention_disable(); - ti_lib_vims_mode_set(VIMS_BASE, VIMS_MODE_OFF); - - /* Deep Sleep */ - ti_lib_prcm_deep_sleep(); - - /* - * When we reach here, some interrupt woke us up. The global interrupt - * flag is off, hence we have a chance to run things here. We will wake up - * the chip properly, and then we will enable the global interrupt without - * unpending events so the handlers can fire - */ - wake_up(); - - ti_lib_int_master_enable(); + } else if(max_pm == LPM_MODE_DEEP_SLEEP) { + deep_sleep(); } + + ti_lib_int_master_enable(); } /*---------------------------------------------------------------------------*/ void diff --git a/cpu/cc26xx-cc13xx/lpm.h b/cpu/cc26xx-cc13xx/lpm.h index cc144809b..2d6f56d00 100644 --- a/cpu/cc26xx-cc13xx/lpm.h +++ b/cpu/cc26xx-cc13xx/lpm.h @@ -49,6 +49,7 @@ #include /*---------------------------------------------------------------------------*/ +#define LPM_MODE_AWAKE 0 #define LPM_MODE_SLEEP 1 #define LPM_MODE_DEEP_SLEEP 2 #define LPM_MODE_SHUTDOWN 3 From ff6d336e8b1657e9249f688360a226a70eafe264 Mon Sep 17 00:00:00 2001 From: Billy Kozak Date: Fri, 26 Feb 2016 08:26:31 -0700 Subject: [PATCH 046/374] Fix warning about missing strcasecmp definition On platforms which do not define the macro __SDCC the strcasecmp function may not have a definition (true at least on CC26xx). The prototype for this function is now defined if __SDCC is false. --- core/net/ip/resolv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/net/ip/resolv.c b/core/net/ip/resolv.c index 0dd06104b..2a3d39106 100644 --- a/core/net/ip/resolv.c +++ b/core/net/ip/resolv.c @@ -111,6 +111,9 @@ strcasecmp(const char *s1, const char *s2) /* TODO: Add case support! */ return strcmp(s1, s2); } +#else +int strcasecmp(const char *s1, const char *s2); +int strncasecmp(const char *s1, const char *s2, size_t n); #endif /* __SDCC */ #define UIP_UDP_BUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN]) From d7ee5630237fc6c9e7cd618c59d804b5307e9340 Mon Sep 17 00:00:00 2001 From: Jelmer Tiete Date: Mon, 29 Feb 2016 13:48:24 +0100 Subject: [PATCH 047/374] Updates cc2538-bsl to 4340542, main changes are fix for contiki-os/contiki#1533 and an added option to invert the RTS and DTR lines when auto starting the bootloader --- tools/cc2538-bsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/cc2538-bsl b/tools/cc2538-bsl index 6185d8b16..434054237 160000 --- a/tools/cc2538-bsl +++ b/tools/cc2538-bsl @@ -1 +1 @@ -Subproject commit 6185d8b16f10047053fd57000a552340273d7d85 +Subproject commit 4340542370d3e319d692f9f969c5683231fce438 From de7850ed5829286cb5fdcabe327a8620d0413274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Wed, 2 Mar 2016 07:00:57 +0100 Subject: [PATCH 048/374] core/lib/settings.h: fix warning: function declaration isn't a prototype --- core/lib/settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/lib/settings.h b/core/lib/settings.h index e102b8b0b..bef6d0461 100644 --- a/core/lib/settings.h +++ b/core/lib/settings.h @@ -186,7 +186,7 @@ extern settings_status_t settings_delete(settings_key_t key, uint8_t index); typedef eeprom_addr_t settings_iter_t; /** Will return \ref SETTINGS_INVALID_ITER if the settings store is empty. */ -extern settings_iter_t settings_iter_begin(); +extern settings_iter_t settings_iter_begin(void); /** Will return \ref SETTINGS_INVALID_ITER if at the end of settings list. */ extern settings_iter_t settings_iter_next(settings_iter_t iter); From 7c11034ab71cbd8dcd17e4da08485cd6e41da42c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Wed, 2 Mar 2016 07:00:57 +0100 Subject: [PATCH 049/374] core/lib/trickle-timer.c: fix warning: function declaration isn't a prototype --- core/lib/trickle-timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/lib/trickle-timer.c b/core/lib/trickle-timer.c index 2b88f60ef..fd2d7c537 100644 --- a/core/lib/trickle-timer.c +++ b/core/lib/trickle-timer.c @@ -79,7 +79,7 @@ static void double_interval(void *ptr); #if TRICKLE_TIMER_WIDE_RAND /* Returns a 4-byte wide, unsigned random number */ static uint32_t -wide_rand() +wide_rand(void) { return ((uint32_t)random_rand() << 16 | random_rand()); } From 2e47bf9cdc3d1c52a0762e7067fb2a61098d192f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Wed, 2 Mar 2016 07:00:57 +0100 Subject: [PATCH 050/374] core/net/ipv6/sicslowpan.c: fix warning: function declaration isn't a prototype --- core/net/ipv6/sicslowpan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/net/ipv6/sicslowpan.c b/core/net/ipv6/sicslowpan.c index d0bf14799..3b722d598 100644 --- a/core/net/ipv6/sicslowpan.c +++ b/core/net/ipv6/sicslowpan.c @@ -452,7 +452,7 @@ rime_sniffer_remove(struct rime_sniffer *s) } static void -set_packet_attrs() +set_packet_attrs(void) { int c = 0; /* set protocol in NETWORK_ID */ From 52e7ea9cc4d9b414e5d9fce9a9ad4164e43986a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Wed, 2 Mar 2016 07:00:57 +0100 Subject: [PATCH 051/374] core/net/rpl/rpl-dag.c: fix warning: function declaration isn't a prototype --- core/net/rpl/rpl-dag.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 46f2936ef..9cd69e7b0 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -88,7 +88,7 @@ rpl_instance_t *default_instance; /*---------------------------------------------------------------------------*/ void -rpl_print_neighbor_list() +rpl_print_neighbor_list(void) { if(default_instance != NULL && default_instance->current_dag != NULL && default_instance->of != NULL && default_instance->of->calculate_rank != NULL) { @@ -160,7 +160,7 @@ rpl_get_parent_link_metric(const uip_lladdr_t *addr) { uip_ds6_nbr_t *nbr; nbr = nbr_table_get_from_lladdr(ds6_neighbors, (const linkaddr_t *)addr); - + if(nbr != NULL) { return nbr->link_metric; } else { @@ -645,7 +645,7 @@ rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr) p->dag = dag; p->rank = dio->rank; p->dtsn = dio->dtsn; - + /* Check whether we have a neighbor that has not gotten a link metric yet */ if(nbr != NULL && nbr->link_metric == 0) { nbr->link_metric = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR; From d7d836fda0d5299b1a7f03f245b760b09b00fbc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Wed, 2 Mar 2016 07:00:57 +0100 Subject: [PATCH 052/374] core/net/rpl/rpl.h: fix warning: function declaration isn't a prototype --- core/net/rpl/rpl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h index c3d693b26..54b63c875 100644 --- a/core/net/rpl/rpl.h +++ b/core/net/rpl/rpl.h @@ -179,7 +179,7 @@ typedef struct rpl_instance rpl_instance_t; * update_metric_container(dag) * * Updates the metric container for outgoing DIOs in a certain DAG. - * If the objective function of the DAG does not use metric containers, + * If the objective function of the DAG does not use metric containers, * the function should set the object type to RPL_DAG_MC_NONE. */ struct rpl_of { @@ -257,7 +257,7 @@ rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr); uint16_t rpl_get_parent_link_metric(const uip_lladdr_t *addr); void rpl_dag_init(void); uip_ds6_nbr_t *rpl_get_nbr(rpl_parent_t *parent); -void rpl_print_neighbor_list(); +void rpl_print_neighbor_list(void); /* Per-parent RPL information */ NBR_TABLE_DECLARE(rpl_parents); From e32b46a86690448a733d83c5d96de00393b30d0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Wed, 2 Mar 2016 07:04:34 +0100 Subject: [PATCH 053/374] core/lib/gcr.c: fix warning: function declaration isn't a prototype --- core/lib/gcr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/lib/gcr.c b/core/lib/gcr.c index 1fba2f40b..36ee98ea2 100644 --- a/core/lib/gcr.c +++ b/core/lib/gcr.c @@ -64,13 +64,13 @@ static unsigned char gcr_bits = 0; static unsigned short gcr_val = 0; /* Call before starting encoding or decoding */ -void gcr_init() { +void gcr_init(void) { gcr_val = 0; gcr_bits = 0; } /* Use this to check if encoding / decoding is complete for now */ -unsigned char gcr_finished() { +unsigned char gcr_finished(void) { return gcr_bits == 0; } @@ -100,7 +100,7 @@ void gcr_decode(unsigned char gcr_data) { } /* check if the current decoded stream is correct */ -unsigned char gcr_valid() { +unsigned char gcr_valid(void) { if (gcr_bits >= 10) { unsigned short val = gcr_val & 0x3ff; if ((GCR_decode[val >> 5u] << 4u) == 0xff || From 9159903f5a9fbf9ffc22dc8639a7ff3e7d2e837b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Wed, 2 Mar 2016 07:12:01 +0100 Subject: [PATCH 054/374] apps/er-coap/er-coap-transactions.h: fix warning: function declaration isn't a prototype --- apps/er-coap/er-coap-transactions.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/er-coap/er-coap-transactions.h b/apps/er-coap/er-coap-transactions.h index 18bb421b1..10697134a 100644 --- a/apps/er-coap/er-coap-transactions.h +++ b/apps/er-coap/er-coap-transactions.h @@ -67,7 +67,7 @@ typedef struct coap_transaction { * Use snprintf(buf, len+1, "", ...) to completely fill payload */ } coap_transaction_t; -void coap_register_as_transaction_handler(); +void coap_register_as_transaction_handler(void); coap_transaction_t *coap_new_transaction(uint16_t mid, uip_ipaddr_t *addr, uint16_t port); @@ -75,6 +75,6 @@ void coap_send_transaction(coap_transaction_t *t); void coap_clear_transaction(coap_transaction_t *t); coap_transaction_t *coap_get_transaction_by_mid(uint16_t mid); -void coap_check_transactions(); +void coap_check_transactions(void); #endif /* COAP_TRANSACTIONS_H_ */ From 4ff571beb205cb7ccd289ca376fe2746ee0c929c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Wed, 2 Mar 2016 07:12:01 +0100 Subject: [PATCH 055/374] apps/er-coap/er-coap-separate.h: fix warning: function declaration isn't a prototype --- apps/er-coap/er-coap-separate.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/er-coap/er-coap-separate.h b/apps/er-coap/er-coap-separate.h index dbecf1b39..33a923240 100644 --- a/apps/er-coap/er-coap-separate.h +++ b/apps/er-coap/er-coap-separate.h @@ -61,7 +61,7 @@ typedef struct coap_separate { int coap_separate_handler(resource_t *resource, void *request, void *response); -void coap_separate_reject(); +void coap_separate_reject(void); void coap_separate_accept(void *request, coap_separate_t *separate_store); void coap_separate_resume(void *response, coap_separate_t *separate_store, uint8_t code); From 12197903129e2362179bb55e4a8f60602f66d58d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Wed, 2 Mar 2016 07:25:19 +0100 Subject: [PATCH 056/374] examples/er-rest-example/resources/res-event.c: fix warning: function declaration isn't a prototype --- examples/er-rest-example/resources/res-event.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/er-rest-example/resources/res-event.c b/examples/er-rest-example/resources/res-event.c index d20f0caa9..7524d2ad2 100644 --- a/examples/er-rest-example/resources/res-event.c +++ b/examples/er-rest-example/resources/res-event.c @@ -53,7 +53,7 @@ #endif static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); -static void res_event_handler(); +static void res_event_handler(void); /* * Example for an event resource. @@ -86,7 +86,7 @@ res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr * It is called through .trigger(), usually from the server process. */ static void -res_event_handler() +res_event_handler(void) { /* Do the update triggered by the event here, e.g., sampling a sensor. */ ++event_counter; From 6876b97466aca2dc1fea0be4b76fd903480fe858 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt Date: Sun, 6 Mar 2016 21:11:18 +0100 Subject: [PATCH 057/374] Adjusted segment names to match recent cc65 change. --- platform/apple2enh/lib/pfs.S | 2 +- platform/c128/lib/pfs.S | 2 +- platform/c64/lib/pfs.S | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/apple2enh/lib/pfs.S b/platform/apple2enh/lib/pfs.S index ed44dfc1e..5c2ac488c 100644 --- a/platform/apple2enh/lib/pfs.S +++ b/platform/apple2enh/lib/pfs.S @@ -66,7 +66,7 @@ read_count_out: .word $0000 ;TRANS_COUNT close_param: .byte $01 ;PARAM_COUNT close_fd: .byte $00 ;REF_NUM ;--------------------------------------------------------------------- - .segment "INIT" + .segment "ONCE" init_pfs: ; Allow exec() to keep file open diff --git a/platform/c128/lib/pfs.S b/platform/c128/lib/pfs.S index acec45959..62a2a7840 100644 --- a/platform/c128/lib/pfs.S +++ b/platform/c128/lib/pfs.S @@ -72,7 +72,7 @@ pw: .byte $2C, $50, $2C, $57 ;,p,w cmdc: .byte 0 flags: .res 10 ;--------------------------------------------------------------------- - .segment "INIT" + .segment "ONCE" init_pfs: ldy #F_MAXLEN+8 diff --git a/platform/c64/lib/pfs.S b/platform/c64/lib/pfs.S index 35e64f652..c63d08d2e 100644 --- a/platform/c64/lib/pfs.S +++ b/platform/c64/lib/pfs.S @@ -72,7 +72,7 @@ pw: .byte $2C, $50, $2C, $57 ;,p,w cmdc: .byte 0 flags: .res 10 ;--------------------------------------------------------------------- - .segment "INIT" + .segment "ONCE" init_pfs: ldy #F_MAXLEN+8 From 07ec06ad092c6029c6a580fe5560e116f89332ca Mon Sep 17 00:00:00 2001 From: Robert Olsson Date: Sun, 6 Mar 2016 21:35:19 +0100 Subject: [PATCH 058/374] Setting node_id and RIME linkaddr from EUI64 chip. --- platform/avr-rss2/contiki-main.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/platform/avr-rss2/contiki-main.c b/platform/avr-rss2/contiki-main.c index 172c6139f..8abac4d04 100644 --- a/platform/avr-rss2/contiki-main.c +++ b/platform/avr-rss2/contiki-main.c @@ -193,9 +193,9 @@ initialize(void) #if 0 /* Do it my way... */ - UBRR0L = 25; - UBRR0H = 0; - UCSR0A = (1 << U2X0); /*Double */ + //UBRR0L = 8; UBRR0H = 0; UCSR0A = (0 << U2X0); // 115.2k err=-3.5% + //UBRR0L = 16; UBRR0H = 0; UCSR0A = (1 << U2X0); // 115.2k 2.1% + //UBRR0L = 3; UBRR0H = 0; UCSR0A = (1 << U2X0); // 500k 0% #endif rs232_set_input(RS232_PORT_0, serial_line_input_byte); @@ -277,17 +277,18 @@ initialize(void) /* Set addresses BEFORE starting tcpip process */ linkaddr_t addr; + char eui64[8]; printf("I2C: "); i2c_probed = i2c_probe(); printf("\n"); if( i2c_probed & I2C_AT24MAC ) { - i2c_at24mac_read((char *)&addr.u8, 1); - linkaddr_set_node_addr(&addr); + i2c_at24mac_read((char *)&eui64, 1); + linkaddr_set_node_addr((linkaddr_t *) &eui64); + node_id = (eui64[1] << 8) + eui64[7]; } else { - char eui64[8]; printf("Random EUI64 address generated\n"); eui64[0] = 0xfc; /* Atmels OUI */ eui64[1] = 0xc2; @@ -297,12 +298,13 @@ initialize(void) eui64[5] = 0; eui64[6] = node_id >> 8; eui64[7] = node_id & 0xff; - linkaddr_set_node_addr(&eui64); + linkaddr_set_node_addr((linkaddr_t *)&eui64); } /* memcpy(&uip_lladdr.addr, &addr.u8, sizeof(linkaddr_t)); */ #if NETSTACK_CONF_WITH_IPV6 + memcpy(&addr.u8, &eui64, sizeof(linkaddr_t)); memcpy(&uip_lladdr.addr, &addr.u8, sizeof(linkaddr_t)); #endif @@ -315,6 +317,9 @@ initialize(void) #else PRINTA("MAC address "); uint8_t i; + addr.u8[0] = eui64[1] ; + addr.u8[1] = eui64[7]; + for(i = sizeof(linkaddr_t); i > 0; i--) { PRINTA("%x:", addr.u8[i - 1]); } From b4c2cd9619aac07bce4eefc706ef443b8b58c3c2 Mon Sep 17 00:00:00 2001 From: thomas-ha Date: Mon, 7 Mar 2016 17:25:40 +0100 Subject: [PATCH 059/374] Macros for TSCH US_TO_RTIMERTICKS(US) and RTIMERTICKS_TO_US(T) --- cpu/cc2538/rtimer-arch.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cpu/cc2538/rtimer-arch.h b/cpu/cc2538/rtimer-arch.h index ddb020af1..45ebc5c5d 100644 --- a/cpu/cc2538/rtimer-arch.h +++ b/cpu/cc2538/rtimer-arch.h @@ -65,6 +65,20 @@ #define RTIMER_ARCH_SECOND 32768 +/* Do the math in 32bits to save precision. + * Round to nearest integer rather than truncate. */ +#define US_TO_RTIMERTICKS(US) ((US) >= 0 ? \ + (((int32_t)(US) * (RTIMER_ARCH_SECOND) + 500000) / 1000000L) : \ + ((int32_t)(US) * (RTIMER_ARCH_SECOND) - 500000) / 1000000L) + +#define RTIMERTICKS_TO_US(T) ((T) >= 0 ? \ + (((int32_t)(T) * 1000000L + ((RTIMER_ARCH_SECOND) / 2)) / (RTIMER_ARCH_SECOND)) : \ + ((int32_t)(T) * 1000000L - ((RTIMER_ARCH_SECOND) / 2)) / (RTIMER_ARCH_SECOND)) + +/* A 64-bit version because the 32-bit one cannot handle T >= 4295 ticks. + Intended only for positive values of T. */ +#define RTIMERTICKS_TO_US_64(T) ((uint32_t)(((uint64_t)(T) * 1000000 + ((RTIMER_ARCH_SECOND) / 2)) / (RTIMER_ARCH_SECOND))) + /** \sa RTIMER_NOW() */ rtimer_clock_t rtimer_arch_now(void); From 73fcfa42c259443b015ca81c498dd789179341a8 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 7 Mar 2016 17:42:17 +0100 Subject: [PATCH 060/374] TSCH: fix compiler warning that shows up when disabling TSCH_LOG_LEVEL --- core/net/mac/tsch/tsch.c | 1 + 1 file changed, 1 insertion(+) diff --git a/core/net/mac/tsch/tsch.c b/core/net/mac/tsch/tsch.c index 1d9701e42..4e24ea8da 100644 --- a/core/net/mac/tsch/tsch.c +++ b/core/net/mac/tsch/tsch.c @@ -936,6 +936,7 @@ send_packet(mac_callback_t sent, void *ptr) tsch_queue_packet_count(addr), p->header_len, queuebuf_datalen(p->qb)); + (void)packet_count_before; /* Discard "variable set but unused" warning in case of TSCH_LOG_LEVEL of 0 */ } } if(ret != MAC_TX_DEFERRED) { From 8b63b41b96a0dbcbf78fe3e430ad20f3bfdb51fd Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 7 Mar 2016 17:43:25 +0100 Subject: [PATCH 061/374] TSCH-security: disable TSCH logs to save ROM, relax checks in 21-z1-rpl-tsch-security.csc accordingly --- examples/ipv6/rpl-tsch/project-conf.h | 2 +- regression-tests/11-ipv6/21-z1-rpl-tsch-security.csc | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/ipv6/rpl-tsch/project-conf.h b/examples/ipv6/rpl-tsch/project-conf.h index 7ecfb74c1..2b602d908 100644 --- a/examples/ipv6/rpl-tsch/project-conf.h +++ b/examples/ipv6/rpl-tsch/project-conf.h @@ -153,7 +153,7 @@ #define TSCH_SCHEDULE_CONF_DEFAULT_LENGTH 2 /* Reduce log level to make space for security on z1 */ #undef TSCH_LOG_CONF_LEVEL -#define TSCH_LOG_CONF_LEVEL 1 +#define TSCH_LOG_CONF_LEVEL 0 #endif /* WITH_SECURITY */ #endif /* CONTIKI_TARGET_Z1 */ diff --git a/regression-tests/11-ipv6/21-z1-rpl-tsch-security.csc b/regression-tests/11-ipv6/21-z1-rpl-tsch-security.csc index a24f7fe5b..e2cda7e44 100644 --- a/regression-tests/11-ipv6/21-z1-rpl-tsch-security.csc +++ b/regression-tests/11-ipv6/21-z1-rpl-tsch-security.csc @@ -270,9 +270,6 @@ make node.z1 TARGET=z1 MAKE_WITH_ORCHESTRA=0 MAKE_WITH_SECURITY=1 + true + + 600 + 0 + 700 + 946 + 6 + + + org.contikios.cooja.plugins.MoteInterfaceViewer + 3 + + Serial port + 0,0 + + 350 + 2 + 300 + 976 + 36 + + diff --git a/examples/ipv6/rpl-udp/rpl-udp.csc b/examples/ipv6/rpl-udp/rpl-udp.csc index cf7c049f1..3aa9b270e 100644 --- a/examples/ipv6/rpl-udp/rpl-udp.csc +++ b/examples/ipv6/rpl-udp/rpl-udp.csc @@ -1,12 +1,13 @@ - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/mobility + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker Data collection network using IPv6 and RPL - 0 generated 5000000 @@ -24,7 +25,7 @@ sky1 Sky Mote Type #sky1 [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.c - make udp-server.sky TARGET=sky + make clean udp-server.sky TARGET=sky DEFINES=TEST_MORE_ROUTES=1 [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.sky org.contikios.cooja.interfaces.Position org.contikios.cooja.interfaces.RimeAddress @@ -47,7 +48,7 @@ sky2 Sky Mote Type #sky2 [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.c - make udp-client.sky TARGET=sky + make clean udp-client.sky TARGET=sky [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.sky org.contikios.cooja.interfaces.Position org.contikios.cooja.interfaces.RimeAddress @@ -73,6 +74,10 @@ -66.16503914182063 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 1 @@ -87,6 +92,10 @@ 98.28771308774003 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 2 @@ -101,6 +110,10 @@ 91.71883780610729 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 3 @@ -115,6 +128,10 @@ 92.47229665488265 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 4 @@ -129,6 +146,10 @@ -30.341495695501195 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 5 @@ -143,6 +164,10 @@ 32.944481932122315 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 6 @@ -157,6 +182,10 @@ 17.879870626121914 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 7 @@ -171,6 +200,10 @@ 57.05973076244069 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 8 @@ -185,6 +218,10 @@ 59.887319605093715 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 9 @@ -199,6 +236,10 @@ 23.9075414163248 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 10 @@ -213,6 +254,10 @@ 75.14274313304935 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 11 @@ -227,6 +272,10 @@ 85.6911670159044 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 12 @@ -241,6 +290,10 @@ -3.9704359883635574 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 13 @@ -255,6 +308,10 @@ -42.39683727590697 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 14 @@ -269,6 +326,10 @@ 26.921376811426246 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 15 @@ -283,6 +344,10 @@ 30.68867105530305 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 16 @@ -297,6 +362,10 @@ -24.313824905298304 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 17 @@ -311,6 +380,10 @@ 48.01822457713635 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 18 @@ -325,6 +398,10 @@ 20.140247172447996 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 19 @@ -339,6 +416,10 @@ -47.6710492173345 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 20 @@ -353,6 +434,10 @@ 92.47229665488265 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 21 @@ -367,6 +452,10 @@ -24.313824905298304 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 22 @@ -381,6 +470,10 @@ -44.657213822233054 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 23 @@ -395,6 +488,10 @@ -1.7100594420374744 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 24 @@ -409,6 +506,10 @@ -2.4635182908128352 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 25 @@ -423,6 +524,10 @@ -9.998106778566445 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 26 @@ -437,6 +542,10 @@ -50.684884612435944 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 27 @@ -451,6 +560,10 @@ 96.99304974753483 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 28 @@ -465,6 +578,10 @@ 59.320107308766765 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 29 @@ -479,6 +596,10 @@ 2.8106936506146916 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 30 @@ -493,6 +614,10 @@ 67.97632874312737 0.0 + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + org.contikios.cooja.mspmote.interfaces.MspMoteID 31 @@ -503,10 +628,10 @@ org.contikios.cooja.plugins.SimControl 259 - 1 + 3 184 - 0 - 0 + 3 + 15 org.contikios.cooja.plugins.Visualizer @@ -517,21 +642,23 @@ 2.349818846983307 0.0 0.0 2.349818846983307 150.19773526533348 176.95275613586946 520 - 3 + 2 523 - 269 - 14 + 14 + 210 org.contikios.cooja.plugins.LogListener + + 937 0 213 - 21 - 464 + 265 + 16 org.contikios.cooja.plugins.ScriptRunner @@ -574,11 +701,11 @@ while(1) { } true - 600 - 2 - 700 - 665 - 6 + 651 + 1 + 550 + 547 + 181 diff --git a/examples/ipv6/rpl-udp/udp-client.c b/examples/ipv6/rpl-udp/udp-client.c index 279703880..e5339fc3d 100644 --- a/examples/ipv6/rpl-udp/udp-client.c +++ b/examples/ipv6/rpl-udp/udp-client.c @@ -40,12 +40,17 @@ #include #include +/* Only for TMOTE Sky? */ +#include "dev/serial-line.h" +#include "dev/uart1.h" +#include "net/ipv6/uip-ds6-route.h" + #define UDP_CLIENT_PORT 8765 #define UDP_SERVER_PORT 5678 #define UDP_EXAMPLE_ID 190 -#define DEBUG DEBUG_PRINT +#define DEBUG DEBUG_FULL #include "net/ip/uip-debug.h" #ifndef PERIOD @@ -64,6 +69,9 @@ static uip_ipaddr_t server_ipaddr; PROCESS(udp_client_process, "UDP client process"); AUTOSTART_PROCESSES(&udp_client_process); /*---------------------------------------------------------------------------*/ +static int seq_id; +static int reply; + static void tcpip_handler(void) { @@ -72,16 +80,32 @@ tcpip_handler(void) if(uip_newdata()) { str = uip_appdata; str[uip_datalen()] = '\0'; - printf("DATA recv '%s'\n", str); + reply++; + printf("DATA recv '%s' (s:%d, r:%d)\n", str, seq_id, reply); } } /*---------------------------------------------------------------------------*/ static void send_packet(void *ptr) { - static int seq_id; char buf[MAX_PAYLOAD_LEN]; +#ifdef SERVER_REPLY + uint8_t num_used = 0; + uip_ds6_nbr_t *nbr; + + nbr = nbr_table_head(ds6_neighbors); + while(nbr != NULL) { + nbr = nbr_table_next(ds6_neighbors, nbr); + num_used++; + } + + if(seq_id > 0) { + ANNOTATE("#A r=%d/%d,color=%s,n=%d %d\n", reply, seq_id, + reply == seq_id ? "GREEN" : "RED", uip_ds6_route_num_routes(), num_used); + } +#endif /* SERVER_REPLY */ + seq_id++; PRINTF("DATA send to %d 'Hello %d'\n", server_ipaddr.u8[sizeof(server_ipaddr.u8) - 1], seq_id); @@ -156,8 +180,9 @@ PROCESS_THREAD(udp_client_process, ev, data) PROCESS_PAUSE(); set_global_address(); - - PRINTF("UDP client process started\n"); + + PRINTF("UDP client process started nbr:%d routes:%d\n", + NBR_TABLE_CONF_MAX_NEIGHBORS, UIP_CONF_MAX_ROUTES); print_local_addresses(); @@ -174,6 +199,11 @@ PROCESS_THREAD(udp_client_process, ev, data) PRINTF(" local/remote port %u/%u\n", UIP_HTONS(client_conn->lport), UIP_HTONS(client_conn->rport)); + /* initialize serial line */ + uart1_set_input(serial_line_input_byte); + serial_line_init(); + + #if WITH_COMPOWER powertrace_sniff(POWERTRACE_ON); #endif @@ -184,7 +214,41 @@ PROCESS_THREAD(udp_client_process, ev, data) if(ev == tcpip_event) { tcpip_handler(); } - + + if(ev == serial_line_event_message && data != NULL) { + char *str; + str = data; + if(str[0] == 'r') { + uip_ds6_route_t *r; + uip_ipaddr_t *nexthop; + uip_ds6_defrt_t *defrt; + uip_ipaddr_t *ipaddr; + defrt = NULL; + if((ipaddr = uip_ds6_defrt_choose()) != NULL) { + defrt = uip_ds6_defrt_lookup(ipaddr); + } + if(defrt != NULL) { + PRINTF("DefRT: :: -> %02d", defrt->ipaddr.u8[15]); + PRINTF(" lt:%lu inf:%d\n", stimer_remaining(&defrt->lifetime), + defrt->isinfinite); + } else { + PRINTF("DefRT: :: -> NULL\n"); + } + + for(r = uip_ds6_route_head(); + r != NULL; + r = uip_ds6_route_next(r)) { + nexthop = uip_ds6_route_nexthop(r); + PRINTF("Route: %02d -> %02d", r->ipaddr.u8[15], nexthop->u8[15]); + /* PRINT6ADDR(&r->ipaddr); */ + /* PRINTF(" -> "); */ + /* PRINT6ADDR(nexthop); */ + PRINTF(" lt:%lu\n", r->state.lifetime); + + } + } + } + if(etimer_expired(&periodic)) { etimer_reset(&periodic); ctimer_set(&backoff_timer, SEND_TIME, send_packet, NULL); diff --git a/examples/ipv6/rpl-udp/udp-server.c b/examples/ipv6/rpl-udp/udp-server.c index 17c1b1fb8..ce87d3b8f 100644 --- a/examples/ipv6/rpl-udp/udp-server.c +++ b/examples/ipv6/rpl-udp/udp-server.c @@ -107,7 +107,8 @@ PROCESS_THREAD(udp_server_process, ev, data) SENSORS_ACTIVATE(button_sensor); - PRINTF("UDP server started\n"); + PRINTF("UDP server started. nbr:%d routes:%d\n", + NBR_TABLE_CONF_MAX_NEIGHBORS, UIP_CONF_MAX_ROUTES); #if UIP_CONF_ROUTER /* The choice of server address determines its 6LoPAN header compression. From fa1b70b723f2eb188fa8a4ece19f801b3d0c2bef Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Mon, 24 Aug 2015 11:13:05 +0200 Subject: [PATCH 109/374] added configuration of DAO route refresh for broadcast DIOs --- core/net/rpl/rpl-icmp6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index b0ab53de4..e043b87a2 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -515,7 +515,7 @@ dio_output(rpl_instance_t *instance, uip_ipaddr_t *uc_addr) buffer[pos++] = instance->dtsn_out; - if(uc_addr == NULL) { + if(RPL_DIO_REFRESH_DAO_ROUTES && uc_addr == NULL) { /* Request new DAO to refresh route. We do not do this for unicast DIO * in order to avoid DAO messages after a DIS-DIO update, * or upon unicast DIO probing. */ From cd98b8b40ec6b238c4faf28b7f72038ec248851d Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Mon, 24 Aug 2015 11:42:50 +0200 Subject: [PATCH 110/374] added periodic debug printout of number of used neighbors and routes --- core/net/rpl/rpl-nbr-policy.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/core/net/rpl/rpl-nbr-policy.c b/core/net/rpl/rpl-nbr-policy.c index 8c9a2ff21..34e67f946 100644 --- a/core/net/rpl/rpl-nbr-policy.c +++ b/core/net/rpl/rpl-nbr-policy.c @@ -68,6 +68,18 @@ static int num_free; static uip_ds6_nbr_t *worst_rank_nbr; /* the parent that has the worst rank */ static rpl_rank_t worst_rank; /*---------------------------------------------------------------------------*/ +#if DEBUG == DEBUG_FULL +static void update_nbr(void); +static struct ctimer periodic_timer; +static int timer_init = 0; +static void +handle_periodic_timer(void *ptr) +{ + update_nbr(); + ctimer_restart(&periodic_timer); +} +#endif /* DEBUG == DEBUG_FULL */ +/*---------------------------------------------------------------------------*/ static void update_nbr(void) { @@ -77,6 +89,14 @@ update_nbr(void) int is_used; rpl_rank_t rank; +#if DEBUG == DEBUG_FULL + if(!timer_init) { + timer_init = 1; + ctimer_set(&periodic_timer, 60 * CLOCK_SECOND, + &handle_periodic_timer, NULL); + } +#endif /* DEBUG == DEBUG_FULL */ + worst_rank = 0; worst_rank_nbr = NULL; num_used = 0; From 60dc6503e585e5833410e308d3493052577f9a3b Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Mon, 24 Aug 2015 15:10:14 +0200 Subject: [PATCH 111/374] disabled DAO ACK and configured for only one DAG per instance to save memory for er-example --- examples/er-rest-example/project-conf.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/examples/er-rest-example/project-conf.h b/examples/er-rest-example/project-conf.h index 53662619a..3d894a5d4 100644 --- a/examples/er-rest-example/project-conf.h +++ b/examples/er-rest-example/project-conf.h @@ -60,6 +60,9 @@ #undef NETSTACK_CONF_RDC #define NETSTACK_CONF_RDC nullrdc_driver +#undef RPL_CONF_MAX_DAG_PER_INSTANCE +#define RPL_CONF_MAX_DAG_PER_INSTANCE 1 + /* Disabling TCP on CoAP nodes. */ #undef UIP_CONF_TCP #define UIP_CONF_TCP 0 @@ -93,6 +96,10 @@ #undef COAP_PROXY_OPTION_PROCESSING #define COAP_PROXY_OPTION_PROCESSING 0 +/* Turn of DAO ACK to make code smaller */ +#undef RPL_CONF_WITH_DAO_ACK +#define RPL_CONF_WITH_DAO_ACK 0 + /* Enable client-side support for COAP observe */ #define COAP_OBSERVE_CLIENT 1 #endif /* __PROJECT_ERBIUM_CONF_H__ */ From 1d92359e72adc44ec32e0e8a9987fd2a6b27ffb7 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Mon, 24 Aug 2015 15:27:38 +0200 Subject: [PATCH 112/374] Replaced MRHof with OF-0 for getting code-size down for er-example --- examples/er-rest-example/project-conf.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/er-rest-example/project-conf.h b/examples/er-rest-example/project-conf.h index 3d894a5d4..adcb75ee1 100644 --- a/examples/er-rest-example/project-conf.h +++ b/examples/er-rest-example/project-conf.h @@ -100,6 +100,9 @@ #undef RPL_CONF_WITH_DAO_ACK #define RPL_CONF_WITH_DAO_ACK 0 +#undef RPL_CONF_OF +#define RPL_CONF_OF rpl_of0 + /* Enable client-side support for COAP observe */ #define COAP_OBSERVE_CLIENT 1 #endif /* __PROJECT_ERBIUM_CONF_H__ */ From 37c5f741e91b1f1ab5fe6f5089dcc442009ce5a0 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Mon, 24 Aug 2015 16:22:07 +0200 Subject: [PATCH 113/374] removed viztool usage of learned-from routing state that was removed --- platform/cc2530dk/viztool.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/platform/cc2530dk/viztool.c b/platform/cc2530dk/viztool.c index e6b2fbed3..1901e9f74 100644 --- a/platform/cc2530dk/viztool.c +++ b/platform/cc2530dk/viztool.c @@ -127,8 +127,8 @@ process_request() CC_NON_BANKED if(rt != NULL) { entry_size = sizeof(i) + sizeof(rt->ipaddr) + sizeof(rt->length) - + sizeof(rt->state.lifetime) - + sizeof(rt->state.learned_from); + + sizeof(rt->state.lifetime); + /* + sizeof(rt->state.learned_from); */ memcpy(buf + len, &i, sizeof(i)); len += sizeof(i); @@ -147,11 +147,11 @@ process_request() CC_NON_BANKED len += sizeof(flip); PRINTF(" - %08lx", rt->state.lifetime); - memcpy(buf + len, &rt->state.learned_from, - sizeof(rt->state.learned_from)); - len += sizeof(rt->state.learned_from); + /* memcpy(buf + len, &rt->state.learned_from, */ + /* sizeof(rt->state.learned_from)); */ + /* len += sizeof(rt->state.learned_from); */ - PRINTF(" - %02x [%u]\n", rt->state.learned_from, entry_size); + PRINTF(" - [%u]\n", entry_size); count++; left -= entry_size; From ad0e624d01637072d23bb4985f32fe5320b179ca Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Mon, 24 Aug 2015 20:49:50 +0200 Subject: [PATCH 114/374] increased number of routes in root node so that it can hold all routes in the simulation --- regression-tests/12-rpl/04-rpl-large-network.csc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression-tests/12-rpl/04-rpl-large-network.csc b/regression-tests/12-rpl/04-rpl-large-network.csc index 8b3ca0d8a..88d3774bf 100644 --- a/regression-tests/12-rpl/04-rpl-large-network.csc +++ b/regression-tests/12-rpl/04-rpl-large-network.csc @@ -1,3 +1,4 @@ +<<<<<<< 1d90b9290e293eedcb6451dd86c474ec168f688c [APPS_DIR]/mrm @@ -7058,4 +7059,3 @@ while(true) { 43 - From 01930d4a649b7628a6c4917ad3f4b31bacc31b2c Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Tue, 25 Aug 2015 09:05:14 +0200 Subject: [PATCH 115/374] changed default configuration of RPL route lifetime --- core/net/rpl/rpl-conf.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/net/rpl/rpl-conf.h b/core/net/rpl/rpl-conf.h index 831765974..baba6aa6c 100644 --- a/core/net/rpl/rpl-conf.h +++ b/core/net/rpl/rpl-conf.h @@ -118,7 +118,7 @@ #ifdef RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME #define RPL_DEFAULT_ROUTE_INFINITE_LIFETIME RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME #else -#define RPL_DEFAULT_ROUTE_INFINITE_LIFETIME 0 +#define RPL_DEFAULT_ROUTE_INFINITE_LIFETIME 1 #endif /* RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME */ /* @@ -200,7 +200,7 @@ * used in RPL lifetime values, in seconds. */ #ifndef RPL_CONF_DEFAULT_LIFETIME_UNIT -#define RPL_DEFAULT_LIFETIME_UNIT 0xffff +#define RPL_DEFAULT_LIFETIME_UNIT 0x60 #else #define RPL_DEFAULT_LIFETIME_UNIT RPL_CONF_DEFAULT_LIFETIME_UNIT #endif @@ -209,7 +209,7 @@ * Default route lifetime as a multiple of the lifetime unit. */ #ifndef RPL_CONF_DEFAULT_LIFETIME -#define RPL_DEFAULT_LIFETIME 0xff +#define RPL_DEFAULT_LIFETIME 0x30 #else #define RPL_DEFAULT_LIFETIME RPL_CONF_DEFAULT_LIFETIME #endif From be81d1d2c60e96d42a52894cec1dba4887e3da75 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Thu, 27 Aug 2015 20:07:13 +0200 Subject: [PATCH 116/374] added uip_clear_buf to avoid the risk of sending received packets --- core/net/rpl/rpl-icmp6.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index e043b87a2..5233c1fdd 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -1084,6 +1084,7 @@ dao_ack_input(void) instance = rpl_get_instance(instance_id); if(instance == NULL) { + uip_clear_buf(); return; } @@ -1092,6 +1093,7 @@ dao_ack_input(void) /* not a known instance - did we switch?? */ // PRINTF("RPL: Received a DAO ACK from a not joined instance: %d", // instance_id); + uip_clear_buf(); return; } @@ -1099,7 +1101,6 @@ dao_ack_input(void) sequence, instance->my_dao_seqno, status); PRINT6ADDR(&UIP_IP_BUF->srcipaddr); PRINTF("\n"); -#endif /* DEBUG */ if(sequence == instance->my_dao_seqno) { PRINTF("RPL: DAO %s for me!\n", status < 128 ? "ACK" : "NACK"); From 444015df675dcdab22ed5043c4085b3932bfb7d9 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Sun, 20 Sep 2015 21:02:30 +0200 Subject: [PATCH 117/374] refactored the rpl-nbr-policy to be called from nbr-table module --- core/contiki-default-conf.h | 7 ++ core/net/ipv6/uip-ds6-nbr.c | 6 +- core/net/ipv6/uip-ds6-nbr.h | 6 +- core/net/ipv6/uip-ds6-route.c | 3 +- core/net/llsec/noncoresec/noncoresec.c | 2 +- core/net/mac/phase.c | 2 +- core/net/nbr-table.c | 115 +++++++++++++++++-------- core/net/nbr-table.h | 13 ++- core/net/rpl/rpl-dag.c | 25 +++--- core/net/rpl/rpl-icmp6.c | 50 ++++++----- core/net/rpl/rpl-nbr-policy.c | 109 ++++++++++------------- core/net/rpl/rpl-private.h | 19 +--- core/net/rpl/rpl-timers.c | 2 + 13 files changed, 198 insertions(+), 161 deletions(-) diff --git a/core/contiki-default-conf.h b/core/contiki-default-conf.h index 0083f7e10..7b001bd58 100644 --- a/core/contiki-default-conf.h +++ b/core/contiki-default-conf.h @@ -148,6 +148,13 @@ #define UIP_CONF_IPV6_RPL 1 #endif /* UIP_CONF_IPV6_RPL */ +/* If RPL is enabled also enable the RPL NBR Policy */ +#if UIP_CONF_IPV6_RPL +#ifndef NBR_TABLE_FIND_REMOVABLE +#define NBR_TABLE_FIND_REMOVABLE rpl_nbr_policy_find_removable +#endif /* NBR_TABLE_FIND_REMOVABLE */ +#endif /* UIP_CONF_IPV6_RPL */ + /* UIP_CONF_MAX_ROUTES specifies the maximum number of routes that each node will be able to handle. */ #ifndef UIP_CONF_MAX_ROUTES diff --git a/core/net/ipv6/uip-ds6-nbr.c b/core/net/ipv6/uip-ds6-nbr.c index 5905993a5..b8666a14a 100644 --- a/core/net/ipv6/uip-ds6-nbr.c +++ b/core/net/ipv6/uip-ds6-nbr.c @@ -79,9 +79,11 @@ uip_ds6_neighbors_init(void) /*---------------------------------------------------------------------------*/ uip_ds6_nbr_t * uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr, - uint8_t isrouter, uint8_t state) + uint8_t isrouter, uint8_t state, nbr_table_reason_t reason, + void *data) { - uip_ds6_nbr_t *nbr = nbr_table_add_lladdr(ds6_neighbors, (linkaddr_t*)lladdr); + uip_ds6_nbr_t *nbr = nbr_table_add_lladdr(ds6_neighbors, (linkaddr_t*)lladdr + ,reason, data); if(nbr) { uip_ipaddr_copy(&nbr->ipaddr, ipaddr); #if UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER diff --git a/core/net/ipv6/uip-ds6-nbr.h b/core/net/ipv6/uip-ds6-nbr.h index b0dd84d4a..2f3a51d28 100644 --- a/core/net/ipv6/uip-ds6-nbr.h +++ b/core/net/ipv6/uip-ds6-nbr.h @@ -86,8 +86,10 @@ typedef struct uip_ds6_nbr { void uip_ds6_neighbors_init(void); /** \brief Neighbor Cache basic routines */ -uip_ds6_nbr_t *uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr, - uint8_t isrouter, uint8_t state); +uip_ds6_nbr_t *uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, + const uip_lladdr_t *lladdr, + uint8_t isrouter, uint8_t state, + nbr_table_reason_t reason, void *data); int uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr); const uip_lladdr_t *uip_ds6_nbr_get_ll(const uip_ds6_nbr_t *nbr); const uip_ipaddr_t *uip_ds6_nbr_get_ipaddr(const uip_ds6_nbr_t *nbr); diff --git a/core/net/ipv6/uip-ds6-route.c b/core/net/ipv6/uip-ds6-route.c index 3113986a1..21ce38f64 100644 --- a/core/net/ipv6/uip-ds6-route.c +++ b/core/net/ipv6/uip-ds6-route.c @@ -348,7 +348,8 @@ uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, initialize this pointer with the list of routing entries that are attached to this neighbor. */ routes = nbr_table_add_lladdr(nbr_routes, - (linkaddr_t *)nexthop_lladdr); + (linkaddr_t *)nexthop_lladdr, + NBR_TABLE_REASON_ROUTE, NULL); if(routes == NULL) { /* This should not happen, as we explicitly deallocated one route table entry above. */ diff --git a/core/net/llsec/noncoresec/noncoresec.c b/core/net/llsec/noncoresec/noncoresec.c index e18a7d734..860f7e613 100644 --- a/core/net/llsec/noncoresec/noncoresec.c +++ b/core/net/llsec/noncoresec/noncoresec.c @@ -188,7 +188,7 @@ parse(void) info = nbr_table_get_from_lladdr(anti_replay_table, sender); if(!info) { - info = nbr_table_add_lladdr(anti_replay_table, sender); + info = nbr_table_add_lladdr(anti_replay_table, sender, NBR_TABLE_REASON_LLSEC, NULL); if(!info) { PRINTF("noncoresec: could not get nbr_table_item\n"); return FRAMER_FAILED; diff --git a/core/net/mac/phase.c b/core/net/mac/phase.c index 47b7e7cf3..d7ded2428 100644 --- a/core/net/mac/phase.c +++ b/core/net/mac/phase.c @@ -122,7 +122,7 @@ phase_update(const linkaddr_t *neighbor, rtimer_clock_t time, } else { /* No matching phase was found, so we allocate a new one. */ if(mac_status == MAC_TX_OK && e == NULL) { - e = nbr_table_add_lladdr(nbr_phase, neighbor); + e = nbr_table_add_lladdr(nbr_phase, neighbor, NBR_TABLE_REASON_MAC, NULL); if(e) { e->time = time; #if PHASE_DRIFT_CORRECT diff --git a/core/net/nbr-table.c b/core/net/nbr-table.c index 6b990a020..42597c598 100644 --- a/core/net/nbr-table.c +++ b/core/net/nbr-table.c @@ -47,11 +47,20 @@ static void handle_periodic_timer(void *ptr); static struct ctimer periodic_timer; static uint8_t initialized = 0; +static void print_table(); #define PRINTF(...) printf(__VA_ARGS__) #else #define PRINTF(...) #endif +/* This is the callback function that will be called when there is a + * nbr-policy active + **/ +#ifdef NBR_TABLE_FIND_REMOVABLE +const linkaddr_t *NBR_TABLE_FIND_REMOVABLE(nbr_table_reason_t reason, void *data); +#endif /* NBR_TABLE_FIND_REMOVABLE */ + + /* List of link-layer addresses of the neighbors, used as key in the tables */ typedef struct nbr_table_key { struct nbr_table_key *next; @@ -170,7 +179,7 @@ nbr_set_bit(uint8_t *bitmap, nbr_table_t *table, nbr_table_item_t *item, int val } /*---------------------------------------------------------------------------*/ static nbr_table_key_t * -nbr_table_allocate(void) +nbr_table_allocate(nbr_table_reason_t reason, void *data) { nbr_table_key_t *key; int least_used_count = 0; @@ -179,39 +188,66 @@ nbr_table_allocate(void) key = memb_alloc(&neighbor_addr_mem); if(key != NULL) { return key; - } else { /* No more space, try to free a neighbor. - * The replacement policy is the following: remove neighbor that is: - * (1) not locked - * (2) used by fewest tables - * (3) oldest (the list is ordered by insertion time) - * */ - /* Get item from first key */ - key = list_head(nbr_table_keys); - while(key != NULL) { - int item_index = index_from_key(key); - int locked = locked_map[item_index]; - /* Never delete a locked item */ - if(!locked) { - int used = used_map[item_index]; - int used_count = 0; - /* Count how many tables are using this item */ - while(used != 0) { - if((used & 1) == 1) { - used_count++; - } - used >>= 1; - } - /* Find least used item */ - if(least_used_key == NULL || used_count < least_used_count) { - least_used_key = key; - least_used_count = used_count; - if(used_count == 0) { /* We won't find any least used item */ - break; - } - } + } else { +#ifdef NBR_TABLE_FIND_REMOVABLE + const linkaddr_t *lladdr; + lladdr = NBR_TABLE_FIND_REMOVABLE(reason, data); + if(lladdr == NULL) { + /* Nothing found that can be deleted - return NULL to indicate failure */ + PRINTF("*** Not removing entry to allocate new\n"); + return NULL; + } else { + /* used least_used_key to indicate what is the least useful entry */ + int index; + int locked; + if((index = index_from_lladdr(lladdr)) != -1) { + least_used_key = key_from_index(index); + locked = locked_map[index]; + } + /* Allow delete of locked item? */ + if(least_used_key != NULL && locked) { + PRINTF("Deleting locked item!\n"); + locked_map[index] = 0; } - key = list_item_next(key); } +#endif /* NBR_TABLE_FIND_REMOVABLE */ + + if(least_used_key == NULL) { + /* No more space, try to free a neighbor. + * The replacement policy is the following: remove neighbor that is: + * (1) not locked + * (2) used by fewest tables + * (3) oldest (the list is ordered by insertion time) + * */ + /* Get item from first key */ + key = list_head(nbr_table_keys); + while(key != NULL) { + int item_index = index_from_key(key); + int locked = locked_map[item_index]; + /* Never delete a locked item */ + if(!locked) { + int used = used_map[item_index]; + int used_count = 0; + /* Count how many tables are using this item */ + while(used != 0) { + if((used & 1) == 1) { + used_count++; + } + used >>= 1; + } + /* Find least used item */ + if(least_used_key == NULL || used_count < least_used_count) { + least_used_key = key; + least_used_count = used_count; + if(used_count == 0) { /* We won't find any least used item */ + break; + } + } + } + key = list_item_next(key); + } + } + if(least_used_key == NULL) { /* We haven't found any unlocked item, allocation fails */ return NULL; @@ -289,7 +325,7 @@ nbr_table_next(nbr_table_t *table, nbr_table_item_t *item) /*---------------------------------------------------------------------------*/ /* Add a neighbor indexed with its link-layer address */ nbr_table_item_t * -nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr) +nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr, nbr_table_reason_t reason, void *data) { int index; nbr_table_item_t *item; @@ -303,7 +339,7 @@ nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr) if((index = index_from_lladdr(lladdr)) == -1) { /* Neighbor not yet in table, let's try to allocate one */ - key = nbr_table_allocate(); + key = nbr_table_allocate(reason, data); /* No space available for new entry */ if(key == NULL) { @@ -327,6 +363,9 @@ nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr) memset(item, 0, table->item_size); nbr_set_bit(used_map, table, item, 1); +#if DEBUG + print_table(); +#endif return item; } /*---------------------------------------------------------------------------*/ @@ -379,7 +418,7 @@ nbr_table_get_lladdr(nbr_table_t *table, const void *item) /*---------------------------------------------------------------------------*/ #if DEBUG static void -handle_periodic_timer(void *ptr) +print_table() { int i, j; /* Printout all neighbors and which tables they are used in */ @@ -394,6 +433,12 @@ handle_periodic_timer(void *ptr) PRINTF("\n"); } } +} +/*---------------------------------------------------------------------------*/ +static void +handle_periodic_timer(void *ptr) +{ + print_table(); ctimer_reset(&periodic_timer); } #endif diff --git a/core/net/nbr-table.h b/core/net/nbr-table.h index 516901fe3..cc58c2f80 100644 --- a/core/net/nbr-table.h +++ b/core/net/nbr-table.h @@ -75,6 +75,17 @@ typedef struct nbr_table { /** \brief Declaration of non-static neighbor tables */ #define NBR_TABLE_DECLARE(name) extern nbr_table_t *name +typedef enum { + NBR_TABLE_REASON_UNDEFINED, + NBR_TABLE_REASON_RPL_DIO, + NBR_TABLE_REASON_RPL_DAO, + NBR_TABLE_REASON_RPL_DIS, + NBR_TABLE_REASON_ROUTE, + NBR_TABLE_REASON_IPV6_ND, + NBR_TABLE_REASON_MAC, + NBR_TABLE_REASON_LLSEC +} nbr_table_reason_t; + /** \name Neighbor tables: register and loop through table elements */ /** @{ */ int nbr_table_register(nbr_table_t *table, nbr_table_callback *callback); @@ -84,7 +95,7 @@ nbr_table_item_t *nbr_table_next(nbr_table_t *table, nbr_table_item_t *item); /** \name Neighbor tables: add and get data */ /** @{ */ -nbr_table_item_t *nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr); +nbr_table_item_t *nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr, nbr_table_reason_t reason, void *data); nbr_table_item_t *nbr_table_get_from_lladdr(nbr_table_t *table, const linkaddr_t *lladdr); /** @} */ diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 79f83a84e..9d32c2773 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -634,8 +634,9 @@ rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr) PRINT6ADDR(addr); PRINTF("\n"); if(lladdr != NULL) { - /* Add parent in rpl_parents */ - p = nbr_table_add_lladdr(rpl_parents, (linkaddr_t *)lladdr); + /* Add parent in rpl_parents - again this is due to DIO */ + p = nbr_table_add_lladdr(rpl_parents, (linkaddr_t *)lladdr, + NBR_TABLE_REASON_RPL_DIO, dio); if(p == NULL) { PRINTF("RPL: rpl_add_parent p NULL\n"); } else { @@ -1028,7 +1029,7 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio) rpl_set_default_route(instance, from); if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES) { - rpl_schedule_dao_immediately(instance); + rpl_schedule_dao(instance); } else { PRINTF("RPL: The DIO does not meet the prerequisites for sending a DAO\n"); } @@ -1255,18 +1256,14 @@ rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p) static int add_nbr_from_dio(uip_ipaddr_t *from, rpl_dio_t *dio) { - /* check if it is ok to add this nbr based on this DIO */ - if(RPL_NBR_POLICY.check_add_from_dio(from, dio)) { - /* add this to the neighbor cache if not already there */ - if(rpl_icmp6_update_nbr_table(from) == NULL) { - PRINTF("RPL: Out of memory, dropping DIO from "); - PRINT6ADDR(from); - PRINTF("\n"); - return 0; - } - return 1; + /* add this to the neighbor cache if not already there */ + if(rpl_icmp6_update_nbr_table(from, NBR_TABLE_REASON_RPL_DIO, dio) == NULL) { + PRINTF("RPL: Out of memory, dropping DIO from "); + PRINT6ADDR(from); + PRINTF("\n"); + return 0; } - return 0; + return 1; } /*---------------------------------------------------------------------------*/ void diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 5233c1fdd..83dd71897 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -182,14 +182,14 @@ set16(uint8_t *buffer, int pos, uint16_t value) } /*---------------------------------------------------------------------------*/ uip_ds6_nbr_t * -rpl_icmp6_update_nbr_table(uip_ipaddr_t *from) +rpl_icmp6_update_nbr_table(uip_ipaddr_t *from, nbr_table_reason_t reason, void *data) { uip_ds6_nbr_t *nbr; if((nbr = uip_ds6_nbr_lookup(from)) == NULL) { if((nbr = uip_ds6_nbr_add(from, (uip_lladdr_t *) packetbuf_addr(PACKETBUF_ADDR_SENDER), - 0, NBR_REACHABLE)) != NULL) { + 0, NBR_REACHABLE, reason, data)) != NULL) { PRINTF("RPL: Neighbor added to neighbor cache "); PRINT6ADDR(from); PRINTF(", "); @@ -231,19 +231,18 @@ dis_input(void) } else { #endif /* !RPL_LEAF_ONLY */ /* Check if this neighbor should be added according to the policy. */ - if(RPL_NBR_POLICY.check_add_from_dis(&UIP_IP_BUF->srcipaddr)) { - /* Add this to the neighbor cache if not already there */ - if(rpl_icmp6_update_nbr_table(&UIP_IP_BUF->srcipaddr) == NULL) { - PRINTF("RPL: Out of Memory, not sending unicast DIO, DIS from "); - PRINT6ADDR(&UIP_IP_BUF->srcipaddr); - PRINTF(", "); - PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); - PRINTF("\n"); - return; - } - PRINTF("RPL: Unicast DIS, reply to sender\n"); - dio_output(instance, &UIP_IP_BUF->srcipaddr); - } + if(rpl_icmp6_update_nbr_table(&UIP_IP_BUF->srcipaddr, + NBR_TABLE_REASON_RPL_DIS, NULL) == NULL) { + PRINTF("RPL: Out of Memory, not sending unicast DIO, DIS from "); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF(", "); + PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); + PRINTF("\n"); + } else { + PRINTF("RPL: Unicast DIS, reply to sender\n"); + dio_output(instance, &UIP_IP_BUF->srcipaddr); + } + /* } */ } } } @@ -806,18 +805,18 @@ dao_input(void) PRINTF("RPL: adding DAO route\n"); - /* Check if we should add another neighbor based on DAO. */ - if(!RPL_NBR_POLICY.check_add_from_dao(&dao_sender_addr)) { - /* Do not add the neighbor. */ - return; - } /* Update and add neighbor - if no room - fail. */ - if((nbr = rpl_icmp6_update_nbr_table(&dao_sender_addr)) == NULL) { + if((nbr = rpl_icmp6_update_nbr_table(&dao_sender_addr, NBR_TABLE_REASON_RPL_DAO, NULL)) == NULL) { PRINTF("RPL: Out of Memory, dropping DAO from "); PRINT6ADDR(&dao_sender_addr); PRINTF(", "); PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); PRINTF("\n"); + if(flags & RPL_DAO_K_FLAG) { + /* signal the failure to add the node */ + dao_ack_output(instance, &dao_sender_addr, sequence, + RPL_DAO_ACK_UNABLE_TO_ACCEPT); + } goto discard; } @@ -931,7 +930,9 @@ handle_dao_retransmission(void *ptr) return; } - ctimer_set(&instance->dao_retransmit_timer, RPL_DAO_RETRANSMISSION_TIMEOUT, + ctimer_set(&instance->dao_retransmit_timer, + RPL_DAO_RETRANSMISSION_TIMEOUT / 2 + + (random_rand() % (RPL_DAO_RETRANSMISSION_TIMEOUT / 2)), handle_dao_retransmission, parent); instance->my_dao_transmissions++; @@ -1079,6 +1080,7 @@ dao_ack_input(void) buffer = UIP_ICMP_PAYLOAD; + instance_id = buffer[0]; sequence = buffer[2]; status = buffer[3]; @@ -1131,7 +1133,9 @@ dao_ack_input(void) if(nexthop == NULL) { PRINTF("No next hop to fwd DAO ACK to\n"); } else { - PRINTF("Fwd DAO ACK\n"); + PRINTF("Fwd DAO ACK to:"); + PRINT6ADDR(nexthop); + PRINTF("\n"); buffer[2] = re->state.dao_seqno_in; uip_icmp6_send(nexthop, ICMP6_RPL, RPL_CODE_DAO_ACK, 4); } diff --git a/core/net/rpl/rpl-nbr-policy.c b/core/net/rpl/rpl-nbr-policy.c index 34e67f946..51d0df8db 100644 --- a/core/net/rpl/rpl-nbr-policy.c +++ b/core/net/rpl/rpl-nbr-policy.c @@ -49,7 +49,7 @@ #include "net/ipv6/uip-ds6-nbr.h" #include "net/ipv6/uip-ds6-route.h" -#define DEBUG DEBUG_NONE +#define DEBUG DEBUG_FULL #include "net/ip/uip-debug.h" /* @@ -58,14 +58,18 @@ * - max X children (nexthops) * - max Y "best parents" * => at least MAX_NBRS - (Y + X + 1) free slots for other. + * + * NOTE: this policy assumes that all neighbors end up being IPv6 + * neighbors and are not only MAC neighbors. */ #define MAX_CHILDREN (NBR_TABLE_MAX_NEIGHBORS - 3) +#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) static int num_parents; /* any node that are possible parents */ static int num_children; /* all children that we have as nexthop */ static int num_free; -static uip_ds6_nbr_t *worst_rank_nbr; /* the parent that has the worst rank */ +static linkaddr_t *worst_rank_nbr; /* the parent that has the worst rank */ static rpl_rank_t worst_rank; /*---------------------------------------------------------------------------*/ #if DEBUG == DEBUG_FULL @@ -124,8 +128,12 @@ update_nbr(void) parent->dag->instance != NULL && (rank = parent->dag->instance->of->calculate_rank(parent, 0)) > worst_rank) { /* This is the worst-rank neighbor - this is a good candidate for removal */ - worst_rank = rank; - worst_rank_nbr = nbr; + if(uip_ds6_route_is_nexthop((uip_lladdr_t *)lladdr) == 0) { + worst_rank = rank; + worst_rank_nbr = lladdr; + } else { + printf("*** Can not use this as worst rank as it is a next hop\n"); + } } } @@ -138,10 +146,9 @@ update_nbr(void) if(is_used == 0) { /* This neighbor is neither parent or child and can be safely removed */ - worst_rank_nbr = nbr; + worst_rank_nbr = lladdr; worst_rank = INFINITE_RANK; } else if(is_used > 1) { - /* Both parent and child - this should never happen! */ PRINTF("NBR-POLICY: *** Neighbor is both child and candidate parent: "); PRINTLLADDR((uip_lladdr_t *)lladdr); PRINTF("\n"); @@ -157,67 +164,36 @@ update_nbr(void) num_free, num_children, num_parents, uip_ds6_route_num_routes()); } /*---------------------------------------------------------------------------*/ -static int -remove_worst_nbr(void) -{ - /* we assume that it is possible to remove the worst parent at the moment */ - if(worst_rank_nbr != NULL) { - PRINTF("Removing worst ranked nbr "); - PRINTLLADDR((uip_lladdr_t*)nbr_table_get_lladdr(ds6_neighbors, worst_rank_nbr)); - PRINTF(" with rank %d\n", worst_rank); - if(uip_ds6_nbr_rm(worst_rank_nbr)) { - worst_rank_nbr = NULL; - return 1; - } - PRINTF("FAILED to remove worst ranked nbr!\n"); - return 0; - } - PRINTF("FAILED to remove worst rank nbr - no found\n"); - return 0; -} -/*---------------------------------------------------------------------------*/ /* Called whenever we get a unicast DIS - e.g. someone that already have this node in its table - since it is a unicast */ -static int -check_add_from_dis(uip_ipaddr_t *from) +const linkaddr_t * +find_removable_dis(uip_ipaddr_t *from) { - /* do a lookup to see if it is alread there - then allow add/update */ - if(uip_ds6_nbr_lookup(from)) { - return 1; - } update_nbr(); if(num_free > 0) { - return 1; + printf("num-free > 0 = %d", num_free); + printf("**** Should remove unused elements but can not... \n"); + /* return 1; */ } if(num_children < MAX_CHILDREN) { - return remove_worst_nbr(); + return worst_rank_nbr; } - return 0; + return NULL; } /*---------------------------------------------------------------------------*/ -static int -check_add_from_dio(uip_ipaddr_t *from, rpl_dio_t *dio) +const linkaddr_t * +find_removable_dio(uip_ipaddr_t *from, rpl_dio_t *dio) { rpl_instance_t *instance; rpl_rank_t rank; - /* Do a lookup to see if it is already there - then allow add/update. */ - if(uip_ds6_nbr_lookup(from)) { - return 1; - } - update_nbr(); - /* If there is room for this neighbor just add it. */ - if(num_free > 0) { - return 1; - } - instance = rpl_get_instance(dio->instance_id); if(instance == NULL || instance->current_dag == NULL) { PRINTF("Did not find instance id: %d\n", dio->instance_id); - return 0; + return NULL; } /* Add the new neighbor only if it is better than the preferred parent. */ @@ -227,38 +203,43 @@ check_add_from_dio(uip_ipaddr_t *from, rpl_dio_t *dio) PRINTF("Found better neighbor %d < %d - add to cache...\n", rank, worst_rank); - return remove_worst_nbr(); + return worst_rank_nbr; } PRINTF("Found worse neighbor with new %d and old %d - NOT add to cache.\n", rank, worst_rank); - return 0; + return NULL; } /*---------------------------------------------------------------------------*/ -static int -check_add_from_dao(uip_ipaddr_t *from) +const linkaddr_t * +find_removable_dao(uip_ipaddr_t *from) { - /* Do a lookup to see if it is alread there - then allow add/update. */ - if(uip_ds6_nbr_lookup(from)) { - return 1; - } - update_nbr(); /* Check if this DAO sender is not yet neighbor and there is already too many children. */ if(num_children >= MAX_CHILDREN) { PRINTF("Can not add another child - already at max.\n"); - return 0; + return NULL; } - - return 1; + /* remove the worst ranked nbr */ + return worst_rank_nbr; } /*---------------------------------------------------------------------------*/ -const struct nbr_policy rpl_nbr_policy = { - check_add_from_dis, - check_add_from_dio, - check_add_from_dao -}; +const linkaddr_t * +rpl_nbr_policy_find_removable(nbr_table_reason_t reason,void * data) { + /* When we get the DIO/DAO/DIS we know that UIP contains the + incoming packet */ + switch(reason) { + case NBR_TABLE_REASON_RPL_DIO: + return find_removable_dio(&UIP_IP_BUF->srcipaddr, data); + case NBR_TABLE_REASON_RPL_DAO: + return find_removable_dao(&UIP_IP_BUF->srcipaddr); + case NBR_TABLE_REASON_RPL_DIS: + return find_removable_dis(&UIP_IP_BUF->srcipaddr); + default: + return NULL; + } +} /*---------------------------------------------------------------------------*/ /** @}*/ diff --git a/core/net/rpl/rpl-private.h b/core/net/rpl/rpl-private.h index 0eecca0e0..017efb474 100644 --- a/core/net/rpl/rpl-private.h +++ b/core/net/rpl/rpl-private.h @@ -270,22 +270,6 @@ typedef struct rpl_stats rpl_stats_t; extern rpl_stats_t rpl_stats; #endif -struct nbr_policy { - /** check if it is ok to add a nbr via UC DIS - positive => ok */ - int (* check_add_from_dis)(uip_ipaddr_t *from); - int (* check_add_from_dio)(uip_ipaddr_t *from, rpl_dio_t *dio); - int (* check_add_from_dao)(uip_ipaddr_t *from); -}; - - -#ifdef RPL_CONF_NBR_POLICY -#define RPL_NBR_POLICY RPL_CONF_NBR_POLICY -#else /* RPL_CONF_NBR_POLICY */ -#define RPL_NBR_POLICY rpl_nbr_policy -#endif /* RPL_CONF_NBR_POLICY */ - -extern const struct nbr_policy RPL_NBR_POLICY; - /*---------------------------------------------------------------------------*/ /* RPL macros. */ @@ -307,7 +291,8 @@ void dao_output(rpl_parent_t *, uint8_t lifetime); void dao_output_target(rpl_parent_t *, uip_ipaddr_t *, uint8_t lifetime); void dao_ack_output(rpl_instance_t *, uip_ipaddr_t *, uint8_t, uint8_t); void rpl_icmp6_register_handlers(void); -uip_ds6_nbr_t *rpl_icmp6_update_nbr_table(uip_ipaddr_t *from); +uip_ds6_nbr_t *rpl_icmp6_update_nbr_table(uip_ipaddr_t *from, + nbr_table_reason_t r, void *data); /* RPL logic functions. */ void rpl_join_dag(uip_ipaddr_t *from, rpl_dio_t *dio); diff --git a/core/net/rpl/rpl-timers.c b/core/net/rpl/rpl-timers.c index ac993691d..158f5fd74 100644 --- a/core/net/rpl/rpl-timers.c +++ b/core/net/rpl/rpl-timers.c @@ -224,6 +224,8 @@ set_dao_lifetime_timer(rpl_instance_t *instance) expiration_time = (clock_time_t)instance->default_lifetime * (clock_time_t)instance->lifetime_unit * CLOCK_SECOND / 2; + /* make the time for the re registration be betwen 1/2 - 3/4 of lifetime */ + expiration_time = expiration_time + (random_rand() % (expiration_time / 2)); PRINTF("RPL: Scheduling DAO lifetime timer %u ticks in the future\n", (unsigned)expiration_time); ctimer_set(&instance->dao_lifetime_timer, expiration_time, From 4246a8fbe63231518373325083a138b7c49e7581 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Sun, 20 Sep 2015 21:17:32 +0200 Subject: [PATCH 118/374] updated more nbr_add calls --- core/net/ip/tcpip.c | 2 +- core/net/ipv6/uip-nd6.c | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/core/net/ip/tcpip.c b/core/net/ip/tcpip.c index 00607ba14..09d182db3 100644 --- a/core/net/ip/tcpip.c +++ b/core/net/ip/tcpip.c @@ -644,7 +644,7 @@ tcpip_ipv6_output(void) nbr = uip_ds6_nbr_lookup(nexthop); if(nbr == NULL) { #if UIP_ND6_SEND_NA - if((nbr = uip_ds6_nbr_add(nexthop, NULL, 0, NBR_INCOMPLETE)) == NULL) { + if((nbr = uip_ds6_nbr_add(nexthop, NULL, 0, NBR_INCOMPLETE, NBR_TABLE_REASON_IPV6_ND, NULL)) == NULL) { uip_clear_buf(); return; } else { diff --git a/core/net/ipv6/uip-nd6.c b/core/net/ipv6/uip-nd6.c index 143cfe369..ffad6260e 100644 --- a/core/net/ipv6/uip-nd6.c +++ b/core/net/ipv6/uip-nd6.c @@ -201,9 +201,8 @@ ns_input(void) #endif /*UIP_CONF_IPV6_CHECKS */ nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr); if(nbr == NULL) { - uip_lladdr_t lladdr_aligned; - extract_lladdr_aligned(&lladdr_aligned); - uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE); + uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, + 0, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL); } else { uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr); if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], @@ -634,14 +633,17 @@ rs_input(void) extract_lladdr_aligned(&lladdr_aligned); if((nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr)) == NULL) { /* we need to add the neighbor */ - uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE); + uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, + 0, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL); } else { /* If LL address changed, set neighbor state to stale */ if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], uip_ds6_nbr_get_ll(nbr), UIP_LLADDR_LEN) != 0) { uip_ds6_nbr_t nbr_data = *nbr; uip_ds6_nbr_rm(nbr); - nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE); + nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, + nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, 0, NBR_STALE, + NBR_TABLE_REASON_IPV6_ND, NULL); nbr->reachable = nbr_data.reachable; nbr->sendns = nbr_data.sendns; nbr->nscount = nbr_data.nscount; @@ -870,7 +872,8 @@ ra_input(void) if(nbr == NULL) { uip_lladdr_t lladdr_aligned; extract_lladdr_aligned(&lladdr_aligned); - nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 1, NBR_STALE); + nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 1, + NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL); } else { uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr); if(nbr->state == NBR_INCOMPLETE) { From baa8f3c6f5a1407c5b38059a5c5aba20153c9fa9 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Tue, 22 Sep 2015 20:13:31 +0200 Subject: [PATCH 119/374] minor fixes to the simulation files --- .../21-large-rpl/code/node/client.c | 20 ++++++-- .../21-large-rpl/code/router/router.c | 46 ++++++++++++++++++- 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/regression-tests/21-large-rpl/code/node/client.c b/regression-tests/21-large-rpl/code/node/client.c index 386f18529..3616c1aad 100644 --- a/regression-tests/21-large-rpl/code/node/client.c +++ b/regression-tests/21-large-rpl/code/node/client.c @@ -10,6 +10,7 @@ static struct http_socket s; static int bytes_received = 0; static int restarts; static struct ctimer reconnect_timer; +static int connect = 0; static void callback(struct http_socket *s, void *ptr, http_socket_event_t e, @@ -22,9 +23,9 @@ AUTOSTART_PROCESSES(&http_example_process); static void reconnect(void *dummy) { + printf("#A color=orange\n"); rpl_set_mode(RPL_MODE_MESH); - http_socket_get(&s, "http://www.contiki-os.org/", 0, 0, - callback, NULL); + connect = 1; } /*---------------------------------------------------------------------------*/ static void @@ -33,6 +34,8 @@ restart(void) int scale; restarts++; printf("restart %d\n", restarts); + rpl_set_mode(RPL_MODE_FEATHER); + printf("#A color=red\n"); scale = restarts; if(scale > 5) { @@ -62,6 +65,7 @@ callback(struct http_socket *s, void *ptr, if(bytes_received > 0) { printf("HTTP socket closed, %d bytes received\n", bytes_received); leds_off(LEDS_RED); + printf("#A color=blue\n"); rpl_set_mode(RPL_MODE_FEATHER); } else { restart(); @@ -72,6 +76,7 @@ callback(struct http_socket *s, void *ptr, } } /*---------------------------------------------------------------------------*/ + PROCESS_THREAD(http_example_process, ev, data) { static struct etimer et; @@ -88,14 +93,19 @@ PROCESS_THREAD(http_example_process, ev, data) PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); http_socket_init(&s); - http_socket_get(&s, "http://www.contiki-os.org/", 0, 0, - callback, NULL); + connect = 1; leds_on(LEDS_RED); restarts = 0; - etimer_set(&et, CLOCK_SECOND); + etimer_set(&et, CLOCK_SECOND * 5); while(1) { PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); etimer_reset(&et); + if(connect && rpl_has_downward_link()) { + printf("#A color=green\n"); + http_socket_get(&s, "http://www.contiki-os.org/", 0, 0, + callback, NULL); + connect = 0; + } } PROCESS_END(); diff --git a/regression-tests/21-large-rpl/code/router/router.c b/regression-tests/21-large-rpl/code/router/router.c index 844afdc1c..65882c36c 100644 --- a/regression-tests/21-large-rpl/code/router/router.c +++ b/regression-tests/21-large-rpl/code/router/router.c @@ -3,13 +3,23 @@ #include "ip64.h" #include "net/netstack.h" #include "net/rpl/rpl-dag-root.h" - +#include "net/rpl/rpl.h" +#include "net/ipv6/uip-ds6-route.h" +#include /*---------------------------------------------------------------------------*/ PROCESS(router_node_process, "Router node"); AUTOSTART_PROCESSES(&router_node_process); /*---------------------------------------------------------------------------*/ +uip_lladdr_t * uip_ds6_route_nexthop_lladdr(uip_ds6_route_t *route); + + PROCESS_THREAD(router_node_process, ev, data) { + uip_ipaddr_t *nexthop = NULL; + uip_ds6_defrt_t *defrt; + uip_ipaddr_t *ipaddr; + uip_ds6_route_t *r; + static struct etimer et; PROCESS_BEGIN(); /* Set us up as a RPL root node. */ @@ -18,9 +28,41 @@ PROCESS_THREAD(router_node_process, ev, data) /* Initialize the IP64 module so we'll start translating packets */ ip64_init(); + /* etimer_set(&et, CLOCK_SECOND * 60); */ + /* PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); */ + /* ... and do nothing more. */ while(1) { - PROCESS_WAIT_EVENT(); + etimer_set(&et, CLOCK_SECOND * 20); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + defrt = NULL; + if((ipaddr = uip_ds6_defrt_choose()) != NULL) { + defrt = uip_ds6_defrt_lookup(ipaddr); + } + if(defrt != NULL) { + printf("DefRT: :: -> %02d", defrt->ipaddr.u8[15]); + printf(" lt:%lu inf:%d\n", stimer_remaining(&defrt->lifetime), + defrt->isinfinite); + } else { + printf("DefRT: :: -> NULL\n"); + } + + if(uip_ds6_route_head() != NULL) { + printf("found head\n"); + for(r = uip_ds6_route_head(); + r != NULL; + r = uip_ds6_route_next(r)) { + nexthop = uip_ds6_route_nexthop(r); + if(nexthop != NULL) { + printf("Route: %02d -> %02d", r->ipaddr.u8[15], nexthop->u8[15]); + } else { + //printf("Route: %p %02d -> ? nbr-routes:%p", r, r->ipaddr.u8[15], + //r->neighbor_routes); + } + printf(" lt:%lu\n", r->state.lifetime); + } + } } PROCESS_END(); From ee65a3982cb8420ab5cde4a35fbf3d2a7c89c9c9 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Tue, 22 Sep 2015 20:14:29 +0200 Subject: [PATCH 120/374] configure short routing lifetime in the RPL ROOT / router --- regression-tests/21-large-rpl/code/router/project-conf.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/regression-tests/21-large-rpl/code/router/project-conf.h b/regression-tests/21-large-rpl/code/router/project-conf.h index eb0b0b1a7..bec41cd5e 100644 --- a/regression-tests/21-large-rpl/code/router/project-conf.h +++ b/regression-tests/21-large-rpl/code/router/project-conf.h @@ -7,5 +7,5 @@ #undef NBR_TABLE_CONF_MAX_NEIGHBORS #define NBR_TABLE_CONF_MAX_NEIGHBORS 8 -/*#define RPL_CONF_DEFAULT_LIFETIME_UNIT 10 - #define RPL_CONF_DEFAULT_LIFETIME 10*/ +#define RPL_CONF_DEFAULT_LIFETIME_UNIT 60 +#define RPL_CONF_DEFAULT_LIFETIME 5 From 1fcef0f90df20a19dd386aef6ce83f2a5beaa901 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Tue, 22 Sep 2015 21:01:55 +0200 Subject: [PATCH 121/374] added function for checking downward route and added configuration for DAO NACK repair - default off --- core/net/rpl/rpl-conf.h | 11 +++++++++++ core/net/rpl/rpl-dag.c | 6 ++++++ core/net/rpl/rpl-icmp6.c | 26 ++++++++++++++++++++++++++ core/net/rpl/rpl-nbr-policy.c | 4 ++-- core/net/rpl/rpl.h | 8 ++++++++ 5 files changed, 53 insertions(+), 2 deletions(-) diff --git a/core/net/rpl/rpl-conf.h b/core/net/rpl/rpl-conf.h index baba6aa6c..6822ff550 100644 --- a/core/net/rpl/rpl-conf.h +++ b/core/net/rpl/rpl-conf.h @@ -245,6 +245,17 @@ #define RPL_WITH_DAO_ACK 1 #endif /* RPL_CONF_WITH_DAO_ACK */ +/* + * RPL REPAIR ON DAO NACK. When enabled, DAO NACK will trigger a local + * repair in order to quickly find a new parent to send DAO's to. + * NOTE: this is too agressive in some cases so use with care. + * */ +#ifdef RPL_CONF_RPL_REPAIR_ON_DAO_NACK +#define RPL_REPAIR_ON_DAO_NACK RPL_CONF_RPL_REPAIR_ON_DAO_NACK +#else +#define RPL_REPAIR_ON_DAO_NACK 0 +#endif /* RPL_CONF_RPL_REPAIR_ON_DAO_NACK */ + /* * Setting the DIO_REFRESH_DAO_ROUTES will make RPL always increase * the DTSN (Destination Advertisement Trigger Sequence Number) when diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 9d32c2773..034678ff5 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -1156,6 +1156,9 @@ global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio) RPL_STAT(rpl_stats.global_repairs++); } + +void rpl_set_downward_link(uint8_t link); + /*---------------------------------------------------------------------------*/ void rpl_local_repair(rpl_instance_t *instance) @@ -1174,6 +1177,9 @@ rpl_local_repair(rpl_instance_t *instance) } } + /* no downward link anymore */ + rpl_set_downward_link(0); + rpl_reset_dio_timer(instance); /* Request refresh of DAO registrations next DIO */ RPL_LOLLIPOP_INCREMENT(instance->dtsn_out); diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 83dd71897..af7a05d67 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -89,6 +89,7 @@ void RPL_DEBUG_DAO_OUTPUT(rpl_parent_t *); #endif static uint8_t dao_sequence = RPL_LOLLIPOP_INIT; +static uint8_t downward = 0; extern rpl_of_t RPL_OF; @@ -102,6 +103,19 @@ UIP_ICMP6_HANDLER(dio_handler, ICMP6_RPL, RPL_CODE_DIO, dio_input); UIP_ICMP6_HANDLER(dao_handler, ICMP6_RPL, RPL_CODE_DAO, dao_input); UIP_ICMP6_HANDLER(dao_ack_handler, ICMP6_RPL, RPL_CODE_DAO_ACK, dao_ack_input); /*---------------------------------------------------------------------------*/ + +void +rpl_set_downward_link(uint8_t link) +{ + downward = link; +} + +int +rpl_has_downward_link() +{ + return downward; +} + #if RPL_WITH_DAO_ACK static uip_ds6_route_t * find_route_entry_by_dao_ack(uint8_t seq) @@ -967,6 +981,13 @@ dao_output(rpl_parent_t *parent, uint8_t lifetime) instance->my_dao_transmissions = 1; ctimer_set(&instance->dao_retransmit_timer, RPL_DAO_RETRANSMISSION_TIMEOUT, handle_dao_retransmission, parent); + if(lifetime == RPL_ZERO_LIFETIME) { + rpl_set_downward_link(0); + } +#else + /* We know that we have tried to register so now we are assuming + that we have a down-link - unless this is a zero lifetime one */ + rpl_set_downward_link(lifetime != RPL_ZERO_LIFETIME); #endif /* RPL_WITH_DAO_ACK */ } /*---------------------------------------------------------------------------*/ @@ -1107,6 +1128,8 @@ dao_ack_input(void) if(sequence == instance->my_dao_seqno) { PRINTF("RPL: DAO %s for me!\n", status < 128 ? "ACK" : "NACK"); + rpl_set_downward_link(status < 128); + /* always stop the retransmit timer when the ACK arrived */ ctimer_stop(&instance->dao_retransmit_timer); @@ -1115,11 +1138,14 @@ dao_ack_input(void) instance->of->dao_ack_callback(parent, status); } +#if RPL_REPAIR_ON_DAO_NACK if(status >= RPL_DAO_ACK_UNABLE_TO_ACCEPT) { /* failed the DAO transmission - need to remove the default route. */ /* Trigger a local repair since we can not get our DAO in... */ rpl_local_repair(instance); } +#endif + } else { /* this DAO should be forwarded to another recently registered route */ uip_ds6_route_t *re; diff --git a/core/net/rpl/rpl-nbr-policy.c b/core/net/rpl/rpl-nbr-policy.c index 51d0df8db..7b0e28ff1 100644 --- a/core/net/rpl/rpl-nbr-policy.c +++ b/core/net/rpl/rpl-nbr-policy.c @@ -49,7 +49,7 @@ #include "net/ipv6/uip-ds6-nbr.h" #include "net/ipv6/uip-ds6-route.h" -#define DEBUG DEBUG_FULL +#define DEBUG DEBUG_NONE #include "net/ip/uip-debug.h" /* @@ -63,7 +63,7 @@ * neighbors and are not only MAC neighbors. */ -#define MAX_CHILDREN (NBR_TABLE_MAX_NEIGHBORS - 3) +#define MAX_CHILDREN (NBR_TABLE_MAX_NEIGHBORS - 2) #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) static int num_parents; /* any node that are possible parents */ diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h index b7d7757c2..dfc081d4b 100644 --- a/core/net/rpl/rpl.h +++ b/core/net/rpl/rpl.h @@ -300,5 +300,13 @@ enum rpl_mode rpl_set_mode(enum rpl_mode mode); */ enum rpl_mode rpl_get_mode(void); + +/** + * Get the RPL's best guess on if we have downward link or not. + * + * \retval 1 if we have a downward link, 0 if not. + */ +int rpl_has_downward_link(void); + /*---------------------------------------------------------------------------*/ #endif /* RPL_H */ From 13b8c04c6f603030b484ba455d690719f49e86fa Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Tue, 22 Sep 2015 22:12:06 +0200 Subject: [PATCH 122/374] fixed so that nbr policy for RPL Root do not save room for parents --- core/net/rpl/rpl-icmp6.c | 2 +- core/net/rpl/rpl-nbr-policy.c | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index af7a05d67..6ff0dcfee 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -820,7 +820,7 @@ dao_input(void) PRINTF("RPL: adding DAO route\n"); /* Update and add neighbor - if no room - fail. */ - if((nbr = rpl_icmp6_update_nbr_table(&dao_sender_addr, NBR_TABLE_REASON_RPL_DAO, NULL)) == NULL) { + if((nbr = rpl_icmp6_update_nbr_table(&dao_sender_addr, NBR_TABLE_REASON_RPL_DAO, instance)) == NULL) { PRINTF("RPL: Out of Memory, dropping DAO from "); PRINT6ADDR(&dao_sender_addr); PRINTF(", "); diff --git a/core/net/rpl/rpl-nbr-policy.c b/core/net/rpl/rpl-nbr-policy.c index 7b0e28ff1..9c750a7e0 100644 --- a/core/net/rpl/rpl-nbr-policy.c +++ b/core/net/rpl/rpl-nbr-policy.c @@ -62,7 +62,6 @@ * NOTE: this policy assumes that all neighbors end up being IPv6 * neighbors and are not only MAC neighbors. */ - #define MAX_CHILDREN (NBR_TABLE_MAX_NEIGHBORS - 2) #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) @@ -212,13 +211,21 @@ find_removable_dio(uip_ipaddr_t *from, rpl_dio_t *dio) } /*---------------------------------------------------------------------------*/ const linkaddr_t * -find_removable_dao(uip_ipaddr_t *from) +find_removable_dao(uip_ipaddr_t *from, rpl_instance_t *instance) { + int max = MAX_CHILDREN; update_nbr(); + if(instance != NULL) { + /* No need to reserve space for parents for RPL ROOT */ + if(instance->current_dag->rank == ROOT_RANK(instance)) { + max = NBR_TABLE_MAX_NEIGHBORS; + } + } + /* Check if this DAO sender is not yet neighbor and there is already too many children. */ - if(num_children >= MAX_CHILDREN) { + if(num_children >= max) { PRINTF("Can not add another child - already at max.\n"); return NULL; } @@ -234,7 +241,7 @@ rpl_nbr_policy_find_removable(nbr_table_reason_t reason,void * data) { case NBR_TABLE_REASON_RPL_DIO: return find_removable_dio(&UIP_IP_BUF->srcipaddr, data); case NBR_TABLE_REASON_RPL_DAO: - return find_removable_dao(&UIP_IP_BUF->srcipaddr); + return find_removable_dao(&UIP_IP_BUF->srcipaddr, data); case NBR_TABLE_REASON_RPL_DIS: return find_removable_dis(&UIP_IP_BUF->srcipaddr); default: From dae21fcb76fbed260cd1dd7f618d40d04e5a1643 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Tue, 22 Sep 2015 23:21:03 +0200 Subject: [PATCH 123/374] made ZERO LIFETIME routes live 30 seconds instead of 60 and shortened route lifetime in travis test --- regression-tests/21-large-rpl/code/router/project-conf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression-tests/21-large-rpl/code/router/project-conf.h b/regression-tests/21-large-rpl/code/router/project-conf.h index bec41cd5e..7f338deca 100644 --- a/regression-tests/21-large-rpl/code/router/project-conf.h +++ b/regression-tests/21-large-rpl/code/router/project-conf.h @@ -8,4 +8,4 @@ #define NBR_TABLE_CONF_MAX_NEIGHBORS 8 #define RPL_CONF_DEFAULT_LIFETIME_UNIT 60 -#define RPL_CONF_DEFAULT_LIFETIME 5 +#define RPL_CONF_DEFAULT_LIFETIME 3 From 8afe3fb9b79c6b39130e52f1188c4900557e3154 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Wed, 23 Sep 2015 09:12:35 +0200 Subject: [PATCH 124/374] fixed so that DAO NACK now is either for the path or for RPL root - if from root then do not try to switch parent since that will not help --- core/net/rpl/rpl-icmp6.c | 10 +++++++--- core/net/rpl/rpl-mrhof.c | 5 ++++- core/net/rpl/rpl-private.h | 1 + 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 6ff0dcfee..0851cd9a2 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -663,6 +663,7 @@ dao_input(void) int learned_from; rpl_parent_t *parent; uip_ds6_nbr_t *nbr; + int is_root; prefixlen = 0; parent = NULL; @@ -695,6 +696,8 @@ dao_input(void) sequence = buffer[pos++]; dag = instance->current_dag; + is_root = (dag->rank == ROOT_RANK(instance)); + /* Is the DAG ID present? */ if(flags & RPL_DAO_D_FLAG) { if(memcmp(&dag->dag_id, &buffer[pos], sizeof(dag->dag_id))) { @@ -829,7 +832,8 @@ dao_input(void) if(flags & RPL_DAO_K_FLAG) { /* signal the failure to add the node */ dao_ack_output(instance, &dao_sender_addr, sequence, - RPL_DAO_ACK_UNABLE_TO_ACCEPT); + is_root ? RPL_DAO_ACK_UNABLE_TO_ACCEPT_ROOT : + RPL_DAO_ACK_UNABLE_TO_ACCEPT); } goto discard; } @@ -838,11 +842,11 @@ dao_input(void) if(rep == NULL) { RPL_STAT(rpl_stats.mem_overflows++); PRINTF("RPL: Could not add a route after receiving a DAO\n"); - if(flags & RPL_DAO_K_FLAG) { /* signal the failure to add the node */ dao_ack_output(instance, &dao_sender_addr, sequence, - RPL_DAO_ACK_UNABLE_TO_ACCEPT); + is_root ? RPL_DAO_ACK_UNABLE_TO_ACCEPT_ROOT : + RPL_DAO_ACK_UNABLE_TO_ACCEPT); } goto discard; } diff --git a/core/net/rpl/rpl-mrhof.c b/core/net/rpl/rpl-mrhof.c index acf2b1d54..6da2ec304 100644 --- a/core/net/rpl/rpl-mrhof.c +++ b/core/net/rpl/rpl-mrhof.c @@ -122,8 +122,11 @@ reset(rpl_dag_t *dag) static void dao_ack_callback(rpl_parent_t *p, int status) { + if(status == RPL_DAO_ACK_UNABLE_TO_ACCEPT_ROOT) { + return; + } /* here we need to handle failed DAO's and other stuff */ - PRINTF("RPL: MRHOF - DAO ACK received with status: %d", status); + PRINTF("RPL: MRHOF - DAO ACK received with status: %d\n", status); if(status >= RPL_DAO_ACK_UNABLE_TO_ACCEPT) { /* punish the ETX as if this was 10 packets lost */ neighbor_link_callback(p, MAC_TX_OK, 10); diff --git a/core/net/rpl/rpl-private.h b/core/net/rpl/rpl-private.h index 017efb474..161cdc532 100644 --- a/core/net/rpl/rpl-private.h +++ b/core/net/rpl/rpl-private.h @@ -94,6 +94,7 @@ #define RPL_DAO_ACK_UNCONDITIONAL_ACCEPT 0 #define RPL_DAO_ACK_ACCEPT 1 /* 1 - 127 is OK but not good */ #define RPL_DAO_ACK_UNABLE_TO_ACCEPT 128 /* >127 is fail */ +#define RPL_DAO_ACK_UNABLE_TO_ACCEPT_ROOT 255 /* root can not accept */ #define RPL_DAO_ACK_TIMEOUT -1 From 09c624dcd39653a26f0687805df4368d6956903c Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Fri, 2 Oct 2015 07:38:52 +0200 Subject: [PATCH 125/374] fixed clearing of state flag and avoid starting retransmission timer --- core/net/ipv6/uip-ds6-route.h | 3 +++ core/net/ipv6/uip-nd6.c | 11 ++++++----- core/net/rpl/rpl-icmp6.c | 29 +++++++++++++++-------------- core/net/rpl/rpl.c | 2 ++ 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/core/net/ipv6/uip-ds6-route.h b/core/net/ipv6/uip-ds6-route.h index 3324a8e08..7a5d805f0 100644 --- a/core/net/ipv6/uip-ds6-route.h +++ b/core/net/ipv6/uip-ds6-route.h @@ -106,6 +106,9 @@ void uip_ds6_notification_rm(struct uip_ds6_notification *n); #define RPL_ROUTE_SET_NOPATH_RECEIVED(route) do { \ (route)->state.state_flags |= RPL_ROUTE_ENTRY_NOPATH_RECEIVED; \ } while(0) +#define RPL_ROUTE_CLEAR_NOPATH_RECEIVED(route) do { \ + (route)->state.state_flags &= ~RPL_ROUTE_ENTRY_NOPATH_RECEIVED; \ + } while(0) #define RPL_ROUTE_IS_DAO_PENDING(route) \ ((route->state.state_flags & RPL_ROUTE_ENTRY_DAO_PENDING) != 0) diff --git a/core/net/ipv6/uip-nd6.c b/core/net/ipv6/uip-nd6.c index ffad6260e..107e66369 100644 --- a/core/net/ipv6/uip-nd6.c +++ b/core/net/ipv6/uip-nd6.c @@ -201,6 +201,8 @@ ns_input(void) #endif /*UIP_CONF_IPV6_CHECKS */ nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr); if(nbr == NULL) { + uip_lladdr_t lladdr_aligned; + extract_lladdr_aligned(&lladdr_aligned); uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL); } else { @@ -638,12 +640,11 @@ rs_input(void) } else { /* If LL address changed, set neighbor state to stale */ if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], - uip_ds6_nbr_get_ll(nbr), UIP_LLADDR_LEN) != 0) { + uip_ds6_nbr_get_ll(nbr), UIP_LLADDR_LEN) != 0) { uip_ds6_nbr_t nbr_data = *nbr; uip_ds6_nbr_rm(nbr); nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, - nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, 0, NBR_STALE, - NBR_TABLE_REASON_IPV6_ND, NULL); + 0, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL); nbr->reachable = nbr_data.reachable; nbr->sendns = nbr_data.sendns; nbr->nscount = nbr_data.nscount; @@ -872,8 +873,8 @@ ra_input(void) if(nbr == NULL) { uip_lladdr_t lladdr_aligned; extract_lladdr_aligned(&lladdr_aligned); - nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 1, - NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL); + nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, + 1, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL); } else { uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr); if(nbr->state == NBR_INCOMPLETE) { diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 0851cd9a2..4320181e8 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -53,6 +53,7 @@ #include "net/rpl/rpl-private.h" #include "net/packetbuf.h" #include "net/ipv6/multicast/uip-mcast6.h" +#include "random.h" #include #include @@ -811,11 +812,12 @@ dao_input(void) uip_icmp6_send(rpl_get_parent_ipaddr(dag->preferred_parent), ICMP6_RPL, RPL_CODE_DAO, buffer_length); } - if(flags & RPL_DAO_K_FLAG) { - /* indicate that we accepted the no-path DAO */ - dao_ack_output(instance, &dao_sender_addr, sequence, - RPL_DAO_ACK_UNCONDITIONAL_ACCEPT); - } + } + /* independent if we remove or not - ACK the request */ + if(flags & RPL_DAO_K_FLAG) { + /* indicate that we accepted the no-path DAO */ + dao_ack_output(instance, &dao_sender_addr, sequence, + RPL_DAO_ACK_UNCONDITIONAL_ACCEPT); } goto discard; } @@ -851,8 +853,9 @@ dao_input(void) goto discard; } - /* State is all zeroes, set lifetime but no need for other initialization. */ + /* set lifetime and clear NOPATH bit */ rep->state.lifetime = RPL_LIFETIME(instance, lifetime); + RPL_ROUTE_CLEAR_NOPATH_RECEIVED(rep); #if RPL_CONF_MULTICAST fwd_dao: @@ -978,15 +981,13 @@ dao_output(rpl_parent_t *parent, uint8_t lifetime) /* Sending a DAO with own prefix as target */ dao_output_target(parent, &prefix, lifetime); - /* keep track of my own sending of DAO for handling ack and loss of ack */ - instance->my_dao_seqno = dao_sequence; - #if RPL_WITH_DAO_ACK - instance->my_dao_transmissions = 1; - ctimer_set(&instance->dao_retransmit_timer, RPL_DAO_RETRANSMISSION_TIMEOUT, - handle_dao_retransmission, parent); - if(lifetime == RPL_ZERO_LIFETIME) { - rpl_set_downward_link(0); + /* keep track of my own sending of DAO for handling ack and loss of ack */ + if(lifetime != RPL_ZERO_LIFETIME) { + instance->my_dao_seqno = dao_sequence; + instance->my_dao_transmissions = 1; + ctimer_set(&instance->dao_retransmit_timer, RPL_DAO_RETRANSMISSION_TIMEOUT, + handle_dao_retransmission, parent); } #else /* We know that we have tried to register so now we are assuming diff --git a/core/net/rpl/rpl.c b/core/net/rpl/rpl.c index 90b434102..c541463d4 100644 --- a/core/net/rpl/rpl.c +++ b/core/net/rpl/rpl.c @@ -238,6 +238,8 @@ rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix, int prefix_len, rep->state.dag = dag; rep->state.lifetime = RPL_LIFETIME(dag->instance, dag->instance->default_lifetime); + /* always clear state flags for the no-path received when adding/refreshing */ + RPL_ROUTE_CLEAR_NOPATH_RECEIVED(rep); PRINTF("RPL: Added a route to "); PRINT6ADDR(prefix); From ab4a0e08c7c175d317f785802176a97a760f5c8a Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Fri, 2 Oct 2015 07:41:57 +0200 Subject: [PATCH 126/374] fixed simulation files to be closer to defaults in configuration --- regression-tests/12-rpl/04-rpl-large-network.csc | 3 +-- regression-tests/21-large-rpl/code/node/client.c | 7 +++++++ regression-tests/21-large-rpl/code/router/project-conf.h | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/regression-tests/12-rpl/04-rpl-large-network.csc b/regression-tests/12-rpl/04-rpl-large-network.csc index 88d3774bf..145cad14c 100644 --- a/regression-tests/12-rpl/04-rpl-large-network.csc +++ b/regression-tests/12-rpl/04-rpl-large-network.csc @@ -1,4 +1,3 @@ -<<<<<<< 1d90b9290e293eedcb6451dd86c474ec168f688c [APPS_DIR]/mrm @@ -7058,4 +7057,4 @@ while(true) { 603 43 - + \ No newline at end of file diff --git a/regression-tests/21-large-rpl/code/node/client.c b/regression-tests/21-large-rpl/code/node/client.c index 3616c1aad..36dc40923 100644 --- a/regression-tests/21-large-rpl/code/node/client.c +++ b/regression-tests/21-large-rpl/code/node/client.c @@ -105,6 +105,13 @@ PROCESS_THREAD(http_example_process, ev, data) http_socket_get(&s, "http://www.contiki-os.org/", 0, 0, callback, NULL); connect = 0; + } else if(connect) { + connect++; + /* If connect have been "tried" 5 timer we quit trying now... */ + if(connect > 5) { + restart(); + connect = 0; + } } } diff --git a/regression-tests/21-large-rpl/code/router/project-conf.h b/regression-tests/21-large-rpl/code/router/project-conf.h index 7f338deca..857ab6929 100644 --- a/regression-tests/21-large-rpl/code/router/project-conf.h +++ b/regression-tests/21-large-rpl/code/router/project-conf.h @@ -7,5 +7,5 @@ #undef NBR_TABLE_CONF_MAX_NEIGHBORS #define NBR_TABLE_CONF_MAX_NEIGHBORS 8 -#define RPL_CONF_DEFAULT_LIFETIME_UNIT 60 -#define RPL_CONF_DEFAULT_LIFETIME 3 +/* #define RPL_CONF_DEFAULT_LIFETIME_UNIT 60 */ +/* #define RPL_CONF_DEFAULT_LIFETIME 10 */ From 6fa3479aa89f1ed279c688cdbdd2e5622922ad21 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 18 Nov 2015 15:25:13 +0100 Subject: [PATCH 127/374] RPL: improved debug messages for No-Path DAOs Conflicts: core/net/rpl/rpl-icmp6.c --- core/net/rpl/rpl-icmp6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 4320181e8..050a894da 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -802,7 +802,7 @@ dao_input(void) uint8_t out_seq; out_seq = prepare_for_dao_fwd(sequence, rep); - PRINTF("RPL: Forwarding no-path DAO to parent - out_seq:%d", + PRINTF("RPL: Forwarding No-path DAO to parent - out_seq:%d", out_seq); PRINT6ADDR(rpl_get_parent_ipaddr(dag->preferred_parent)); PRINTF("\n"); From 19b04098d55ebdaaa16657f0c8a643af49e9577c Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 23 Nov 2015 13:38:48 +0100 Subject: [PATCH 128/374] Improved RPL debug logs --- core/net/rpl/rpl-icmp6.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 050a894da..c7e4cbc8a 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -671,11 +671,6 @@ dao_input(void) uip_ipaddr_copy(&dao_sender_addr, &UIP_IP_BUF->srcipaddr); - /* Destination Advertisement Object */ - PRINTF("RPL: Received a DAO from "); - PRINT6ADDR(&dao_sender_addr); - PRINTF("\n"); - buffer = UIP_ICMP_PAYLOAD; buffer_length = uip_len - uip_l3_icmp_hdr_len; @@ -711,8 +706,12 @@ dao_input(void) learned_from = uip_is_addr_mcast(&dao_sender_addr) ? RPL_ROUTE_FROM_MULTICAST_DAO : RPL_ROUTE_FROM_UNICAST_DAO; - PRINTF("RPL: DAO from %s\n", - learned_from == RPL_ROUTE_FROM_UNICAST_DAO? "unicast": "multicast"); + /* Destination Advertisement Object */ + PRINTF("RPL: Received a (%s) DAO with sequence number %u from ", + learned_from == RPL_ROUTE_FROM_UNICAST_DAO? "unicast": "multicast", sequence); + PRINT6ADDR(&dao_sender_addr); + PRINTF("\n"); + if(learned_from == RPL_ROUTE_FROM_UNICAST_DAO) { /* Check whether this is a DAO forwarding loop. */ parent = rpl_find_parent(dag, &dao_sender_addr); @@ -822,7 +821,7 @@ dao_input(void) goto discard; } - PRINTF("RPL: adding DAO route\n"); + PRINTF("RPL: Adding DAO route\n"); /* Update and add neighbor - if no room - fail. */ if((nbr = rpl_icmp6_update_nbr_table(&dao_sender_addr, NBR_TABLE_REASON_RPL_DAO, instance)) == NULL) { @@ -897,7 +896,7 @@ fwd_dao: } if(should_ack) { - PRINTF("RPL: sending DAO ACK\n"); + PRINTF("RPL: Sending DAO ACK\n"); dao_ack_output(instance, &dao_sender_addr, sequence, RPL_DAO_ACK_UNCONDITIONAL_ACCEPT); } @@ -1081,7 +1080,8 @@ dao_output_target_seq(rpl_parent_t *parent, uip_ipaddr_t *prefix, buffer[pos++] = 0; /* path seq - ignored */ buffer[pos++] = lifetime; - PRINTF("RPL: Sending %sDAO with prefix ", lifetime == RPL_ZERO_LIFETIME ? "No-Path " : ""); + PRINTF("RPL: Sending a %sDAO with sequence number %u, lifetime %u, prefix ", + lifetime == RPL_ZERO_LIFETIME ? "No-Path " : "", seq_no, lifetime); PRINT6ADDR(prefix); PRINTF(" to "); PRINT6ADDR(rpl_get_parent_ipaddr(parent)); @@ -1125,14 +1125,13 @@ dao_ack_input(void) return; } - PRINTF("RPL: Received a DAO ACK with sequence number %d (%d) and status %d from ", + PRINTF("RPL: Received a DAO %s with sequence number %d (%d) and status %d from ", + status < 128 ? "ACK" : "NACK", sequence, instance->my_dao_seqno, status); PRINT6ADDR(&UIP_IP_BUF->srcipaddr); PRINTF("\n"); if(sequence == instance->my_dao_seqno) { - PRINTF("RPL: DAO %s for me!\n", status < 128 ? "ACK" : "NACK"); - rpl_set_downward_link(status < 128); /* always stop the retransmit timer when the ACK arrived */ @@ -1152,7 +1151,7 @@ dao_ack_input(void) #endif } else { - /* this DAO should be forwarded to another recently registered route */ + /* this DAO ACK should be forwarded to another recently registered route */ uip_ds6_route_t *re; uip_ipaddr_t *nexthop; if((re = find_route_entry_by_dao_ack(sequence)) != NULL) { @@ -1162,9 +1161,9 @@ dao_ack_input(void) nexthop = uip_ds6_route_nexthop(re); if(nexthop == NULL) { - PRINTF("No next hop to fwd DAO ACK to\n"); + PRINTF("RPL: No next hop to fwd DAO ACK to\n"); } else { - PRINTF("Fwd DAO ACK to:"); + PRINTF("RPL: Fwd DAO ACK to:"); PRINT6ADDR(nexthop); PRINTF("\n"); buffer[2] = re->state.dao_seqno_in; @@ -1176,7 +1175,7 @@ dao_ack_input(void) uip_ds6_route_rm(re); } } else { - PRINTF("No route entry to fwd DAO ACK to\n"); + PRINTF("RPL: No route entry to fwd DAO ACK to\n"); } } #endif /* RPL_WITH_DAO_ACK */ @@ -1190,7 +1189,7 @@ dao_ack_output(rpl_instance_t *instance, uip_ipaddr_t *dest, uint8_t sequence, #if RPL_WITH_DAO_ACK unsigned char *buffer; - PRINTF("RPL: Sending a DAO ACK with sequence number %d to ", sequence); + PRINTF("RPL: Sending a DAO %s with sequence number %d to ", status < 128 ? "ACK" : "NACK", sequence); PRINT6ADDR(dest); PRINTF(" with status %d\n", status); From e1f9369a091c5c17e8ed2de3a0e3cba6d7b42786 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 23 Nov 2015 13:39:49 +0100 Subject: [PATCH 129/374] RPL DAO-ACK: move initialization of current ougoing DAO from da_output to dao_output_target_seq --- core/net/rpl/rpl-icmp6.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index c7e4cbc8a..566aa8b93 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -966,7 +966,6 @@ dao_output(rpl_parent_t *parent, uint8_t lifetime) { /* Destination Advertisement Object */ uip_ipaddr_t prefix; - rpl_instance_t *instance; if(get_global_addr(&prefix) == 0) { PRINTF("RPL: No global address set for this node - suppressing DAO\n"); @@ -976,23 +975,9 @@ dao_output(rpl_parent_t *parent, uint8_t lifetime) if(parent == NULL || parent->dag == NULL || parent->dag->instance == NULL) { return; } - instance = parent->dag->instance; /* Sending a DAO with own prefix as target */ dao_output_target(parent, &prefix, lifetime); -#if RPL_WITH_DAO_ACK - /* keep track of my own sending of DAO for handling ack and loss of ack */ - if(lifetime != RPL_ZERO_LIFETIME) { - instance->my_dao_seqno = dao_sequence; - instance->my_dao_transmissions = 1; - ctimer_set(&instance->dao_retransmit_timer, RPL_DAO_RETRANSMISSION_TIMEOUT, - handle_dao_retransmission, parent); - } -#else - /* We know that we have tried to register so now we are assuming - that we have a down-link - unless this is a zero lifetime one */ - rpl_set_downward_link(lifetime != RPL_ZERO_LIFETIME); -#endif /* RPL_WITH_DAO_ACK */ } /*---------------------------------------------------------------------------*/ void @@ -1089,6 +1074,19 @@ dao_output_target_seq(rpl_parent_t *parent, uip_ipaddr_t *prefix, if(rpl_get_parent_ipaddr(parent) != NULL) { uip_icmp6_send(rpl_get_parent_ipaddr(parent), ICMP6_RPL, RPL_CODE_DAO, pos); +#if RPL_WITH_DAO_ACK + if(lifetime != RPL_ZERO_LIFETIME) { + /* keep track of my own sending of DAO for handling ack and loss of ack */ + instance->my_dao_seqno = dao_sequence; + instance->my_dao_transmissions = 1; + ctimer_set(&instance->dao_retransmit_timer, RPL_DAO_RETRANSMISSION_TIMEOUT, + handle_dao_retransmission, parent); + } +#else /* RPL_WITH_DAO_ACK */ + /* We know that we have tried to register so now we are assuming + that we have a down-link - unless this is a zero lifetime one */ + rpl_set_downward_link(lifetime != RPL_ZERO_LIFETIME); +#endif /* RPL_WITH_DAO_ACK */ } } /*---------------------------------------------------------------------------*/ From ffb10094ab1f81cfd4d8b0ba28063eed33ddf03e Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Thu, 18 Feb 2016 15:19:32 +0100 Subject: [PATCH 130/374] added init value of locked variable --- core/net/nbr-table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/net/nbr-table.c b/core/net/nbr-table.c index 42597c598..ddae06fca 100644 --- a/core/net/nbr-table.c +++ b/core/net/nbr-table.c @@ -199,7 +199,7 @@ nbr_table_allocate(nbr_table_reason_t reason, void *data) } else { /* used least_used_key to indicate what is the least useful entry */ int index; - int locked; + int locked = 0; if((index = index_from_lladdr(lladdr)) != -1) { least_used_key = key_from_index(index); locked = locked_map[index]; From ee97dc4bcd4aae89f4819711d90326d1c2495990 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Thu, 18 Feb 2016 15:52:35 +0100 Subject: [PATCH 131/374] tuned configuration for rpl-collect and micaz platform --- examples/ipv6/rpl-collect/Makefile | 2 + examples/ipv6/rpl-collect/project-conf.h | 59 ++++++++++++++++++++++++ platform/micaz/contiki-conf.h | 11 +++-- 3 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 examples/ipv6/rpl-collect/project-conf.h diff --git a/examples/ipv6/rpl-collect/Makefile b/examples/ipv6/rpl-collect/Makefile index ce20c79e2..e2a1021a0 100644 --- a/examples/ipv6/rpl-collect/Makefile +++ b/examples/ipv6/rpl-collect/Makefile @@ -3,6 +3,8 @@ APPS = powertrace collect-view CONTIKI_PROJECT = udp-sender udp-sink PROJECT_SOURCEFILES += collect-common.c +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + ifdef PERIOD CFLAGS=-DPERIOD=$(PERIOD) endif diff --git a/examples/ipv6/rpl-collect/project-conf.h b/examples/ipv6/rpl-collect/project-conf.h new file mode 100644 index 000000000..4b39f7de9 --- /dev/null +++ b/examples/ipv6/rpl-collect/project-conf.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015, 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. + */ + +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +#undef NBR_TABLE_CONF_MAX_NEIGHBORS +#undef UIP_CONF_MAX_ROUTES + +#ifdef TEST_MORE_ROUTES +/* configure number of neighbors and routes */ +#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 +#define UIP_CONF_MAX_ROUTES 30 +#else +/* configure number of neighbors and routes */ +#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 +#define UIP_CONF_MAX_ROUTES 10 +#endif /* TEST_MORE_ROUTES */ + +#undef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC nullrdc_driver +#undef NULLRDC_CONF_802154_AUTOACK +#define NULLRDC_CONF_802154_AUTOACK 1 + +/* Define as minutes */ +#define RPL_CONF_DEFAULT_LIFETIME_UNIT 60 + +/* 10 minutes lifetime of routes */ +#define RPL_CONF_DEFAULT_LIFETIME 10 + +#define RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME 1 + +#endif /* PROJECT_CONF_H_ */ diff --git a/platform/micaz/contiki-conf.h b/platform/micaz/contiki-conf.h index 16e74567a..04aaccf6b 100644 --- a/platform/micaz/contiki-conf.h +++ b/platform/micaz/contiki-conf.h @@ -125,10 +125,11 @@ #define UIP_CONF_ROUTER 0 /* configure number of neighbors and routes */ -#define NBR_TABLE_CONF_MAX_NEIGHBORS 5 -#define UIP_CONF_MAX_ROUTES 5 +#define NBR_TABLE_CONF_MAX_NEIGHBORS 5 +#define UIP_CONF_MAX_ROUTES 5 -#define RPL_CONF_MAX_PARENTS 4 +#define RPL_CONF_MAX_PARENTS 4 +#define RPL_CONF_MAX_DAG_PER_INSTANCE 1 #define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_ND6_REACHABLE_TIME 600000 @@ -140,12 +141,12 @@ #define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_NETIF_MAX_ADDRESSES 3 #define UIP_CONF_IP_FORWARD 0 -#define UIP_CONF_BUFFER_SIZE 240 +#define UIP_CONF_BUFFER_SIZE 200 #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 #ifndef SICSLOWPAN_CONF_FRAG #define SICSLOWPAN_CONF_FRAG 1 -#define SICSLOWPAN_CONF_FRAGMENT_BUFFERS 4 +#define SICSLOWPAN_CONF_FRAGMENT_BUFFERS 3 #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 From 12ac02650bf9af8490f1f4713b35f5ec09d4ab1a Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Thu, 18 Feb 2016 22:40:30 +0100 Subject: [PATCH 132/374] fixed a bug in nbr policy and DAO retransmission handling and added new wismote simulation --- core/net/rpl/rpl-icmp6.c | 32 +- core/net/rpl/rpl-nbr-policy.c | 25 +- .../ipv6/rpl-udp/rpl-udp-scale-wismote.csc | 721 ++++++++++++++++++ 3 files changed, 751 insertions(+), 27 deletions(-) create mode 100644 examples/ipv6/rpl-udp/rpl-udp-scale-wismote.csc diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 566aa8b93..2296f0d97 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -976,6 +976,25 @@ dao_output(rpl_parent_t *parent, uint8_t lifetime) return; } +#if RPL_WITH_DAO_ACK + /* set up the state since this will be the first transmission of DAO */ + /* retransmissions will call directly to dao_output_target_seq */ + /* keep track of my own sending of DAO for handling ack and loss of ack */ + if(lifetime != RPL_ZERO_LIFETIME) { + rpl_instance_t *instance; + instance = parent->dag->instance; + + instance->my_dao_seqno = dao_sequence; + instance->my_dao_transmissions = 1; + ctimer_set(&instance->dao_retransmit_timer, RPL_DAO_RETRANSMISSION_TIMEOUT, + handle_dao_retransmission, parent); + } +#else + /* We know that we have tried to register so now we are assuming + that we have a down-link - unless this is a zero lifetime one */ + rpl_set_downward_link(lifetime != RPL_ZERO_LIFETIME); +#endif /* RPL_WITH_DAO_ACK */ + /* Sending a DAO with own prefix as target */ dao_output_target(parent, &prefix, lifetime); } @@ -1074,19 +1093,6 @@ dao_output_target_seq(rpl_parent_t *parent, uip_ipaddr_t *prefix, if(rpl_get_parent_ipaddr(parent) != NULL) { uip_icmp6_send(rpl_get_parent_ipaddr(parent), ICMP6_RPL, RPL_CODE_DAO, pos); -#if RPL_WITH_DAO_ACK - if(lifetime != RPL_ZERO_LIFETIME) { - /* keep track of my own sending of DAO for handling ack and loss of ack */ - instance->my_dao_seqno = dao_sequence; - instance->my_dao_transmissions = 1; - ctimer_set(&instance->dao_retransmit_timer, RPL_DAO_RETRANSMISSION_TIMEOUT, - handle_dao_retransmission, parent); - } -#else /* RPL_WITH_DAO_ACK */ - /* We know that we have tried to register so now we are assuming - that we have a down-link - unless this is a zero lifetime one */ - rpl_set_downward_link(lifetime != RPL_ZERO_LIFETIME); -#endif /* RPL_WITH_DAO_ACK */ } } /*---------------------------------------------------------------------------*/ diff --git a/core/net/rpl/rpl-nbr-policy.c b/core/net/rpl/rpl-nbr-policy.c index 9c750a7e0..6f0dd9ca3 100644 --- a/core/net/rpl/rpl-nbr-policy.c +++ b/core/net/rpl/rpl-nbr-policy.c @@ -111,36 +111,33 @@ update_nbr(void) linkaddr_t *lladdr = nbr_table_get_lladdr(ds6_neighbors, nbr); is_used = 0; + /* Check if this neighbor is used as nexthop and therefor being a + RPL child. */ + if(uip_ds6_route_is_nexthop((uip_lladdr_t *)lladdr) != 0) { + is_used++; + num_children++; + } + parent = rpl_get_parent((uip_lladdr_t *)lladdr); if(parent != NULL) { num_parents++; - is_used++; if(parent->dag != NULL && parent->dag->preferred_parent == parent) { /* This is the preferred parent for the DAG and must not be removed */ /* Note: this assumes that only RPL adds default routes. */ - } else if(worst_rank < INFINITE_RANK && + } else if(is_used == 0 && worst_rank < INFINITE_RANK && parent->rank > 0 && parent->dag != NULL && parent->dag->instance != NULL && (rank = parent->dag->instance->of->calculate_rank(parent, 0)) > worst_rank) { /* This is the worst-rank neighbor - this is a good candidate for removal */ - if(uip_ds6_route_is_nexthop((uip_lladdr_t *)lladdr) == 0) { - worst_rank = rank; - worst_rank_nbr = lladdr; - } else { - printf("*** Can not use this as worst rank as it is a next hop\n"); - } + worst_rank = rank; + worst_rank_nbr = lladdr; } - } - - /* Check if this neighbor is used as nexthop and therefor being a - RPL child. */ - if(uip_ds6_route_is_nexthop((uip_lladdr_t *)lladdr) != 0) { + /* add to is_used after evaluation of is_used above */ is_used++; - num_children++; } if(is_used == 0) { diff --git a/examples/ipv6/rpl-udp/rpl-udp-scale-wismote.csc b/examples/ipv6/rpl-udp/rpl-udp-scale-wismote.csc new file mode 100644 index 000000000..3aea07ab0 --- /dev/null +++ b/examples/ipv6/rpl-udp/rpl-udp-scale-wismote.csc @@ -0,0 +1,721 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + RPL up and downstream scaleability test network using IPv6 and RPL + generated + 5000000 + + org.contikios.cooja.radiomediums.UDGM + 150.0 + 150.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.WismoteMoteType + sky1 + WisMote Type #sky1 + [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.c + make SERVER_REPLY=1 clean udp-server.wismote TARGET=wismote DEFINES=TEST_MORE_ROUTES=1 + [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.wismote + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.MspButton + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspDefaultSerial + org.contikios.cooja.mspmote.interfaces.MspLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + org.contikios.cooja.mspmote.WismoteMoteType + sky2 + WisMote Type #sky2 + [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.c + make SERVER_REPLY=1 clean udp-client.wismote TARGET=wismote + [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.wismote + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.MspButton + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspDefaultSerial + org.contikios.cooja.mspmote.interfaces.MspLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + 48.435974731198804 + -66.16503914182063 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + -65.3176930733124 + 17.4304162608286 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 127.9689727848476 + 91.71883780610729 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 154.92605604103275 + 40.97896551774433 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 47.34887596588397 + -30.341495695501195 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 47.13486576528276 + 32.944481932122315 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -11.42091423859419 + 17.879870626121914 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 118.92746659954325 + 57.05973076244069 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 8 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 56.66768196114595 + 74.35652008990945 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 9 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 16.45706316609417 + 23.9075414163248 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 10 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -13.423161364506493 + -38.483037144768275 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 11 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -9.034961217472201 + 44.411389162165406 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 12 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 35.60049910164592 + 87.95154356223047 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 13 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 66.93880603404335 + -42.39683727590697 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 14 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 94.81678343873172 + 26.921376811426246 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 15 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -49.449656689283934 + 57.924813144367945 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 16 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -34.02467970185502 + -24.313824905298304 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 17 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -28.750467760427494 + 48.01822457713635 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 18 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 124.95513738974614 + 20.140247172447996 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 19 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 14.85247487703553 + -34.478542892943686 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 20 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 154.43072661267115 + -3.279765376986134 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 21 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 99.90960713878738 + -21.76043658444847 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 22 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 88.4612185198951 + -49.763990463932714 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 23 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 24.745110502623138 + -1.7100594420374744 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 24 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 94.06332458995635 + -2.4635182908128352 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 25 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -4.639784599615941 + -10.849236218849724 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 26 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 2.4901685804620115 + -60.89843789583528 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 27 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 100.55144245441083 + 97.41861446767646 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 28 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -12.355761328741393 + 82.72616691655692 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 29 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 57.79962925723111 + 0.6828700499064966 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 30 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 76.5550413097159 + 77.33875258624342 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 31 + + sky2 + + + + org.contikios.cooja.plugins.SimControl + 289 + 4 + 184 + 31 + 41 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.AttributeVisualizerSkin + 2.349818846983307 0.0 0.0 2.349818846983307 187.19773526533345 190.95275613586946 + + 659 + 2 + 622 + 296 + 11 + + + org.contikios.cooja.plugins.LogListener + + ID:22.*DAO + + + + 937 + 3 + 442 + 20 + 297 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 600 + 5 + 700 + 946 + 6 + + + org.contikios.cooja.plugins.MoteInterfaceViewer + 3 + + Position + 0,0 + + 350 + 6 + 300 + 976 + 36 + + + From 12a75c3e4325d960eb62bc3f7ff78b4c3b1dd667 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Sat, 26 Mar 2016 20:12:52 +0100 Subject: [PATCH 133/374] fixed codestyle, improved APIs, and cleaned up comments --- core/net/ipv6/uip-ds6-nbr.c | 2 +- core/net/ipv6/uip-ds6-route.c | 9 +++- core/net/ipv6/uip-ds6-route.h | 5 ++- core/net/nbr-table.h | 2 +- core/net/rpl/rpl-dag.c | 18 ++++++-- core/net/rpl/rpl-icmp6.c | 43 ++++++++----------- core/net/rpl/rpl-mrhof.c | 8 +++- core/net/rpl/rpl-nbr-policy.c | 33 ++++++++------ core/net/rpl/rpl-of0.c | 2 + core/net/rpl/rpl-private.h | 2 +- core/net/rpl/rpl.h | 16 +++++-- .../21-large-rpl/code/node/client.c | 2 +- 12 files changed, 91 insertions(+), 51 deletions(-) diff --git a/core/net/ipv6/uip-ds6-nbr.c b/core/net/ipv6/uip-ds6-nbr.c index b8666a14a..e5c6167e5 100644 --- a/core/net/ipv6/uip-ds6-nbr.c +++ b/core/net/ipv6/uip-ds6-nbr.c @@ -83,7 +83,7 @@ uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr, void *data) { uip_ds6_nbr_t *nbr = nbr_table_add_lladdr(ds6_neighbors, (linkaddr_t*)lladdr - ,reason, data); + , reason, data); if(nbr) { uip_ipaddr_copy(&nbr->ipaddr, ipaddr); #if UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER diff --git a/core/net/ipv6/uip-ds6-route.c b/core/net/ipv6/uip-ds6-route.c index 21ce38f64..043ca78d4 100644 --- a/core/net/ipv6/uip-ds6-route.c +++ b/core/net/ipv6/uip-ds6-route.c @@ -207,8 +207,15 @@ uip_ds6_route_next(uip_ds6_route_t *r) } /*---------------------------------------------------------------------------*/ int -uip_ds6_route_is_nexthop(const uip_lladdr_t *lladdr) +uip_ds6_route_is_nexthop(const uip_ipaddr_t *ipaddr) { + const uip_lladdr_t *lladdr; + lladdr = uip_ds6_nbr_lladdr_from_ipaddr(ipaddr); + + if(lladdr == NULL) { + return 0; + } + return nbr_table_get_from_lladdr(nbr_routes, (linkaddr_t *)lladdr) != NULL; } /*---------------------------------------------------------------------------*/ diff --git a/core/net/ipv6/uip-ds6-route.h b/core/net/ipv6/uip-ds6-route.h index 7a5d805f0..6ca533c9b 100644 --- a/core/net/ipv6/uip-ds6-route.h +++ b/core/net/ipv6/uip-ds6-route.h @@ -124,6 +124,9 @@ void uip_ds6_notification_rm(struct uip_ds6_notification *n); #define RPL_ROUTE_SET_DAO_NACKED(route) do { \ (route)->state.state_flags |= RPL_ROUTE_ENTRY_DAO_NACK; \ } while(0) +#define RPL_ROUTE_CLEAR_DAO_NACKED(route) do { \ + (route)->state.state_flags &= ~RPL_ROUTE_ENTRY_DAO_NACK; \ + } while(0) #define RPL_ROUTE_CLEAR_DAO(route) do { \ (route)->state.state_flags &= ~(RPL_ROUTE_ENTRY_DAO_NACK|RPL_ROUTE_ENTRY_DAO_PENDING); \ @@ -200,7 +203,7 @@ uip_ipaddr_t *uip_ds6_route_nexthop(uip_ds6_route_t *); int uip_ds6_route_num_routes(void); uip_ds6_route_t *uip_ds6_route_head(void); uip_ds6_route_t *uip_ds6_route_next(uip_ds6_route_t *); -int uip_ds6_route_is_nexthop(const uip_lladdr_t *lladdr); +int uip_ds6_route_is_nexthop(const uip_ipaddr_t *ipaddr); /** @} */ #endif /* UIP_DS6_ROUTE_H */ diff --git a/core/net/nbr-table.h b/core/net/nbr-table.h index cc58c2f80..88a90a46c 100644 --- a/core/net/nbr-table.h +++ b/core/net/nbr-table.h @@ -83,7 +83,7 @@ typedef enum { NBR_TABLE_REASON_ROUTE, NBR_TABLE_REASON_IPV6_ND, NBR_TABLE_REASON_MAC, - NBR_TABLE_REASON_LLSEC + NBR_TABLE_REASON_LLSEC } nbr_table_reason_t; /** \name Neighbor tables: register and loop through table elements */ diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 034678ff5..27f781bdf 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -899,6 +899,18 @@ rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent) parent->dag = dag_dst; } /*---------------------------------------------------------------------------*/ +int +rpl_has_downward_route(void) +{ + int i; + for(i = 0; i < RPL_MAX_INSTANCES; ++i) { + if(instance_table[i].used && instance_table[i].has_downward_route) { + return 1; + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ rpl_dag_t * rpl_get_any_dag(void) { @@ -1157,8 +1169,6 @@ global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio) RPL_STAT(rpl_stats.global_repairs++); } -void rpl_set_downward_link(uint8_t link); - /*---------------------------------------------------------------------------*/ void rpl_local_repair(rpl_instance_t *instance) @@ -1177,8 +1187,8 @@ rpl_local_repair(rpl_instance_t *instance) } } - /* no downward link anymore */ - rpl_set_downward_link(0); + /* no downward route anymore */ + instance->has_downward_route = 0; rpl_reset_dio_timer(instance); /* Request refresh of DAO registrations next DIO */ diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 2296f0d97..0f20ddb67 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -90,7 +90,6 @@ void RPL_DEBUG_DAO_OUTPUT(rpl_parent_t *); #endif static uint8_t dao_sequence = RPL_LOLLIPOP_INIT; -static uint8_t downward = 0; extern rpl_of_t RPL_OF; @@ -105,18 +104,6 @@ UIP_ICMP6_HANDLER(dao_handler, ICMP6_RPL, RPL_CODE_DAO, dao_input); UIP_ICMP6_HANDLER(dao_ack_handler, ICMP6_RPL, RPL_CODE_DAO_ACK, dao_ack_input); /*---------------------------------------------------------------------------*/ -void -rpl_set_downward_link(uint8_t link) -{ - downward = link; -} - -int -rpl_has_downward_link() -{ - return downward; -} - #if RPL_WITH_DAO_ACK static uip_ds6_route_t * find_route_entry_by_dao_ack(uint8_t seq) @@ -215,8 +202,10 @@ rpl_icmp6_update_nbr_table(uip_ipaddr_t *from, nbr_table_reason_t reason, void * if(nbr != NULL) { #if UIP_ND6_SEND_NA - /* set reachable timer if we added or found the nbr entry */ + /* set reachable timer if we added or found the nbr entry - and update + neighbor entry to reachable to avoid sending NS/NA, etc. */ stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000); + nbr->state = NBR_REACHABLE; #endif /* UIP_ND6_SEND_NA */ } return nbr; @@ -833,7 +822,7 @@ dao_input(void) if(flags & RPL_DAO_K_FLAG) { /* signal the failure to add the node */ dao_ack_output(instance, &dao_sender_addr, sequence, - is_root ? RPL_DAO_ACK_UNABLE_TO_ACCEPT_ROOT : + is_root ? RPL_DAO_ACK_UNABLE_TO_ADD_ROUTE_AT_ROOT : RPL_DAO_ACK_UNABLE_TO_ACCEPT); } goto discard; @@ -846,7 +835,7 @@ dao_input(void) if(flags & RPL_DAO_K_FLAG) { /* signal the failure to add the node */ dao_ack_output(instance, &dao_sender_addr, sequence, - is_root ? RPL_DAO_ACK_UNABLE_TO_ACCEPT_ROOT : + is_root ? RPL_DAO_ACK_UNABLE_TO_ADD_ROUTE_AT_ROOT : RPL_DAO_ACK_UNABLE_TO_ACCEPT); } goto discard; @@ -864,8 +853,12 @@ fwd_dao: int should_ack = 0; if(flags & RPL_DAO_K_FLAG) { - /* check if this route is already installed and we can ack now! */ - /* not pending - and same seq-no means that we can ack. */ + /* + * check if this route is already installed and we can ack now! + * not pending - and same seq-no means that we can ack. + * (e.g. the route is installed already so it will not take any + * more room that it already takes - so should be ok!) + */ if((!RPL_ROUTE_IS_DAO_PENDING(rep) && rep->state.dao_seqno_in == sequence) || dag->rank == ROOT_RANK(instance)) { @@ -992,7 +985,7 @@ dao_output(rpl_parent_t *parent, uint8_t lifetime) #else /* We know that we have tried to register so now we are assuming that we have a down-link - unless this is a zero lifetime one */ - rpl_set_downward_link(lifetime != RPL_ZERO_LIFETIME); + parent->dag->instance->has_downward_route = lifetime != RPL_ZERO_LIFETIME; #endif /* RPL_WITH_DAO_ACK */ /* Sending a DAO with own prefix as target */ @@ -1122,9 +1115,7 @@ dao_ack_input(void) parent = rpl_find_parent(instance->current_dag, &UIP_IP_BUF->srcipaddr); if(parent == NULL) { - /* not a known instance - did we switch?? */ - // PRINTF("RPL: Received a DAO ACK from a not joined instance: %d", - // instance_id); + /* not a known instance - drop the packet and ignore */ uip_clear_buf(); return; } @@ -1136,7 +1127,7 @@ dao_ack_input(void) PRINTF("\n"); if(sequence == instance->my_dao_seqno) { - rpl_set_downward_link(status < 128); + instance->has_downward_route = status < 128; /* always stop the retransmit timer when the ACK arrived */ ctimer_stop(&instance->dao_retransmit_timer); @@ -1148,8 +1139,10 @@ dao_ack_input(void) #if RPL_REPAIR_ON_DAO_NACK if(status >= RPL_DAO_ACK_UNABLE_TO_ACCEPT) { - /* failed the DAO transmission - need to remove the default route. */ - /* Trigger a local repair since we can not get our DAO in... */ + /* + * Failed the DAO transmission - need to remove the default route. + * Trigger a local repair since we can not get our DAO in. + */ rpl_local_repair(instance); } #endif diff --git a/core/net/rpl/rpl-mrhof.c b/core/net/rpl/rpl-mrhof.c index 6da2ec304..f9ea76080 100644 --- a/core/net/rpl/rpl-mrhof.c +++ b/core/net/rpl/rpl-mrhof.c @@ -54,7 +54,9 @@ static void reset(rpl_dag_t *); static void neighbor_link_callback(rpl_parent_t *, int, int); +#if RPL_WITH_DAO_ACK static void dao_ack_callback(rpl_parent_t *, int); +#endif static rpl_parent_t *best_parent(rpl_parent_t *, rpl_parent_t *); static rpl_dag_t *best_dag(rpl_dag_t *, rpl_dag_t *); static rpl_rank_t calculate_rank(rpl_parent_t *, rpl_rank_t); @@ -63,7 +65,9 @@ static void update_metric_container(rpl_instance_t *); rpl_of_t rpl_mrhof = { reset, neighbor_link_callback, +#if RPL_WITH_DAO_ACK dao_ack_callback, +#endif best_parent, best_dag, calculate_rank, @@ -119,10 +123,11 @@ reset(rpl_dag_t *dag) PRINTF("RPL: Reset MRHOF\n"); } +#if RPL_WITH_DAO_ACK static void dao_ack_callback(rpl_parent_t *p, int status) { - if(status == RPL_DAO_ACK_UNABLE_TO_ACCEPT_ROOT) { + if(status == RPL_DAO_ACK_UNABLE_TO_ADD_ROUTE_AT_ROOT) { return; } /* here we need to handle failed DAO's and other stuff */ @@ -135,6 +140,7 @@ dao_ack_callback(rpl_parent_t *p, int status) neighbor_link_callback(p, MAC_TX_OK, 10); } } +#endif /* RPL_WITH_DAO_ACK */ static void neighbor_link_callback(rpl_parent_t *p, int status, int numtx) diff --git a/core/net/rpl/rpl-nbr-policy.c b/core/net/rpl/rpl-nbr-policy.c index 6f0dd9ca3..87849af40 100644 --- a/core/net/rpl/rpl-nbr-policy.c +++ b/core/net/rpl/rpl-nbr-policy.c @@ -72,6 +72,10 @@ static linkaddr_t *worst_rank_nbr; /* the parent that has the worst rank */ static rpl_rank_t worst_rank; /*---------------------------------------------------------------------------*/ #if DEBUG == DEBUG_FULL +/* + * This create a periodic call of the update_nbr function that will print + * useful debugging information when in DEBUG_FULL mode + */ static void update_nbr(void); static struct ctimer periodic_timer; static int timer_init = 0; @@ -111,9 +115,12 @@ update_nbr(void) linkaddr_t *lladdr = nbr_table_get_lladdr(ds6_neighbors, nbr); is_used = 0; - /* Check if this neighbor is used as nexthop and therefor being a - RPL child. */ - if(uip_ds6_route_is_nexthop((uip_lladdr_t *)lladdr) != 0) { + /* + * Check if this neighbor is used as nexthop and therefor being a + * RPL child. + */ + + if(uip_ds6_route_is_nexthop(&nbr->ipaddr) != 0) { is_used++; num_children++; } @@ -123,10 +130,10 @@ update_nbr(void) num_parents++; if(parent->dag != NULL && parent->dag->preferred_parent == parent) { - /* This is the preferred parent for the DAG and must not be removed */ - - /* Note: this assumes that only RPL adds default routes. */ - + /* + * This is the preferred parent for the DAG and must not be removed + * Note: this assumes that only RPL adds default routes. + */ } else if(is_used == 0 && worst_rank < INFINITE_RANK && parent->rank > 0 && parent->dag != NULL && @@ -168,9 +175,10 @@ find_removable_dis(uip_ipaddr_t *from) update_nbr(); if(num_free > 0) { - printf("num-free > 0 = %d", num_free); - printf("**** Should remove unused elements but can not... \n"); - /* return 1; */ + /* there are free entries (e.g. unsused by RPL and ND6) but since it is + used by other modules we can not pick these entries for removal. */ + PRINTF("Num-free > 0 = %d - Other for RPL/ND6 unused NBR entry exists .", + num_free); } if(num_children < MAX_CHILDREN) { return worst_rank_nbr; @@ -192,7 +200,7 @@ find_removable_dio(uip_ipaddr_t *from, rpl_dio_t *dio) return NULL; } - /* Add the new neighbor only if it is better than the preferred parent. */ + /* Add the new neighbor only if it is better than the worst parent. */ rank = instance->of->calculate_rank(NULL, dio->rank); if(rank < worst_rank - instance->min_hoprankinc / 2) { /* Found *great* neighbor - add! */ @@ -231,7 +239,8 @@ find_removable_dao(uip_ipaddr_t *from, rpl_instance_t *instance) } /*---------------------------------------------------------------------------*/ const linkaddr_t * -rpl_nbr_policy_find_removable(nbr_table_reason_t reason,void * data) { +rpl_nbr_policy_find_removable(nbr_table_reason_t reason,void * data) +{ /* When we get the DIO/DAO/DIS we know that UIP contains the incoming packet */ switch(reason) { diff --git a/core/net/rpl/rpl-of0.c b/core/net/rpl/rpl-of0.c index ed76bac4b..b0a909a4d 100644 --- a/core/net/rpl/rpl-of0.c +++ b/core/net/rpl/rpl-of0.c @@ -55,7 +55,9 @@ static void update_metric_container(rpl_instance_t *); rpl_of_t rpl_of0 = { reset, NULL, +#if RPL_WITH_DAO_ACK NULL, +#endif best_parent, best_dag, calculate_rank, diff --git a/core/net/rpl/rpl-private.h b/core/net/rpl/rpl-private.h index 161cdc532..ec885eaea 100644 --- a/core/net/rpl/rpl-private.h +++ b/core/net/rpl/rpl-private.h @@ -94,7 +94,7 @@ #define RPL_DAO_ACK_UNCONDITIONAL_ACCEPT 0 #define RPL_DAO_ACK_ACCEPT 1 /* 1 - 127 is OK but not good */ #define RPL_DAO_ACK_UNABLE_TO_ACCEPT 128 /* >127 is fail */ -#define RPL_DAO_ACK_UNABLE_TO_ACCEPT_ROOT 255 /* root can not accept */ +#define RPL_DAO_ACK_UNABLE_TO_ADD_ROUTE_AT_ROOT 255 /* root can not accept */ #define RPL_DAO_ACK_TIMEOUT -1 diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h index dfc081d4b..532df4b3a 100644 --- a/core/net/rpl/rpl.h +++ b/core/net/rpl/rpl.h @@ -181,11 +181,19 @@ typedef struct rpl_instance rpl_instance_t; * Updates the metric container for outgoing DIOs in a certain DAG. * If the objective function of the DAG does not use metric containers, * the function should set the object type to RPL_DAG_MC_NONE. + * + * dao_ack_callback(parent, status) + * + * A callback on the result of the DAO ACK. Similar to the neighbor link + * callback. A failed DAO_ACK (NACK) can be used for switching to another + * parent via changed link metric or other mechanisms. */ struct rpl_of { void (*reset)(struct rpl_dag *); void (*neighbor_link_callback)(rpl_parent_t *, int, int); +#if RPL_WITH_DAO_ACK void (*dao_ack_callback)(rpl_parent_t *, int status); +#endif rpl_parent_t *(*best_parent)(rpl_parent_t *, rpl_parent_t *); rpl_dag_t *(*best_dag)(rpl_dag_t *, rpl_dag_t *); rpl_rank_t (*calculate_rank)(rpl_parent_t *, rpl_rank_t); @@ -220,6 +228,8 @@ struct rpl_instance { /* my last registered DAO that I might be waiting for ACK on */ uint8_t my_dao_seqno; uint8_t my_dao_transmissions; + /* this is intended to keep track if this instance have a route downward */ + uint8_t has_downward_route; rpl_rank_t max_rankinc; rpl_rank_t min_hoprankinc; uint16_t lifetime_unit; /* lifetime in seconds = l_u * d_l */ @@ -302,11 +312,11 @@ enum rpl_mode rpl_get_mode(void); /** - * Get the RPL's best guess on if we have downward link or not. + * Get the RPL's best guess on if we have downward route or not. * - * \retval 1 if we have a downward link, 0 if not. + * \retval 1 if we have a downward route from RPL Root, 0 if not. */ -int rpl_has_downward_link(void); +int rpl_has_downward_route(void); /*---------------------------------------------------------------------------*/ #endif /* RPL_H */ diff --git a/regression-tests/21-large-rpl/code/node/client.c b/regression-tests/21-large-rpl/code/node/client.c index 36dc40923..1e82e2df0 100644 --- a/regression-tests/21-large-rpl/code/node/client.c +++ b/regression-tests/21-large-rpl/code/node/client.c @@ -100,7 +100,7 @@ PROCESS_THREAD(http_example_process, ev, data) while(1) { PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); etimer_reset(&et); - if(connect && rpl_has_downward_link()) { + if(connect && rpl_has_downward_route()) { printf("#A color=green\n"); http_socket_get(&s, "http://www.contiki-os.org/", 0, 0, callback, NULL); From 4f28289df2b411154d4f5cf8d3235b54da515d94 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt Date: Mon, 28 Mar 2016 14:06:47 +0200 Subject: [PATCH 134/374] Added a pfs_remove() function and a pfs_seek() stub to the Commodore platforms. - "Normalized" some Assembly code. - Implemented CFS_APPEND in pfs_open(). - Made CFS_WRITE work in VICE's virtual disk/file system. --- .gitignore | 2 +- cpu/6502/lib/pfs.h | 16 +- platform/c128/Makefile.c128 | 2 +- platform/c128/lib/pfs.S | 521 +++++++++++++++++---------------- platform/c128/lib/pfs_remove.S | 59 ++++ platform/c128/lib/pfs_seek.S | 46 +++ platform/c128/lib/pfs_write.S | 47 +-- platform/c64/Makefile.c64 | 2 +- platform/c64/lib/pfs.S | 521 +++++++++++++++++---------------- platform/c64/lib/pfs_remove.S | 59 ++++ platform/c64/lib/pfs_seek.S | 46 +++ platform/c64/lib/pfs_write.S | 47 +-- 12 files changed, 818 insertions(+), 550 deletions(-) create mode 100644 platform/c128/lib/pfs_remove.S create mode 100644 platform/c128/lib/pfs_seek.S create mode 100644 platform/c64/lib/pfs_remove.S create mode 100644 platform/c64/lib/pfs_seek.S diff --git a/.gitignore b/.gitignore index c166681da..f4905fca9 100644 --- a/.gitignore +++ b/.gitignore @@ -80,7 +80,7 @@ contiki-cc2530dk.lib *.dsc #cc65 build artifacts -*.S +*.s *.eth *.dsk *.po diff --git a/cpu/6502/lib/pfs.h b/cpu/6502/lib/pfs.h index 25c62e8bf..73102ce55 100644 --- a/cpu/6502/lib/pfs.h +++ b/cpu/6502/lib/pfs.h @@ -27,7 +27,7 @@ * SUCH DAMAGE. * * This file is part of the Contiki operating system. - * + * * Author: Oliver Schmidt * */ @@ -35,11 +35,13 @@ #ifndef PFS_H_ #define PFS_H_ -int __fastcall__ pfs_open(const char* name, int flags); -void __fastcall__ pfs_close(int fd); -int __fastcall__ pfs_read(int fd, void* buf, unsigned int len); -int __fastcall__ pfs_write(int fd, void* buf, unsigned int len); -int __fastcall__ pfs_seek(int fd, int offset, int whence); -int __fastcall__ pfs_remove(const char *name); +#include + +int __fastcall__ pfs_open(const char *name, int flags); +void __fastcall__ pfs_close(int fd); +int __fastcall__ pfs_read(int fd, void *buf, unsigned int len); +int __fastcall__ pfs_write(int fd, const void *buf, unsigned int len); +off_t __fastcall__ pfs_seek(int fd, off_t offset, int whence); +int __fastcall__ pfs_remove(const char *name); #endif /* PFS_H_ */ diff --git a/platform/c128/Makefile.c128 b/platform/c128/Makefile.c128 index b186fac60..55889d4ab 100644 --- a/platform/c128/Makefile.c128 +++ b/platform/c128/Makefile.c128 @@ -31,7 +31,7 @@ # Author: Oliver Schmidt # -CONTIKI_TARGET_SOURCEFILES += lseek.c pfs.S pfs_write.S +CONTIKI_TARGET_SOURCEFILES += lseek.c pfs.S pfs_remove.S pfs_seek.S pfs_write.S CONTIKI_CPU = $(CONTIKI)/cpu/6502 include $(CONTIKI_CPU)/Makefile.6502 diff --git a/platform/c128/lib/pfs.S b/platform/c128/lib/pfs.S index 62a2a7840..7947b67d8 100644 --- a/platform/c128/lib/pfs.S +++ b/platform/c128/lib/pfs.S @@ -29,99 +29,212 @@ ; This file is part of the Contiki operating system. ; ; Author: Kajtar Zsolt +; Author: Greg King ; ;--------------------------------------------------------------------- - .define F_IDE64 0 ; support IDE64, not on C128 +.define F_IDE64 0 ; C128 doesn't have IDE64 - .constructor init_pfs - .destructor done_pfs - .importzp ptr1, ptr2, ptr3, sp - .import curunit, __filetype, popax, addysp, subysp - .export pfs_rwcommon, pfs_rwsetflags, pfs_rwcommonend - .if F_IDE64 - .export ide64_rwprepare, ide64_rwfinish - .endif - .export _pfs_open, _pfs_read, _pfs_close + .constructor init_pfs + .destructor done_pfs + .importzp sp, ptr1, ptr2, ptr3 + .import curunit, __filetype, popax, addysp, subysp + .export pfs_rwcommon, pfs_rwsetflags, pfs_rwcommonend +.if F_IDE64 + .export ide64_rwprepare, ide64_rwfinish +.endif + .export cmdc, flags + .export pfs_makename, pfs_scratch + + .export _pfs_open, _pfs_read, _pfs_close ;--------------------------------------------------------------------- -F_EOF = $80 -F_NBLK = $40 -F_OPEN = $20 -F_MAXLEN = 80 ;max filename length -ST = $90 ;status -FN = $BB ;filename -FNL = $B7 ;filenamelength -LF = $B8 ;logical file number -SA = $B9 ;secondary address -OPEN = $FFC0 -CLOSE = $FFC3 -CHKIN = $FFC6 -CHKOUT = $FFC9 -CLRCHN = $FFCC -CHRIN = $FFCF -CHROUT = $FFD2 -SETLFS = $FFBA -SETNAM = $FFBD -CLALL = $FFE7 -WRITE = $DEF1 -READ = $DEF4 +MAXLEN = 80 ;maximum filename length + +; Flag bits +F_EOF = %10000000 ;end of file +F_NBLK = %01000000 ;block read/write not available +F_OPEN = %00100000 + +; Kernal variables +ST := $90 ;status +FN := $BB ;filename +FNL := $B7 ;filename length +LF := $B8 ;logical file number + +OPNVec := $031A ;address vector to OPEN function's code + +; IDEDOS function +READ := $DEF4 + +; Kernal functions +SETLFS := $FFBA +SETNAM := $FFBD +OPEN := $FFC0 +CLOSE := $FFC3 +CHKIN := $FFC6 +CHKOUT := $FFC9 +CLRCHN := $FFCC +CHRIN := $FFCF +CHROUT := $FFD2 ;--------------------------------------------------------------------- .data -illchr: .byte $3A, $2A, $3F, $3D ;illegal chars -pw: .byte $2C, $50, $2C, $57 ;,p,w +; illchr and sw must stay together because the comma, also, is illegal in names. +illchr: .byte "*?:=" ;illegal chars +sw: .byte ",s,w" cmdc: .byte 0 -flags: .res 10 +flags: .res 10 ;(Kernal allows only ten open files) ;--------------------------------------------------------------------- .segment "ONCE" init_pfs: - ldy #F_MAXLEN+8 - jsr subysp ;allocate - lda #0 - sta FNL ;no name - ldy #15-1 - jsr open2 ;open command channel + ldy #MAXLEN + 8 + jsr subysp ;allocate because open2 will free it + lda #0 ;no name, file number 1 + sta FNL + ldy #15 - 1 ;secondary address 15 + jsr open2 ;open command channel sta cmdc rts ;--------------------------------------------------------------------- .code -error3: jmp error - _pfs_open: - sta ptr2 - ; Pop and store name + sta ptr2 ;save open-mode flags + + ; Get and store name jsr popax + jsr pfs_makename + lda FNL + beq error ;must have a filename + + lda #2 - 1 ;file number + tay ;secondary address +open2: sta ptr2 + sty ptr2 + 1 + +next: inc ptr2 ;next file number + ldx ptr2 ;file number + cpx #.sizeof(flags) + 1 + bcs error ;no more files + lda flags - 1,x + bne next ;already used + lda ptr2 + 1 + bne nextsa + inx + stx ptr2 + 1 +nextsa: inc ptr2 + 1 ;next channel +retr: lda ptr2 ;file number + ldx curunit + ldy ptr2 + 1 ;secondary address (channel number) + jsr SETLFS + jsr OPEN ;open a pair of files (in computer and drive) + bcs oerr ;branch if could not open computer file + ldx cmdc + beq opok ;branch if error channel just was openned + jsr CHKIN + bcs error + jsr CHRIN + pha ;first digit of error code + jsr CHRIN + sta ptr1 ;second digit +@L4: jsr CHRIN ;flush status message + lda ST + beq @L4 + jsr CLRCHN + pla + cmp #'2' + bcc opok ;no serious error + pha + lda ptr2 + jsr CLOSE ;close computer file + pla + ldx ptr1 + cmp #'7' ;no channel? + bne nnoc + cpx #'0' + bne error ;not "no channel" + lda ptr2 + 1 + cmp #14 + bcc nextsa ;try next channel + bcs error ;give up + +opok: ldx ptr2 + lda #F_OPEN + sta flags - 1,x + txa ;OK, return file number +ret0: ldx #>$0000 +ret: ldy #MAXLEN + 8 ;free filename space + jmp addysp + +oerr: dec ptr2 + 1 + cmp #2 ;already open, + beq next ;retry with next + +error: lda #<-1 + tax ;failed + bne ret + +nnoc: inc ptr3 + bne error ;no retry + cmp #'6' + bne error ;not "file exists" + cpx #'3' + bne error + jsr pfs_scratch + bcc retr + bcs error ;branch always + +pfs_scratch: + ldx cmdc + jsr CHKOUT + bcs @L5 + ldy #1 + lda #'s' ;scratch +@L4: jsr CHROUT + lda (FN),y + iny + cmp #',' + bne @L4 + lda #$0D ;carriage return + jsr CHROUT + jsr CLRCHN + clc ;carry = 0: OK +@L5: rts ;carry = 1: error + +pfs_makename: sta FN - stx FN+1 ;filename (kernal) - ldy #F_MAXLEN+8 - jsr subysp ;allocate name - ldy #255 + stx FN+1 ;Kernal filename pointer + ldy #MAXLEN + 8 + jsr subysp ;allocate name space + + ; Validate the name; and, find its length + ldy #<-1 sty ptr3 sty ptr1 @L10: iny - cpy #F_MAXLEN - bcs error3 ;too long... - ldx #4 ;4+1 (comma) + cpy #MAXLEN + bcs badchr ;too long + lda (FN),y + ldx #.sizeof(illchr); 4 + 1 (includes comma) @L12: cmp illchr,x - beq error3 ;illegal char? + beq badchr ;illegal char dex bpl @L12 - cmp #$2F + cmp #'/' bne @L11 - sty ptr1 ;last slash -@L11: lda (FN),y + sty ptr1 ;last slash +@L11: tax ;test for '\0' bne @L10 - sty FNL + cpy #0 + beq badchr ;no name - tay - tax - lda #$30 ;this partition + tay ;zero index reg. + lda #'0' ;drive 0 or current partition sta (sp),y iny inc ptr1 beq nopath - lda #$2F + lda #'/' @L13: sta (sp),y iny lda (FN,x) @@ -130,158 +243,67 @@ _pfs_open: inc FN+1 @L14: cpy ptr1 bcc @L13 - lda #$2F + ;lda #'/' ; (.A already has a slash) sta (sp),y iny -nopath: lda #$3A +nopath: lda #':' @L16: sta (sp),y iny lda (FN,x) inc FN bne @L15 inc FN+1 -@L15: ora #0 +@L15: ora #$00 ;test for '\0' bne @L16 lsr ptr2 - bcs ro ;read only + bcs ro ;read-only (read-write not supported) lda __filetype - sta pw+1 ;set filetype - ldx #252 -@L20: lda pw-252,x - sta (sp),y ;write + sta sw + 1 ;set filetype + lsr ptr2 + lda #'w' ;write-only + lsr ptr2 + bcc write + lda #'a' ;append +write: sta sw + 3 ;set mode + ldx #$0100 - .sizeof(sw) +@L20: lda sw - ($0100 - .sizeof(sw)),x + sta (sp),y iny inx bne @L20 -ro: tya ;name length (kernal) +ro: tya ;pathname length ldx sp ldy sp+1 - jsr SETNAM +namset: jmp SETNAM - lda #0 ;file number - tay ;secondary address -open2: sta ptr2 - sty ptr2+1 - -next: inc ptr2 ;next file number - ldx ptr2 ;file number - cpx #11 - bcs error ;no more files - lda flags-1,x - bne next ;already used - lda ptr2+1 - bne nextsa - inx - stx ptr2+1 -nextsa: inc ptr2+1 ;next channel -retr: lda ptr2 ;file number - ldx curunit - ldy ptr2+1 ;secondary address - jsr SETLFS - jsr OPEN ;open - bcs oerr - ldx cmdc - beq opok ;error channel open - jsr CHKIN - bcs error - jsr CHRIN - pha - jsr CHRIN - sta ptr1 -@L4: jsr CHRIN - lda ST - beq @L4 - jsr CLRCHN - pla - tax - lsr - cmp #$18 ;no serious error - beq opok - txa - pha - lda ptr2 - jsr CLOSE ;close - pla - ldx ptr1 - cmp #$37 ;no channel? - bne nnoc - cpx #$30 - bne error ;not no channel - lda ptr2+1 - cmp #14 - bcc nextsa ;try next channel - bcs error ;give up - -opok: ldx ptr2 - lda #F_OPEN - sta flags-1,x - txa ;ok, return file number - ldx #0 -ret: ldy #F_MAXLEN+8 ; free filename - jmp addysp - -oerr: dec ptr2+1 - cmp #2 ;already open, - beq next ;retry with next - -error: lda #$FF - tax ;failed - bne ret - -nnoc: inc ptr3 - bne error ;no retry - cmp #$36 - bne error ;no exists - cpx #$33 - bne error - ldx cmdc - jsr CHKOUT - bcs error - lda FNL - sec - sbc #5 - tax - lda #$53 ;scratch - jsr CHROUT - ldy #1 -@L4: lda (FN),y - iny - jsr CHROUT - dex - bne @L4 - lda #$3D - jsr CHROUT - iny - lda (FN),y - jsr CHROUT - lda #$0d - jsr CHROUT - jsr CLRCHN - jmp retr +badchr: lda #0 + beq namset .proc _pfs_read jsr pfs_rwcommon ; pop params, check handle beq error2 ; not open bmi eof - .if F_IDE64 - asl + +.if F_IDE64 + asl a bmi nblk ; no block operation jsr CHKIN bcs error2 - + ; check support jsr ide64_rwprepare bcs norm - - ; read + + ; do a block read jsr READ bcs nosup jmp ide64_rwfinish nosup: lda #F_NBLK jsr pfs_rwsetflags - .endif +.endif ; Valid lfn. Make it the input file nblk: jsr CHKIN @@ -292,15 +314,15 @@ norm: ldy #0 @L3: inc ptr1 bne @L0 inc ptr1+1 - beq done ; branch always + beq done ; Read the next byte @L0: jsr CHRIN tax ; save the input byte - lda ST ; read the IEEE status - cmp #1 ; save it - and #%10111111 ; check anything but the EOI bit + lda ST ; read the file status + cmp #$01 ; save it + and #%10111111 ; check anything but the EOF bit bne error5 ; assume device not present ; Store the byte just read @@ -310,45 +332,60 @@ norm: ldy #0 bne @L1 inc ptr2+1 ; *buf++ = A; - ; Get the status again and check the EOI bit -@L1: bcc @L3 ; loop if no end of file + ; Get the status again; and, check the EOF bit +@L1: bcc @L3 ; loop if not end of file - ; Set the EOI flag and bail out + ; Set the EOF flag; and, bail out lda #F_EOF jsr pfs_rwsetflags - ; Read done, close the input channel -done: jsr CLRCHN ; clrchn + ; Read done; cancel the input channel +done: jsr CLRCHN ; Return the number of chars read -eof: jmp pfs_rwcommonend +eof: +; jmp pfs_rwcommonend ; (fall through) +.endproc + +.proc pfs_rwcommonend + lda ptr2 + sec + sbc ptr3 + pha + lda ptr2+1 + sbc ptr3+1 + tax + pla + rts .endproc - ; Error entry, file is not open done_pfs: - ldx #10 -@L2: ldy flags-1,x ; file open? + ldx #.sizeof(flags) +@L2: ldy flags - 1,x ; file open? beq @L1 txa - jsr _pfs_close + jsr close1 @L1: dex - bne @L2 + bne @L2 rts -error5: jsr CLRCHN ; clrchn +error5: jsr CLRCHN -error2: ldx #255 + ; Error entry, file is not open +error2: ldx #>-1 txa rts _pfs_close: - pha - jsr CLOSE ;close + cmp #.sizeof(flags) + 1 + bcs close0 ; don't close if not valid file number +close1: pha + jsr CLOSE pla tax - lda #0 - sta flags-1,x - rts + lda #$00 + sta flags - 1,x +close0: rts ; .X = file number .proc pfs_rwcommon eor #$FF @@ -366,70 +403,56 @@ _pfs_close: jsr popax ; get the handle sta LF - lda #0 - beq pfs_rwsetflags + lda #$00 +; beq pfs_rwsetflags ; (fall through) .endproc - .if F_IDE64 -.proc ide64_rwprepare - sec - lda ptr1+1 - eor #255 - beq small ; too small, not worth it - tay - lda ptr1 ; setup registers - eor #255 - tax - lda $031B - eor #$DE - bne noide ; open vector set? - lda $DE60 - eor #$49 - bne noide ; check identification - lda $DE61 - eor #$44 - bne noide - lda $DE62 - eor #$45 - bne noide - clc - lda #ptr2 -small: rts - -noide: lda #F_NBLK - bne pfs_rwsetflags -.endproc - .endif - .proc pfs_rwsetflags ldx LF - ora flags-1,x - sta flags-1,x + ora flags - 1,x + sta flags - 1,x rts .endproc - .if F_IDE64 +.if F_IDE64 +.proc ide64_rwprepare + sec ; assume it won't use IDEDOS + lda ptr1+1 + eor #$FF ; convert -count-1 back to count + beq small ; too small, not worth it + tay + lda ptr1 ; set up registers + eor #$FF + tax + lda OPNVec+1 + eor #>$DE00 + bne noide ; is OPEN vector set to IDEDOS? + lda $DE60 + eor #'i' + bne noide ; check identification + lda $DE61 + eor #'d' + bne noide + lda $DE62 + eor #'e' + bne noide + clc ; it will use IDEDOS + lda #ptr2 +small: rts + +noide: lda #F_NBLK + bne pfs_rwsetflags +.endproc + .proc ide64_rwfinish - txa + txa ; push .YX pha tya pha jsr CLRCHN - pla - tax - pla - rts -.endproc - .endif - -.proc pfs_rwcommonend - lda ptr2 - sec - sbc ptr3 - pha - lda ptr2+1 - sbc ptr3+1 + pla ; pull .XA tax pla rts .endproc +.endif diff --git a/platform/c128/lib/pfs_remove.S b/platform/c128/lib/pfs_remove.S new file mode 100644 index 000000000..7477e4314 --- /dev/null +++ b/platform/c128/lib/pfs_remove.S @@ -0,0 +1,59 @@ +; +; Copyright (c) 2016, Greg King +; 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 author nor the names of contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +; +; Author: Greg King +; +;--------------------------------------------------------------------- + .importzp ptr2 + .import addysp + .import pfs_makename, pfs_scratch + + .export _pfs_remove +;--------------------------------------------------------------------- +MAXLEN = 80 ; max. filename length + +FNL := $B7 ; filename length +;--------------------------------------------------------------------- +.proc _pfs_remove + asl ptr2 ; force pfs_makename to format for pfs_scratch + jsr pfs_makename + ldx FNL + beq error ; no name + + jsr pfs_scratch + ldx #>$0000 + bcs error +ret: txa + ldy #MAXLEN + 8 ; free filename space + jmp addysp + +error: dex ;(ldx #>-1) + bne ret +.endproc diff --git a/platform/c128/lib/pfs_seek.S b/platform/c128/lib/pfs_seek.S new file mode 100644 index 000000000..4ef0014d1 --- /dev/null +++ b/platform/c128/lib/pfs_seek.S @@ -0,0 +1,46 @@ +; +; Copyright (c) 2016, Greg King +; 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 author nor the names of contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +; +; Author: Greg King +; +;--------------------------------------------------------------------- + .importzp sp, sreg, ptr1, ptr2, ptr3 + .import popax, incsp6 + .import cmdc, flags + + .export _pfs_seek +;--------------------------------------------------------------------- +.proc _pfs_seek + lda #<-1 ; seek not implemented + tax + stx sreg ; return long data type + stx sreg+1 + jmp incsp6 ; drop int and long arguments from stack +.endproc diff --git a/platform/c128/lib/pfs_write.S b/platform/c128/lib/pfs_write.S index 0fc8e3160..e17ff91b7 100644 --- a/platform/c128/lib/pfs_write.S +++ b/platform/c128/lib/pfs_write.S @@ -31,27 +31,33 @@ ; Author: Kajtar Zsolt ; ;--------------------------------------------------------------------- - .define F_IDE64 0 ; support IDE64, 100 byte only +.define F_IDE64 0 ; c128 doesn't have IDE64 - .importzp ptr1, ptr2 - .import pfs_rwcommon, pfs_rwsetflags, pfs_rwcommonend - .if F_IDE64 - .import ide64_rwprepare, ide64_rwfinish - .endif - .export _pfs_write + .importzp ptr1, ptr2 + .import pfs_rwcommon, pfs_rwsetflags, pfs_rwcommonend +.if F_IDE64 + .import ide64_rwprepare, ide64_rwfinish +.endif + + .export _pfs_write ;--------------------------------------------------------------------- -F_NBLK = $40 -ST = $90 ;status -CHKOUT = $FFC9 -CLRCHN = $FFCC -CHROUT = $FFD2 -WRITE = $DEF1 +F_NBLK = %01000000 ;block read/write not available + +ST := $90 ;status + +; IDEDOS function +WRITE := $DEF1 + +; Kernal functions +CHKOUT := $FFC9 +CLRCHN := $FFCC +CHROUT := $FFD2 ;--------------------------------------------------------------------- .code -error5: jsr CLRCHN ; clrchn +error5: jsr CLRCHN -error2: ldx #255 +error2: ldx #>-1 txa rts @@ -59,8 +65,8 @@ error2: ldx #255 jsr pfs_rwcommon ; pop params, check handle beq error2 ; not open - .if F_IDE64 - asl +.if F_IDE64 + asl a bmi nblk ; no block operation jsr CHKOUT @@ -70,7 +76,7 @@ error2: ldx #255 jsr ide64_rwprepare bcs norm - ; write + ; do a block write jsr WRITE bcs nosup jmp ide64_rwfinish @@ -98,10 +104,9 @@ norm: ldy #0 lda ST beq @L3 bne error5 ; bail out on errors -@L2: - ; Wrote all chars, close the output channel - jsr CLRCHN + ; Wrote all chars.; cancel the output channel +@L2: jsr CLRCHN ; Return the number of chars written jmp pfs_rwcommonend diff --git a/platform/c64/Makefile.c64 b/platform/c64/Makefile.c64 index bf0197565..5dce702a8 100644 --- a/platform/c64/Makefile.c64 +++ b/platform/c64/Makefile.c64 @@ -31,7 +31,7 @@ # Author: Oliver Schmidt # -CONTIKI_TARGET_SOURCEFILES += lseek.c pfs.S pfs_write.S +CONTIKI_TARGET_SOURCEFILES += lseek.c pfs.S pfs_remove.S pfs_seek.S pfs_write.S CONTIKI_CPU = $(CONTIKI)/cpu/6502 include $(CONTIKI_CPU)/Makefile.6502 diff --git a/platform/c64/lib/pfs.S b/platform/c64/lib/pfs.S index c63d08d2e..49ef496ec 100644 --- a/platform/c64/lib/pfs.S +++ b/platform/c64/lib/pfs.S @@ -29,99 +29,212 @@ ; This file is part of the Contiki operating system. ; ; Author: Kajtar Zsolt +; Author: Greg King ; ;--------------------------------------------------------------------- - .define F_IDE64 1 ; support IDE64, 100 byte only +.define F_IDE64 1 ; support IDE64, >= $0100 bytes only - .constructor init_pfs - .destructor done_pfs - .importzp ptr1, ptr2, ptr3, sp - .import curunit, __filetype, popax, addysp, subysp - .export pfs_rwcommon, pfs_rwsetflags, pfs_rwcommonend - .if F_IDE64 - .export ide64_rwprepare, ide64_rwfinish - .endif - .export _pfs_open, _pfs_read, _pfs_close + .constructor init_pfs + .destructor done_pfs + .importzp sp, ptr1, ptr2, ptr3 + .import curunit, __filetype, popax, addysp, subysp + .export pfs_rwcommon, pfs_rwsetflags, pfs_rwcommonend +.if F_IDE64 + .export ide64_rwprepare, ide64_rwfinish +.endif + .export cmdc, flags + .export pfs_makename, pfs_scratch + + .export _pfs_open, _pfs_read, _pfs_close ;--------------------------------------------------------------------- -F_EOF = $80 -F_NBLK = $40 -F_OPEN = $20 -F_MAXLEN = 80 ;max filename length -ST = $90 ;status -FN = $BB ;filename -FNL = $B7 ;filenamelength -LF = $B8 ;logical file number -SA = $B9 ;secondary address -OPEN = $FFC0 -CLOSE = $FFC3 -CHKIN = $FFC6 -CHKOUT = $FFC9 -CLRCHN = $FFCC -CHRIN = $FFCF -CHROUT = $FFD2 -SETLFS = $FFBA -SETNAM = $FFBD -CLALL = $FFE7 -WRITE = $DEF1 -READ = $DEF4 +MAXLEN = 80 ;maximum filename length + +; Flag bits +F_EOF = %10000000 ;end of file +F_NBLK = %01000000 ;block read/write not available +F_OPEN = %00100000 + +; Kernal variables +ST := $90 ;status +FN := $BB ;filename +FNL := $B7 ;filename length +LF := $B8 ;logical file number + +OPNVec := $031A ;address vector to OPEN function's code + +; IDEDOS function +READ := $DEF4 + +; Kernal functions +SETLFS := $FFBA +SETNAM := $FFBD +OPEN := $FFC0 +CLOSE := $FFC3 +CHKIN := $FFC6 +CHKOUT := $FFC9 +CLRCHN := $FFCC +CHRIN := $FFCF +CHROUT := $FFD2 ;--------------------------------------------------------------------- .data -illchr: .byte $3A, $2A, $3F, $3D ;illegal chars -pw: .byte $2C, $50, $2C, $57 ;,p,w +; illchr and sw must stay together because the comma, also, is illegal in names. +illchr: .byte "*?:=" ;illegal chars +sw: .byte ",s,w" cmdc: .byte 0 -flags: .res 10 +flags: .res 10 ;(Kernal allows only ten open files) ;--------------------------------------------------------------------- .segment "ONCE" init_pfs: - ldy #F_MAXLEN+8 - jsr subysp ;allocate - lda #0 - sta FNL ;no name - ldy #15-1 - jsr open2 ;open command channel + ldy #MAXLEN + 8 + jsr subysp ;allocate because open2 will free it + lda #0 ;no name, file number 1 + sta FNL + ldy #15 - 1 ;secondary address 15 + jsr open2 ;open command channel sta cmdc rts ;--------------------------------------------------------------------- .code -error3: jmp error - _pfs_open: - sta ptr2 - ; Pop and store name + sta ptr2 ;save open-mode flags + + ; Get and store name jsr popax + jsr pfs_makename + lda FNL + beq error ;must have a filename + + lda #2 - 1 ;file number + tay ;secondary address +open2: sta ptr2 + sty ptr2 + 1 + +next: inc ptr2 ;next file number + ldx ptr2 ;file number + cpx #.sizeof(flags) + 1 + bcs error ;no more files + lda flags - 1,x + bne next ;already used + lda ptr2 + 1 + bne nextsa + inx + stx ptr2 + 1 +nextsa: inc ptr2 + 1 ;next channel +retr: lda ptr2 ;file number + ldx curunit + ldy ptr2 + 1 ;secondary address (channel number) + jsr SETLFS + jsr OPEN ;open a pair of files (in computer and drive) + bcs oerr ;branch if could not open computer file + ldx cmdc + beq opok ;branch if error channel just was openned + jsr CHKIN + bcs error + jsr CHRIN + pha ;first digit of error code + jsr CHRIN + sta ptr1 ;second digit +@L4: jsr CHRIN ;flush status message + lda ST + beq @L4 + jsr CLRCHN + pla + cmp #'2' + bcc opok ;no serious error + pha + lda ptr2 + jsr CLOSE ;close computer file + pla + ldx ptr1 + cmp #'7' ;no channel? + bne nnoc + cpx #'0' + bne error ;not "no channel" + lda ptr2 + 1 + cmp #14 + bcc nextsa ;try next channel + bcs error ;give up + +opok: ldx ptr2 + lda #F_OPEN + sta flags - 1,x + txa ;OK, return file number +ret0: ldx #>$0000 +ret: ldy #MAXLEN + 8 ;free filename space + jmp addysp + +oerr: dec ptr2 + 1 + cmp #2 ;already open, + beq next ;retry with next + +error: lda #<-1 + tax ;failed + bne ret + +nnoc: inc ptr3 + bne error ;no retry + cmp #'6' + bne error ;not "file exists" + cpx #'3' + bne error + jsr pfs_scratch + bcc retr + bcs error ;branch always + +pfs_scratch: + ldx cmdc + jsr CHKOUT + bcs @L5 + ldy #1 + lda #'s' ;scratch +@L4: jsr CHROUT + lda (FN),y + iny + cmp #',' + bne @L4 + lda #$0D ;carriage return + jsr CHROUT + jsr CLRCHN + clc ;carry = 0: OK +@L5: rts ;carry = 1: error + +pfs_makename: sta FN - stx FN+1 ;filename (kernal) - ldy #F_MAXLEN+8 - jsr subysp ;allocate name - ldy #255 + stx FN+1 ;Kernal filename pointer + ldy #MAXLEN + 8 + jsr subysp ;allocate name space + + ; Validate the name; and, find its length + ldy #<-1 sty ptr3 sty ptr1 @L10: iny - cpy #F_MAXLEN - bcs error3 ;too long... - ldx #4 ;4+1 (comma) + cpy #MAXLEN + bcs badchr ;too long + lda (FN),y + ldx #.sizeof(illchr); 4 + 1 (includes comma) @L12: cmp illchr,x - beq error3 ;illegal char? + beq badchr ;illegal char dex bpl @L12 - cmp #$2F + cmp #'/' bne @L11 - sty ptr1 ;last slash -@L11: lda (FN),y + sty ptr1 ;last slash +@L11: tax ;test for '\0' bne @L10 - sty FNL + cpy #0 + beq badchr ;no name - tay - tax - lda #$30 ;this partition + tay ;zero index reg. + lda #'0' ;drive 0 or current partition sta (sp),y iny inc ptr1 beq nopath - lda #$2F + lda #'/' @L13: sta (sp),y iny lda (FN,x) @@ -130,158 +243,67 @@ _pfs_open: inc FN+1 @L14: cpy ptr1 bcc @L13 - lda #$2F + ;lda #'/' ; (.A already has a slash) sta (sp),y iny -nopath: lda #$3A +nopath: lda #':' @L16: sta (sp),y iny lda (FN,x) inc FN bne @L15 inc FN+1 -@L15: ora #0 +@L15: ora #$00 ;test for '\0' bne @L16 lsr ptr2 - bcs ro ;read only + bcs ro ;read-only (read-write not supported) lda __filetype - sta pw+1 ;set filetype - ldx #252 -@L20: lda pw-252,x - sta (sp),y ;write + sta sw + 1 ;set filetype + lsr ptr2 + lda #'w' ;write-only + lsr ptr2 + bcc write + lda #'a' ;append +write: sta sw + 3 ;set mode + ldx #$0100 - .sizeof(sw) +@L20: lda sw - ($0100 - .sizeof(sw)),x + sta (sp),y iny inx bne @L20 -ro: tya ;name length (kernal) +ro: tya ;pathname length ldx sp ldy sp+1 - jsr SETNAM +namset: jmp SETNAM - lda #0 ;file number - tay ;secondary address -open2: sta ptr2 - sty ptr2+1 - -next: inc ptr2 ;next file number - ldx ptr2 ;file number - cpx #11 - bcs error ;no more files - lda flags-1,x - bne next ;already used - lda ptr2+1 - bne nextsa - inx - stx ptr2+1 -nextsa: inc ptr2+1 ;next channel -retr: lda ptr2 ;file number - ldx curunit - ldy ptr2+1 ;secondary address - jsr SETLFS - jsr OPEN ;open - bcs oerr - ldx cmdc - beq opok ;error channel open - jsr CHKIN - bcs error - jsr CHRIN - pha - jsr CHRIN - sta ptr1 -@L4: jsr CHRIN - lda ST - beq @L4 - jsr CLRCHN - pla - tax - lsr - cmp #$18 ;no serious error - beq opok - txa - pha - lda ptr2 - jsr CLOSE ;close - pla - ldx ptr1 - cmp #$37 ;no channel? - bne nnoc - cpx #$30 - bne error ;not no channel - lda ptr2+1 - cmp #14 - bcc nextsa ;try next channel - bcs error ;give up - -opok: ldx ptr2 - lda #F_OPEN - sta flags-1,x - txa ;ok, return file number - ldx #0 -ret: ldy #F_MAXLEN+8 ; free filename - jmp addysp - -oerr: dec ptr2+1 - cmp #2 ;already open, - beq next ;retry with next - -error: lda #$FF - tax ;failed - bne ret - -nnoc: inc ptr3 - bne error ;no retry - cmp #$36 - bne error ;no exists - cpx #$33 - bne error - ldx cmdc - jsr CHKOUT - bcs error - lda FNL - sec - sbc #5 - tax - lda #$53 ;scratch - jsr CHROUT - ldy #1 -@L4: lda (FN),y - iny - jsr CHROUT - dex - bne @L4 - lda #$3D - jsr CHROUT - iny - lda (FN),y - jsr CHROUT - lda #$0d - jsr CHROUT - jsr CLRCHN - jmp retr +badchr: lda #0 + beq namset .proc _pfs_read jsr pfs_rwcommon ; pop params, check handle beq error2 ; not open bmi eof - .if F_IDE64 - asl + +.if F_IDE64 + asl a bmi nblk ; no block operation jsr CHKIN bcs error2 - + ; check support jsr ide64_rwprepare bcs norm - - ; read + + ; do a block read jsr READ bcs nosup jmp ide64_rwfinish nosup: lda #F_NBLK jsr pfs_rwsetflags - .endif +.endif ; Valid lfn. Make it the input file nblk: jsr CHKIN @@ -292,15 +314,15 @@ norm: ldy #0 @L3: inc ptr1 bne @L0 inc ptr1+1 - beq done ; branch always + beq done ; Read the next byte @L0: jsr CHRIN tax ; save the input byte - lda ST ; read the IEEE status - cmp #1 ; save it - and #%10111111 ; check anything but the EOI bit + lda ST ; read the file status + cmp #$01 ; save it + and #%10111111 ; check anything but the EOF bit bne error5 ; assume device not present ; Store the byte just read @@ -310,45 +332,60 @@ norm: ldy #0 bne @L1 inc ptr2+1 ; *buf++ = A; - ; Get the status again and check the EOI bit -@L1: bcc @L3 ; loop if no end of file + ; Get the status again; and, check the EOF bit +@L1: bcc @L3 ; loop if not end of file - ; Set the EOI flag and bail out + ; Set the EOF flag; and, bail out lda #F_EOF jsr pfs_rwsetflags - ; Read done, close the input channel -done: jsr CLRCHN ; clrchn + ; Read done; cancel the input channel +done: jsr CLRCHN ; Return the number of chars read -eof: jmp pfs_rwcommonend +eof: +; jmp pfs_rwcommonend ; (fall through) +.endproc + +.proc pfs_rwcommonend + lda ptr2 + sec + sbc ptr3 + pha + lda ptr2+1 + sbc ptr3+1 + tax + pla + rts .endproc - ; Error entry, file is not open done_pfs: - ldx #10 -@L2: ldy flags-1,x ; file open? + ldx #.sizeof(flags) +@L2: ldy flags - 1,x ; file open? beq @L1 txa - jsr _pfs_close + jsr close1 @L1: dex - bne @L2 + bne @L2 rts -error5: jsr CLRCHN ; clrchn +error5: jsr CLRCHN -error2: ldx #255 + ; Error entry, file is not open +error2: ldx #>-1 txa rts _pfs_close: - pha - jsr CLOSE ;close + cmp #.sizeof(flags) + 1 + bcs close0 ; don't close if not valid file number +close1: pha + jsr CLOSE pla tax - lda #0 - sta flags-1,x - rts + lda #$00 + sta flags - 1,x +close0: rts ; .X = file number .proc pfs_rwcommon eor #$FF @@ -366,70 +403,56 @@ _pfs_close: jsr popax ; get the handle sta LF - lda #0 - beq pfs_rwsetflags + lda #$00 +; beq pfs_rwsetflags ; (fall through) .endproc - .if F_IDE64 -.proc ide64_rwprepare - sec - lda ptr1+1 - eor #255 - beq small ; too small, not worth it - tay - lda ptr1 ; setup registers - eor #255 - tax - lda $031B - eor #$DE - bne noide ; open vector set? - lda $DE60 - eor #$49 - bne noide ; check identification - lda $DE61 - eor #$44 - bne noide - lda $DE62 - eor #$45 - bne noide - clc - lda #ptr2 -small: rts - -noide: lda #F_NBLK - bne pfs_rwsetflags -.endproc - .endif - .proc pfs_rwsetflags ldx LF - ora flags-1,x - sta flags-1,x + ora flags - 1,x + sta flags - 1,x rts .endproc - .if F_IDE64 +.if F_IDE64 +.proc ide64_rwprepare + sec ; assume it won't use IDEDOS + lda ptr1+1 + eor #$FF ; convert -count-1 back to count + beq small ; too small, not worth it + tay + lda ptr1 ; set up registers + eor #$FF + tax + lda OPNVec+1 + eor #>$DE00 + bne noide ; is OPEN vector set to IDEDOS? + lda $DE60 + eor #'i' + bne noide ; check identification + lda $DE61 + eor #'d' + bne noide + lda $DE62 + eor #'e' + bne noide + clc ; it will use IDEDOS + lda #ptr2 +small: rts + +noide: lda #F_NBLK + bne pfs_rwsetflags +.endproc + .proc ide64_rwfinish - txa + txa ; push .YX pha tya pha jsr CLRCHN - pla - tax - pla - rts -.endproc - .endif - -.proc pfs_rwcommonend - lda ptr2 - sec - sbc ptr3 - pha - lda ptr2+1 - sbc ptr3+1 + pla ; pull .XA tax pla rts .endproc +.endif diff --git a/platform/c64/lib/pfs_remove.S b/platform/c64/lib/pfs_remove.S new file mode 100644 index 000000000..7477e4314 --- /dev/null +++ b/platform/c64/lib/pfs_remove.S @@ -0,0 +1,59 @@ +; +; Copyright (c) 2016, Greg King +; 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 author nor the names of contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +; +; Author: Greg King +; +;--------------------------------------------------------------------- + .importzp ptr2 + .import addysp + .import pfs_makename, pfs_scratch + + .export _pfs_remove +;--------------------------------------------------------------------- +MAXLEN = 80 ; max. filename length + +FNL := $B7 ; filename length +;--------------------------------------------------------------------- +.proc _pfs_remove + asl ptr2 ; force pfs_makename to format for pfs_scratch + jsr pfs_makename + ldx FNL + beq error ; no name + + jsr pfs_scratch + ldx #>$0000 + bcs error +ret: txa + ldy #MAXLEN + 8 ; free filename space + jmp addysp + +error: dex ;(ldx #>-1) + bne ret +.endproc diff --git a/platform/c64/lib/pfs_seek.S b/platform/c64/lib/pfs_seek.S new file mode 100644 index 000000000..4ef0014d1 --- /dev/null +++ b/platform/c64/lib/pfs_seek.S @@ -0,0 +1,46 @@ +; +; Copyright (c) 2016, Greg King +; 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 author nor the names of contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +; +; Author: Greg King +; +;--------------------------------------------------------------------- + .importzp sp, sreg, ptr1, ptr2, ptr3 + .import popax, incsp6 + .import cmdc, flags + + .export _pfs_seek +;--------------------------------------------------------------------- +.proc _pfs_seek + lda #<-1 ; seek not implemented + tax + stx sreg ; return long data type + stx sreg+1 + jmp incsp6 ; drop int and long arguments from stack +.endproc diff --git a/platform/c64/lib/pfs_write.S b/platform/c64/lib/pfs_write.S index 7e511e513..82632df8f 100644 --- a/platform/c64/lib/pfs_write.S +++ b/platform/c64/lib/pfs_write.S @@ -31,27 +31,33 @@ ; Author: Kajtar Zsolt ; ;--------------------------------------------------------------------- - .define F_IDE64 1 ; support IDE64, 100 byte only +.define F_IDE64 1 ; support IDE64, >= $0100 bytes only - .importzp ptr1, ptr2 - .import pfs_rwcommon, pfs_rwsetflags, pfs_rwcommonend - .if F_IDE64 - .import ide64_rwprepare, ide64_rwfinish - .endif - .export _pfs_write + .importzp ptr1, ptr2 + .import pfs_rwcommon, pfs_rwsetflags, pfs_rwcommonend +.if F_IDE64 + .import ide64_rwprepare, ide64_rwfinish +.endif + + .export _pfs_write ;--------------------------------------------------------------------- -F_NBLK = $40 -ST = $90 ;status -CHKOUT = $FFC9 -CLRCHN = $FFCC -CHROUT = $FFD2 -WRITE = $DEF1 +F_NBLK = %01000000 ;block read/write not available + +ST := $90 ;status + +; IDEDOS function +WRITE := $DEF1 + +; Kernal functions +CHKOUT := $FFC9 +CLRCHN := $FFCC +CHROUT := $FFD2 ;--------------------------------------------------------------------- .code -error5: jsr CLRCHN ; clrchn +error5: jsr CLRCHN -error2: ldx #255 +error2: ldx #>-1 txa rts @@ -59,8 +65,8 @@ error2: ldx #255 jsr pfs_rwcommon ; pop params, check handle beq error2 ; not open - .if F_IDE64 - asl +.if F_IDE64 + asl a bmi nblk ; no block operation jsr CHKOUT @@ -70,7 +76,7 @@ error2: ldx #255 jsr ide64_rwprepare bcs norm - ; write + ; do a block write jsr WRITE bcs nosup jmp ide64_rwfinish @@ -98,10 +104,9 @@ norm: ldy #0 lda ST beq @L3 bne error5 ; bail out on errors -@L2: - ; Wrote all chars, close the output channel - jsr CLRCHN + ; Wrote all chars.; cancel the output channel +@L2: jsr CLRCHN ; Return the number of chars written jmp pfs_rwcommonend From 111a976f1e8ef8f31929184403e63a985db8e645 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt Date: Mon, 28 Mar 2016 14:39:16 +0200 Subject: [PATCH 135/374] Explicitly mark constant as 'unsigned' to avoid unnecessary promotion to 'long'. Long constants trigger the performance warning "Constant is long" with cc65. --- core/net/mac/tsch/tsch-conf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/net/mac/tsch/tsch-conf.h b/core/net/mac/tsch/tsch-conf.h index bd9726042..3f877884a 100644 --- a/core/net/mac/tsch/tsch-conf.h +++ b/core/net/mac/tsch/tsch-conf.h @@ -135,7 +135,7 @@ #define TSCH_DEFAULT_TS_MAX_TX 4256 #define TSCH_DEFAULT_TS_TIMESLOT_LENGTH 15000 -#elif TSCH_CONF_DEFAULT_TIMESLOT_LENGTH == 65000 +#elif TSCH_CONF_DEFAULT_TIMESLOT_LENGTH == 65000U /* 65ms timeslot, i.e. nearly the max length allowed by standard (16-bit unsigned in micro-seconds). * Useful for running link-layer security on sky or z1 in Cooja, where only S/W security is supported. * Note: this slot timing would require a total of 120ms. If a slot overlaps with the next active slot, From b287351d9959dd11956966b547605f02fb363f40 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt Date: Mon, 28 Mar 2016 19:43:51 +0200 Subject: [PATCH 136/374] Activated CBM PFS for the C64 Telnet server. Now that the CBM PFS supports file removal (and a file seek stub) it is possible to have the Telnet server leverage the IDE64 support of the CBM PFS. Note: Using the CBM PFS for the Telnet server does _not_ reduce the code size since the POSIX I/O functions are additionally still linked in because the POSIX directory functions internally use the POSIX I/O functions. And that's the very reason why the CBM PFS is _not_ activated for the C128 Telnet server: The CBM PFS for the C128 doesn't bring IDE64 support but is supposed to be used to reduce code size - but this isn't possible for the Telnet server. --- examples/telnet-server/Makefile.c64.defines | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/telnet-server/Makefile.c64.defines b/examples/telnet-server/Makefile.c64.defines index bcd39d550..caf0dfa69 100644 --- a/examples/telnet-server/Makefile.c64.defines +++ b/examples/telnet-server/Makefile.c64.defines @@ -1 +1 @@ -DEFINES = CONNECTIONS=3,WITH_LOGGING,WITH_CLIENT,WITH_DNS +DEFINES = CONNECTIONS=3,WITH_LOGGING,WITH_CLIENT,WITH_DNS,WITH_PFS From 7a5249b0666caa6f515502466327f5416b4fdda1 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt Date: Mon, 28 Mar 2016 20:03:47 +0200 Subject: [PATCH 137/374] Added a Contiki version of the CBM exec() system file; it uses PFS instead of POSIX. It reduces the webbrowsers' size by 735 bytes. --- platform/c128/Makefile.c128 | 2 +- platform/c128/lib/exec.c | 139 ++++++++++++++++++++++++++++++++++++ platform/c64/Makefile.c64 | 2 +- platform/c64/lib/exec.c | 139 ++++++++++++++++++++++++++++++++++++ 4 files changed, 280 insertions(+), 2 deletions(-) create mode 100644 platform/c128/lib/exec.c create mode 100644 platform/c64/lib/exec.c diff --git a/platform/c128/Makefile.c128 b/platform/c128/Makefile.c128 index 55889d4ab..fbbcf8eda 100644 --- a/platform/c128/Makefile.c128 +++ b/platform/c128/Makefile.c128 @@ -31,7 +31,7 @@ # Author: Oliver Schmidt # -CONTIKI_TARGET_SOURCEFILES += lseek.c pfs.S pfs_remove.S pfs_seek.S pfs_write.S +CONTIKI_TARGET_SOURCEFILES += exec.c lseek.c pfs.S pfs_remove.S pfs_seek.S pfs_write.S CONTIKI_CPU = $(CONTIKI)/cpu/6502 include $(CONTIKI_CPU)/Makefile.6502 diff --git a/platform/c128/lib/exec.c b/platform/c128/lib/exec.c new file mode 100644 index 000000000..5a633d45d --- /dev/null +++ b/platform/c128/lib/exec.c @@ -0,0 +1,139 @@ +/* +** Program-chaining function for Commodore platforms. +** +** This copy of the cc65 system library function makes smaller code by using +** Contiki's Personal File System (instead of POSIX) functions. +** +** 2016-03-16, Greg King +** +** This function exploits the program-chaining feature in CBM BASIC's ROM. +** +** CC65's CBM programs have a BASIC program stub. We start those programs by +** RUNning that stub; it SYSes to the Machine Language code. Normally, after +** the ML code exits, the BASIC ROM continues running the stub. But, it has +** no more statements; so, the program stops. +** +** This function puts the desired program's name and device number into a LOAD +** statement. Then, it points BASIC to that statement, so that the ROM will run +** that statement after this program quits. The ROM will load the next program, +** and will execute it (because the LOAD will be seen in a running program). +*/ + +#include +#include +#include +#include +#include + +#include "cfs.h" + + +/* The struct below is a line of BASIC code. It sits in the LOWCODE segment +** to make sure that it won't be hidden by a ROM when BASIC is re-enabled. +** The line is: +** 0 CLR:LOAD""+"" ,01 +** After this function has written into the line, it might look like this: +** 0 CLR:LOAD""+"program name" ,08 +** +** When BASIC's LOAD command asks the Kernal to load a file, it gives the +** Kernal a pointer to a file-name string. CC65's CBM programs use that +** pointer to give a copy of the program's name to main()'s argv[0] parameter. +** But, when BASIC uses a string literal that is in a program, it points +** directly to that literal -- in the models that don't use banked RAM +** (Pet/CBM, VIC-20, and 64). The literal is overwritten by the next program +** that is loaded. So, argv[0] would point to machine code. String operations +** create a new result string -- even when that operation changes nothing. The +** result is put in the string space at the top of BASIC's memory. So, the ""+ +** in this BASIC line guarantees that argv[0] will get a name from a safe place. +*/ +#pragma data-name(push, "LOWCODE") +static struct line { + const char end_of_line; /* fake previous line */ + const struct line* const next; + const unsigned line_num; + const char CLR_token, colon, LOAD_token, quotes[2], add_token, quote; + char name[21]; + const char comma; + char unit[3]; +} basic = { + '\0', &basic + 1, /* high byte of link must be non-zero */ + 0, 0x9C, ':', 0x93, "\"\"", 0xAA, '\"', + "\" ", /* format: "123:1234567890123456\"" */ + ',', "01" +}; +#pragma data-name(pop) + +/* These values are platform-specific. */ +extern const void* vartab; /* points to BASIC program variables */ +#pragma zpsym("vartab") +extern const void* memsize; /* points to top of BASIC RAM */ +#pragma zpsym("memsize") +extern const struct line* txtptr; /* points to BASIC code */ +#pragma zpsym("txtptr") +extern char basbuf[]; /* BASIC's input buffer */ +extern void basbuf_len[]; +#pragma zpsym("basbuf_len") + + +int __fastcall__ +exec(const char *progname, const char *cmdline) +{ + static int fd; + static unsigned char dv, n; + + /* Exclude devices that can't load files. */ + /* (Use hand optimization, to make smaller code.) */ + dv = getcurrentdevice(); + if(dv < 8 && __AX__ != 1 || __AX__ > 30) { + return _mappederrno(9); /* illegal device number */ + } + utoa(dv, basic.unit, 10); + + /* Tape files can be openned only once; skip this test for the Datasette. */ + if(dv != 1) { + /* Don't try to run a program that can't be found. */ + fd = cfs_open(progname, CFS_READ); + if(fd < 0) { + return -1; + } + cfs_close(fd); + } + + n = 0; + do { + if((basic.name[n] = progname[n]) == '\0') { + break; + } + } while(++n < 20); /* truncate long names */ + basic.name[n] = '\"'; + +/* This next part isn't needed by machines that put +** BASIC source and variables in different RAM banks. +*/ +#if !defined(__C128__) + /* cc65 program loads might extend beyond the end of the RAM that is allowed + ** for BASIC. Then, the LOAD statement would complain that it is "out of + ** memory". Some pointers that say where to put BASIC program variables + ** must be changed, so that we do not get that error. One pointer is + ** changed here; a BASIC CLR statement changes the others. Some space is + ** needed for the file-name string. Subtracting an entire RAM page allows + ** better optimization of this expression. + */ + vartab = (char*)memsize - 0x0100; +#endif + + /* Build the next program's argument list. */ + basbuf[0] = 0x8F; /* REM token */ + basbuf[1] = '\0'; + if(cmdline != NULL) { + strncat(basbuf, cmdline, (size_t)basbuf_len - 2); + } + + /* Tell the ROM where to find that BASIC program. */ + txtptr = &basic; + + /* (The return code, in ST [status], will be destroyed by LOAD. + ** So, don't bother to set it here.) + */ + exit(__AX__); +} diff --git a/platform/c64/Makefile.c64 b/platform/c64/Makefile.c64 index 5dce702a8..7769b6ceb 100644 --- a/platform/c64/Makefile.c64 +++ b/platform/c64/Makefile.c64 @@ -31,7 +31,7 @@ # Author: Oliver Schmidt # -CONTIKI_TARGET_SOURCEFILES += lseek.c pfs.S pfs_remove.S pfs_seek.S pfs_write.S +CONTIKI_TARGET_SOURCEFILES += exec.c lseek.c pfs.S pfs_remove.S pfs_seek.S pfs_write.S CONTIKI_CPU = $(CONTIKI)/cpu/6502 include $(CONTIKI_CPU)/Makefile.6502 diff --git a/platform/c64/lib/exec.c b/platform/c64/lib/exec.c new file mode 100644 index 000000000..5a633d45d --- /dev/null +++ b/platform/c64/lib/exec.c @@ -0,0 +1,139 @@ +/* +** Program-chaining function for Commodore platforms. +** +** This copy of the cc65 system library function makes smaller code by using +** Contiki's Personal File System (instead of POSIX) functions. +** +** 2016-03-16, Greg King +** +** This function exploits the program-chaining feature in CBM BASIC's ROM. +** +** CC65's CBM programs have a BASIC program stub. We start those programs by +** RUNning that stub; it SYSes to the Machine Language code. Normally, after +** the ML code exits, the BASIC ROM continues running the stub. But, it has +** no more statements; so, the program stops. +** +** This function puts the desired program's name and device number into a LOAD +** statement. Then, it points BASIC to that statement, so that the ROM will run +** that statement after this program quits. The ROM will load the next program, +** and will execute it (because the LOAD will be seen in a running program). +*/ + +#include +#include +#include +#include +#include + +#include "cfs.h" + + +/* The struct below is a line of BASIC code. It sits in the LOWCODE segment +** to make sure that it won't be hidden by a ROM when BASIC is re-enabled. +** The line is: +** 0 CLR:LOAD""+"" ,01 +** After this function has written into the line, it might look like this: +** 0 CLR:LOAD""+"program name" ,08 +** +** When BASIC's LOAD command asks the Kernal to load a file, it gives the +** Kernal a pointer to a file-name string. CC65's CBM programs use that +** pointer to give a copy of the program's name to main()'s argv[0] parameter. +** But, when BASIC uses a string literal that is in a program, it points +** directly to that literal -- in the models that don't use banked RAM +** (Pet/CBM, VIC-20, and 64). The literal is overwritten by the next program +** that is loaded. So, argv[0] would point to machine code. String operations +** create a new result string -- even when that operation changes nothing. The +** result is put in the string space at the top of BASIC's memory. So, the ""+ +** in this BASIC line guarantees that argv[0] will get a name from a safe place. +*/ +#pragma data-name(push, "LOWCODE") +static struct line { + const char end_of_line; /* fake previous line */ + const struct line* const next; + const unsigned line_num; + const char CLR_token, colon, LOAD_token, quotes[2], add_token, quote; + char name[21]; + const char comma; + char unit[3]; +} basic = { + '\0', &basic + 1, /* high byte of link must be non-zero */ + 0, 0x9C, ':', 0x93, "\"\"", 0xAA, '\"', + "\" ", /* format: "123:1234567890123456\"" */ + ',', "01" +}; +#pragma data-name(pop) + +/* These values are platform-specific. */ +extern const void* vartab; /* points to BASIC program variables */ +#pragma zpsym("vartab") +extern const void* memsize; /* points to top of BASIC RAM */ +#pragma zpsym("memsize") +extern const struct line* txtptr; /* points to BASIC code */ +#pragma zpsym("txtptr") +extern char basbuf[]; /* BASIC's input buffer */ +extern void basbuf_len[]; +#pragma zpsym("basbuf_len") + + +int __fastcall__ +exec(const char *progname, const char *cmdline) +{ + static int fd; + static unsigned char dv, n; + + /* Exclude devices that can't load files. */ + /* (Use hand optimization, to make smaller code.) */ + dv = getcurrentdevice(); + if(dv < 8 && __AX__ != 1 || __AX__ > 30) { + return _mappederrno(9); /* illegal device number */ + } + utoa(dv, basic.unit, 10); + + /* Tape files can be openned only once; skip this test for the Datasette. */ + if(dv != 1) { + /* Don't try to run a program that can't be found. */ + fd = cfs_open(progname, CFS_READ); + if(fd < 0) { + return -1; + } + cfs_close(fd); + } + + n = 0; + do { + if((basic.name[n] = progname[n]) == '\0') { + break; + } + } while(++n < 20); /* truncate long names */ + basic.name[n] = '\"'; + +/* This next part isn't needed by machines that put +** BASIC source and variables in different RAM banks. +*/ +#if !defined(__C128__) + /* cc65 program loads might extend beyond the end of the RAM that is allowed + ** for BASIC. Then, the LOAD statement would complain that it is "out of + ** memory". Some pointers that say where to put BASIC program variables + ** must be changed, so that we do not get that error. One pointer is + ** changed here; a BASIC CLR statement changes the others. Some space is + ** needed for the file-name string. Subtracting an entire RAM page allows + ** better optimization of this expression. + */ + vartab = (char*)memsize - 0x0100; +#endif + + /* Build the next program's argument list. */ + basbuf[0] = 0x8F; /* REM token */ + basbuf[1] = '\0'; + if(cmdline != NULL) { + strncat(basbuf, cmdline, (size_t)basbuf_len - 2); + } + + /* Tell the ROM where to find that BASIC program. */ + txtptr = &basic; + + /* (The return code, in ST [status], will be destroyed by LOAD. + ** So, don't bother to set it here.) + */ + exit(__AX__); +} From bc2f1b5a2ac2f83594b587d1efa6bbff2ee48206 Mon Sep 17 00:00:00 2001 From: thomas-ha Date: Tue, 29 Mar 2016 10:24:38 +0200 Subject: [PATCH 138/374] update delay constants --- platform/cc2538dk/contiki-conf.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/platform/cc2538dk/contiki-conf.h b/platform/cc2538dk/contiki-conf.h index ae7c3275d..22891f5ba 100644 --- a/platform/cc2538dk/contiki-conf.h +++ b/platform/cc2538dk/contiki-conf.h @@ -42,9 +42,10 @@ typedef uint32_t rtimer_clock_t; /*---------------------------------------------------------------------------*/ #define TSCH_CONF_HW_FRAME_FILTERING 0 -/* TODO: measure the delays, this are only estimations */ -#define RADIO_DELAY_BEFORE_TX ((unsigned)US_TO_RTIMERTICKS(300)) -#define RADIO_DELAY_BEFORE_RX ((unsigned)US_TO_RTIMERTICKS(100)) +/* 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 /*---------------------------------------------------------------------------*/ /** From 855703e93627e571f7172085c848ec5abbf2188b Mon Sep 17 00:00:00 2001 From: Carlo Vallati Date: Thu, 31 Mar 2016 10:09:47 +0200 Subject: [PATCH 139/374] Fixed a bug into tsch-schedule - tsch_schedule_add_link that causes deadlock if a new link cannot be created --- core/net/mac/tsch/tsch-schedule.c | 1 + 1 file changed, 1 insertion(+) diff --git a/core/net/mac/tsch/tsch-schedule.c b/core/net/mac/tsch/tsch-schedule.c index 8b15e0faf..e0028c492 100644 --- a/core/net/mac/tsch/tsch-schedule.c +++ b/core/net/mac/tsch/tsch-schedule.c @@ -191,6 +191,7 @@ tsch_schedule_add_link(struct tsch_slotframe *slotframe, l = memb_alloc(&link_memb); if(l == NULL) { PRINTF("TSCH-schedule:! add_link memb_alloc failed\n"); + tsch_release_lock(); } else { static int current_link_handle = 0; struct tsch_neighbor *n; From 871c725144210b0d85c153e64fa6f19403aba5cd Mon Sep 17 00:00:00 2001 From: thomas-ha Date: Thu, 31 Mar 2016 11:24:57 +0200 Subject: [PATCH 140/374] spaces instead of tabs --- core/net/mac/tsch/tsch-conf.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/net/mac/tsch/tsch-conf.h b/core/net/mac/tsch/tsch-conf.h index b23355539..43e50d7c3 100644 --- a/core/net/mac/tsch/tsch-conf.h +++ b/core/net/mac/tsch/tsch-conf.h @@ -177,9 +177,9 @@ /* HW frame filtering enabled */ #ifdef TSCH_CONF_HW_FRAME_FILTERING -#define TSCH_HW_FRAME_FILTERING TSCH_CONF_HW_FRAME_FILTERING +#define TSCH_HW_FRAME_FILTERING TSCH_CONF_HW_FRAME_FILTERING #else /* TSCH_CONF_HW_FRAME_FILTERING */ #define TSCH_HW_FRAME_FILTERING 1 -#endif +#endif /* TSCH_CONF_HW_FRAME_FILTERING */ #endif /* __TSCH_CONF_H__ */ From c7c3ef3b9cac5d71f50e602ea10b5777ee77d75c Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Thu, 31 Mar 2016 13:41:08 +0300 Subject: [PATCH 141/374] Cooja: add Msp802154BitErrorRadio interface The interface more accurately models bit errors due to signal fading as observed in IEEE 802.15.4-compatible radios, such as CC2420 and CC2520. --- .../interfaces/Msp802154BitErrorRadio.java | 370 ++++++++++++++++++ .../mspmote/interfaces/Msp802154Radio.java | 8 +- 2 files changed, 374 insertions(+), 4 deletions(-) create mode 100644 tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154BitErrorRadio.java diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154BitErrorRadio.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154BitErrorRadio.java new file mode 100644 index 000000000..53b971755 --- /dev/null +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154BitErrorRadio.java @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2014, Uppsala University + * 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. + * + */ + +package org.contikios.cooja.mspmote.interfaces; + +import java.util.Random; + +import org.apache.log4j.Logger; + +import org.contikios.cooja.ClassDescription; +import org.contikios.cooja.Mote; +import org.contikios.cooja.Simulation; +import org.contikios.cooja.radiomediums.AbstractRadioMedium; + +import org.contikios.cooja.mspmote.MspMoteTimeEvent; +import org.contikios.cooja.mspmote.interfaces.Msp802154Radio; + + +/** + * Extension of MSPSim 802.15.4 radio wrapper with bit-level errors. + * + * Only errors due to signal fading are supported (as opposed to errors to interference). + * Interesting modelling effects can obtained if this is used together with a dynamic + * channel fading model. + * + * @author Atis Elsts + */ +@ClassDescription("IEEE 802.15.4 Bit Error Radio") +public class Msp802154BitErrorRadio extends Msp802154Radio { + private static Logger logger = Logger.getLogger(Msp802154Radio.class); + + private static final double NOISE_FLOOR = AbstractRadioMedium.SS_WEAK; + private static final double GOOD_SIGNAL = NOISE_FLOOR + 15.0; + + private Random random = null; + + public Msp802154BitErrorRadio(Mote m) { + super(m); + + random = getMote().getSimulation().getRandomGenerator(); + } + + /* The MSK-transformed symbol-to-codeword table. + * It's used for mapping between symbols and codeword by some popular + * 802.15.4 radios such as CC2420 and CC2520. */ + private static final int[] mskEncodeTable = { + 1618456172, + 1309113062, + 1826650030, + 1724778362, + 778887287, + 2061946375, + 2007919840, + 125494990, + 529027475, + 838370585, + 320833617, + 422705285, + 1368596360, + 85537272, + 139563807, + 2021988657 + }; + + /* Calculates the Hamming distance between two words */ + private int hammingDistance(int x1, int x2) { + return Integer.bitCount(x1 ^ x2); + } + + /* Send a symbol over the air with a specific bit error rate */ + private int transceiveSymbolWithErrors(int txSymbol, double bitErrorRate) { + /* First, transmit (encode and randomly corrupt) it */ + int chipSequence = mskEncodeTable[txSymbol]; + /* Note: loop until 31, not until 32 here, as the highest bit in the codeword + * is irrelevant for MSK encoded data, and therefore should not come into + * the Hamming distance calculations. */ + for (int i = 0; i < 31; ++i) { + double p = random.nextDouble(); + if (p < bitErrorRate) { + chipSequence ^= (1 << i); + } + } + + /* Now receive (decode) it */ + int bestRxSymbol = 0; + int bestHammingDistance = 32; + for (byte i = 0; i < 16; ++i) { + /* Resolve ties in a specific order: + * s7, s6, ... , s0, s15, s14 , ..., s8 */ + int rxSymbol = i < 8 ? 7 - i : 15 - i + 8; + + int hd = hammingDistance(chipSequence, mskEncodeTable[rxSymbol]); + if (hd < bestHammingDistance) { + bestRxSymbol = rxSymbol; + bestHammingDistance = hd; + if (hd == 0) { + break; + } + } + } + return bestRxSymbol; + } + + /* This is the probability that a bit will received incorrectly, for + * -95.0, -94.9, -94.8, ..., -80.0 dBm signal levels. + * It is modelled as Additive White Gaussian Noise (AWGN) channel + * with constellation size = 4, and log2(4) = 2 bits per over-the-air symbol. + * (See "Digital Communications" by Proakis, page 311) + * + * The table was generated with the following Python code: + * + * noise_floor = -95.0 + * good_signal = noise_floor + 15.0 + * + * # chips per second / carrier frequency + * # In this case: + * # 250 kbps * symbols_per_bit / 5 MHz 802.15.4 channel bandwidth + * spectral_efficiency = 250000 * (32 / 4) / 5000000. + * + * def snr_from_rssi(signal): + * return signal - noise_floor + * + * def combinations(n, k): + * return math.factorial(n) / (math.factorial(k) * math.factorial(n - k)) + * + * def chip_error_rate(signal): + * M_sk = 4 # constellation size + * K_b = 2 # bits per symbol + * snr = snr_from_rssi(signal) * spectral_efficiency # signal-noise ratio + * result = 0.0 + * for k in range(1, M_sk): + * result += ((-1)**(k + 1) / (k + 1.0)) * combinations(M_sk - 1, k) * math.exp(- (k / (k + 1.0)) * K_b * snr) + * return result * (M_sk / 2) / (M_sk - 1) + * + * for signal in range(int(noise_floor), int(good_signal + 1)): + * for decimal_part in range(10): + * s = signal + decimal_part / 10.0 + * print("{}: {:.16}".format(s, chip_error_rate(s))) + */ + private static final double[] bitErrorRateTable = { + 0.5000000000000000, + 0.4857075690874351, + 0.4717195981917559, + 0.4580362793082289, + 0.4446572346573086, + 0.4315815642818357, + 0.4188078906959320, + 0.4063344007440545, + 0.3941588848209507, + 0.3822787735959348, + 0.3706911723779558, + 0.3593928932511307, + 0.3483804851041035, + 0.3376502616704103, + 0.3271983276911817, + 0.3170206033059785, + 0.3071128467721474, + 0.2974706756080624, + 0.2880895862507204, + 0.2789649723135144, + 0.2700921415256470, + 0.2614663314303489, + 0.2530827239151328, + 0.2449364586434322, + 0.2370226454533358, + 0.2293363757856961, + 0.2218727332005190, + 0.2146268030374602, + 0.2075936812732179, + 0.2007684826257659, + 0.1941463479526962, + 0.1877224509883067, + 0.1814920044616803, + 0.1754502656356323, + 0.1695925413041991, + 0.1639141922842669, + 0.1584106374348990, + 0.1530773572360710, + 0.1479098969566969, + 0.1429038694401250, + 0.1380549575336883, + 0.1333589161873203, + 0.1288115742448300, + 0.1244088359500270, + 0.1201466821885792, + 0.1160211714852698, + 0.1120284407751141, + 0.1081647059657158, + 0.1044262623071727, + 0.1008094845848469, + 0.0973108271493890, + 0.0939268237974889, + 0.0906540875160106, + 0.0874893101013543, + 0.0844292616651377, + 0.0814707900365929, + 0.0786108200713800, + 0.0758463528759084, + 0.0731744649556428, + 0.0705923072953072, + 0.0680971043783837, + 0.0656861531527741, + 0.0633568219490458, + 0.0611065493572223, + 0.0589328430676567, + 0.0568332786811473, + 0.0548054984930601, + 0.0528472102558939, + 0.0509561859243809, + 0.0491302603869077, + 0.0473673301867607, + 0.0456653522364111, + 0.0440223425278144, + 0.0424363748414465, + 0.0409055794565784, + 0.0394281418650815, + 0.0380023014908522, + 0.0366263504167641, + 0.0352986321208818, + 0.0340175402235017, + 0.0327815172464461, + 0.0315890533858807, + 0.0304386852998058, + 0.0293289949112408, + 0.0282586082280085, + 0.0272261941799208, + 0.0262304634740650, + 0.0252701674687994, + 0.0243440970669807, + 0.0234510816288642, + 0.0225899879050480, + 0.0217597189897583, + 0.0209592132947168, + 0.0201874435437662, + 0.0194434157883799, + 0.0187261684441326, + 0.0180347713481601, + 0.0173683248375987, + 0.0167259588489542, + 0.0161068320383143, + 0.0155101309222909, + 0.0149350690395443, + 0.0143808861327198, + 0.0138468473506013, + 0.0133322424702643, + 0.0128363851389939, + 0.0123586121357148, + 0.0118982826516654, + 0.0114547775900349, + 0.0110274988842702, + 0.0106158688347500, + 0.0102193294635131, + 0.0098373418867231, + 0.0094693857045423, + 0.0091149584080853, + 0.0087735748031163, + 0.0084447664501541, + 0.0081280811206428, + 0.0078230822688482, + 0.0075293485191375, + 0.0072464731683002, + 0.0069740637025694, + 0.0067117413290037, + 0.0064591405208906, + 0.0062159085768378, + 0.0059817051932169, + 0.0057562020496316, + 0.0055390824070828, + 0.0053300407185094, + 0.0051287822513842, + 0.0049350227220528, + 0.0047484879415055, + 0.0045689134722762, + 0.0043960442961698, + 0.0042296344925230, + 0.0040694469267080, + 0.0039152529485966, + 0.0037668321007033, + 0.0036239718357372, + 0.0034864672432910, + 0.0033541207854084, + 0.0032267420407699, + 0.0031041474572487, + 0.0029861601125883, + 0.0028726094829638, + 0.0027633312191911, + 0.0026581669303560, + 0.0025569639746388, + 0.0024595752571165, + 0.0023658590343307, + 0.0022756787254125 + }; + + private double getBitErrorRate(double signal) { + if (signal <= NOISE_FLOOR) { + return 0.5; + } else if (signal >= GOOD_SIGNAL) { + return 0.0; + } else { + long position = Math.round((signal - NOISE_FLOOR) * 10.0); + return bitErrorRateTable[(int)position]; + } + } + + public void receiveCustomData(Object data) { + if (!(data instanceof Byte)) { + logger.fatal("Bad custom data: " + data); + return; + } + lastIncomingByte = (Byte) data; + + final byte inputByte; + if (isInterfered()) { + inputByte = (byte)0xFF; + } else { + double bitErrorRate = getBitErrorRate(currentSignalStrength); + if (bitErrorRate == 0.0) { + inputByte = lastIncomingByte; + } else if (bitErrorRate >= 0.5) { + inputByte = (byte) 0xFF; + } else { + /* convert to an unsigned int in order to prettify subsequent operations with bits */ + int incomingByteAsInt = lastIncomingByte; + if (incomingByteAsInt < 0) incomingByteAsInt += 256; + + /* a byte consists of 2 symbols; independently transceive each of them */ + int firstSymbol = transceiveSymbolWithErrors(incomingByteAsInt >> 4, bitErrorRate); + int secondSymbol = transceiveSymbolWithErrors(incomingByteAsInt & 0xf, bitErrorRate); + + inputByte = (byte)((firstSymbol << 4) + secondSymbol); + } + } + + mote.getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) { + public void execute(long t) { + super.execute(t); + radio.receivedByte(inputByte); + mote.requestImmediateWakeup(); + } + }, mote.getSimulation().getSimulationTime()); + + } +} diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154Radio.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154Radio.java index 31aa30377..baa9676a9 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154Radio.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154Radio.java @@ -69,16 +69,16 @@ public class Msp802154Radio extends Radio implements CustomDataRadio { private RadioEvent lastEvent = RadioEvent.UNKNOWN; - private final MspMote mote; - private final Radio802154 radio; + protected final MspMote mote; + protected final Radio802154 radio; private boolean isInterfered = false; private boolean isTransmitting = false; private boolean isReceiving = false; private boolean isSynchronized = false; - private byte lastOutgoingByte; - private byte lastIncomingByte; + protected byte lastOutgoingByte; + protected byte lastIncomingByte; private RadioPacket lastOutgoingPacket = null; private RadioPacket lastIncomingPacket = null; From 1818700bde933c1a61dd27c40b1971614e024a18 Mon Sep 17 00:00:00 2001 From: Marko Gucanin Date: Thu, 31 Mar 2016 13:51:03 +0200 Subject: [PATCH 142/374] JN516x clock module sign error fix --- platform/jn516x/dev/clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/jn516x/dev/clock.c b/platform/jn516x/dev/clock.c index b1927f5d6..8b2c316c0 100644 --- a/platform/jn516x/dev/clock.c +++ b/platform/jn516x/dev/clock.c @@ -258,7 +258,7 @@ clock_arch_time_to_etimer(void) clock_time_t time_to_etimer; if(etimer_pending()) { time_to_etimer = etimer_next_expiration_time() - clock_time(); - if(time_to_etimer < 0) { + if((int32_t)time_to_etimer < 0) { time_to_etimer = 0; } } else { From a81b4007b034c27c7ee6970c903675dfebad585e Mon Sep 17 00:00:00 2001 From: Toni Lozano Date: Mon, 4 Apr 2016 10:48:43 +0200 Subject: [PATCH 143/374] Allow to use up to 6xADC channels (now hardcoded), disabling the user button (PA3) if ADC6 is enabled --- platform/zoul/contiki-main.c | 4 +- platform/zoul/dev/adc-sensors.c | 2 +- platform/zoul/dev/adc-zoul.c | 8 +- platform/zoul/dev/adc-zoul.h | 14 +++- platform/zoul/dev/zoul-sensors.c | 7 +- platform/zoul/firefly/board.h | 122 +++++++++++++++++++++++++------ platform/zoul/remote/board.h | 107 +++++++++++++++++++++------ 7 files changed, 210 insertions(+), 54 deletions(-) diff --git a/platform/zoul/contiki-main.c b/platform/zoul/contiki-main.c index 80ca1ab21..b577066fe 100644 --- a/platform/zoul/contiki-main.c +++ b/platform/zoul/contiki-main.c @@ -218,9 +218,9 @@ main(void) #endif /* NETSTACK_CONF_WITH_IPV6 */ process_start(&sensors_process, NULL); - +#if PLATFOM_HAS_BUTTON SENSORS_ACTIVATE(button_sensor); - +#endif energest_init(); ENERGEST_ON(ENERGEST_TYPE_CPU); diff --git a/platform/zoul/dev/adc-sensors.c b/platform/zoul/dev/adc-sensors.c index c38455f19..6cc37fb4b 100644 --- a/platform/zoul/dev/adc-sensors.c +++ b/platform/zoul/dev/adc-sensors.c @@ -175,7 +175,7 @@ configure(int type, int value) return ADC_WRAPPER_ERROR; } - if((value < 0x01) || (value > 0x07) || (value == BUTTON_USER_PIN)) { + if((value < 0x01) || (value > 0x07) || ((value == BUTTON_USER_PIN) && (ADC_SENSORS_ADC6_PIN < 0))) { PRINTF("ADC sensors: invalid pin value, (PA0-PA1, PA3) are reserved\n"); return ADC_WRAPPER_ERROR; } diff --git a/platform/zoul/dev/adc-zoul.c b/platform/zoul/dev/adc-zoul.c index f31a303ed..f19daab48 100644 --- a/platform/zoul/dev/adc-zoul.c +++ b/platform/zoul/dev/adc-zoul.c @@ -93,6 +93,9 @@ get_channel_pin(int type) if((ZOUL_SENSORS_ADC5) && (type == ZOUL_SENSORS_ADC5)) { return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC5_PIN; } + if((ZOUL_SENSORS_ADC6) && (type == ZOUL_SENSORS_ADC6)) { + return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC6_PIN; + } return ZOUL_SENSORS_ERROR; } /*---------------------------------------------------------------------------*/ @@ -154,9 +157,12 @@ configure(int type, int value) if(value & ZOUL_SENSORS_ADC5) { ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC5_PIN, IOC_OVERRIDE_ANA); } + if(value & ZOUL_SENSORS_ADC6) { + ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC6_PIN, IOC_OVERRIDE_ANA); + } adc_init(); set_decimation_rate(SOC_ADC_ADCCON_DIV_512); - enabled_channels = value; + enabled_channels += value; break; case ZOUL_SENSORS_CONFIGURE_TYPE_DECIMATION_RATE: diff --git a/platform/zoul/dev/adc-zoul.h b/platform/zoul/dev/adc-zoul.h index d47da43c7..fca2643eb 100644 --- a/platform/zoul/dev/adc-zoul.h +++ b/platform/zoul/dev/adc-zoul.h @@ -38,7 +38,9 @@ * * Driver for the Zoul ADC interface * - * This driver supports analogue sensors connected to ADC1, ADC2 and AND3 inputs + * This driver supports analogue sensors connected to ADC1, ADC2, ADC3, + * ADC4, ADC5 and ADC6 inputs. ADC6 is shared with the user button, so disable + * user button if ADC6 is needed. * This is controlled by the type argument of the value() function. Possible * choices are: * @@ -47,6 +49,7 @@ * - ZOUL_SENSORS_ADC3 * - ZOUL_SENSORS_ADC4 * - ZOUL_SENSORS_ADC5 + * - ZOUL_SENSORS_ADC6 * * To initialize the ADC sensors use the configure() function, using as first * argument SENSORS_HW_INIT, and choose which ADC channels to enable passing as @@ -128,13 +131,20 @@ #else #define ZOUL_SENSORS_ADC5 0 #endif + +/* ADC phidget-like connector ADC6 */ +#if ADC_SENSORS_ADC6_PIN >= ZOUL_SENSORS_ADC_MIN +#define ZOUL_SENSORS_ADC6 GPIO_PIN_MASK(ADC_SENSORS_ADC6_PIN) +#else +#define ZOUL_SENSORS_ADC6 0 +#endif /* * This is safe as the disabled sensors should have a zero value thus not * affecting the mask operations */ #define ZOUL_SENSORS_ADC_ALL (ZOUL_SENSORS_ADC1 + ZOUL_SENSORS_ADC2 + \ ZOUL_SENSORS_ADC3 + ZOUL_SENSORS_ADC4 + \ - ZOUL_SENSORS_ADC5) + ZOUL_SENSORS_ADC5 + ZOUL_SENSORS_ADC6) /** @} */ /*---------------------------------------------------------------------------*/ extern const struct sensors_sensor adc_zoul; diff --git a/platform/zoul/dev/zoul-sensors.c b/platform/zoul/dev/zoul-sensors.c index e6e02c258..da755fc79 100644 --- a/platform/zoul/dev/zoul-sensors.c +++ b/platform/zoul/dev/zoul-sensors.c @@ -47,7 +47,12 @@ #include /*---------------------------------------------------------------------------*/ /** \brief Exports global symbols for the sensor API */ -SENSORS(&button_sensor, &vdd3_sensor, &cc2538_temp_sensor); +SENSORS(&vdd3_sensor, +#if PLATFORM_HAS_BUTTON + &button_sensor, +#endif + &cc2538_temp_sensor +); /*---------------------------------------------------------------------------*/ /** * @} diff --git a/platform/zoul/firefly/board.h b/platform/zoul/firefly/board.h index 101a95706..7cf92b39c 100644 --- a/platform/zoul/firefly/board.h +++ b/platform/zoul/firefly/board.h @@ -168,6 +168,92 @@ #define UART1_RTS_PIN (-1) /**< 0 */ /** @} */ /*---------------------------------------------------------------------------*/ +/** + * \name ADC configuration + * + * These values configure which CC2538 pins and ADC channels to use for the ADC + * inputs. There pins are suggested as they can be changed, but note that only + * pins from PA can be configured as ADC. + * + * - ADC1: up to 3.3V. + * - ADC2: up to 3.3V. + * - ADC3: up to 3.3V. + * - ADC4: up to 3.3V. + * - ADC5: up to 3.3V. + * - ADC6: up to 3.3V, shared with user button. + * + * Only ADC1 and ADC3 are enabled as default. + * + * The internal ADC reference is 1190mV, use either a voltage divider as input, + * or a different voltage reference, like AVDD5 or other externally (AIN7 or + * AIN6). + * @{ + */ +#define ADC_SENSORS_PORT GPIO_A_NUM /**< ADC GPIO control port */ + +#ifndef ADC_SENSORS_CONF_ADC1_PIN +#define ADC_SENSORS_ADC1_PIN 5 /**< ADC1 to PA5 */ +#else +#if ((ADC_SENSORS_CONF_ADC1_PIN != -1) && (ADC_SENSORS_CONF_ADC1_PIN != 5)) +#error "ADC1 channel should be mapped to PA5 or disabled with -1" +#else +#define ADC_SENSORS_ADC1_PIN ADC_SENSORS_CONF_ADC1_PIN +#endif +#endif + +#ifndef ADC_SENSORS_CONF_ADC2_PIN +#define ADC_SENSORS_ADC2_PIN 4 /**< ADC2 to PA4 */ +#else +#if ((ADC_SENSORS_CONF_ADC2_PIN != -1) && (ADC_SENSORS_CONF_ADC2_PIN != 4)) +#error "ADC2 channel should be mapped to PA4 or disabled with -1" +#else +#define ADC_SENSORS_ADC2_PIN ADC_SENSORS_CONF_ADC2_PIN +#endif +#endif + +#ifndef ADC_SENSORS_CONF_ADC3_PIN +#define ADC_SENSORS_ADC3_PIN 2 /**< ADC3 to PA2 */ +#else +#if ((ADC_SENSORS_CONF_ADC3_PIN != -1) && (ADC_SENSORS_CONF_ADC3_PIN != 2)) +#error "ADC3 channel should be mapped to PA2 or disabled with -1" +#else +#define ADC_SENSORS_ADC3_PIN ADC_SENSORS_CONF_ADC3_PIN +#endif +#endif + +#ifndef ADC_SENSORS_CONF_ADC4_PIN +#define ADC_SENSORS_ADC4_PIN 6 /**< ADC4 to PA6 */ +#else +#if ((ADC_SENSORS_CONF_ADC4_PIN != -1) && (ADC_SENSORS_CONF_ADC4_PIN != 6)) +#error "ADC4 channel should be mapped to PA6 or disabled with -1" +#else +#define ADC_SENSORS_ADC4_PIN ADC_SENSORS_CONF_ADC4_PIN +#endif +#endif + +#ifndef ADC_SENSORS_CONF_ADC5_PIN +#define ADC_SENSORS_ADC5_PIN 7 /**< ADC5 to PA7 */ +#else +#if ((ADC_SENSORS_CONF_ADC5_PIN != -1) && (ADC_SENSORS_CONF_ADC5_PIN != 7)) +#error "ADC5 channel should be mapped to PA7 or disabled with -1" +#else +#define ADC_SENSORS_ADC5_PIN ADC_SENSORS_CONF_ADC5_PIN +#endif +#endif + +#ifndef ADC_SENSORS_CONF_ADC6_PIN +#define ADC_SENSORS_ADC6_PIN (-1) /**< ADC6 not declared */ +#else +#define ADC_SENSORS_ADC6_PIN 3 /**< Hard-coded to PA3 */ +#endif + +#ifndef ADC_SENSORS_CONF_MAX +#define ADC_SENSORS_MAX 5 /**< Maximum sensors */ +#else +#define ADC_SENSORS_MAX ADC_SENSORS_CONF_MAX +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ /** \name Firefly Button configuration * * Buttons on the Firefly are connected as follows: @@ -180,31 +266,19 @@ #define BUTTON_USER_PIN 3 #define BUTTON_USER_VECTOR NVIC_INT_GPIO_PORT_A -/* Notify various examples that we have Buttons */ -#define PLATFORM_HAS_BUTTON 1 -/** @} */ -/*---------------------------------------------------------------------------*/ -/** - * \name ADC configuration - * - * These values configure which CC2538 pins and ADC channels to use for the ADC - * inputs. There pins are suggested as they can be changed, but note that only - * pins from PA can be configured as ADC. - * - * The Firefly, as it is, only allows 3.3VDC sensors. - * - * The internal ADC reference is 1190mV, use either a voltage divider as input, - * or a different voltage reference, like AVDD5 or other externally (AIN7 or - * AIN6). - * @{ +/* Notify various examples that we have an user button. + * If ADC6 channel is used, then disable the user button */ -#define ADC_SENSORS_PORT GPIO_A_NUM /**< ADC GPIO control port */ -#define ADC_SENSORS_ADC1_PIN 5 /**< ADC1 to PA5, 3V3 */ -#define ADC_SENSORS_ADC2_PIN 4 /**< ADC2 to PA4, 3V3 */ -#define ADC_SENSORS_ADC3_PIN 2 /**< ADC3 to PA2, 3V3 */ -#define ADC_SENSORS_ADC4_PIN 6 /**< ADC4 to PA6, 3V3 */ -#define ADC_SENSORS_ADC5_PIN 7 /**< ADC5 to PA7, 3V3 */ -#define ADC_SENSORS_MAX 5 /**< PA2, PA4, PA5, PA6, PA7 */ +#ifdef PLATFORM_CONF_WITH_BUTTON +#if (PLATFORM_CONF_WITH_BUTTON && (ADC_SENSORS_ADC6_PIN == 3)) +#error "The ADC6 (PA3) and user button cannot be enabled at the same time" +#else +#define PLATFORM_HAS_BUTTON (PLATFORM_CONF_WITH_BUTTON && \ + !(ADC_SENSORS_ADC6_PIN == 3)) +#endif /* (PLATFORM_CONF_WITH_BUTTON && (ADC_SENSORS_ADC6_PIN == 3)) */ +#else +#define PLATFORM_HAS_BUTTON !(ADC_SENSORS_ADC6_PIN == 3) +#endif /* PLATFORM_CONF_WITH_BUTTON */ /** @} */ /*---------------------------------------------------------------------------*/ /** diff --git a/platform/zoul/remote/board.h b/platform/zoul/remote/board.h index 2ae4d8927..2887f452a 100644 --- a/platform/zoul/remote/board.h +++ b/platform/zoul/remote/board.h @@ -171,23 +171,6 @@ #define UART1_RTS_PIN (-1) /** @} */ /*---------------------------------------------------------------------------*/ -/** \name RE-Mote Button configuration - * - * Buttons on the RE-Mote are connected as follows: - * - BUTTON_USER -> PA3, S1 user button, shared with bootloader and RTC_INT1 - * - BUTTON_RESET -> RESET_N line, S2 reset both CC2538 and CoP - * - BUTTON_PIC1W -> shared with SHUTDOWN_ENABLE, not mounted. - * @{ - */ -/** BUTTON_USER -> PA3 */ -#define BUTTON_USER_PORT GPIO_A_NUM -#define BUTTON_USER_PIN 3 -#define BUTTON_USER_VECTOR NVIC_INT_GPIO_PORT_A - -/* Notify various examples that we have Buttons */ -#define PLATFORM_HAS_BUTTON 1 -/** @} */ -/*---------------------------------------------------------------------------*/ /** * \name ADC configuration * @@ -201,6 +184,12 @@ * - ADC2: up to 3.3V, shared with RTC_INT * - ADC3: up to 5V, by means of a 2/3 voltage divider. * + * Also there are other ADC channels shared by default with Micro SD card and + * user button implementations: + * - ADC4: up to 3.3V. + * - ADC5: up to 3.3V. + * - ADC6: up to 3.3V. + * * ADC inputs can only be on port A. * All ADCx are exposed in JP5 connector, but only ADC1 and ADC3 have GND and * VDD (3/5V) pins next to it, so these can be exposed into a 3-pin phidget-like @@ -216,12 +205,84 @@ * @{ */ #define ADC_SENSORS_PORT GPIO_A_NUM /**< ADC GPIO control port */ -#define ADC_SENSORS_ADC1_PIN 5 /**< ADC1 to PA5, 3V3 */ -#define ADC_SENSORS_ADC2_PIN (-1) /**< ADC2 to PA4, 3V3 */ -#define ADC_SENSORS_ADC3_PIN 2 /**< ADC3 to PA2, 5V0 */ -#define ADC_SENSORS_ADC4_PIN (-1) /**< Not present */ -#define ADC_SENSORS_ADC5_PIN (-1) /**< Not present */ -#define ADC_SENSORS_MAX 2 /**< PA2, PA5 */ + +#ifndef ADC_SENSORS_CONF_ADC1_PIN +#define ADC_SENSORS_ADC1_PIN 5 /**< ADC1 to PA5, 3V3 */ +#else +#if ((ADC_SENSORS_CONF_ADC1_PIN != -1) && (ADC_SENSORS_CONF_ADC1_PIN != 5)) +#error "ADC1 channel should be mapped to PA5 or disabled with -1" +#else +#define ADC_SENSORS_ADC1_PIN ADC_SENSORS_CONF_ADC1_PIN +#endif +#endif + +#ifndef ADC_SENSORS_CONF_ADC3_PIN +#define ADC_SENSORS_ADC3_PIN 2 /**< ADC3 to PA2, 5V */ +#else +#if ((ADC_SENSORS_CONF_ADC3_PIN != -1) && (ADC_SENSORS_CONF_ADC3_PIN != 2)) +#error "ADC3 channel should be mapped to PA2 or disabled with -1" +#else +#define ADC_SENSORS_ADC3_PIN ADC_SENSORS_CONF_ADC3_PIN +#endif +#endif + +#ifndef ADC_SENSORS_CONF_ADC2_PIN +#define ADC_SENSORS_ADC2_PIN (-1) /**< ADC2 no declared */ +#else +#define ADC_SENSORS_ADC2_PIN 4 /**< Hard-coded to PA4 */ +#endif + +#ifndef ADC_SENSORS_CONF_ADC4_PIN +#define ADC_SENSORS_ADC4_PIN (-1) /**< ADC4 not declared */ +#else +#define ADC_SENSORS_ADC4_PIN 6 /**< Hard-coded to PA6 */ +#endif + +#ifndef ADC_SENSORS_CONF_ADC5_PIN +#define ADC_SENSORS_ADC5_PIN (-1) /**< ADC5 not declared */ +#else +#define ADC_SENSORS_ADC5_PIN 7 /**< Hard-coded to PA7 */ +#endif + +#ifndef ADC_SENSORS_CONF_ADC6_PIN +#define ADC_SENSORS_ADC6_PIN (-1) /**< ADC6 not declared */ +#else +#define ADC_SENSORS_ADC6_PIN 3 /**< Hard-coded to PA3 */ +#endif + +#ifndef ADC_SENSORS_CONF_MAX +#define ADC_SENSORS_MAX 2 /**< Maximum sensors */ +#else +#define ADC_SENSORS_MAX ADC_SENSORS_CONF_MAX +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name RE-Mote Button configuration + * + * Buttons on the RE-Mote are connected as follows: + * - BUTTON_USER -> PA3, S1 user button, shared with bootloader and RTC_INT1 + * - BUTTON_RESET -> RESET_N line, S2 reset both CC2538 and CoP + * - BUTTON_PIC1W -> shared with SHUTDOWN_ENABLE, not mounted. + * @{ + */ +/** BUTTON_USER -> PA3 */ +#define BUTTON_USER_PORT GPIO_A_NUM +#define BUTTON_USER_PIN 3 +#define BUTTON_USER_VECTOR NVIC_INT_GPIO_PORT_A + +/* Notify various examples that we have an user button. + * If ADC6 channel is used, then disable the user button + */ +#ifdef PLATFORM_CONF_WITH_BUTTON +#if (PLATFORM_CONF_WITH_BUTTON && (ADC_SENSORS_ADC6_PIN == 3)) +#error "The ADC6 (PA3) and user button cannot be enabled at the same time" +#else +#define PLATFORM_HAS_BUTTON (PLATFORM_CONF_WITH_BUTTON && \ + !(ADC_SENSORS_ADC6_PIN == 3)) +#endif /* (PLATFORM_CONF_WITH_BUTTON && (ADC_SENSORS_ADC6_PIN == 3)) */ +#else +#define PLATFORM_HAS_BUTTON !(ADC_SENSORS_ADC6_PIN == 3) +#endif /* PLATFORM_CONF_WITH_BUTTON */ /** @} */ /*---------------------------------------------------------------------------*/ /** From 2a6999921497172f94fa2237aea3d4e052857c32 Mon Sep 17 00:00:00 2001 From: thomas-ha Date: Tue, 5 Apr 2016 17:12:48 +0200 Subject: [PATCH 144/374] space instead of tab --- core/net/mac/tsch/tsch-conf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/net/mac/tsch/tsch-conf.h b/core/net/mac/tsch/tsch-conf.h index 43e50d7c3..0cbce5913 100644 --- a/core/net/mac/tsch/tsch-conf.h +++ b/core/net/mac/tsch/tsch-conf.h @@ -179,7 +179,7 @@ #ifdef TSCH_CONF_HW_FRAME_FILTERING #define TSCH_HW_FRAME_FILTERING TSCH_CONF_HW_FRAME_FILTERING #else /* TSCH_CONF_HW_FRAME_FILTERING */ -#define TSCH_HW_FRAME_FILTERING 1 +#define TSCH_HW_FRAME_FILTERING 1 #endif /* TSCH_CONF_HW_FRAME_FILTERING */ #endif /* __TSCH_CONF_H__ */ From 2c48f3b232d269441de776961dea8c7265698b95 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt Date: Tue, 5 Apr 2016 21:11:19 +0200 Subject: [PATCH 145/374] Added compatibility with W5100 shared access. If the setup of socket 0 to 3 with 4+2+1+1KB is detected then the W5100 is _not_ initialized, otherwise it does set up socket 0 and 1 with 4KB each. Either way socket 0 is used - now with 4KB instead of 8KB as before. --- cpu/6502/net/w5100.S | 89 +++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 34 deletions(-) diff --git a/cpu/6502/net/w5100.S b/cpu/6502/net/w5100.S index 8fb040b01..3d8160170 100644 --- a/cpu/6502/net/w5100.S +++ b/cpu/6502/net/w5100.S @@ -97,7 +97,8 @@ fixup: .byte fixup02-fixup01, fixup03-fixup02, fixup04-fixup03 .byte fixup20-fixup19, fixup21-fixup20, fixup22-fixup21 .byte fixup23-fixup22, fixup24-fixup23, fixup25-fixup24 .byte fixup26-fixup25, fixup27-fixup26, fixup28-fixup27 - .byte fixup29-fixup28, fixup30-fixup29 + .byte fixup29-fixup28, fixup30-fixup29, fixup31-fixup30 + .byte fixup32-fixup31 fixups = * - fixup @@ -164,44 +165,64 @@ fixup04:eor data sec rts + ; Check for W5100 shared access + ; RX Memory Size Register: Assign 4+2+1+1KB to socket 0 to 3 ? +: ; ldx #$00 ; Hibyte + ldy #$1A ; Lobyte + jsr set_addr +fixup05:lda data + cmp #$06 + beq :+++ + ; S/W Reset -: lda #$80 -fixup05:sta mode + lda #$80 +fixup06:sta mode : -fixup06:lda mode +fixup07:lda mode bmi :- ; Indirect Bus I/F mode, Address Auto-Increment, Ping Block lda #$13 -fixup07:sta mode +fixup08:sta mode ; Source Hardware Address Register: MAC Address ldx #$00 ; Hibyte ldy #$09 ; Lobyte jsr set_addr : lda mac,x -fixup08:sta data +fixup09:sta data inx cpx #$06 bcc :- - ; RX Memory Size Register: Assign 8KB to socket 0 - ; TX Memory Size Register: Assign 8KB to socket 0 + ; RX Memory Size Register: Assign 4KB each to socket 0 and 1 + ; TX Memory Size Register: Assign 4KB each to socket 0 and 1 ldx #$00 ; Hibyte ldy #$1A ; Lobyte jsr set_addr - lda #$03 -fixup09:sta data + lda #$0A fixup10:sta data +fixup11:sta data + + ; MAC Address: Source Hardware Address Register +: ; ldx #$00 ; Hibyte + ldy #$09 ; Lobyte + jsr set_addr +: +fixup12:lda data + sta mac,x + inx + cpx #$06 + bcc :- ; Socket 0 Mode Register: MACRAW, MAC Filter ; Socket 0 Command Register: OPEN ldy #$00 jsr set_addrsocket0 lda #$44 -fixup11:sta data +fixup13:sta data lda #$01 -fixup12:sta data +fixup14:sta data tya tax clc @@ -213,7 +234,7 @@ poll: ; Check for completion of previous command ; Socket 0 Command Register: = 0 ? jsr set_addrcmdreg0 -fixup13:lda data +fixup15:lda data beq :++ ; No data available @@ -225,8 +246,8 @@ fixup13:lda data ; Socket 0 RX Received Size Register: != 0 ? : ldy #$26 ; Socket RX Received Size Register jsr set_addrsocket0 -fixup14:lda data ; Hibyte -fixup15:ora data ; Lobyte +fixup16:lda data ; Hibyte +fixup17:ora data ; Lobyte beq :-- ; Process the incoming data @@ -243,8 +264,8 @@ fixup15:ora data ; Lobyte ; Calculate and set physical address jsr set_addrphysical - ; Move physical address shadow to $E000-$FFFF - ora #>$8000 + ; Move physical address shadow to $F000-$FFFF + ora #>$F000 tax ; Read MAC raw 2byte packet size header @@ -292,13 +313,13 @@ common: jsr set_addrsocket0 tax lda reg+1 adc adv+1 -fixup16:sta data ; Hibyte -fixup17:stx data ; Lobyte +fixup18:sta data ; Hibyte +fixup19:stx data ; Lobyte ; Set command register tya ; Restore command jsr set_addrcmdreg0 -fixup18:sta data +fixup20:sta data ; Return data length (will be ignored for send) lda len @@ -325,14 +346,14 @@ send: ; Wait for completion of previous command ; Socket 0 Command Register: = 0 ? : jsr set_addrcmdreg0 -fixup19:lda data +fixup21:lda data bne :- ; Socket 0 TX Free Size Register: < length ? : ldy #$20 ; Socket TX Free Size Register jsr set_addrsocket0 -fixup20:lda data ; Hibyte -fixup21:ldx data ; Lobyte +fixup22:lda data ; Hibyte +fixup23:ldx data ; Lobyte cpx len sbc len+1 bcc :- @@ -362,16 +383,16 @@ exit: ;--------------------------------------------------------------------- set_addrphysical: -fixup22:lda data ; Hibyte -fixup23:ldy data ; Lobyte +fixup24:lda data ; Hibyte +fixup25:ldy data ; Lobyte sty reg sta reg+1 - and #>$1FFF ; Socket Mask Address (hibyte) + and #>$0FFF ; Socket Mask Address (hibyte) ora bas ; Socket Base Address (hibyte) tax set_addr: -fixup24:stx addr ; Hibyte -fixup25:sty addr+1 ; Lobyte +fixup26:stx addr ; Hibyte +fixup27:sty addr+1 ; Lobyte rts set_addrcmdreg0: @@ -386,7 +407,7 @@ set_addrbase: beq set_addr ; Always get_datacheckaddr: -fixup26:lda data +fixup28:lda data iny ; Physical address shadow (lobyte) bne :+ inx ; Physical address shadow (hibyte) @@ -399,7 +420,7 @@ set_parameters: ; Setup variables in zero page sta bas ; Socket Base Address clc - adc #>$2000 ; Socket memory size + adc #>$1000 ; Socket memory size sta lim ; Socket memory limit stx dir ; Transfer direction @@ -427,10 +448,10 @@ mov_data: ; R/W without address wraparound possible because ; highest R/W address > actual R/W address ? ; sec -fixup27:sbc addr+1 ; Lobyte +fixup29:sbc addr+1 ; Lobyte tay txa -fixup28:sbc addr ; Hibyte +fixup30:sbc addr ; Hibyte tax tya bcs :+ @@ -491,7 +512,7 @@ rw_data:eor #$FF ; Two's complement part 1 ; Read data : -fixup29:lda data +fixup31:lda data sta (ptr),y iny bne :- @@ -502,7 +523,7 @@ fixup29:lda data ; Write data : lda (ptr),y -fixup30:sta data +fixup32:sta data iny bne :- inc ptr+1 From a7b43de535956178260c22d56eeb3046b2b920e6 Mon Sep 17 00:00:00 2001 From: thomas-ha Date: Wed, 6 Apr 2016 16:54:45 +0200 Subject: [PATCH 146/374] add comment, use spaces --- examples/ipv6/rpl-tsch/project-conf.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/ipv6/rpl-tsch/project-conf.h b/examples/ipv6/rpl-tsch/project-conf.h index 81f7a01b6..1d3ad605d 100644 --- a/examples/ipv6/rpl-tsch/project-conf.h +++ b/examples/ipv6/rpl-tsch/project-conf.h @@ -67,18 +67,19 @@ #define TSCH_CALLBACK_JOINING_NETWORK tsch_rpl_callback_joining_network #define TSCH_CALLBACK_LEAVING_NETWORK tsch_rpl_callback_leaving_network +/* Needed for CC2538 platforms only */ /* For TSCH we have to use the more accurate crystal oscillator * by default the RC oscillator is activated */ #undef SYS_CTRL_CONF_OSC32K_USE_XTAL -#define SYS_CTRL_CONF_OSC32K_USE_XTAL 1 +#define SYS_CTRL_CONF_OSC32K_USE_XTAL 1 /* Needed for cc2420 platforms only */ /* Disable DCO calibration (uses timerB) */ #undef DCOSYNCH_CONF_ENABLED -#define DCOSYNCH_CONF_ENABLED 0 +#define DCOSYNCH_CONF_ENABLED 0 /* Enable SFD timestamps (uses timerB) */ #undef CC2420_CONF_SFD_TIMESTAMPS -#define CC2420_CONF_SFD_TIMESTAMPS 1 +#define CC2420_CONF_SFD_TIMESTAMPS 1 /*******************************************************/ /******************* Configure TSCH ********************/ From 9f1e87466fe2fc66d29e2b522e0ec529897e4dc8 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Wed, 6 Apr 2016 14:02:51 +0100 Subject: [PATCH 147/374] Fix failure of ARM-AAPCS travis job Up till now we have been installing arm-gcc using apt from the team-gcc-arm-embedded ppa. As discussed in #1453 and implemented in #1504, we have decided to lock travis to use the specific version of the toolchain that is documented in the READMEs of relevant platforms. However, the PPA no longer hosts this version, apt fails to install arm-gcc and as a result the job fails too. This commit changes the travis job to wget an installation tarball for the desired version, instead of trying to install via apt. --- .travis.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3a035fd2e..006956968 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,13 +40,13 @@ before_script: arm-none-eabi-gcc --version ; fi - ## Install mainline ARM toolchain. gcc-arm-none-eabi is available - ## in Ubuntu >= 14.04, but this external PPA is needed for 12.04. - ## Install srecord + ## Install mainline ARM toolchain and srecord. - if [ ${BUILD_ARCH:-0} = arm-aapcs ] ; then - sudo add-apt-repository -y ppa:team-gcc-arm-embedded/ppa && - sudo apt-get -qq update && - sudo apt-get -qq install gcc-arm-embedded=5-2015q4-1~precise1 srecord && + sudo apt-get -qq install srecord && + $WGET https://launchpad.net/gcc-arm-embedded/5.0/5-2015-q4-major/+download/gcc-arm-none-eabi-5_2-2015q4-20151219-linux.tar.bz2 && + tar xjf gcc-arm-none-eabi-5_2-2015q4-20151219-linux.tar.bz2 -C /tmp/ && + sudo cp -f -r /tmp/gcc-arm-none-eabi-5_2-2015q4/* /usr/local/ && + rm -rf /tmp/gcc-arm-none-eabi-* gcc-arm-none-eabi-*-linux.tar.bz2 && arm-none-eabi-gcc --version ; fi From 9ac859a2af439cfea168a44c66cc25f2e198118d Mon Sep 17 00:00:00 2001 From: thomas-ha Date: Thu, 7 Apr 2016 15:17:44 +0200 Subject: [PATCH 148/374] add send_on_cca if query --- cpu/cc2538/dev/cc2538-rf.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cpu/cc2538/dev/cc2538-rf.c b/cpu/cc2538/dev/cc2538-rf.c index a9ea369d6..3f79f2bb8 100644 --- a/cpu/cc2538/dev/cc2538-rf.c +++ b/cpu/cc2538/dev/cc2538-rf.c @@ -607,9 +607,11 @@ transmit(unsigned short transmit_len) while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + ONOFF_TIME)); } - if(channel_clear() == CC2538_RF_CCA_BUSY) { - RIMESTATS_ADD(contentiondrop); - return RADIO_TX_COLLISION; + if(send_on_cca) { + if(channel_clear() == CC2538_RF_CCA_BUSY) { + RIMESTATS_ADD(contentiondrop); + return RADIO_TX_COLLISION; + } } /* From 8211db64ae82dc52061a1fc1349993eec158ab61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Briano?= Date: Thu, 7 Apr 2016 10:37:30 -0300 Subject: [PATCH 149/374] Allow creating connections on unspecified local port If the given local port is 0, we get no replies. --- core/net/ip/simple-udp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/net/ip/simple-udp.c b/core/net/ip/simple-udp.c index 8ecd0aaa1..692fea19a 100644 --- a/core/net/ip/simple-udp.c +++ b/core/net/ip/simple-udp.c @@ -119,7 +119,7 @@ simple_udp_register(struct simple_udp_connection *c, PROCESS_CONTEXT_BEGIN(&simple_udp_process); c->udp_conn = udp_new(remote_addr, UIP_HTONS(remote_port), c); - if(c->udp_conn != NULL) { + if(c->udp_conn != NULL && local_port) { udp_bind(c->udp_conn, UIP_HTONS(local_port)); } PROCESS_CONTEXT_END(); From 5753fb5173501e1b4f1c2be440e7ad1d63a23848 Mon Sep 17 00:00:00 2001 From: thomas-ha Date: Thu, 7 Apr 2016 15:41:15 +0200 Subject: [PATCH 150/374] Clean up the driver Move mac_timer_init() into set_poll_mode() and remove now unneccesary clear outs and mask outs of interrupt sources and pending interrupts --- cpu/cc2538/dev/cc2538-rf.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/cpu/cc2538/dev/cc2538-rf.c b/cpu/cc2538/dev/cc2538-rf.c index 3f79f2bb8..12fe9ffae 100644 --- a/cpu/cc2538/dev/cc2538-rf.c +++ b/cpu/cc2538/dev/cc2538-rf.c @@ -344,14 +344,12 @@ set_poll_mode(uint8_t enable) poll_mode = enable; if(enable) { - REG(RFCORE_XREG_RFIRQM0) &= ~RFCORE_XREG_RFIRQM0_FIFOP; // mask out FIFOP interrupt source - REG(RFCORE_SFR_RFIRQF0) &= ~RFCORE_SFR_RFIRQF0_FIFOP; // clear pending FIFOP interrupt - REG(RFCORE_XREG_RFIRQM0) &= ~RFCORE_XREG_RFIRQM0_SFD; // disable SFD interrupt source - nvic_interrupt_disable(NVIC_INT_RF_RXTX); + mac_timer_init(); + REG(RFCORE_XREG_RFIRQM0) &= ~RFCORE_XREG_RFIRQM0_FIFOP; // mask out FIFOP interrupt source + REG(RFCORE_SFR_RFIRQF0) &= ~RFCORE_SFR_RFIRQF0_FIFOP; // clear pending FIFOP interrupt + nvic_interrupt_disable(NVIC_INT_RF_RXTX); // disable RF interrupts } else { - REG(RFCORE_XREG_RFIRQM0) |= RFCORE_XREG_RFIRQM0_FIFOP; // enable FIFOP interrupt source - REG(RFCORE_XREG_RFIRQM0) &= ~RFCORE_XREG_RFIRQM0_SFD; // mask out SFD interrupt source - REG(RFCORE_SFR_RFIRQF0) &= ~RFCORE_SFR_RFIRQF0_SFD; // clear pending SFD interrupt + REG(RFCORE_XREG_RFIRQM0) |= RFCORE_XREG_RFIRQM0_FIFOP; // enable FIFOP interrupt source nvic_interrupt_enable(NVIC_INT_RF_RXTX); // enable RF interrupts } } @@ -521,8 +519,6 @@ init(void) udma_set_channel_src(CC2538_RF_CONF_RX_DMA_CHAN, RFCORE_SFR_RFDATA); } - mac_timer_init(); - set_poll_mode(poll_mode); process_start(&cc2538_rf_process, NULL); From 1d3c37d6da6af000088a4373d1e1fa3da201792b Mon Sep 17 00:00:00 2001 From: Pere Tuset Date: Thu, 11 Feb 2016 01:34:08 +0100 Subject: [PATCH 151/374] Add OpenMote-CC2538 platform and examples. --- examples/openmote-cc2538/Makefile | 9 + examples/openmote-cc2538/openmote-demo.c | 152 +++++ examples/openmote-cc2538/project-conf.h | 46 ++ examples/openmote-cc2538/test-adxl346.c | 86 +++ examples/openmote-cc2538/test-max44009.c | 86 +++ examples/openmote-cc2538/test-sht21.c | 92 +++ examples/openmote-cc2538/test-timer.c | 188 ++++++ .../openmote-cc2538/Makefile.openmote-cc2538 | 50 ++ platform/openmote-cc2538/README.md | 0 platform/openmote-cc2538/board.c | 61 ++ platform/openmote-cc2538/board.h | 166 ++++++ platform/openmote-cc2538/contiki-conf.h | 536 ++++++++++++++++++ platform/openmote-cc2538/contiki-main.c | 248 ++++++++ platform/openmote-cc2538/dev/adxl346.c | 252 ++++++++ platform/openmote-cc2538/dev/adxl346.h | 57 ++ platform/openmote-cc2538/dev/antenna.c | 99 ++++ platform/openmote-cc2538/dev/antenna.h | 50 ++ platform/openmote-cc2538/dev/button-sensor.c | 136 +++++ platform/openmote-cc2538/dev/button-sensor.h | 59 ++ platform/openmote-cc2538/dev/leds-arch.c | 69 +++ platform/openmote-cc2538/dev/max44009.c | 197 +++++++ platform/openmote-cc2538/dev/max44009.h | 56 ++ platform/openmote-cc2538/dev/sht21.c | 208 +++++++ platform/openmote-cc2538/dev/sht21.h | 58 ++ .../openmote-cc2538/dev/smartrf-sensors.c | 53 ++ platform/openmote-cc2538/dev/tps62730.c | 98 ++++ platform/openmote-cc2538/dev/tps62730.h | 54 ++ 27 files changed, 3166 insertions(+) create mode 100644 examples/openmote-cc2538/Makefile create mode 100644 examples/openmote-cc2538/openmote-demo.c create mode 100644 examples/openmote-cc2538/project-conf.h create mode 100644 examples/openmote-cc2538/test-adxl346.c create mode 100644 examples/openmote-cc2538/test-max44009.c create mode 100644 examples/openmote-cc2538/test-sht21.c create mode 100644 examples/openmote-cc2538/test-timer.c create mode 100644 platform/openmote-cc2538/Makefile.openmote-cc2538 create mode 100644 platform/openmote-cc2538/README.md create mode 100644 platform/openmote-cc2538/board.c create mode 100644 platform/openmote-cc2538/board.h create mode 100644 platform/openmote-cc2538/contiki-conf.h create mode 100644 platform/openmote-cc2538/contiki-main.c create mode 100644 platform/openmote-cc2538/dev/adxl346.c create mode 100644 platform/openmote-cc2538/dev/adxl346.h create mode 100644 platform/openmote-cc2538/dev/antenna.c create mode 100644 platform/openmote-cc2538/dev/antenna.h create mode 100644 platform/openmote-cc2538/dev/button-sensor.c create mode 100644 platform/openmote-cc2538/dev/button-sensor.h create mode 100644 platform/openmote-cc2538/dev/leds-arch.c create mode 100644 platform/openmote-cc2538/dev/max44009.c create mode 100644 platform/openmote-cc2538/dev/max44009.h create mode 100644 platform/openmote-cc2538/dev/sht21.c create mode 100644 platform/openmote-cc2538/dev/sht21.h create mode 100644 platform/openmote-cc2538/dev/smartrf-sensors.c create mode 100644 platform/openmote-cc2538/dev/tps62730.c create mode 100644 platform/openmote-cc2538/dev/tps62730.h diff --git a/examples/openmote-cc2538/Makefile b/examples/openmote-cc2538/Makefile new file mode 100644 index 000000000..9f925fb70 --- /dev/null +++ b/examples/openmote-cc2538/Makefile @@ -0,0 +1,9 @@ +DEFINES+=PROJECT_CONF_H=\"project-conf.h\" + +CONTIKI_PROJECT = openmote-demo test-timer test-adxl346 test-max44009 test-sht21 + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../.. +CONTIKI_WITH_RIME = 1 +include $(CONTIKI)/Makefile.include diff --git a/examples/openmote-cc2538/openmote-demo.c b/examples/openmote-cc2538/openmote-demo.c new file mode 100644 index 000000000..10a1c0762 --- /dev/null +++ b/examples/openmote-cc2538/openmote-demo.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2014, OpenMote Technologies, S.L. + * 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. + * + */ + +/** + * \addtogroup openmote-cc2538 + * @{ + * + * \defgroup openmote-examples OpenMote-CC2538 Example Projects + * @{ + * + * \defgroup openmote-demo OpenMote-CC2538 Demo Project + * + * Example project demonstrating the OpenMote-CC2538 functionality + * + * This assumes that you are using an OpenMote-CC2538 + * + * - Boot sequence: LEDs flashing, LED2 followed by LED3 then LED4 + * - etimer/clock : Every LOOP_INTERVAL clock ticks the LED defined as + * LEDS_PERIODIC will turn on + * - rtimer : Exactly LEDS_OFF_HYSTERISIS rtimer ticks later, + * LEDS_PERIODIC will turn back off + * - UART : Every LOOP_INTERVAL the EM will print something over the + * UART. Receiving an entire line of text over UART (ending + * in \\r) will cause LEDS_SERIAL_IN to toggle + * - Radio comms : BTN_SELECT sends a rime broadcast. Reception of a rime + * packet will toggle LEDs defined as LEDS_RF_RX + * + * @{ + * + * \file + * Example demonstrating the OpenMote platform. + * \author + * Pere Tuset + */ +#include "contiki.h" +#include "cpu.h" +#include "sys/etimer.h" +#include "sys/rtimer.h" +#include "dev/leds.h" +#include "dev/uart.h" +#include "dev/button-sensor.h" +#include "dev/watchdog.h" +#include "dev/serial-line.h" +#include "dev/sys-ctrl.h" +#include "net/rime/broadcast.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#define LOOP_INTERVAL CLOCK_SECOND +#define LEDS_OFF_HYSTERISIS (RTIMER_SECOND >> 1) +#define LEDS_PERIODIC LEDS_YELLOW +#define LEDS_BUTTON LEDS_RED +#define LEDS_SERIAL_IN LEDS_ORANGE +#define LEDS_REBOOT LEDS_ALL +#define LEDS_RF_RX (LEDS_YELLOW | LEDS_ORANGE) +#define BROADCAST_CHANNEL 129 +/*---------------------------------------------------------------------------*/ +static struct etimer et; +static struct rtimer rt; +static uint16_t counter; +/*---------------------------------------------------------------------------*/ +PROCESS(openmote_demo_process, "OpenMote-CC2538 demo process"); +AUTOSTART_PROCESSES(&openmote_demo_process); +/*---------------------------------------------------------------------------*/ +static void +broadcast_recv(struct broadcast_conn *c, const linkaddr_t *from) +{ + leds_toggle(LEDS_RF_RX); + printf("Received %u bytes: '0x%04x'\n", packetbuf_datalen(), + *(uint16_t *)packetbuf_dataptr()); +} +/*---------------------------------------------------------------------------*/ +static const struct broadcast_callbacks bc_rx = { broadcast_recv }; +static struct broadcast_conn bc; +/*---------------------------------------------------------------------------*/ +void +rt_callback(struct rtimer *t, void *ptr) +{ + leds_off(LEDS_PERIODIC); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(openmote_demo_process, ev, data) +{ + + PROCESS_EXITHANDLER(broadcast_close(&bc)) + + PROCESS_BEGIN(); + + counter = 0; + broadcast_open(&bc, BROADCAST_CHANNEL, &bc_rx); + + while(1) { + etimer_set(&et, CLOCK_SECOND); + + PROCESS_YIELD(); + + if(ev == PROCESS_EVENT_TIMER) { + leds_on(LEDS_PERIODIC); + printf("Counter = 0x%08x\n", counter); + + etimer_set(&et, CLOCK_SECOND); + rtimer_set(&rt, RTIMER_NOW() + LEDS_OFF_HYSTERISIS, 1, + rt_callback, NULL); + } else if(ev == sensors_event) { + if(data == &button_user_sensor) { + packetbuf_copyfrom(&counter, sizeof(counter)); + broadcast_send(&bc); + } + } else if(ev == serial_line_event_message) { + leds_toggle(LEDS_SERIAL_IN); + } + counter++; + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + * @} + */ diff --git a/examples/openmote-cc2538/project-conf.h b/examples/openmote-cc2538/project-conf.h new file mode 100644 index 000000000..126ea1058 --- /dev/null +++ b/examples/openmote-cc2538/project-conf.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/** + * \addtogroup remote-examples + * @{ + * + * \file + * Project specific configuration defines for the basic RE-Mote examples + */ +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +#define BROADCAST_CHANNEL 129 +#define NETSTACK_CONF_RDC nullrdc_driver + +#endif /* PROJECT_CONF_H_ */ + +/** @} */ diff --git a/examples/openmote-cc2538/test-adxl346.c b/examples/openmote-cc2538/test-adxl346.c new file mode 100644 index 000000000..1a750a67c --- /dev/null +++ b/examples/openmote-cc2538/test-adxl346.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2014, OpenMote Technologies, S.L. + * 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. + * + */ + +/** + * \addtogroup openmote-examples + * @{ + * + * \defgroup openmote-adxl346 + * + * This example tests the correct functionality of the ADXL346 acceleration + * sensor using the I2C bus. + * + * @{ + * + * \file + * Testing the ADXL346 sensor on the OpenMote-CC2538 platform. + * \author + * Pere Tuset + */ + +#include "contiki.h" +#include "dev/adxl346.h" + +#include + +PROCESS(test_adxl346_process, "ADXL346 test"); +AUTOSTART_PROCESSES(&test_adxl346_process); + +PROCESS_THREAD(test_adxl346_process, ev, data) +{ + static struct etimer et; + static unsigned acceleration; + + PROCESS_BEGIN(); + adxl346_init(); + + if (!adxl346_is_present()) { + leds_on(LEDS_ORANGE); + } + + while(1) { + etimer_set(&et, CLOCK_SECOND); + + PROCESS_YIELD(); + + if (ev == PROCESS_EVENT_TIMER) { + acceleration = adxl346_read_x(); + printf("X Acceleration: %u\n", acceleration); + acceleration = adxl346_read_y(); + printf("Y Acceleration: %u\n", acceleration); + acceleration = adxl346_read_z(); + printf("Z Acceleration: %u\n", acceleration); + } + } + + PROCESS_END(); +} diff --git a/examples/openmote-cc2538/test-max44009.c b/examples/openmote-cc2538/test-max44009.c new file mode 100644 index 000000000..8085283ca --- /dev/null +++ b/examples/openmote-cc2538/test-max44009.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2014, OpenMote Technologies, S.L. + * 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. + * + */ + +/** + * \addtogroup openmote-examples + * @{ + * + * \defgroup openmote-max44009 + * + * This example tests the correct functionality of the MAX44009 light + * sensor using the I2C bus. + * + * @{ + * + * \file + * Testing the MAX44009 sensor on the OpenMote-CC2538 platform. + * \author + * Pere Tuset + */ + +#include "contiki.h" +#include "dev/max44009.h" +#include "dev/leds.h" +#include + +PROCESS(test_max44009_process, "MAX44009 test"); +AUTOSTART_PROCESSES(&test_max44009_process); + +PROCESS_THREAD(test_max44009_process, ev, data) +{ + static struct etimer et; + static unsigned raw; + static float light; + + PROCESS_BEGIN(); + max44009_init(); + +if (!max44009_is_present()) { + leds_on(LEDS_ORANGE); + } + + while(1) { + etimer_set(&et, CLOCK_SECOND); + + PROCESS_YIELD(); + + if (ev == PROCESS_EVENT_TIMER) { + leds_on(LEDS_YELLOW); + raw = max44009_read_light(); + light = max44009_convert_light(raw); + printf("Light: %u.%u\n", (unsigned int) light, (unsigned int) (light * 100) % 100); + leds_off(LEDS_YELLOW); + } + } + + PROCESS_END(); +} diff --git a/examples/openmote-cc2538/test-sht21.c b/examples/openmote-cc2538/test-sht21.c new file mode 100644 index 000000000..cefdb3266 --- /dev/null +++ b/examples/openmote-cc2538/test-sht21.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2014, OpenMote Technologies, S.L. + * 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. + * + */ + +/** + * \addtogroup openmote-examples + * @{ + * + * \defgroup openmote-sht21 + * + * This example tests the correct functionality of the SHT21 temperature + * and humidity sensor using the I2C bus. + * + * @{ + * + * \file + * Testing the SHT21 sensor on the OpenMote-CC2538 platform. + * \author + * Pere Tuset + */ + +#include "contiki.h" +#include "dev/sht21.h" +#include "dev/leds.h" +#include "sys/etimer.h" + +#include + +PROCESS(test_sht21_process, "SHT21 test"); +AUTOSTART_PROCESSES(&test_sht21_process); + +PROCESS_THREAD(test_sht21_process, ev, data) +{ + static struct etimer et; + static unsigned raw; + static float temperature; + static float humidity; + + PROCESS_BEGIN(); + sht21_init(); + + if (!sht21_is_present()) { + leds_on(LEDS_ORANGE); + } + + while(1) { + etimer_set(&et, CLOCK_SECOND); + + PROCESS_YIELD(); + + if (ev == PROCESS_EVENT_TIMER) { + leds_on(LEDS_YELLOW); + raw = sht21_read_temperature(); + temperature = sht21_convert_temperature(raw); + printf("Temperature: %u.%u degrees Celsius\n", (unsigned int) temperature, (unsigned int) (temperature * 100) % 100); + raw = sht21_read_humidity(); + humidity = sht21_convert_humidity(raw); + printf("Rel. humidity: %u.%u%%\n", (unsigned int) humidity, (unsigned int) (humidity * 100) % 100); + leds_off(LEDS_YELLOW ); + } + } + + PROCESS_END(); +} diff --git a/examples/openmote-cc2538/test-timer.c b/examples/openmote-cc2538/test-timer.c new file mode 100644 index 000000000..3eb8ff2ff --- /dev/null +++ b/examples/openmote-cc2538/test-timer.c @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2014, OpenMote Technologies, S.L. + * 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. + * + */ + +/** + * \addtogroup openmote-examples + * @{ + * + * \defgroup openmote-timers OpenMote-CC2538 Timer Test Project + * + * This example tests the correct functionality of clocks and timers. + * + * More specifically, it tests clock_seconds, rtimers, etimers and + * clock_delay_usec. + * + * This is largely-based on the same example of the cc2530 port. + * @{ + * + * \file + * Tests related to clocks and timers. + * \author + * Pere Tuset + */ + +#include "contiki.h" +#include "sys/clock.h" +#include "sys/rtimer.h" +#include "dev/leds.h" + +#include +/*---------------------------------------------------------------------------*/ +#define TIMER_TEST_CONF_TEST_CLOCK_DELAY_USEC 1 +#define TIMER_TEST_CONF_TEST_RTIMER 1 +#define TIMER_TEST_CONF_TEST_ETIMER 1 +#define TIMER_TEST_CONF_TEST_CLOCK_SECONDS 1 +/*---------------------------------------------------------------------------*/ +static struct etimer et; + +#if TIMER_TEST_CONF_TEST_CLOCK_DELAY_USEC +static rtimer_clock_t start_count, end_count, diff; +#endif + +#if TIMER_TEST_CONF_TEST_CLOCK_SECONDS +static unsigned long sec; +#endif + +#if TIMER_TEST_CONF_TEST_ETIMER +static clock_time_t count; +#endif + +#if TIMER_TEST_CONF_TEST_RTIMER +static struct rtimer rt; +rtimer_clock_t rt_now, rt_for; +static clock_time_t ct; +#endif + +static uint8_t i; +/*---------------------------------------------------------------------------*/ +PROCESS(timer_test_process, "Timer test process"); +AUTOSTART_PROCESSES(&timer_test_process); +/*---------------------------------------------------------------------------*/ +#if TIMER_TEST_CONF_TEST_RTIMER +void +rt_callback(struct rtimer *t, void *ptr) +{ + rt_now = RTIMER_NOW(); + ct = clock_time(); + printf("Task called at %lu (clock = %lu)\n", rt_now, ct); +} +#endif +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(timer_test_process, ev, data) +{ + + PROCESS_BEGIN(); + + etimer_set(&et, 2 * CLOCK_SECOND); + + PROCESS_YIELD(); + +#if TIMER_TEST_CONF_TEST_CLOCK_DELAY_USEC + printf("-----------------------------------------\n"); + printf("clock_delay_usec test, (10,000 x i) usec:\n"); + printf("N.B. clock_delay_usec is more accurate than rtimers\n"); + i = 1; + while(i < 7) { + start_count = RTIMER_NOW(); + clock_delay_usec(10000 * i); + end_count = RTIMER_NOW(); + diff = end_count - start_count; + printf("Requested: %u usec, Real: %lu rtimer ticks = ~%lu us\n", + 10000 * i, diff, diff * 1000000 / RTIMER_SECOND); + i++; + } +#endif + +#if TIMER_TEST_CONF_TEST_RTIMER + printf("-----------------------------------------\n"); + printf("Rtimer Test, 1 sec (%u rtimer ticks):\n", RTIMER_SECOND); + i = 0; + while(i < 5) { + etimer_set(&et, 2 * CLOCK_SECOND); + printf("=======================\n"); + ct = clock_time(); + rt_now = RTIMER_NOW(); + rt_for = rt_now + RTIMER_SECOND; + printf("Now=%lu (clock = %lu) - For=%lu\n", rt_now, ct, rt_for); + if(rtimer_set(&rt, rt_for, 1, rt_callback, NULL) != RTIMER_OK) { + printf("Error setting\n"); + } + + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + i++; + } +#endif + +#if TIMER_TEST_CONF_TEST_ETIMER + printf("-----------------------------------------\n"); + printf("Clock tick and etimer test, 1 sec (%u clock ticks):\n", + CLOCK_SECOND); + i = 0; + while(i < 10) { + etimer_set(&et, CLOCK_SECOND); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + etimer_reset(&et); + + count = clock_time(); + printf("%lu ticks\n", count); + + leds_toggle(LEDS_RED); + i++; + } +#endif + +#if TIMER_TEST_CONF_TEST_CLOCK_SECONDS + printf("-----------------------------------------\n"); + printf("Clock seconds test (5s):\n"); + i = 0; + while(i < 10) { + etimer_set(&et, 5 * CLOCK_SECOND); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + etimer_reset(&et); + + sec = clock_seconds(); + printf("%lu seconds\n", sec); + + leds_toggle(LEDS_GREEN); + i++; + } +#endif + + printf("Done!\n"); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/Makefile.openmote-cc2538 b/platform/openmote-cc2538/Makefile.openmote-cc2538 new file mode 100644 index 000000000..878b81877 --- /dev/null +++ b/platform/openmote-cc2538/Makefile.openmote-cc2538 @@ -0,0 +1,50 @@ +# openmote-cc2538 platform makefile + +ifndef CONTIKI + $(error CONTIKI not defined! You must specify where CONTIKI resides!) +endif + +### Configure the build for the board and pull in board-specific sources +CONTIKI_TARGET_DIRS += . dev +PLATFORM_ROOT_DIR = $(CONTIKI)/platform/$(TARGET) + +### Include +CONTIKI_TARGET_SOURCEFILES += contiki-main.c board.c +CONTIKI_TARGET_SOURCEFILES += leds-arch.c button-sensor.c smartrf-sensors.c +CONTIKI_TARGET_SOURCEFILES += antenna.c adxl346.c max44009.c sht21.c tps62730.c + +CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) + +CLEAN += *.openmote-cc2538 + +### Unless the example dictates otherwise, build with code size optimisations +ifndef SMALL + SMALL = 1 +endif + +### Define the CPU directory +CONTIKI_CPU=$(CONTIKI)/cpu/cc2538 +include $(CONTIKI_CPU)/Makefile.cc2538 + +MODULES += core/net core/net/mac \ + core/net/mac/contikimac \ + core/net/llsec core/net/llsec/noncoresec + +PYTHON = python +BSL_FLAGS += -e -w --bootloader-invert-lines -b 115200 -v + +ifdef PORT + BSL_FLAGS += -p $(PORT) +endif + +BSL = $(CONTIKI)/tools/cc2538-bsl/cc2538-bsl.py + +%.upload: %.bin %.elf +ifeq ($(wildcard $(BSL)), ) + @echo "ERROR: Could not find the cc2538-bsl script. Did you run 'git submodule update --init' ?" +else + $(eval BSL_ADDRESS_ARG := -a $(shell $(OBJDUMP) -h $*.elf | grep -B1 LOAD | \ + grep -Ev 'LOAD|\-\-' | awk '{print "0x" $$5}' | \ + sort -g | head -1)) + $(PYTHON) $(BSL) $(BSL_FLAGS) $(BSL_ADDRESS_ARG) $< +endif diff --git a/platform/openmote-cc2538/README.md b/platform/openmote-cc2538/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/platform/openmote-cc2538/board.c b/platform/openmote-cc2538/board.c new file mode 100644 index 000000000..0b565b43c --- /dev/null +++ b/platform/openmote-cc2538/board.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup openmote-cc2538 + * @{ + * + * \file + * Board-initialisation for the OpenMote-CC2538 platform + * + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "dev/antenna.h" +#include +#include +/*---------------------------------------------------------------------------*/ +static void +configure_unused_pins(void) +{ + /* FIXME */ +} +/*---------------------------------------------------------------------------*/ +void +board_init() +{ + antenna_init(); + configure_unused_pins(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + */ + diff --git a/platform/openmote-cc2538/board.h b/platform/openmote-cc2538/board.h new file mode 100644 index 000000000..08538a995 --- /dev/null +++ b/platform/openmote-cc2538/board.h @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +/** + * \addtogroup platform + * @{ + * + * \defgroup openmote + * + * \file + * Header file with definitions related to the I/O connections on the + * OpenMote-CC2538 platform. This file provides connectivity information on + * LEDs, Buttons, UART and other peripherals. + * + * \note + * Do not include this file directly. It gets included by contiki-conf + * after all relevant directives have been set. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ +/*---------------------------------------------------------------------------*/ +#include "dev/gpio.h" +#include "dev/nvic.h" +/*---------------------------------------------------------------------------*/ +/** \name OpenMote-CC2538 LED configuration + * + * LEDs on the OpenMote-CC2538 are connected as follows: + * - LED1 (Red) -> PC4 + * - LED2 (Yellow) -> PC6 + * - LED3 (Green) -> PC7 + * - LED4 (Orange) -> PC5 + * + * @{ + */ +/*---------------------------------------------------------------------------*/ +/* Some files include leds.h before us, so we need to get rid of defaults in + * leds.h before we provide correct definitions */ +#undef LEDS_GREEN +#undef LEDS_YELLOW +#undef LEDS_RED +#undef LEDS_CONF_ALL + +#define LEDS_RED 16 /**< LED1 (Red) -> PC4 */ +#define LEDS_YELLOW 64 /**< LED2 (Yellow) -> PC6 */ +#define LEDS_GREEN 128 /**< LED3 (Green) -> PC7 */ +#define LEDS_ORANGE 32 /**< LED4 (Orange) -> PC5 */ +#define LEDS_CONF_ALL 240 + +/* Notify various examples that we have LEDs */ +#define PLATFORM_HAS_LEDS 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name USB configuration + * + * The USB pullup is driven by PC0 + */ +#define USB_PULLUP_PORT GPIO_C_NUM +#define USB_PULLUP_PIN 0 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name UART configuration + * + * On the OpenMote, the UART is connected to the + * following ports/pins + * - RX: PA0 + * - TX: PA1 + * - CTS: PB0 (Can only be used with UART1) + * - RTS: PD3 (Can only be used with UART1) + * + * We configure the port to use UART0. To use UART1, replace UART0_* with + * UART1_* below. + * @{ + */ +#define UART0_RX_PORT GPIO_A_NUM +#define UART0_RX_PIN 0 + +#define UART0_TX_PORT GPIO_A_NUM +#define UART0_TX_PIN 1 + +#define UART1_CTS_PORT GPIO_B_NUM +#define UART1_CTS_PIN 0 + +#define UART1_RTS_PORT GPIO_D_NUM +#define UART1_RTS_PIN 3 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name OpenMote-CC2538 Button configuration + * + * Buttons on the OpenMote-CC2538 are connected as follows: + * - BUTTON_USER -> PC3 + * @{ + */ +/** BUTTON_USER -> PC3 */ +#define BUTTON_USER_PORT GPIO_C_NUM +#define BUTTON_USER_PIN 3 +#define BUTTON_USER_VECTOR NVIC_INT_GPIO_PORT_C +/* Notify various examples that we have Buttons */ +#define PLATFORM_HAS_BUTTON 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SPI configuration + * + * These values configure which CC2538 pins to use for the SPI lines. + * @{ + */ +#define SPI_CLK_PORT GPIO_A_NUM +#define SPI_CLK_PIN 2 +#define SPI_MOSI_PORT GPIO_A_NUM +#define SPI_MOSI_PIN 5 +#define SPI_MISO_PORT GPIO_A_NUM +#define SPI_MISO_PIN 4 +#define SPI_SEL_PORT GPIO_A_NUM +#define SPI_SEL_PIN 3 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name I2C configuration + * + * These values configure which CC2538 pins to use for the I2C lines. + * @{ + */ +#define I2C_SCL_PORT GPIO_B_NUM +#define I2C_SCL_PIN 3 +#define I2C_SDA_PORT GPIO_B_NUM +#define I2C_SDA_PIN 4 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Device string used on startup + * @{ + */ +#define BOARD_STRING "OpenMote-CC2538" +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* BOARD_H_ */ +/** @} */ diff --git a/platform/openmote-cc2538/contiki-conf.h b/platform/openmote-cc2538/contiki-conf.h new file mode 100644 index 000000000..44a15e539 --- /dev/null +++ b/platform/openmote-cc2538/contiki-conf.h @@ -0,0 +1,536 @@ +/** + * \addtogroup openmote + * @{ + * + * \file + * Configuration for the OpenMote-CC2538 platform. + */ +#ifndef CONTIKI_CONF_H_ +#define CONTIKI_CONF_H_ + +#include +#include +/*---------------------------------------------------------------------------*/ +/* Include Project Specific conf */ +#ifdef PROJECT_CONF_H +#include PROJECT_CONF_H +#endif /* PROJECT_CONF_H */ +/*---------------------------------------------------------------------------*/ +/** + * \name Compiler configuration and platform-specific type definitions + * + * Those values are not meant to be modified by the user + * @{ + */ +#define CLOCK_CONF_SECOND 128 + +/* Compiler configurations */ +#define CCIF +#define CLIF + +/* Platform typedefs */ +typedef uint32_t clock_time_t; +typedef uint32_t uip_stats_t; + +/* + * rtimer.h typedefs rtimer_clock_t as unsigned short. We need to define + * RTIMER_CLOCK_LT to override this + */ +typedef uint32_t rtimer_clock_t; +#define RTIMER_CLOCK_LT(a, b) ((int32_t)((a) - (b)) < 0) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Serial Boot Loader Backdoor configuration + * + * @{ + */ +#ifndef FLASH_CCA_CONF_BOOTLDR_BACKDOOR +#define FLASH_CCA_CONF_BOOTLDR_BACKDOOR 1 /** RAM DMA channel */ +#define USB_ARCH_CONF_TX_DMA_CHAN 1 /**< RAM -> USB DMA channel */ +#define CC2538_RF_CONF_TX_DMA_CHAN 2 /**< RF -> RAM DMA channel */ +#define CC2538_RF_CONF_RX_DMA_CHAN 3 /**< RAM -> RF DMA channel */ +#define UDMA_CONF_MAX_CHANNEL CC2538_RF_CONF_RX_DMA_CHAN +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Character I/O Configuration + * + * @{ + */ +#ifndef UART_CONF_ENABLE +#define UART_CONF_ENABLE 1 /**< Enable/Disable UART I/O */ +#endif + +#ifndef UART0_CONF_BAUD_RATE +#define UART0_CONF_BAUD_RATE 115200 /**< Default UART0 baud rate */ +#endif + +#ifndef UART1_CONF_BAUD_RATE +#define UART1_CONF_BAUD_RATE 115200 /**< Default UART1 baud rate */ +#endif + +#ifndef SLIP_ARCH_CONF_USB +#define SLIP_ARCH_CONF_USB 0 /**< SLIP over UART by default */ +#endif + +#ifndef CC2538_RF_CONF_SNIFFER_USB +#define CC2538_RF_CONF_SNIFFER_USB 0 /**< Sniffer out over UART by default */ +#endif + +#ifndef DBG_CONF_USB +#define DBG_CONF_USB 0 /**< All debugging over UART by default */ +#endif + +#ifndef SERIAL_LINE_CONF_UART +#define SERIAL_LINE_CONF_UART 0 /**< UART to use with serial line */ +#endif + +#if !SLIP_ARCH_CONF_USB +#ifndef SLIP_ARCH_CONF_UART +#define SLIP_ARCH_CONF_UART 0 /**< UART to use with SLIP */ +#endif +#endif + +#if !CC2538_RF_CONF_SNIFFER_USB +#ifndef CC2538_RF_CONF_SNIFFER_UART +#define CC2538_RF_CONF_SNIFFER_UART 0 /**< UART to use with sniffer */ +#endif +#endif + +#if !DBG_CONF_USB +#ifndef DBG_CONF_UART +#define DBG_CONF_UART 0 /**< UART to use for debugging */ +#endif +#endif + +#ifndef UART1_CONF_UART +#define UART1_CONF_UART 0 /**< UART to use for examples relying on + the uart1_* API */ +#endif + +/* Turn off example-provided putchars */ +#define SLIP_BRIDGE_CONF_NO_PUTCHAR 1 +#define SLIP_RADIO_CONF_NO_PUTCHAR 1 + +#ifndef SLIP_ARCH_CONF_ENABLED +/* + * Determine whether we need SLIP + * This will keep working while UIP_FALLBACK_INTERFACE and CMD_CONF_OUTPUT + * keep using SLIP + */ +#if defined(UIP_FALLBACK_INTERFACE) || defined(CMD_CONF_OUTPUT) +#define SLIP_ARCH_CONF_ENABLED 1 +#endif +#endif + +/* + * When set, the radio turns off address filtering and sends all captured + * frames down a peripheral (UART or USB, depending on the value of + * CC2538_RF_CONF_SNIFFER_USB) + */ +#ifndef CC2538_RF_CONF_SNIFFER +#define CC2538_RF_CONF_SNIFFER 0 +#endif + +/** + * \brief Define this as 1 to build a headless node. + * + * The UART will not be initialised its clock will be gated, offering some + * energy savings. The USB will not be initialised either + */ +#ifndef CC2538_CONF_QUIET +#define CC2538_CONF_QUIET 0 +#endif + +/* CC2538_CONF_QUIET is hard and overrides all other related defines */ +#if CC2538_CONF_QUIET +#undef USB_SERIAL_CONF_ENABLE +#define USB_SERIAL_CONF_ENABLE 0 + +#undef UART_CONF_ENABLE +#define UART_CONF_ENABLE 0 + +#undef STARTUP_CONF_VERBOSE +#define STARTUP_CONF_VERBOSE 0 + +/* Little sanity check: We can't have quiet sniffers */ +#if CC2538_RF_CONF_SNIFFER +#error "CC2538_RF_CONF_SNIFFER == 1 and CC2538_CONF_QUIET == 1" +#error "These values are conflicting. Please set either to 0" +#endif +#endif /* CC2538_CONF_QUIET */ + +/** + * \brief Enable the USB core only if we need it + */ +#ifndef USB_SERIAL_CONF_ENABLE +#define USB_SERIAL_CONF_ENABLE \ + ((SLIP_ARCH_CONF_USB & SLIP_ARCH_CONF_ENABLED) | \ + DBG_CONF_USB | \ + (CC2538_RF_CONF_SNIFFER & CC2538_RF_CONF_SNIFFER_USB)) +#endif + +/* + * If debugging and SLIP use the same peripheral, this will be 1. Don't modify + * this + */ +#if SLIP_ARCH_CONF_ENABLED +#define DBG_CONF_SLIP_MUX (SLIP_ARCH_CONF_USB == DBG_CONF_USB && \ + (SLIP_ARCH_CONF_USB || \ + SLIP_ARCH_CONF_UART == DBG_CONF_UART)) +#endif + +/* + * Automatic detection of whether a specific UART is in use + */ +#define UART_IN_USE_BY_SERIAL_LINE(u) (SERIAL_LINE_CONF_UART == (u)) +#define UART_IN_USE_BY_SLIP(u) (SLIP_ARCH_CONF_ENABLED && \ + !SLIP_ARCH_CONF_USB && \ + SLIP_ARCH_CONF_UART == (u)) +#define UART_IN_USE_BY_RF_SNIFFER(u) (CC2538_RF_CONF_SNIFFER && \ + !CC2538_RF_CONF_SNIFFER_USB && \ + CC2538_RF_CONF_SNIFFER_UART == (u)) +#define UART_IN_USE_BY_DBG(u) (!DBG_CONF_USB && DBG_CONF_UART == (u)) +#define UART_IN_USE_BY_UART1(u) (UART1_CONF_UART == (u)) + +#define UART_IN_USE(u) ( \ + UART_CONF_ENABLE && \ + (UART_IN_USE_BY_SERIAL_LINE(u) || \ + UART_IN_USE_BY_SLIP(u) || \ + UART_IN_USE_BY_RF_SNIFFER(u) || \ + UART_IN_USE_BY_DBG(u) || \ + UART_IN_USE_BY_UART1(u)) \ +) +/** @} */ +/*---------------------------------------------------------------------------*/ +/* board.h assumes that basic configuration is done */ +#include "board.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Network Stack Configuration + * + * @{ + */ +#ifndef NETSTACK_CONF_NETWORK +#if NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_NETWORK sicslowpan_driver +#else +#define NETSTACK_CONF_NETWORK rime_driver +#endif /* NETSTACK_CONF_WITH_IPV6 */ +#endif /* NETSTACK_CONF_NETWORK */ + +#ifndef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC csma_driver +#endif + +#ifndef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC contikimac_driver +#endif + +/* Configure NullRDC for when it's selected */ +#define NULLRDC_802154_AUTOACK 1 +#define NULLRDC_802154_AUTOACK_HW 1 + +/* Configure ContikiMAC for when it's selected */ +#define CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION 0 +#define WITH_FAST_SLEEP 1 + +#ifndef NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE +#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 +#endif + +#ifndef NETSTACK_CONF_FRAMER +#if NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_FRAMER framer_802154 +#else /* NETSTACK_CONF_WITH_IPV6 */ +#define NETSTACK_CONF_FRAMER contikimac_framer +#endif /* NETSTACK_CONF_WITH_IPV6 */ +#endif /* NETSTACK_CONF_FRAMER */ + +#ifndef NETSTACK_CONF_RADIO +#define NETSTACK_CONF_RADIO cc2538_rf_driver +#endif + +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name LPM configuration + * @{ + */ +#ifndef LPM_CONF_ENABLE +#define LPM_CONF_ENABLE 1 /**< Set to 0 to disable LPM entirely */ +#endif + +/** + * \brief Maximum PM + * + * The SoC will never drop to a Power Mode deeper than the one specified here. + * 0 for PM0, 1 for PM1 and 2 for PM2 + */ +#ifndef LPM_CONF_MAX_PM +#define LPM_CONF_MAX_PM 1 +#endif + +#ifndef LPM_CONF_STATS +#define LPM_CONF_STATS 0 /**< Set to 1 to enable LPM-related stats */ +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name IEEE address configuration + * + * Used to generate our RIME & IPv6 address + * @{ + */ +/** + * \brief Location of the IEEE address + * 0 => Read from InfoPage, + * 1 => Use a hardcoded address, configured by IEEE_ADDR_CONF_ADDRESS + */ +#ifndef IEEE_ADDR_CONF_HARDCODED +#define IEEE_ADDR_CONF_HARDCODED 0 +#endif + +/** + * \brief The hardcoded IEEE address to be used when IEEE_ADDR_CONF_HARDCODED + * is defined as 1 + */ +#ifndef IEEE_ADDR_CONF_ADDRESS +#define IEEE_ADDR_CONF_ADDRESS { 0x00, 0x12, 0x4B, 0x00, 0x89, 0xAB, 0xCD, 0xEF } +#endif + +/** + * \brief Location of the IEEE address in the InfoPage when + * IEEE_ADDR_CONF_HARDCODED is defined as 0 + * 0 => Use the primary address location + * 1 => Use the secondary address location + */ +#ifndef IEEE_ADDR_CONF_USE_SECONDARY_LOCATION +#define IEEE_ADDR_CONF_USE_SECONDARY_LOCATION 0 +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name RF configuration + * + * @{ + */ +/* RF Config */ +#ifndef IEEE802154_CONF_PANID +#define IEEE802154_CONF_PANID 0xABCD +#endif + +#ifndef CC2538_RF_CONF_CHANNEL +#define CC2538_RF_CONF_CHANNEL 26 +#endif /* CC2538_RF_CONF_CHANNEL */ + +#ifndef CC2538_RF_CONF_AUTOACK +#define CC2538_RF_CONF_AUTOACK 1 /**< RF H/W generates ACKs */ +#endif /* CC2538_CONF_AUTOACK */ + +#ifndef CC2538_RF_CONF_TX_USE_DMA +#define CC2538_RF_CONF_TX_USE_DMA 1 /**< RF TX over DMA */ +#endif + +#ifndef CC2538_RF_CONF_RX_USE_DMA +#define CC2538_RF_CONF_RX_USE_DMA 1 /**< RF RX over DMA */ +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name IPv6, RIME and network buffer configuration + * + * @{ + */ + +/* Don't let contiki-default-conf.h decide if we are an IPv6 build */ +#ifndef NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_WITH_IPV6 0 +#endif + +#if NETSTACK_CONF_WITH_IPV6 +/* Addresses, Sizes and Interfaces */ +/* 8-byte addresses here, 2 otherwise */ +#define LINKADDR_CONF_SIZE 8 +#define UIP_CONF_LL_802154 1 +#define UIP_CONF_LLH_LEN 0 +#define UIP_CONF_NETIF_MAX_ADDRESSES 3 + +/* TCP, UDP, ICMP */ +#ifndef UIP_CONF_TCP +#define UIP_CONF_TCP 1 +#endif +#ifndef UIP_CONF_TCP_MSS +#define UIP_CONF_TCP_MSS 64 +#endif +#define UIP_CONF_UDP 1 +#define UIP_CONF_UDP_CHECKSUMS 1 +#define UIP_CONF_ICMP6 1 + +/* ND and Routing */ +#ifndef UIP_CONF_ROUTER +#define UIP_CONF_ROUTER 1 +#endif + +#define UIP_CONF_ND6_SEND_RA 0 +#define UIP_CONF_IP_FORWARD 0 +#define RPL_CONF_STATS 0 + +#ifndef RPL_CONF_OF +#define RPL_CONF_OF rpl_mrhof +#endif + +#define UIP_CONF_ND6_REACHABLE_TIME 600000 +#define UIP_CONF_ND6_RETRANS_TIMER 10000 + +#ifndef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 20 +#endif +#ifndef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 20 +#endif + +/* uIP */ +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 1300 +#endif + +#define UIP_CONF_IPV6_QUEUE_PKT 0 +#define UIP_CONF_IPV6_CHECKS 1 +#define UIP_CONF_IPV6_REASSEMBLY 0 +#define UIP_CONF_MAX_LISTENPORTS 8 + +/* 6lowpan */ +#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 +#ifndef SICSLOWPAN_CONF_COMPRESSION_THRESHOLD +#define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 63 +#endif +#ifndef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +#endif +#define SICSLOWPAN_CONF_MAXAGE 8 + +/* Define our IPv6 prefixes/contexts here */ +#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 1 +#ifndef SICSLOWPAN_CONF_ADDR_CONTEXT_0 +#define SICSLOWPAN_CONF_ADDR_CONTEXT_0 { \ + addr_contexts[0].prefix[0] = 0xaa; \ + addr_contexts[0].prefix[1] = 0xaa; \ +} +#endif + +#define MAC_CONF_CHANNEL_CHECK_RATE 8 + +#ifndef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 8 +#endif +/*---------------------------------------------------------------------------*/ +#else /* NETSTACK_CONF_WITH_IPV6 */ +/* Network setup for non-IPv6 (rime). */ +#define UIP_CONF_IP_FORWARD 1 + +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 108 +#endif + +#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0 + +#ifndef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 8 +#endif + +#endif /* NETSTACK_CONF_WITH_IPV6 */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Security + * + * @{ + */ +#ifndef CRYPTO_CONF_INIT +#define CRYPTO_CONF_INIT 1 /**< Whether to init cryptoprocessor */ +#endif + +#ifndef AES_128_CONF +#define AES_128_CONF cc2538_aes_128_driver /**< AES-128 driver */ +#endif + +#ifndef CCM_STAR_CONF +#define CCM_STAR_CONF cc2538_ccm_star_driver /**< AES-CCM* driver */ +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ + +#endif /* CONTIKI_CONF_H_ */ + +/** @} */ diff --git a/platform/openmote-cc2538/contiki-main.c b/platform/openmote-cc2538/contiki-main.c new file mode 100644 index 000000000..72648088c --- /dev/null +++ b/platform/openmote-cc2538/contiki-main.c @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/** + * \addtogroup cc2538-platforms + * @{ + * + * \defgroup openmote The OpenMote-CC2538 platform + * + * The OpenMote-CC2538 is based on the CC2538, the new platform by Texas Instruments + * based on an ARM Cortex-M3 core and a IEEE 802.15.4 radio. + * @{ + * + * \file + * Main module for the OpenMote-CC2538 platform + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/leds.h" +#include "dev/sys-ctrl.h" +#include "dev/scb.h" +#include "dev/nvic.h" +#include "dev/uart.h" +#include "dev/watchdog.h" +#include "dev/ioc.h" +#include "dev/button-sensor.h" +#include "dev/serial-line.h" +#include "dev/slip.h" +#include "dev/cc2538-rf.h" +#include "dev/udma.h" +#include "dev/crypto.h" +#include "usb/usb-serial.h" +#include "lib/random.h" +#include "net/netstack.h" +#include "net/queuebuf.h" +#include "net/ip/tcpip.h" +#include "net/ip/uip.h" +#include "net/mac/frame802154.h" +#include "cpu.h" +#include "reg.h" +#include "ieee-addr.h" +#include "lpm.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#if STARTUP_CONF_VERBOSE +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#if UART_CONF_ENABLE +#define PUTS(s) puts(s) +#else +#define PUTS(s) +#endif +/*---------------------------------------------------------------------------*/ +/** \brief Board specific iniatialisation */ +void board_init(void); +/*---------------------------------------------------------------------------*/ +static void +fade(unsigned char l) +{ + volatile int i; + int k, j; + for(k = 0; k < 800; ++k) { + j = k > 400 ? 800 - k : k; + + leds_on(l); + for(i = 0; i < j; ++i) { + asm("nop"); + } + leds_off(l); + for(i = 0; i < 400 - j; ++i) { + asm("nop"); + } + } +} +/*---------------------------------------------------------------------------*/ +static void +set_rf_params(void) +{ + uint16_t short_addr; + uint8_t ext_addr[8]; + + ieee_addr_cpy_to(ext_addr, 8); + + short_addr = ext_addr[7]; + short_addr |= ext_addr[6] << 8; + + /* Populate linkaddr_node_addr. Maintain endianness */ + memcpy(&linkaddr_node_addr, &ext_addr[8 - LINKADDR_SIZE], LINKADDR_SIZE); + +#if STARTUP_CONF_VERBOSE + { + int i; + printf("Rime configured with address "); + for(i = 0; i < LINKADDR_SIZE - 1; i++) { + printf("%02x:", linkaddr_node_addr.u8[i]); + } + printf("%02x\n", linkaddr_node_addr.u8[i]); + } +#endif + + NETSTACK_RADIO.set_value(RADIO_PARAM_PAN_ID, IEEE802154_PANID); + NETSTACK_RADIO.set_value(RADIO_PARAM_16BIT_ADDR, short_addr); + NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, CC2538_RF_CHANNEL); + NETSTACK_RADIO.set_object(RADIO_PARAM_64BIT_ADDR, ext_addr, 8); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Main routine for the OpenMote-CC2538 platforms + */ +int +main(void) +{ + nvic_init(); + ioc_init(); + sys_ctrl_init(); + clock_init(); + lpm_init(); + rtimer_init(); + gpio_init(); + leds_init(); + fade(LEDS_RED); + process_init(); + watchdog_init(); + + /* + * Character I/O Initialisation. + * When the UART receives a character it will call serial_line_input_byte to + * notify the core. The same applies for the USB driver. + * + * If slip-arch is also linked in afterwards (e.g. if we are a border router) + * it will overwrite one of the two peripheral input callbacks. Characters + * received over the relevant peripheral will be handled by + * slip_input_byte instead + */ +#if UART_CONF_ENABLE + uart_init(0); + uart_init(1); + uart_set_input(SERIAL_LINE_CONF_UART, serial_line_input_byte); +#endif + +#if USB_SERIAL_CONF_ENABLE + usb_serial_init(); + usb_serial_set_input(serial_line_input_byte); +#endif + + serial_line_init(); + + INTERRUPTS_ENABLE(); + fade(LEDS_BLUE); + + PUTS(CONTIKI_VERSION_STRING); + PUTS(BOARD_STRING); + + /* Initialise the H/W RNG engine. */ + random_init(0); + + udma_init(); + + process_start(&etimer_process, NULL); + ctimer_init(); + + board_init(); + +#if CRYPTO_CONF_INIT + crypto_init(); + crypto_disable(); +#endif + + netstack_init(); + set_rf_params(); + + PRINTF(" Net: "); + PRINTF("%s\n", NETSTACK_NETWORK.name); + PRINTF(" MAC: "); + PRINTF("%s\n", NETSTACK_MAC.name); + PRINTF(" RDC: "); + PRINTF("%s\n", NETSTACK_RDC.name); + +#if NETSTACK_CONF_WITH_IPV6 + memcpy(&uip_lladdr.addr, &linkaddr_node_addr, sizeof(uip_lladdr.addr)); + queuebuf_init(); + process_start(&tcpip_process, NULL); +#endif /* NETSTACK_CONF_WITH_IPV6 */ + + process_start(&sensors_process, NULL); + + SENSORS_ACTIVATE(button_sensor); + + energest_init(); + ENERGEST_ON(ENERGEST_TYPE_CPU); + + autostart_start(autostart_processes); + + watchdog_start(); + fade(LEDS_GREEN); + + while(1) { + uint8_t r; + do { + /* Reset watchdog and handle polls and events */ + watchdog_periodic(); + + r = process_run(); + } while(r > 0); + + /* We have serviced all pending events. Enter a Low-Power mode. */ + lpm_enter(); + } +} +/*---------------------------------------------------------------------------*/ + +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/dev/adxl346.c b/platform/openmote-cc2538/dev/adxl346.c new file mode 100644 index 000000000..bdb934d2d --- /dev/null +++ b/platform/openmote-cc2538/dev/adxl346.c @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2014, OpenMote Technologies, S.L. + * 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. + * + */ + +/** + * \addtogroup platform + * @{ + * + * \defgroup openmote + * + * \file + * Driver for the ADXL346 acceleration sensor in OpenMote-CC2538. + * + * \author + * Pere Tuset + */ + +/*---------------------------------------------------------------------------*/ +#include "dev/i2c.h" +#include "dev/adxl346.h" +/*---------------------------------------------------------------------------*/ +/* ADDRESS AND IDENTIFIER */ +#define ADXL346_ADDRESS (0x53) +#define ADXL346_DEVID_VALUE (0xE6) + +/* REGISTER ADDRESSES */ +#define ADXL346_DEVID_ADDR (0x00) +#define ADXL346_THRES_TAP_ADDR (0x1D) +#define ADXL346_OFSX_ADDR (0x1E) +#define ADXL346_OFSY_ADDR (0x1F) +#define ADXL346_OFSZ_ADDR (0x20) +#define ADXL346_DUR_ADDR (0x21) +#define ADXL346_LATENT_ADDR (0x22) +#define ADXL346_WINDOW_ADDR (0x23) +#define ADXL346_THRESH_ACT_ADDR (0x24) +#define ADXL346_THRESH_INACT_ADDR (0x25) +#define ADXL346_TIME_INACT_ADDR (0x26) +#define ADXL346_ACT_INACT_CTL_ADDR (0x27) +#define ADXL346_THRESH_FF_ADDR (0x28) +#define ADXL346_TIME_FF_ADDR (0x29) +#define ADXL346_TAP_AXES_ADDR (0x2A) +#define ADXL346_ACT_TAP_STATUS_ADDR (0x2B) +#define ADXL346_BW_RATE_ADDR (0x2C) +#define ADXL346_POWER_CTL_ADDR (0x2D) +#define ADXL346_INT_ENABLE_ADDR (0x2E) +#define ADXL346_INT_MAP_ADDR (0x2F) +#define ADXL346_INT_SOURCE_ADDR (0x30) +#define ADXL346_DATA_FORMAT_ADDR (0x31) +#define ADXL346_DATAX0_ADDR (0x32) +#define ADXL346_DATAX1_ADDR (0x33) +#define ADXL346_DATAY0_ADDR (0x34) +#define ADXL346_DATAY1_ADDR (0x35) +#define ADXL346_DATAZ0_ADDR (0x36) +#define ADXL346_DATAZ1_ADDR (0x37) +#define ADXL346_FIFO_CTL_ADDR (0x38) +#define ADXL346_FIFO_STATUS_ADDR (0x39) +#define ADXL346_TAP_SIGN_ADDR (0x3A) +#define ADXL346_ORIENT_CONF_ADDR (0x3B) +#define ADXL346_ORIENT_ADDR (0x3C) + +/* INT_ENABLE/INT_MAP/INT_SOURCE */ +#define ADXL346_INT_ENABLE_DATA_READY (1 << 7) +#define ADXL346_INT_ENABLE_SINGLE_TAP (1 << 6) +#define ADXL346_INT_ENABLE_DOUBLE_TAP (1 << 5) +#define ADXL346_INT_ENABLE_ACTIVITY (1 << 4) +#define ADXL346_INT_ENABLE_INACTIVITY (1 << 3) +#define ADXL346_INT_ENABLE_FREE_FALL (1 << 2) +#define ADXL346_INT_ENABLE_WATERMARK (1 << 1) +#define ADXL346_INT_ENABLE_OVERRUN (1 << 0) + +/* ACT_INACT_CONTROL */ +#define ADXL346_ACT_INACT_CTL_ACT_ACDC (1 << 7) +#define ADXL346_ACT_INACT_CTL_ACT_X_EN (1 << 6) +#define ADXL346_ACT_INACT_CTL_ACT_Y_EN (1 << 5) +#define ADXL346_ACT_INACT_CTL_ACT_Z_EN (1 << 4) +#define ADXL346_ACT_INACT_CTL_INACT_ACDC (1 << 3) +#define ADXL346_ACT_INACT_CTL_INACT_X_EN (1 << 2) +#define ADXL346_ACT_INACT_CTL_INACT_Y_EN (1 << 1) +#define ADXL346_ACT_INACT_CTL_INACT_Z_EN (1 << 0) + +/* TAP_AXES */ +#define ADXL346_TAP_AXES_SUPPRESS (1 << 3) +#define ADXL346_TAP_AXES_TAP_X_EN (1 << 2) +#define ADXL346_TAP_AXES_TAP_Y_EN (1 << 1) +#define ADXL346_TAP_AXES_TAP_Z_EN (1 << 0) + +/* ACT_TAP_STATUS */ +#define ADXL346_ACT_TAP_STATUS_ACT_X_SRC (1 << 6) +#define ADXL346_ACT_TAP_STATUS_ACT_Y_SRC (1 << 5) +#define ADXL346_ACT_TAP_STATUS_ACT_Z_SRC (1 << 4) +#define ADXL346_ACT_TAP_STATUS_ASLEEP (1 << 3) +#define ADXL346_ACT_TAP_STATUS_TAP_X_SRC (1 << 2) +#define ADXL346_ACT_TAP_STATUS_TAP_Y_SRC (1 << 1) +#define ADXL346_ACT_TAP_STATUS_TAP_Z_SRC (1 << 0) + +/* BW_RATE */ +#define ADXL346_BW_RATE_POWER (1 << 4) +#define ADXL346_BW_RATE_RATE(x) ((x) & 0x0F) + +/* POWER CONTROL */ +#define ADXL346_POWER_CTL_LINK (1 << 5) +#define ADXL346_POWER_CTL_AUTO_SLEEP (1 << 4) +#define ADXL346_POWER_CTL_MEASURE (1 << 3) +#define ADXL346_POWER_CTL_SLEEP (1 << 2) +#define ADXL346_POWER_CTL_WAKEUP(x) ((x) & 0x03) + +/* DATA_FORMAT */ +#define ADXL346_DATA_FORMAT_SELF_TEST (1 << 7) +#define ADXL346_DATA_FORMAT_SPI (1 << 6) +#define ADXL346_DATA_FORMAT_INT_INVERT (1 << 5) +#define ADXL346_DATA_FORMAT_FULL_RES (1 << 3) +#define ADXL346_DATA_FORMAT_JUSTIFY (1 << 2) +#define ADXL346_DATA_FORMAT_RANGE(x) ((x) & 0x03) +#define ADXL346_DATA_FORMAT_RANGE_PM_2g (0) +#define ADXL346_DATA_FORMAT_RANGE_PM_4g (1) +#define ADXL346_DATA_FORMAT_RANGE_PM_8g (2) +#define ADXL346_DATA_FORMAT_RANGE_PM_16g (3) +/*---------------------------------------------------------------------------*/ +/** + * + */ +void +adxl346_init(void) +{ + uint8_t config[2]; + + i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, + I2C_SCL_NORMAL_BUS_SPEED); + + config[0] = ADXL346_BW_RATE_ADDR; + config[1] = (ADXL346_BW_RATE_RATE(11)); + i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); + + config[0] = ADXL346_DATA_FORMAT_ADDR; + config[1] = (ADXL346_DATA_FORMAT_SELF_TEST | + ADXL346_DATA_FORMAT_FULL_RES | + ADXL346_DATA_FORMAT_RANGE_PM_16g); + i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); + + config[0] = ADXL346_POWER_CTL_ADDR; + config[1] = (ADXL346_POWER_CTL_MEASURE); + i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); +} +/*---------------------------------------------------------------------------*/ +/** + * + */ +void +adxl346_reset(void) +{ +} +/*---------------------------------------------------------------------------*/ +/** + * + */ +uint8_t +adxl346_is_present(void) +{ + uint8_t is_present; + + i2c_single_send(ADXL346_ADDRESS, ADXL346_DEVID_ADDR); + i2c_single_receive(ADXL346_ADDRESS, &is_present); + + return is_present == ADXL346_DEVID_VALUE; +} +/*---------------------------------------------------------------------------*/ +/** + * + */ +uint16_t +adxl346_read_x(void) +{ + uint8_t acceleration[2]; + uint16_t x; + + i2c_single_send(ADXL346_ADDRESS, ADXL346_DATAX0_ADDR); + i2c_single_receive(ADXL346_ADDRESS, &acceleration[0]); + i2c_single_send(ADXL346_ADDRESS, ADXL346_DATAX1_ADDR); + i2c_single_receive(ADXL346_ADDRESS, &acceleration[1]); + + x = (acceleration[0] << 8) | acceleration[1]; + + return x; +} +/*---------------------------------------------------------------------------*/ +/** + * + */ +uint16_t +adxl346_read_y(void) +{ + uint8_t acceleration[2]; + uint16_t y; + + i2c_single_send(ADXL346_ADDRESS, ADXL346_DATAY0_ADDR); + i2c_single_receive(ADXL346_ADDRESS, &acceleration[0]); + i2c_single_send(ADXL346_ADDRESS, ADXL346_DATAY1_ADDR); + i2c_single_receive(ADXL346_ADDRESS, &acceleration[1]); + + y = (acceleration[0] << 8) | acceleration[1]; + + return y; +} +/*---------------------------------------------------------------------------*/ +/** + * + */ +uint16_t +adxl346_read_z(void) +{ + uint8_t acceleration[2]; + uint16_t z; + + i2c_single_send(ADXL346_ADDRESS, ADXL346_DATAZ0_ADDR); + i2c_single_receive(ADXL346_ADDRESS, &acceleration[0]); + i2c_single_send(ADXL346_ADDRESS, ADXL346_DATAZ1_ADDR); + i2c_single_receive(ADXL346_ADDRESS, &acceleration[1]); + + z = (acceleration[0] << 8) | acceleration[1]; + + return z; +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/openmote-cc2538/dev/adxl346.h b/platform/openmote-cc2538/dev/adxl346.h new file mode 100644 index 000000000..d5e9eac76 --- /dev/null +++ b/platform/openmote-cc2538/dev/adxl346.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014, OpenMote Technologies, S.L. + * 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. + * + */ + +/** + * \addtogroup platform + * @{ + * + * \defgroup openmote + * + * \file + * Header for the ADXL346 acceleration sensor in OpenMote-CC2538. + * + * \author + * Pere Tuset + */ + +#ifndef __ADXL346_H__ +#define __ADXL346_H__ +/*---------------------------------------------------------------------------*/ +void adxl346_init(void); +void adxl346_reset(void); +uint8_t adxl346_is_present(void); +uint16_t adxl346_read_x(void); +uint16_t adxl346_read_y(void); +uint16_t adxl346_read_z(void); +/*---------------------------------------------------------------------------*/ +#endif /* ifndef __ADXL346_H__ */ +/** @} */ diff --git a/platform/openmote-cc2538/dev/antenna.c b/platform/openmote-cc2538/dev/antenna.c new file mode 100644 index 000000000..b0ad7b07e --- /dev/null +++ b/platform/openmote-cc2538/dev/antenna.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2014, Thingsquare, http://www.thingsquare.com/. + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + * + */ + +/** + * \addtogroup platform + * @{ + * + * \defgroup openmote + * + * \file + * Driver for the antenna selection on the OpenMote-CC2538 platform. + */ + +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "dev/gpio.h" +#include "dev/antenna.h" +/*---------------------------------------------------------------------------*/ +#define BSP_RADIO_BASE (GPIO_D_BASE) +#define BSP_RADIO_INT (1 << 5) +#define BSP_RADIO_EXT (1 << 4) +/*---------------------------------------------------------------------------*/ +static void +gpio_set(int port, int bit) +{ + REG((port | GPIO_DATA) + (bit << 2)) = bit; +} +/*---------------------------------------------------------------------------*/ +static void +gpio_reset(int port, int bit) +{ + REG((port | GPIO_DATA) + (bit << 2)) = 0; +} +/*---------------------------------------------------------------------------*/ +/** + * Configure the antenna using the RF switch + * INT is the internal antenna (chip) configured through ANT1_SEL (V1) + * EXT is the external antenna (connector) configured through ANT2_SEL (V2) + */ +void +antenna_init(void) +{ + /* Configure the ANT1 and ANT2 GPIO as output */ + GPIO_SET_OUTPUT(BSP_RADIO_BASE, BSP_RADIO_INT); + GPIO_SET_OUTPUT(BSP_RADIO_BASE, BSP_RADIO_EXT); + + /* Select external antenna by default. */ + antenna_external(); +} +/*---------------------------------------------------------------------------*/ +/** + * Select the external (connector) antenna + */ +void +antenna_external(void) +{ + gpio_reset(BSP_RADIO_BASE, BSP_RADIO_INT); + gpio_set(BSP_RADIO_BASE, BSP_RADIO_EXT); +} +/*---------------------------------------------------------------------------*/ +/** + * Select the internal (chip) antenna + */ +void +antenna_internal(void) +{ + gpio_reset(BSP_RADIO_BASE, BSP_RADIO_EXT); + gpio_set(BSP_RADIO_BASE, BSP_RADIO_INT); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/openmote-cc2538/dev/antenna.h b/platform/openmote-cc2538/dev/antenna.h new file mode 100644 index 000000000..8b14df4b0 --- /dev/null +++ b/platform/openmote-cc2538/dev/antenna.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014, Thingsquare, http://www.thingsquare.com/. + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + * + */ + +/** + * \addtogroup platform + * @{ + * + * \defgroup openmote + * + * \file + * Header for the antenna selection on the OpenMote-CC2538 platform. + */ + +#ifndef ANTENNA_H_ +#define ANTENNA_H_ +/*---------------------------------------------------------------------------*/ +void antenna_init(void); +void antenna_internal(void); +void antenna_external(void); +/*---------------------------------------------------------------------------*/ +#endif /* ANTENNA_H_ */ +/** @} */ diff --git a/platform/openmote-cc2538/dev/button-sensor.c b/platform/openmote-cc2538/dev/button-sensor.c new file mode 100644 index 000000000..6d85400d7 --- /dev/null +++ b/platform/openmote-cc2538/dev/button-sensor.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +/** + * \addtogroup platform + * @{ + * + * \defgroup openmote + * + * \file + * Driver for the OpenMote-CC2538 buttons + * + */ + +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/nvic.h" +#include "dev/ioc.h" +#include "dev/gpio.h" +#include "dev/button-sensor.h" +#include "sys/timer.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#define BUTTON_USER_PORT_BASE GPIO_PORT_TO_BASE(BUTTON_USER_PORT) +#define BUTTON_USER_PIN_MASK GPIO_PIN_MASK(BUTTON_USER_PIN) +/*---------------------------------------------------------------------------*/ +static struct timer debouncetimer; +/*---------------------------------------------------------------------------*/ +/** + * \brief Common initialiser for all buttons + * \param port_base GPIO port's register offset + * \param pin_mask Pin mask corresponding to the button's pin + */ +static void +config(uint32_t port_base, uint32_t pin_mask) +{ + /* Software controlled */ + GPIO_SOFTWARE_CONTROL(port_base, pin_mask); + + /* Set pin to input */ + GPIO_SET_INPUT(port_base, pin_mask); + + /* Enable edge detection */ + GPIO_DETECT_EDGE(port_base, pin_mask); + + /* Single edge */ + GPIO_TRIGGER_SINGLE_EDGE(port_base, pin_mask); + + /* Trigger interrupt on Falling edge */ + GPIO_DETECT_RISING(port_base, pin_mask); + + GPIO_ENABLE_INTERRUPT(port_base, pin_mask); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Callback registered with the GPIO module. Gets fired with a button + * port/pin generates an interrupt + * \param port The port number that generated the interrupt + * \param pin The pin number that generated the interrupt. This is the pin + * absolute number (i.e. 0, 1, ..., 7), not a mask + */ +static void +btn_callback(uint8_t port, uint8_t pin) +{ + if(!timer_expired(&debouncetimer)) { + return; + } + timer_set(&debouncetimer, CLOCK_SECOND / 8); + if(port == GPIO_C_NUM) { + sensors_changed(&button_user_sensor); + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Init function for the select button. + * + * Parameters are ignored. They have been included because the prototype is + * dictated by the core sensor api. The return value is also not required by + * the API but otherwise ignored. + * + * \param type ignored + * \param value ignored + * \return ignored + */ +static int +config_user(int type, int value) +{ + config(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + + ioc_set_over(BUTTON_USER_PORT, BUTTON_USER_PIN, IOC_OVERRIDE_PUE); + + nvic_interrupt_enable(BUTTON_USER_VECTOR); + + gpio_register_callback(btn_callback, BUTTON_USER_PORT, BUTTON_USER_PIN); + return 1; +} +/*---------------------------------------------------------------------------*/ +void +button_sensor_init() +{ + timer_set(&debouncetimer, 0); +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(button_user_sensor, BUTTON_SENSOR, NULL, config_user, NULL); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/openmote-cc2538/dev/button-sensor.h b/platform/openmote-cc2538/dev/button-sensor.h new file mode 100644 index 000000000..ec7849ee1 --- /dev/null +++ b/platform/openmote-cc2538/dev/button-sensor.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +/** + * \addtogroup platform + * @{ + * + * \defgroup openmote + * + * \file + * Header for the OpenMote-CC2538 buttons + * + */ + +#ifndef BUTTON_SENSOR_H_ +#define BUTTON_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +#include "dev/gpio.h" +/*---------------------------------------------------------------------------*/ +#define BUTTON_SENSOR "Button" +/*---------------------------------------------------------------------------*/ +#define button_sensor button_user_sensor +extern const struct sensors_sensor button_user_sensor; +/*---------------------------------------------------------------------------*/ +#endif /* BUTTON_SENSOR_H_ */ + +/** \brief Common initialiser for all SmartRF Buttons */ +void button_sensor_init(); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/openmote-cc2538/dev/leds-arch.c b/platform/openmote-cc2538/dev/leds-arch.c new file mode 100644 index 000000000..13a4c1347 --- /dev/null +++ b/platform/openmote-cc2538/dev/leds-arch.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +/** + * \addtogroup platform + * @{ + * + * \defgroup openmote + * + * \file + * Driver for the OpenMote-CC2538 LEDs + * + */ + +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "reg.h" +#include "dev/leds.h" +#include "dev/gpio.h" +/*---------------------------------------------------------------------------*/ +#define LEDS_GPIO_PIN_MASK LEDS_ALL +/*---------------------------------------------------------------------------*/ +void +leds_arch_init(void) +{ + GPIO_SET_OUTPUT(GPIO_C_BASE, LEDS_GPIO_PIN_MASK); +} +/*---------------------------------------------------------------------------*/ +unsigned char +leds_arch_get(void) +{ + return GPIO_READ_PIN(GPIO_C_BASE, LEDS_GPIO_PIN_MASK); +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set(unsigned char leds) +{ + GPIO_WRITE_PIN(GPIO_C_BASE, LEDS_GPIO_PIN_MASK, leds); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/openmote-cc2538/dev/max44009.c b/platform/openmote-cc2538/dev/max44009.c new file mode 100644 index 000000000..34bce89ab --- /dev/null +++ b/platform/openmote-cc2538/dev/max44009.c @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2014, OpenMote Technologies, S.L. + * 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. + * + */ + +/** + * \addtogroup platform + * @{ + * + * \defgroup openmote + * + * \file + * Driver for the MAX44009 light sensor in OpenMote-CC2538. + * + * \author + * Pere Tuset + */ + +/*---------------------------------------------------------------------------*/ +#include "dev/i2c.h" +#include "dev/max44009.h" +/*---------------------------------------------------------------------------*/ +/* ADDRESS AND NOT_FOUND VALUE */ +#define MAX44009_ADDRESS (0x4A) +#define MAX44009_NOT_FOUND (0x00) + +/* REGISTER ADDRESSES */ +#define MAX44009_INT_STATUS_ADDR (0x00) /* R */ +#define MAX44009_INT_ENABLE_ADDR (0x01) /* R/W */ +#define MAX44009_CONFIG_ADDR (0x02) /* R/W */ +#define MAX44009_LUX_HIGH_ADDR (0x03) /* R */ +#define MAX44009_LUX_LOW_ADDR (0x04) /* R */ +#define MAX44009_THR_HIGH_ADDR (0x05) /* R/W */ +#define MAX44009_THR_LOW_ADDR (0x06) /* R/W */ +#define MAX44009_THR_TIMER_ADDR (0x07) /* R/W */ + +/* INTERRUPT VALUES */ +#define MAX44009_INT_STATUS_OFF (0x00) +#define MAX44009_INT_STATUS_ON (0x01) +#define MAX44009_INT_DISABLED (0x00) +#define MAX44009_INT_ENABLED (0x01) + +/* CONFIGURATION VALUES */ +#define MAX44009_CONFIG_DEFAULT (0 << 7) +#define MAX44009_CONFIG_CONTINUOUS (1 << 7) +#define MAX44009_CONFIG_AUTO (0 << 6) +#define MAX44009_CONFIG_MANUAL (1 << 6) +#define MAX44009_CONFIG_CDR_NORMAL (0 << 5) +#define MAX44009_CONFIG_CDR_DIVIDED (1 << 5) +#define MAX44009_CONFIG_INTEGRATION_800ms (0 << 0) +#define MAX44009_CONFIG_INTEGRATION_400ms (1 << 0) +#define MAX44009_CONFIG_INTEGRATION_200ms (2 << 0) +#define MAX44009_CONFIG_INTEGRATION_100ms (3 << 0) +#define MAX44009_CONFIG_INTEGRATION_50ms (4 << 0) +#define MAX44009_CONFIG_INTEGRATION_25ms (5 << 0) +#define MAX44009_CONFIG_INTEGRATION_12ms (6 << 0) +#define MAX44009_CONFIG_INTEGRATION_6ms (7 << 0) + +/* DEFAULT CONFIGURATION */ +#define MAX44009_DEFAULT_CONFIGURATION (MAX44009_CONFIG_DEFAULT | \ + MAX44009_CONFIG_AUTO | \ + MAX44009_CONFIG_CDR_NORMAL | \ + MAX44009_CONFIG_INTEGRATION_100ms) +/*---------------------------------------------------------------------------*/ +/** + * + */ +void +max44009_init(void) +{ + uint8_t max44009_address[5] = { MAX44009_INT_ENABLE_ADDR, MAX44009_CONFIG_ADDR, \ + MAX44009_THR_HIGH_ADDR, MAX44009_THR_LOW_ADDR, \ + MAX44009_THR_TIMER_ADDR }; + uint8_t max44009_value[5]; + uint8_t max44009_data[2]; + uint8_t i; + + max44009_value[0] = (MAX44009_INT_STATUS_ON); + max44009_value[1] = (MAX44009_DEFAULT_CONFIGURATION); + max44009_value[2] = (0xFF); + max44009_value[3] = (0x00); + max44009_value[4] = (0xFF); + + i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, + I2C_SCL_NORMAL_BUS_SPEED); + + for(i = 0; i < sizeof(max44009_address); i++) { + max44009_data[0] = max44009_value[i]; + max44009_data[1] = max44009_data[i]; + i2c_burst_send(MAX44009_ADDRESS, max44009_data, 2); + } +} +/*---------------------------------------------------------------------------*/ +/** + * + */ +void +max44009_reset(void) +{ + uint8_t max44009_address[5] = { MAX44009_INT_ENABLE_ADDR, MAX44009_CONFIG_ADDR, \ + MAX44009_THR_HIGH_ADDR, MAX44009_THR_LOW_ADDR, \ + MAX44009_THR_TIMER_ADDR }; + uint8_t max44009_value[5] = { 0x00, 0x03, 0xFF, 0x00, 0xFF }; + uint8_t max44009_data[2]; + uint8_t i; + + for(i = 0; i < sizeof(max44009_address); i++) { + max44009_data[0] = max44009_value[i]; + max44009_data[1] = max44009_data[i]; + i2c_burst_send(MAX44009_ADDRESS, max44009_data, 2); + } +} +/*---------------------------------------------------------------------------*/ +/** + * + */ +uint8_t +max44009_is_present(void) +{ + uint8_t is_present; + + i2c_single_send(MAX44009_ADDRESS, MAX44009_CONFIG_ADDR); + i2c_single_receive(MAX44009_ADDRESS, &is_present); + + return is_present != MAX44009_NOT_FOUND; +} +/*---------------------------------------------------------------------------*/ +/** + * + */ +uint16_t +max44009_read_light(void) +{ + uint8_t exponent, mantissa; + uint8_t max44009_data[2]; + uint16_t result; + + i2c_single_send(MAX44009_ADDRESS, MAX44009_LUX_HIGH_ADDR); + i2c_single_receive(MAX44009_ADDRESS, &max44009_data[0]); + i2c_single_send(MAX44009_ADDRESS, MAX44009_LUX_LOW_ADDR); + i2c_single_receive(MAX44009_ADDRESS, &max44009_data[1]); + + exponent = ((max44009_data[0] >> 4) & 0x0E); + mantissa = ((max44009_data[0] & 0x0F) << 4) | (max44009_data[1] & 0x0F); + + result = ((uint16_t)exponent << 8) | ((uint16_t)mantissa << 0); + + return result; +} +/*---------------------------------------------------------------------------*/ +/** + * + */ +float +max44009_convert_light(uint16_t lux) +{ + uint8_t exponent, mantissa; + float result = 0.045; + + exponent = (lux >> 8) & 0xFF; + exponent = (exponent == 0x0F ? exponent & 0x0E : exponent); + + mantissa = (lux >> 0) & 0xFF; + + result *= 2 ^ exponent * mantissa; + + return result; +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/openmote-cc2538/dev/max44009.h b/platform/openmote-cc2538/dev/max44009.h new file mode 100644 index 000000000..dbc40775d --- /dev/null +++ b/platform/openmote-cc2538/dev/max44009.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2014, OpenMote Technologies, S.L. + * 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. + * + */ + +/** + * \addtogroup platform + * @{ + * + * \defgroup openmote + * + * \file + * Header for the MAX44009 light sensor in OpenMote-CC2538. + * + * \author + * Pere Tuset + */ + +#ifndef __MAX44009_H__ +#define __MAX44009_H__ +/*---------------------------------------------------------------------------*/ +void max44009_init(void); +void max44009_reset(void); +uint8_t max44009_is_present(void); +uint16_t max44009_read_light(void); +float max44009_convert_light(uint16_t light); +/*---------------------------------------------------------------------------*/ +#endif /* ifndef __MAX44009_H__ */ +/** @} */ diff --git a/platform/openmote-cc2538/dev/sht21.c b/platform/openmote-cc2538/dev/sht21.c new file mode 100644 index 000000000..1ad07836f --- /dev/null +++ b/platform/openmote-cc2538/dev/sht21.c @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2014, OpenMote Technologies, S.L. + * 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. + * + */ + +/** + * \addtogroup platform + * @{ + * + * \defgroup openmote + * + * \file + * Driver for the SHT21 temperature and humidity sensor in OpenMote-CC2538. + * + * \author + * Pere Tuset + */ + +/*---------------------------------------------------------------------------*/ +#include "i2c.h" +#include "sht21.h" +/*---------------------------------------------------------------------------*/ +#define SHT21_ADDRESS (0x40) + +#define SHT21_USER_REG_READ (0xE7) +#define SHT21_USER_REG_WRITE (0xE6) +#define SHT21_USER_REG_RESERVED_BITS (0x38) + +#define SHT21_RESOLUTION_12b_14b ((0 << 7) | (0 << 0)) +#define SHT21_RESOLUTION_8b_12b ((0 << 7) | (1 << 0)) +#define SHT21_RESOLUTION_10b_13b ((1 << 7) | (0 << 0)) +#define SHT21_RESOLUTION_11b_11b ((1 << 7) | (1 << 0)) +#define SHT21_BATTERY_ABOVE_2V25 (0 << 6) +#define SHT21_BATTERY_BELOW_2V25 (1 << 6) +#define SHT21_ONCHIP_HEATER_ENABLE (1 << 2) +#define SHT21_ONCHIP_HEATER_DISABLE (0 << 2) +#define SHT21_OTP_RELOAD_ENABLE (0 << 1) +#define SHT21_OTP_RELOAD_DISABLE (1 << 1) + +#define SHT21_TEMPERATURE_HM_CMD (0xE3) +#define SHT21_HUMIDITY_HM_CMD (0xE5) +#define SHT21_TEMPERATURE_NHM_CMD (0xF3) +#define SHT21_HUMIDITY_NHM_CMD (0xF5) +#define SHT21_RESET_CMD (0xFE) + +#define SHT21_STATUS_MASK ( 0xFC ) + +#define SHT21_DEFAULT_CONFIG (SHT21_RESOLUTION_12b_14b | \ + SHT21_ONCHIP_HEATER_DISABLE | \ + SHT21_BATTERY_ABOVE_2V25 | \ + SHT21_OTP_RELOAD_DISABLE) + +#define SHT21_USER_CONFIG (SHT21_RESOLUTION_8b_12b | \ + SHT21_ONCHIP_HEATER_DISABLE | \ + SHT21_BATTERY_ABOVE_2V25 | \ + SHT21_OTP_RELOAD_DISABLE) +/*---------------------------------------------------------------------------*/ +/** + * + */ +void +sht21_init(void) +{ + uint8_t config[2]; + + i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, + I2C_SCL_NORMAL_BUS_SPEED); + + /* Setup the configuration vector, the first position holds address */ + /* and the second position holds the actual configuration */ + config[0] = SHT21_USER_REG_WRITE; + config[1] = 0; + + /* Read the current configuration according to the datasheet (pag. 9, fig. 18) */ + i2c_single_send(SHT21_ADDRESS, SHT21_USER_REG_READ); + i2c_single_receive(SHT21_ADDRESS, &config[1]); + + /* Clean all the configuration bits except those reserved */ + config[1] &= SHT21_USER_REG_RESERVED_BITS; + + /* Set the configuration bits without changing those reserved */ + config[1] |= SHT21_USER_CONFIG; + + i2c_burst_send(SHT21_ADDRESS, config, sizeof(config)); +} +/*---------------------------------------------------------------------------*/ +/** + * + */ +void +sht21_reset(void) +{ + /* Send a soft-reset command according to the datasheet (pag. 9, fig. 17) */ + i2c_single_send(SHT21_ADDRESS, SHT21_RESET_CMD); +} +/*---------------------------------------------------------------------------*/ +/** + * + */ +uint8_t +sht21_is_present(void) +{ + uint8_t is_present; + + /* Read the current configuration according to the datasheet (pag. 9, fig. 18) */ + i2c_single_send(SHT21_ADDRESS, SHT21_USER_REG_READ); + i2c_single_receive(SHT21_ADDRESS, &is_present); + + /* Clear the reserved bits according to the datasheet (pag. 9, tab. 8) */ + is_present &= ~SHT21_USER_REG_RESERVED_BITS; + + is_present = ((is_present == SHT21_USER_CONFIG) || (is_present == SHT21_DEFAULT_CONFIG)); + + return is_present; +} +/*---------------------------------------------------------------------------*/ +/** + * + */ +uint16_t +sht21_read_temperature(void) +{ + uint8_t sht21_temperature[2]; + uint16_t temperature; + + /* Read the current temperature according to the datasheet (pag. 8, fig. 15) */ + i2c_single_send(SHT21_ADDRESS, SHT21_TEMPERATURE_HM_CMD); + i2c_burst_receive(SHT21_ADDRESS, sht21_temperature, sizeof(sht21_temperature)); + + temperature = (sht21_temperature[0] << 8) | (sht21_temperature[1] & SHT21_STATUS_MASK); + + return temperature; +} +/*---------------------------------------------------------------------------*/ +/** + * + */ +float +sht21_convert_temperature(uint16_t temperature) +{ + float result; + + result = -46.85; + result += 175.72 * (float) temperature / 65536.0; + + return result; +} +/*---------------------------------------------------------------------------*/ +/** + * + */ +uint16_t +sht21_read_humidity(void) +{ + uint8_t sht21_humidity[2]; + uint16_t humidity; + + /* Read the current humidity according to the datasheet (pag. 8, fig. 15) */ + i2c_single_send(SHT21_ADDRESS, SHT21_HUMIDITY_HM_CMD); + i2c_burst_receive(SHT21_ADDRESS, sht21_humidity, sizeof(sht21_humidity)); + + humidity = (sht21_humidity[0] << 8) | (sht21_humidity[1] & SHT21_STATUS_MASK); + + return humidity; +} +/*---------------------------------------------------------------------------*/ +/** + * + */ +float +sht21_convert_humidity(uint16_t humidity) +{ + float result; + + result = -6.0; + result += 125.0 * (float) humidity / 65536.0; + + return result; +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/openmote-cc2538/dev/sht21.h b/platform/openmote-cc2538/dev/sht21.h new file mode 100644 index 000000000..c95e02edf --- /dev/null +++ b/platform/openmote-cc2538/dev/sht21.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2014, OpenMote Technologies, S.L. + * 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. + * + */ + +/** + * \addtogroup platform + * @{ + * + * \defgroup openmote + * + * \file + * Header for the SHT21 temperature and humidity sensor in OpenMote-CC2538. + * + * \author + * Pere Tuset + */ + +#ifndef __SHT21_H__ +#define __SHT21_H__ +/*---------------------------------------------------------------------------*/ +void sht21_init(void); +void sht21_reset(void); +uint8_t sht21_is_present(void); +uint16_t sht21_read_temperature(void); +float sht21_convert_temperature(uint16_t temperature); +uint16_t sht21_read_humidity(void); +float sht21_convert_humidity(uint16_t humidity); +/*---------------------------------------------------------------------------*/ +#endif /* ifndef __SHT21_H__ */ +/** @} */ diff --git a/platform/openmote-cc2538/dev/smartrf-sensors.c b/platform/openmote-cc2538/dev/smartrf-sensors.c new file mode 100644 index 000000000..d8948a017 --- /dev/null +++ b/platform/openmote-cc2538/dev/smartrf-sensors.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +/** + * \addtogroup platform + * @{ + * + * \defgroup openmote + * + * \file + * Implementation of a generic module controlling OpenMote-CC2538 sensors. + */ + +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/button-sensor.h" + +#include +/*---------------------------------------------------------------------------*/ +/** + *\brief Exports a global symbol to be used by the sensor API + */ +SENSORS(&button_user_sensor); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/openmote-cc2538/dev/tps62730.c b/platform/openmote-cc2538/dev/tps62730.c new file mode 100644 index 000000000..0356077f9 --- /dev/null +++ b/platform/openmote-cc2538/dev/tps62730.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2014, OpenMote Technologies, S.L. + * 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. + * + */ + +/** + * \addtogroup platform + * @{ + * + * \defgroup openmote + * + * \file + * Driver for the TPS62730 voltage regulator on the OpenMote-CC2538. + * + * \author + * Pere Tuset + */ + +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "dev/gpio.h" +#include "dev/tps62730.h" +/*---------------------------------------------------------------------------*/ +#define BSP_TPS62730_BASE (GPIO_B_BASE) +#define BSP_TPS62730_ON (1 << 1) +#define BSP_TPS62730_STATUS (1 << 0) +/*---------------------------------------------------------------------------*/ +static void +gpio_set(int port, int bit) +{ + REG((port | GPIO_DATA) + (bit << 2)) = bit; +} +/*---------------------------------------------------------------------------*/ +static void +gpio_reset(int port, int bit) +{ + REG((port | GPIO_DATA) + (bit << 2)) = 0; +} +/*---------------------------------------------------------------------------*/ +/** + * Initializes the TPS62730 voltage regulator + * By default it is in bypass mode, Vout = Vin, Iq < 1 uA + */ +void +tps62730_init(void) +{ + GPIO_SET_OUTPUT(BSP_TPS62730_BASE, BSP_TPS62730_ON); + GPIO_SET_INPUT(BSP_TPS62730_BASE, BSP_TPS62730_STATUS); + + tps62730_bypass(); +} +/*---------------------------------------------------------------------------*/ +/** + * Enables the TPS62730, Vout = 2.2V, Iq = 30 uA + */ +void +tps62730_on(void) +{ + gpio_set(BSP_TPS62730_BASE, BSP_TPS62730_ON); +} +/*---------------------------------------------------------------------------*/ +/** + * Disables the TPS62730, Vout = Vin, Iq < 1 uA + */ +void +tps62730_bypass(void) +{ + gpio_reset(BSP_TPS62730_BASE, BSP_TPS62730_ON); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/openmote-cc2538/dev/tps62730.h b/platform/openmote-cc2538/dev/tps62730.h new file mode 100644 index 000000000..b3e99bc8d --- /dev/null +++ b/platform/openmote-cc2538/dev/tps62730.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014, OpenMote Technologies, S.L. + * 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. + * + */ + +/** + * \addtogroup platform + * @{ + * + * \defgroup openmote + * + * \file + * Header for the TPS62730 voltage regulator on the OpenMote-CC2538. + * + * \author + * Pere Tuset + */ + +#ifndef TPS62730_H_ +#define TPS62730_H_ +/*---------------------------------------------------------------------------*/ +void tps62730_init(void); +void tps62730_on(void); +void tps62730_bypass(void); +/*---------------------------------------------------------------------------*/ +#endif /* TPS62730_H_ */ +/** @} */ From 0379af3624f8173972a1f27123129a18cc327957 Mon Sep 17 00:00:00 2001 From: kkrentz Date: Thu, 17 Dec 2015 01:42:00 -0800 Subject: [PATCH 152/374] llsec: Do not define surrogates in packetbuf.h, as otherwise configuration errors go unnoticed --- core/net/llsec/anti-replay.c | 4 ++++ core/net/llsec/ccm-star-packetbuf.c | 4 ++++ core/net/llsec/noncoresec/noncoresec.c | 3 +++ core/net/mac/tsch/tsch-slot-operation.c | 4 ++++ core/net/packetbuf.h | 23 ----------------------- 5 files changed, 15 insertions(+), 23 deletions(-) diff --git a/core/net/llsec/anti-replay.c b/core/net/llsec/anti-replay.c index 7c392bff7..a59f6b4c8 100644 --- a/core/net/llsec/anti-replay.c +++ b/core/net/llsec/anti-replay.c @@ -45,6 +45,9 @@ #include "net/llsec/anti-replay.h" #include "net/packetbuf.h" +#include "net/llsec/llsec802154.h" + +#if LLSEC802154_USES_FRAME_COUNTER /* This node's current frame counter value */ static uint32_t counter; @@ -107,5 +110,6 @@ anti_replay_was_replayed(struct anti_replay_info *info) } } /*---------------------------------------------------------------------------*/ +#endif /* LLSEC802154_USES_FRAME_COUNTER */ /** @} */ diff --git a/core/net/llsec/ccm-star-packetbuf.c b/core/net/llsec/ccm-star-packetbuf.c index 61e681b1c..9b3a95644 100644 --- a/core/net/llsec/ccm-star-packetbuf.c +++ b/core/net/llsec/ccm-star-packetbuf.c @@ -41,8 +41,11 @@ #include "llsec/ccm-star-packetbuf.h" #include "net/linkaddr.h" #include "net/packetbuf.h" +#include "net/llsec/llsec802154.h" #include +#if LLSEC802154_SECURITY_LEVEL && LLSEC802154_USES_FRAME_COUNTER + /*---------------------------------------------------------------------------*/ static const uint8_t * get_extended_address(const linkaddr_t *addr) @@ -76,3 +79,4 @@ ccm_star_packetbuf_set_nonce(uint8_t *nonce, int forward) nonce[12] = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL); } /*---------------------------------------------------------------------------*/ +#endif /* LLSEC802154_SECURITY_LEVEL && LLSEC802154_USES_FRAME_COUNTER */ diff --git a/core/net/llsec/noncoresec/noncoresec.c b/core/net/llsec/noncoresec/noncoresec.c index 860f7e613..97d018ede 100644 --- a/core/net/llsec/noncoresec/noncoresec.c +++ b/core/net/llsec/noncoresec/noncoresec.c @@ -76,6 +76,8 @@ #define PRINTF(...) #endif /* DEBUG */ +#if LLSEC802154_SECURITY_LEVEL && LLSEC802154_USES_FRAME_COUNTER + /* network-wide CCM* key */ static uint8_t key[16] = NONCORESEC_KEY; NBR_TABLE(struct anti_replay_info, anti_replay_table); @@ -256,5 +258,6 @@ const struct framer noncoresec_framer = { parse }; /*---------------------------------------------------------------------------*/ +#endif /* LLSEC802154_SECURITY_LEVEL && LLSEC802154_USES_FRAME_COUNTER */ /** @} */ diff --git a/core/net/mac/tsch/tsch-slot-operation.c b/core/net/mac/tsch/tsch-slot-operation.c index befd5a18f..6bad7cf47 100644 --- a/core/net/mac/tsch/tsch-slot-operation.c +++ b/core/net/mac/tsch/tsch-slot-operation.c @@ -604,7 +604,11 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) log->tx.drift = drift_correction; log->tx.drift_used = is_drift_correction_used; log->tx.is_data = ((((uint8_t *)(queuebuf_dataptr(current_packet->qb)))[0]) & 7) == FRAME802154_DATAFRAME; +#if TSCH_SECURITY_ENABLED log->tx.sec_level = queuebuf_attr(current_packet->qb, PACKETBUF_ATTR_SECURITY_LEVEL); +#else /* TSCH_SECURITY_ENABLED */ + log->tx.sec_level = 0; +#endif /* TSCH_SECURITY_ENABLED */ log->tx.dest = TSCH_LOG_ID_FROM_LINKADDR(queuebuf_addr(current_packet->qb, PACKETBUF_ADDR_RECEIVER)); ); diff --git a/core/net/packetbuf.h b/core/net/packetbuf.h index 12b0d9dce..969e020cd 100644 --- a/core/net/packetbuf.h +++ b/core/net/packetbuf.h @@ -365,29 +365,6 @@ enum { PACKETBUF_ATTR_MAX }; -/* Define surrogates when 802.15.4 security is off */ -#if !LLSEC802154_SECURITY_LEVEL -enum { - PACKETBUF_ATTR_SECURITY_LEVEL, -}; -#endif /* LLSEC802154_SECURITY_LEVEL */ - -#if !LLSEC802154_USES_FRAME_COUNTER -enum { - PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, - PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3 -}; -#endif /* LLSEC802154_USES_FRAME_COUNTER */ - -/* Define surrogates when not using explicit keys */ -#if !LLSEC802154_USES_EXPLICIT_KEYS -enum { - PACKETBUF_ATTR_KEY_ID_MODE, - PACKETBUF_ATTR_KEY_INDEX, - PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1 -}; -#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ - #if NETSTACK_CONF_WITH_RIME #define PACKETBUF_NUM_ADDRS 4 #else /* NETSTACK_CONF_WITH_RIME */ From 10d8b05bc684b1582c43c00c6a587b58fe5ff951 Mon Sep 17 00:00:00 2001 From: kkrentz Date: Thu, 17 Dec 2015 03:13:32 -0800 Subject: [PATCH 153/374] llsec: Permit dynamic security levels --- core/contiki-default-conf.h | 7 ---- core/net/llsec/ccm-star-packetbuf.c | 4 +-- core/net/llsec/llsec802154.h | 35 +++++++------------ core/net/llsec/noncoresec/noncoresec.c | 29 +++++++++------ core/net/mac/frame802154.c | 16 ++++----- core/net/mac/framer-802154.c | 8 ++--- core/net/mac/rdc.h | 2 +- core/net/mac/tsch/README.md | 6 ++-- core/net/mac/tsch/tsch-packet.c | 16 ++++----- core/net/mac/tsch/tsch-security.h | 30 +++++++++++----- core/net/mac/tsch/tsch-slot-operation.c | 26 +++++++------- core/net/mac/tsch/tsch.c | 20 +++++------ core/net/mac/tsch/tsch.h | 4 +-- core/net/packetbuf.h | 4 +-- examples/ipv6/rpl-tsch/node.c | 6 ++-- examples/ipv6/rpl-tsch/project-conf.h | 6 ++-- examples/jn516x/tsch/common-conf.h | 2 +- .../tsch/simple-sensor-network/node/node.c | 4 +-- .../ccm-star-tests/encryption/project-conf.h | 2 +- .../llsec/ccm-star-tests/encryption/tests.c | 15 ++++---- .../verification/project-conf.h | 2 +- .../llsec/ccm-star-tests/verification/tests.c | 15 ++++---- 22 files changed, 137 insertions(+), 122 deletions(-) diff --git a/core/contiki-default-conf.h b/core/contiki-default-conf.h index 7b001bd58..ed82c73ac 100644 --- a/core/contiki-default-conf.h +++ b/core/contiki-default-conf.h @@ -78,13 +78,6 @@ #define NETSTACK_CONF_LLSEC nullsec_driver #endif /* NETSTACK_CONF_LLSEC */ -/* To avoid unnecessary complexity, we assume the common case of - a constant LoWPAN-wide IEEE 802.15.4 security level, which - can be specified by defining LLSEC802154_CONF_SECURITY_LEVEL. */ -#ifndef LLSEC802154_CONF_SECURITY_LEVEL -#define LLSEC802154_CONF_SECURITY_LEVEL 0 -#endif /* LLSEC802154_CONF_SECURITY_LEVEL */ - /* NETSTACK_CONF_NETWORK specifies the network layer and can be either sicslowpan_driver, for IPv6 networking, or rime_driver, for the custom Rime network stack. */ diff --git a/core/net/llsec/ccm-star-packetbuf.c b/core/net/llsec/ccm-star-packetbuf.c index 9b3a95644..d5d077301 100644 --- a/core/net/llsec/ccm-star-packetbuf.c +++ b/core/net/llsec/ccm-star-packetbuf.c @@ -44,7 +44,7 @@ #include "net/llsec/llsec802154.h" #include -#if LLSEC802154_SECURITY_LEVEL && LLSEC802154_USES_FRAME_COUNTER +#if LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_FRAME_COUNTER /*---------------------------------------------------------------------------*/ static const uint8_t * @@ -79,4 +79,4 @@ ccm_star_packetbuf_set_nonce(uint8_t *nonce, int forward) nonce[12] = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL); } /*---------------------------------------------------------------------------*/ -#endif /* LLSEC802154_SECURITY_LEVEL && LLSEC802154_USES_FRAME_COUNTER */ +#endif /* LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_FRAME_COUNTER */ diff --git a/core/net/llsec/llsec802154.h b/core/net/llsec/llsec802154.h index 2ccd30515..acbba1f9d 100644 --- a/core/net/llsec/llsec802154.h +++ b/core/net/llsec/llsec802154.h @@ -56,28 +56,13 @@ #include "net/mac/frame802154.h" #include "net/ip/uip.h" -#ifdef LLSEC802154_CONF_SECURITY_LEVEL -#define LLSEC802154_SECURITY_LEVEL LLSEC802154_CONF_SECURITY_LEVEL -#else /* LLSEC802154_CONF_SECURITY_LEVEL */ -#define LLSEC802154_SECURITY_LEVEL FRAME802154_SECURITY_LEVEL_NONE -#endif /* LLSEC802154_CONF_SECURITY_LEVEL */ +#ifdef LLSEC802154_CONF_ENABLED +#define LLSEC802154_ENABLED LLSEC802154_CONF_ENABLED +#else /* LLSEC802154_CONF_ENABLED */ +#define LLSEC802154_ENABLED 0 +#endif /* LLSEC802154_CONF_ENABLED */ -#if ((LLSEC802154_SECURITY_LEVEL < 0) || (LLSEC802154_SECURITY_LEVEL > 7)) -#error "unsupported security level" -#endif - -#define LLSEC802154_SECURITY_LEVEL_MIC (LLSEC802154_SECURITY_LEVEL & 3) -#if LLSEC802154_SECURITY_LEVEL_MIC -#define LLSEC802154_MIC_LENGTH (2 << LLSEC802154_SECURITY_LEVEL_MIC) -#else -#define LLSEC802154_MIC_LENGTH 0 -#endif - -#ifdef LLSEC802154_CONF_USES_ENCRYPTION -#define LLSEC802154_USES_ENCRYPTION LLSEC802154_CONF_USES_ENCRYPTION -#else /* LLSEC802154_CONF_USES_ENCRYPTION */ -#define LLSEC802154_USES_ENCRYPTION (LLSEC802154_SECURITY_LEVEL & (1 << 2)) -#endif /* LLSEC802154_CONF_USES_ENCRYPTION */ +#define LLSEC802154_MIC_LEN(sec_lvl) (2 << (sec_lvl & 3)) #ifdef LLSEC802154_CONF_USES_EXPLICIT_KEYS #define LLSEC802154_USES_EXPLICIT_KEYS LLSEC802154_CONF_USES_EXPLICIT_KEYS @@ -88,9 +73,15 @@ #ifdef LLSEC802154_CONF_USES_FRAME_COUNTER #define LLSEC802154_USES_FRAME_COUNTER LLSEC802154_CONF_USES_FRAME_COUNTER #else /* LLSEC802154_CONF_USES_FRAME_COUNTER */ -#define LLSEC802154_USES_FRAME_COUNTER (LLSEC802154_SECURITY_LEVEL != FRAME802154_SECURITY_LEVEL_NONE) +#define LLSEC802154_USES_FRAME_COUNTER LLSEC802154_ENABLED #endif /* LLSEC802154_CONF_USES_FRAME_COUNTER */ +#ifdef LLSEC802154_CONF_USES_AUX_HEADER +#define LLSEC802154_USES_AUX_HEADER LLSEC802154_CONF_USES_AUX_HEADER +#else /* LLSEC802154_CONF_USES_AUX_HEADER */ +#define LLSEC802154_USES_AUX_HEADER LLSEC802154_ENABLED +#endif /* LLSEC802154_CONF_USES_AUX_HEADER */ + #if UIP_BYTE_ORDER == UIP_LITTLE_ENDIAN #define LLSEC802154_HTONS(n) (n) #define LLSEC802154_HTONL(n) (n) diff --git a/core/net/llsec/noncoresec/noncoresec.c b/core/net/llsec/noncoresec/noncoresec.c index 97d018ede..c55128336 100644 --- a/core/net/llsec/noncoresec/noncoresec.c +++ b/core/net/llsec/noncoresec/noncoresec.c @@ -55,7 +55,14 @@ #include "lib/ccm-star.h" #include -#define WITH_ENCRYPTION (LLSEC802154_SECURITY_LEVEL & (1 << 2)) +#ifdef NONCORESEC_CONF_SEC_LVL +#define SEC_LVL NONCORESEC_CONF_SEC_LVL +#else /* NONCORESEC_CONF_SEC_LVL */ +#define SEC_LVL 2 +#endif /* NONCORESEC_CONF_SEC_LVL */ + +#define WITH_ENCRYPTION (SEC_LVL & (1 << 2)) +#define MIC_LEN LLSEC802154_MIC_LEN(SEC_LVL) #ifdef NONCORESEC_CONF_KEY #define NONCORESEC_KEY NONCORESEC_CONF_KEY @@ -76,7 +83,7 @@ #define PRINTF(...) #endif /* DEBUG */ -#if LLSEC802154_SECURITY_LEVEL && LLSEC802154_USES_FRAME_COUNTER +#if LLSEC802154_USES_AUX_HEADER && SEC_LVL && LLSEC802154_USES_FRAME_COUNTER /* network-wide CCM* key */ static uint8_t key[16] = NONCORESEC_KEY; @@ -93,7 +100,7 @@ aead(uint8_t hdrlen, int forward) uint8_t *a; uint8_t a_len; uint8_t *result; - uint8_t generated_mic[LLSEC802154_MIC_LENGTH]; + uint8_t generated_mic[MIC_LEN]; uint8_t *mic; ccm_star_packetbuf_set_nonce(nonce, forward); @@ -115,14 +122,14 @@ aead(uint8_t hdrlen, int forward) CCM_STAR.aead(nonce, m, m_len, a, a_len, - result, LLSEC802154_MIC_LENGTH, + result, MIC_LEN, forward); if(forward) { - packetbuf_set_datalen(packetbuf_datalen() + LLSEC802154_MIC_LENGTH); + packetbuf_set_datalen(packetbuf_datalen() + MIC_LEN); return 1; } else { - return (memcmp(generated_mic, mic, LLSEC802154_MIC_LENGTH) == 0); + return (memcmp(generated_mic, mic, MIC_LEN) == 0); } } /*---------------------------------------------------------------------------*/ @@ -131,7 +138,7 @@ add_security_header(void) { if(!packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL)) { packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME); - packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, LLSEC802154_SECURITY_LEVEL); + packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, SEC_LVL); anti_replay_set_counter(); } } @@ -170,7 +177,7 @@ parse(void) return result; } - if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) != LLSEC802154_SECURITY_LEVEL) { + if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) != SEC_LVL) { PRINTF("noncoresec: received frame with wrong security level\n"); return FRAMER_FAILED; } @@ -180,7 +187,7 @@ parse(void) return FRAMER_FAILED; } - packetbuf_set_datalen(packetbuf_datalen() - LLSEC802154_MIC_LENGTH); + packetbuf_set_datalen(packetbuf_datalen() - MIC_LEN); if(!aead(result, 0)) { PRINTF("noncoresec: received unauthentic frame %"PRIu32"\n", @@ -235,7 +242,7 @@ static int length(void) { add_security_header(); - return framer_802154.length() + LLSEC802154_MIC_LENGTH; + return framer_802154.length() + MIC_LEN; } /*---------------------------------------------------------------------------*/ static void @@ -258,6 +265,6 @@ const struct framer noncoresec_framer = { parse }; /*---------------------------------------------------------------------------*/ -#endif /* LLSEC802154_SECURITY_LEVEL && LLSEC802154_USES_FRAME_COUNTER */ +#endif /* LLSEC802154_USES_AUX_HEADER && SEC_LVL && LLSEC802154_USES_FRAME_COUNTER */ /** @} */ diff --git a/core/net/mac/frame802154.c b/core/net/mac/frame802154.c index c2982a014..77727ab47 100644 --- a/core/net/mac/frame802154.c +++ b/core/net/mac/frame802154.c @@ -102,7 +102,7 @@ addr_len(uint8_t mode) } } /*----------------------------------------------------------------------------*/ -#if LLSEC802154_USES_EXPLICIT_KEYS +#if LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_EXPLICIT_KEYS static uint8_t get_key_id_len(uint8_t key_id_mode) { @@ -117,7 +117,7 @@ get_key_id_len(uint8_t key_id_mode) return 0; } } -#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ +#endif /* LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_EXPLICIT_KEYS */ /*---------------------------------------------------------------------------*/ /* Get current PAN ID */ uint16_t @@ -317,7 +317,7 @@ field_len(frame802154_t *p, field_length_t *flen) flen->dest_addr_len = addr_len(p->fcf.dest_addr_mode & 3); flen->src_addr_len = addr_len(p->fcf.src_addr_mode & 3); -#if LLSEC802154_SECURITY_LEVEL +#if LLSEC802154_USES_AUX_HEADER /* Aux security header */ if(p->fcf.security_enabled & 1) { flen->aux_sec_len = 1; /* FCF + possibly frame counter and key ID */ @@ -333,7 +333,7 @@ field_len(frame802154_t *p, field_length_t *flen) #endif /* LLSEC802154_USES_EXPLICIT_KEYS */ ; } -#endif /* LLSEC802154_SECURITY_LEVEL */ +#endif /* LLSEC802154_USES_AUX_HEADER */ } /*----------------------------------------------------------------------------*/ /** @@ -418,7 +418,7 @@ frame802154_create(frame802154_t *p, uint8_t *buf) for(c = flen.src_addr_len; c > 0; c--) { buf[pos++] = p->src_addr[c - 1]; } -#if LLSEC802154_SECURITY_LEVEL +#if LLSEC802154_USES_AUX_HEADER /* Aux header */ if(flen.aux_sec_len) { buf[pos++] = p->aux_hdr.security_control.security_level @@ -447,7 +447,7 @@ frame802154_create(frame802154_t *p, uint8_t *buf) } #endif /* LLSEC802154_USES_EXPLICIT_KEYS */ } -#endif /* LLSEC802154_SECURITY_LEVEL */ +#endif /* LLSEC802154_USES_AUX_HEADER */ return (int)pos; } @@ -570,7 +570,7 @@ frame802154_parse(uint8_t *data, int len, frame802154_t *pf) pf->src_pid = 0; } -#if LLSEC802154_SECURITY_LEVEL +#if LLSEC802154_USES_AUX_HEADER if(fcf.security_enabled) { pf->aux_hdr.security_control.security_level = p[0] & 7; #if LLSEC802154_USES_EXPLICIT_KEYS @@ -599,7 +599,7 @@ frame802154_parse(uint8_t *data, int len, frame802154_t *pf) } #endif /* LLSEC802154_USES_EXPLICIT_KEYS */ } -#endif /* LLSEC802154_SECURITY_LEVEL */ +#endif /* LLSEC802154_USES_AUX_HEADER */ /* header length */ c = p - data; diff --git a/core/net/mac/framer-802154.c b/core/net/mac/framer-802154.c index 14ccc5aa3..7e524afb1 100644 --- a/core/net/mac/framer-802154.c +++ b/core/net/mac/framer-802154.c @@ -98,7 +98,7 @@ create_frame(int type, int do_create) /* Insert IEEE 802.15.4 version bits. */ params.fcf.frame_version = FRAME802154_VERSION; -#if LLSEC802154_SECURITY_LEVEL +#if LLSEC802154_USES_AUX_HEADER if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL)) { params.fcf.security_enabled = 1; } @@ -116,7 +116,7 @@ create_frame(int type, int do_create) params.aux_hdr.key_index = packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX); params.aux_hdr.key_source.u16[0] = packetbuf_attr(PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1); #endif /* LLSEC802154_USES_EXPLICIT_KEYS */ -#endif /* LLSEC802154_SECURITY_LEVEL */ +#endif /* LLSEC802154_USES_AUX_HEADER */ /* Increment and set the data sequence number. */ if(!do_create) { @@ -238,7 +238,7 @@ parse(void) packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, frame.seq); #endif -#if LLSEC802154_SECURITY_LEVEL +#if LLSEC802154_USES_AUX_HEADER if(frame.fcf.security_enabled) { packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, frame.aux_hdr.security_control.security_level); #if LLSEC802154_USES_FRAME_COUNTER @@ -251,7 +251,7 @@ parse(void) packetbuf_set_attr(PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1, frame.aux_hdr.key_source.u16[0]); #endif /* LLSEC802154_USES_EXPLICIT_KEYS */ } -#endif /* LLSEC802154_SECURITY_LEVEL */ +#endif /* LLSEC802154_USES_AUX_HEADER */ PRINTF("15.4-IN: %2X", frame.fcf.frame_type); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)); diff --git a/core/net/mac/rdc.h b/core/net/mac/rdc.h index 0818a9b40..72717455b 100644 --- a/core/net/mac/rdc.h +++ b/core/net/mac/rdc.h @@ -51,7 +51,7 @@ frame because it has seen its sequence number already. Replay protection should be implemented at the LLSEC layer where the authenticity of frames is verified. */ -#define RDC_WITH_DUPLICATE_DETECTION !LLSEC802154_CONF_SECURITY_LEVEL +#define RDC_WITH_DUPLICATE_DETECTION !LLSEC802154_CONF_ENABLED #endif /* RDC_CONF_WITH_DUPLICATE_DETECTION */ /* List of packets to be sent by RDC layer */ diff --git a/core/net/mac/tsch/README.md b/core/net/mac/tsch/README.md index ffd6dc789..a70b4806d 100644 --- a/core/net/mac/tsch/README.md +++ b/core/net/mac/tsch/README.md @@ -128,8 +128,10 @@ To configure TSCH, see the macros in `.h` files under `core/net/mac/tsch/` and r To include TSCH standard-compliant security, set the following: ``` /* Enable security */ -#undef LLSEC802154_CONF_SECURITY_LEVEL -#define LLSEC802154_CONF_SECURITY_LEVEL 1 +#undef LLSEC802154_CONF_ENABLED +#define LLSEC802154_CONF_ENABLED 1 +#undef TSCH_SECURITY_CONF_LEVEL +#define TSCH_SECURITY_CONF_LEVEL 1 /* TSCH uses explicit keys to identify k1 and k2 */ #undef LLSEC802154_CONF_USES_EXPLICIT_KEYS #define LLSEC802154_CONF_USES_EXPLICIT_KEYS 1 diff --git a/core/net/mac/tsch/tsch-packet.c b/core/net/mac/tsch/tsch-packet.c index dbfad6082..9f9a8e107 100644 --- a/core/net/mac/tsch/tsch-packet.c +++ b/core/net/mac/tsch/tsch-packet.c @@ -94,7 +94,7 @@ tsch_packet_create_eack(uint8_t *buf, int buf_size, p.src_pid = IEEE802154_PANID; linkaddr_copy((linkaddr_t *)&p.src_addr, &linkaddr_node_addr); #endif -#if TSCH_SECURITY_ENABLED +#if LLSEC802154_ENABLED if(tsch_is_pan_secured) { p.fcf.security_enabled = 1; p.aux_hdr.security_control.security_level = TSCH_SECURITY_KEY_SEC_LEVEL_ACK; @@ -103,7 +103,7 @@ tsch_packet_create_eack(uint8_t *buf, int buf_size, p.aux_hdr.security_control.frame_counter_size = 1; p.aux_hdr.key_index = TSCH_SECURITY_KEY_INDEX_ACK; } -#endif /* TSCH_SECURITY_ENABLED */ +#endif /* LLSEC802154_ENABLED */ if((curr_len = frame802154_create(&p, buf)) == 0) { return 0; @@ -166,13 +166,13 @@ tsch_packet_parse_eack(const uint8_t *buf, int buf_size, if(frame->fcf.ie_list_present) { int mic_len = 0; -#if TSCH_SECURITY_ENABLED +#if LLSEC802154_ENABLED /* Check if there is space for the security MIC (if any) */ mic_len = tsch_security_mic_len(frame); if(buf_size < curr_len + mic_len) { return 0; } -#endif /* TSCH_SECURITY_ENABLED */ +#endif /* LLSEC802154_ENABLED */ /* Parse information elements. We need to substract the MIC length, as the exact payload len is needed while parsing */ if((ret = frame802154e_parse_information_elements(buf + curr_len, buf_size - curr_len - mic_len, ies)) == -1) { return 0; @@ -222,7 +222,7 @@ tsch_packet_create_eb(uint8_t *buf, int buf_size, uint8_t seqno, p.dest_addr[0] = 0xff; p.dest_addr[1] = 0xff; -#if TSCH_SECURITY_ENABLED +#if LLSEC802154_ENABLED if(tsch_is_pan_secured) { p.fcf.security_enabled = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) > 0; p.aux_hdr.security_control.security_level = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL); @@ -231,7 +231,7 @@ tsch_packet_create_eb(uint8_t *buf, int buf_size, uint8_t seqno, p.aux_hdr.security_control.frame_counter_size = 1; p.aux_hdr.key_index = packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX); } -#endif /* TSCH_SECURITY_ENABLED */ +#endif /* LLSEC802154_ENABLED */ if((curr_len = frame802154_create(&p, buf)) == 0) { return 0; @@ -387,14 +387,14 @@ tsch_packet_parse_eb(const uint8_t *buf, int buf_size, if(frame->fcf.ie_list_present) { /* Calculate space needed for the security MIC, if any, before attempting to parse IEs */ int mic_len = 0; -#if TSCH_SECURITY_ENABLED +#if LLSEC802154_ENABLED if(!frame_without_mic) { mic_len = tsch_security_mic_len(frame); if(buf_size < curr_len + mic_len) { return 0; } } -#endif /* TSCH_SECURITY_ENABLED */ +#endif /* LLSEC802154_ENABLED */ /* Parse information elements. We need to substract the MIC length, as the exact payload len is needed while parsing */ if((ret = frame802154e_parse_information_elements(buf + curr_len, buf_size - curr_len - mic_len, ies)) == -1) { diff --git a/core/net/mac/tsch/tsch-security.h b/core/net/mac/tsch/tsch-security.h index 694afa78e..c01e7ea6b 100644 --- a/core/net/mac/tsch/tsch-security.h +++ b/core/net/mac/tsch/tsch-security.h @@ -39,22 +39,36 @@ #include "net/mac/tsch/tsch-asn.h" #include "net/mac/tsch/tsch-private.h" #include "net/mac/frame802154.h" +#include "net/llsec/llsec802154.h" #include "net/mac/frame802154e-ie.h" /******** Configuration *******/ /* To enable TSCH security: - * - set LLSEC802154_CONF_SECURITY_LEVEL + * - set LLSEC802154_CONF_ENABLED + * - set TSCH_SECURITY_CONF_LEVEL * - set LLSEC802154_CONF_USES_EXPLICIT_KEYS * - unset LLSEC802154_CONF_USES_FRAME_COUNTER * */ -#define TSCH_SECURITY_ENABLED (LLSEC802154_CONF_SECURITY_LEVEL != 0) -#if TSCH_SECURITY_ENABLED && !LLSEC802154_CONF_USES_EXPLICIT_KEYS -#error TSCH_SECURITY_ENABLED set but LLSEC802154_CONF_USES_EXPLICIT_KEYS unset -#endif /* TSCH_SECURITY_ENABLED */ -#if TSCH_SECURITY_ENABLED && LLSEC802154_CONF_USES_FRAME_COUNTER -#error TSCH_SECURITY_ENABLED set but LLSEC802154_CONF_USES_FRAME_COUNTER set -#endif /* TSCH_SECURITY_ENABLED */ + +#ifdef TSCH_SECURITY_CONF_LEVEL +#define TSCH_SECURITY_LEVEL TSCH_SECURITY_CONF_LEVEL +#else /* TSCH_SECURITY_CONF_LEVEL */ +#define TSCH_SECURITY_LEVEL FRAME802154_SECURITY_LEVEL_NONE +#endif /* TSCH_SECURITY_CONF_LEVEL */ + +#if LLSEC802154_ENABLED && !TSCH_SECURITY_LEVEL +#error LLSEC802154_ENABLED set but TSCH_SECURITY_LEVEL unset +#endif /* LLSEC802154_ENABLED */ +#if !LLSEC802154_ENABLED && TSCH_SECURITY_LEVEL +#error TSCH_SECURITY_LEVEL set but LLSEC802154_ENABLED unset +#endif /* LLSEC802154_ENABLED */ +#if LLSEC802154_ENABLED && !LLSEC802154_USES_EXPLICIT_KEYS +#error LLSEC802154_ENABLED set but LLSEC802154_USES_EXPLICIT_KEYS unset +#endif /* LLSEC802154_ENABLED */ +#if LLSEC802154_ENABLED && LLSEC802154_USES_FRAME_COUNTER +#error LLSEC802154_ENABLED set but LLSEC802154_USES_FRAME_COUNTER set +#endif /* LLSEC802154_ENABLED */ /* K1, defined in 6TiSCH minimal, is well-known (offers no security) and used for EBs only */ #ifdef TSCH_SECURITY_CONF_K1 diff --git a/core/net/mac/tsch/tsch-slot-operation.c b/core/net/mac/tsch/tsch-slot-operation.c index 6bad7cf47..03905617e 100644 --- a/core/net/mac/tsch/tsch-slot-operation.c +++ b/core/net/mac/tsch/tsch-slot-operation.c @@ -404,10 +404,10 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) } else { /* packet payload */ static void *packet; -#if TSCH_SECURITY_ENABLED +#if LLSEC802154_ENABLED /* encrypted payload */ static uint8_t encrypted_packet[TSCH_PACKET_MAX_LEN]; -#endif /* TSCH_SECURITY_ENABLED */ +#endif /* LLSEC802154_ENABLED */ /* packet payload length */ static uint8_t packet_len; /* packet seqno */ @@ -434,7 +434,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) packet_ready = 1; } -#if TSCH_SECURITY_ENABLED +#if LLSEC802154_ENABLED if(tsch_is_pan_secured) { /* If we are going to encrypt, we need to generate the output in a separate buffer and keep * the original untouched. This is to allow for future retransmissions. */ @@ -445,7 +445,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) packet = encrypted_packet; } } -#endif /* TSCH_SECURITY_ENABLED */ +#endif /* LLSEC802154_ENABLED */ /* prepare packet to send: copy to radio buffer */ if(packet_ready && NETSTACK_RADIO.prepare(packet, packet_len) == 0) { /* 0 means success */ @@ -530,7 +530,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) ack_len = 0; } -#if TSCH_SECURITY_ENABLED +#if LLSEC802154_ENABLED if(ack_len != 0) { if(!tsch_security_parse_frame(ackbuf, ack_hdrlen, ack_len - ack_hdrlen - tsch_security_mic_len(&frame), &frame, ¤t_neighbor->addr, ¤t_asn)) { @@ -544,7 +544,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) snprintf(log->message, sizeof(log->message), "!failed to parse ACK")); } -#endif /* TSCH_SECURITY_ENABLED */ +#endif /* LLSEC802154_ENABLED */ } if(ack_len != 0) { @@ -604,11 +604,11 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) log->tx.drift = drift_correction; log->tx.drift_used = is_drift_correction_used; log->tx.is_data = ((((uint8_t *)(queuebuf_dataptr(current_packet->qb)))[0]) & 7) == FRAME802154_DATAFRAME; -#if TSCH_SECURITY_ENABLED +#if LLSEC802154_ENABLED log->tx.sec_level = queuebuf_attr(current_packet->qb, PACKETBUF_ATTR_SECURITY_LEVEL); -#else /* TSCH_SECURITY_ENABLED */ +#else /* LLSEC802154_ENABLED */ log->tx.sec_level = 0; -#endif /* TSCH_SECURITY_ENABLED */ +#endif /* LLSEC802154_ENABLED */ log->tx.dest = TSCH_LOG_ID_FROM_LINKADDR(queuebuf_addr(current_packet->qb, PACKETBUF_ADDR_RECEIVER)); ); @@ -712,7 +712,7 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t)) packet_duration = TSCH_PACKET_DURATION(current_input->len); -#if TSCH_SECURITY_ENABLED +#if LLSEC802154_ENABLED /* Decrypt and verify incoming frame */ if(frame_valid) { if(tsch_security_parse_frame( @@ -731,7 +731,7 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t)) "!failed to parse frame %u %u", header_len, current_input->len)); frame_valid = 0; } -#endif /* TSCH_SECURITY_ENABLED */ +#endif /* LLSEC802154_ENABLED */ if(frame_valid) { if(linkaddr_cmp(&destination_address, &linkaddr_node_addr) @@ -765,12 +765,12 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t)) ack_len = tsch_packet_create_eack(ack_buf, sizeof(ack_buf), &source_address, frame.seq, (int16_t)RTIMERTICKS_TO_US(estimated_drift), do_nack); -#if TSCH_SECURITY_ENABLED +#if LLSEC802154_ENABLED if(tsch_is_pan_secured) { /* Secure ACK frame. There is only header and header IEs, therefore data len == 0. */ ack_len += tsch_security_secure_frame(ack_buf, ack_buf, ack_len, 0, ¤t_asn); } -#endif /* TSCH_SECURITY_ENABLED */ +#endif /* LLSEC802154_ENABLED */ /* Copy to radio buffer */ NETSTACK_RADIO.prepare((const void *)ack_buf, ack_len); diff --git a/core/net/mac/tsch/tsch.c b/core/net/mac/tsch/tsch.c index fa92fe8ad..442323abc 100644 --- a/core/net/mac/tsch/tsch.c +++ b/core/net/mac/tsch/tsch.c @@ -141,7 +141,7 @@ int tsch_is_coordinator = 0; /* Are we associated to a TSCH network? */ int tsch_is_associated = 0; /* Is the PAN running link-layer security? */ -int tsch_is_pan_secured = TSCH_SECURITY_ENABLED; +int tsch_is_pan_secured = LLSEC802154_ENABLED; /* The current Absolute Slot Number (ASN) */ struct asn_t current_asn; /* Device rank or join priority: @@ -177,7 +177,7 @@ tsch_set_coordinator(int enable) void tsch_set_pan_secured(int enable) { - tsch_is_pan_secured = TSCH_SECURITY_ENABLED && enable; + tsch_is_pan_secured = LLSEC802154_ENABLED && enable; } /*---------------------------------------------------------------------------*/ void @@ -455,21 +455,21 @@ tsch_associate(const struct input_packet *input_eb, rtimer_clock_t timestamp) } #endif /* TSCH_JOIN_SECURED_ONLY */ -#if TSCH_SECURITY_ENABLED +#if LLSEC802154_ENABLED if(!tsch_security_parse_frame(input_eb->payload, hdrlen, input_eb->len - hdrlen - tsch_security_mic_len(&frame), &frame, (linkaddr_t*)&frame.src_addr, ¤t_asn)) { PRINTF("TSCH:! parse_eb: failed to authenticate\n"); return 0; } -#endif /* TSCH_SECURITY_ENABLED */ +#endif /* LLSEC802154_ENABLED */ -#if !TSCH_SECURITY_ENABLED +#if !LLSEC802154_ENABLED if(frame.fcf.security_enabled == 1) { PRINTF("TSCH:! parse_eb: we do not support security, but EB is secured\n"); return 0; } -#endif /* !TSCH_SECURITY_ENABLED */ +#endif /* !LLSEC802154_ENABLED */ #if TSCH_JOIN_MY_PANID_ONLY /* Check if the EB comes from the PAN ID we expect */ @@ -746,14 +746,14 @@ PROCESS_THREAD(tsch_send_eb_process, ev, data) } packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_BEACONFRAME); packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, tsch_packet_seqno); -#if TSCH_SECURITY_ENABLED +#if LLSEC802154_ENABLED if(tsch_is_pan_secured) { /* Set security level, key id and index */ packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, TSCH_SECURITY_KEY_SEC_LEVEL_EB); packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, FRAME802154_1_BYTE_KEY_ID_MODE); /* Use 1-byte key index */ packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX, TSCH_SECURITY_KEY_INDEX_EB); } -#endif /* TSCH_SECURITY_ENABLED */ +#endif /* LLSEC802154_ENABLED */ eb_len = tsch_packet_create_eb(packetbuf_dataptr(), PACKETBUF_SIZE, tsch_packet_seqno, &hdr_len, &tsch_sync_ie_offset); if(eb_len != 0) { @@ -907,14 +907,14 @@ send_packet(mac_callback_t sent, void *ptr) packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME); packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, tsch_packet_seqno); -#if TSCH_SECURITY_ENABLED +#if LLSEC802154_ENABLED if(tsch_is_pan_secured) { /* Set security level, key id and index */ packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, TSCH_SECURITY_KEY_SEC_LEVEL_OTHER); packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, FRAME802154_1_BYTE_KEY_ID_MODE); /* Use 1-byte key index */ packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX, TSCH_SECURITY_KEY_INDEX_OTHER); } -#endif /* TSCH_SECURITY_ENABLED */ +#endif /* LLSEC802154_ENABLED */ packet_count_before = tsch_queue_packet_count(addr); diff --git a/core/net/mac/tsch/tsch.h b/core/net/mac/tsch/tsch.h index 31b5d41f9..d548df9d5 100644 --- a/core/net/mac/tsch/tsch.h +++ b/core/net/mac/tsch/tsch.h @@ -84,8 +84,8 @@ #ifdef TSCH_CONF_JOIN_SECURED_ONLY #define TSCH_JOIN_SECURED_ONLY TSCH_CONF_JOIN_SECURED_ONLY #else -/* By default, set if TSCH_SECURITY_ENABLED is also non-zero */ -#define TSCH_JOIN_SECURED_ONLY TSCH_SECURITY_ENABLED +/* By default, set if LLSEC802154_ENABLED is also non-zero */ +#define TSCH_JOIN_SECURED_ONLY LLSEC802154_ENABLED #endif /* By default, join any PAN ID. Otherwise, wait for an EB from IEEE802154_PANID */ diff --git a/core/net/packetbuf.h b/core/net/packetbuf.h index 969e020cd..bbdd1a6cf 100644 --- a/core/net/packetbuf.h +++ b/core/net/packetbuf.h @@ -332,9 +332,9 @@ enum { #endif /* NETSTACK_CONF_WITH_RIME */ PACKETBUF_ATTR_PENDING, PACKETBUF_ATTR_FRAME_TYPE, -#if LLSEC802154_SECURITY_LEVEL +#if LLSEC802154_USES_AUX_HEADER PACKETBUF_ATTR_SECURITY_LEVEL, -#endif /* LLSEC802154_SECURITY_LEVEL */ +#endif /* LLSEC802154_USES_AUX_HEADER */ #if LLSEC802154_USES_FRAME_COUNTER PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, diff --git a/examples/ipv6/rpl-tsch/node.c b/examples/ipv6/rpl-tsch/node.c index 203dfd9a9..79f8719ea 100644 --- a/examples/ipv6/rpl-tsch/node.c +++ b/examples/ipv6/rpl-tsch/node.c @@ -144,7 +144,7 @@ PROCESS_THREAD(node_process, ev, data) /* Set node with ID == 1 as coordinator, convenient in Cooja. */ if(node_id == 1) { - if(LLSEC802154_CONF_SECURITY_LEVEL) { + if(TSCH_SECURITY_LEVEL) { node_role = role_6dr_sec; } else { node_role = role_6dr; @@ -169,7 +169,7 @@ PROCESS_THREAD(node_process, ev, data) || etimer_expired(&et)); if(ev == sensors_event && data == &button_sensor && button_sensor.value(0) > 0) { node_role = (node_role + 1) % 3; - if(LLSEC802154_CONF_SECURITY_LEVEL == 0 && node_role == role_6dr_sec) { + if(TSCH_SECURITY_LEVEL == 0 && node_role == role_6dr_sec) { node_role = (node_role + 1) % 3; } etimer_restart(&et); @@ -182,7 +182,7 @@ PROCESS_THREAD(node_process, ev, data) printf("Init: node starting with role %s\n", node_role == role_6ln ? "6ln" : (node_role == role_6dr) ? "6dr" : "6dr-sec"); - tsch_set_pan_secured(LLSEC802154_CONF_SECURITY_LEVEL && (node_role == role_6dr_sec)); + tsch_set_pan_secured(TSCH_SECURITY_LEVEL && (node_role == role_6dr_sec)); is_coordinator = node_role > role_6ln; if(is_coordinator) { diff --git a/examples/ipv6/rpl-tsch/project-conf.h b/examples/ipv6/rpl-tsch/project-conf.h index 2b602d908..11c882c43 100644 --- a/examples/ipv6/rpl-tsch/project-conf.h +++ b/examples/ipv6/rpl-tsch/project-conf.h @@ -100,8 +100,10 @@ #if WITH_SECURITY /* Enable security */ -#undef LLSEC802154_CONF_SECURITY_LEVEL -#define LLSEC802154_CONF_SECURITY_LEVEL 1 +#undef TSCH_SECURITY_CONF_LEVEL +#define TSCH_SECURITY_CONF_LEVEL 1 +#undef LLSEC802154_CONF_ENABLED +#define LLSEC802154_CONF_ENABLED 1 /* TSCH uses explicit keys to identify k1 and k2 */ #undef LLSEC802154_CONF_USES_EXPLICIT_KEYS #define LLSEC802154_CONF_USES_EXPLICIT_KEYS 1 diff --git a/examples/jn516x/tsch/common-conf.h b/examples/jn516x/tsch/common-conf.h index b42e6c810..91037c794 100644 --- a/examples/jn516x/tsch/common-conf.h +++ b/examples/jn516x/tsch/common-conf.h @@ -142,7 +142,7 @@ #if WITH_TSCH_SECURITY /* Set security level to the maximum, even if unused, to all crypto code */ -#define LLSEC802154_CONF_SECURITY_LEVEL 7 +#define LLSEC802154_CONF_ENABLED 1 /* Attempt to associate from both secured and non-secured EBs */ #define TSCH_CONF_JOIN_SECURED_ONLY 0 /* We need explicit keys to identify k1 and k2 */ diff --git a/examples/jn516x/tsch/simple-sensor-network/node/node.c b/examples/jn516x/tsch/simple-sensor-network/node/node.c index 48b7c4ff5..561df6a47 100644 --- a/examples/jn516x/tsch/simple-sensor-network/node/node.c +++ b/examples/jn516x/tsch/simple-sensor-network/node/node.c @@ -152,7 +152,7 @@ PROCESS_THREAD(node_process, ev, data) /* Set node with ID == 1 as coordinator, handy in Cooja. */ if(node_id == 1) { - if(LLSEC802154_CONF_SECURITY_LEVEL) { + if(LLSEC802154_ENABLED) { node_role = role_6dr_sec; } else { node_role = role_6dr; @@ -165,7 +165,7 @@ PROCESS_THREAD(node_process, ev, data) node_role == role_6ln ? "6ln" : (node_role == role_6dr) ? "6dr" : "6dr-sec"); #if WITH_TSCH - tsch_set_pan_secured(LLSEC802154_CONF_SECURITY_LEVEL && (node_role == role_6dr_sec)); + tsch_set_pan_secured(LLSEC802154_ENABLED && (node_role == role_6dr_sec)); #endif /* WITH_TSCH */ is_coordinator = node_role > role_6ln; diff --git a/examples/llsec/ccm-star-tests/encryption/project-conf.h b/examples/llsec/ccm-star-tests/encryption/project-conf.h index 613619373..55e4e35d4 100644 --- a/examples/llsec/ccm-star-tests/encryption/project-conf.h +++ b/examples/llsec/ccm-star-tests/encryption/project-conf.h @@ -37,4 +37,4 @@ * Konrad Krentz */ -#define LLSEC802154_CONF_SECURITY_LEVEL 6 +#define LLSEC802154_CONF_ENABLED 1 diff --git a/examples/llsec/ccm-star-tests/encryption/tests.c b/examples/llsec/ccm-star-tests/encryption/tests.c index b5c296799..0ef158960 100644 --- a/examples/llsec/ccm-star-tests/encryption/tests.c +++ b/examples/llsec/ccm-star-tests/encryption/tests.c @@ -47,6 +47,9 @@ #include #include +#define SEC_LVL 6 +#define MIC_LEN LLSEC802154_MIC_LEN(6) + /*---------------------------------------------------------------------------*/ /* Test vector C.2.1.2 from IEEE 802.15.4-2006 */ static void @@ -70,8 +73,8 @@ test_sec_lvl_6() /* Frame Counter */ 0x05 , 0x00 , 0x00 , 0x00 , 0x01 , 0xCE }; - uint8_t oracle[LLSEC802154_MIC_LENGTH] = { 0x4F , 0xDE , 0x52 , 0x90 , - 0x61 , 0xF9 , 0xC6 , 0xF1 }; + uint8_t oracle[MIC_LEN] = { 0x4F , 0xDE , 0x52 , 0x90 , + 0x61 , 0xF9 , 0xC6 , 0xF1 }; uint8_t nonce[13]; frame802154_frame_counter_t counter; @@ -84,7 +87,7 @@ test_sec_lvl_6() counter.u32 = 5; packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, counter.u16[0]); packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, counter.u16[1]); - packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, LLSEC802154_SECURITY_LEVEL); + packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, SEC_LVL); packetbuf_hdrreduce(29); CCM_STAR.set_key(key); @@ -92,10 +95,10 @@ test_sec_lvl_6() CCM_STAR.aead(nonce, packetbuf_dataptr(), packetbuf_datalen(), packetbuf_hdrptr(), packetbuf_hdrlen(), - ((uint8_t *) packetbuf_hdrptr()) + 30, LLSEC802154_MIC_LENGTH, + ((uint8_t *) packetbuf_hdrptr()) + 30, MIC_LEN, 1); - if(memcmp(((uint8_t *) packetbuf_hdrptr()) + 30, oracle, LLSEC802154_MIC_LENGTH) == 0) { + if(memcmp(((uint8_t *) packetbuf_hdrptr()) + 30, oracle, MIC_LEN) == 0) { printf("Success\n"); } else { printf("Failure\n"); @@ -115,7 +118,7 @@ test_sec_lvl_6() CCM_STAR.aead(nonce, packetbuf_dataptr(), packetbuf_datalen(), packetbuf_hdrptr(), packetbuf_hdrlen(), - ((uint8_t *) packetbuf_hdrptr()) + 30, LLSEC802154_MIC_LENGTH, + ((uint8_t *) packetbuf_hdrptr()) + 30, MIC_LEN, 0); if(((uint8_t *) packetbuf_hdrptr())[29] == 0xCE) { printf("Success\n"); diff --git a/examples/llsec/ccm-star-tests/verification/project-conf.h b/examples/llsec/ccm-star-tests/verification/project-conf.h index 9f8776b90..3d7e42488 100644 --- a/examples/llsec/ccm-star-tests/verification/project-conf.h +++ b/examples/llsec/ccm-star-tests/verification/project-conf.h @@ -37,4 +37,4 @@ * Konrad Krentz */ -#define LLSEC802154_CONF_SECURITY_LEVEL 2 +#define LLSEC802154_CONF_ENABLED 1 diff --git a/examples/llsec/ccm-star-tests/verification/tests.c b/examples/llsec/ccm-star-tests/verification/tests.c index 4de463fee..3c981552d 100644 --- a/examples/llsec/ccm-star-tests/verification/tests.c +++ b/examples/llsec/ccm-star-tests/verification/tests.c @@ -48,6 +48,9 @@ #include #include +#define SEC_LVL 2 +#define MIC_LEN LLSEC802154_MIC_LEN(2) + /*---------------------------------------------------------------------------*/ /* Test vector C.1 from FIPS Pub 197 */ static void @@ -97,10 +100,10 @@ test_sec_lvl_2() 0x05 , 0x00 , 0x00 , 0x00 , /* Payload */ 0x55 , 0xCF , 0x00 , 0x00 , 0x51 , 0x52 , 0x53 , 0x54 }; - uint8_t oracle[LLSEC802154_MIC_LENGTH] = { 0x22 , 0x3B , 0xC1 , 0xEC , - 0x84 , 0x1A , 0xB5 , 0x53 }; + uint8_t oracle[MIC_LEN] = { 0x22 , 0x3B , 0xC1 , 0xEC , + 0x84 , 0x1A , 0xB5 , 0x53 }; frame802154_frame_counter_t counter; - uint8_t mic[LLSEC802154_MIC_LENGTH]; + uint8_t mic[MIC_LEN]; uint8_t nonce[13]; printf("Testing verification ... "); @@ -112,7 +115,7 @@ test_sec_lvl_2() counter.u32 = 5; packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, counter.u16[0]); packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, counter.u16[1]); - packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, LLSEC802154_SECURITY_LEVEL); + packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, SEC_LVL); packetbuf_hdrreduce(18); CCM_STAR.set_key(key); @@ -120,10 +123,10 @@ test_sec_lvl_2() CCM_STAR.aead(nonce, NULL, 0, packetbuf_hdrptr(), packetbuf_totlen(), - ((uint8_t *) packetbuf_dataptr()) + packetbuf_datalen(), LLSEC802154_MIC_LENGTH, + ((uint8_t *) packetbuf_dataptr()) + packetbuf_datalen(), MIC_LEN, 1); - if(memcmp(((uint8_t *) packetbuf_dataptr()) + packetbuf_datalen(), oracle, LLSEC802154_MIC_LENGTH) == 0) { + if(memcmp(((uint8_t *) packetbuf_dataptr()) + packetbuf_datalen(), oracle, MIC_LEN) == 0) { printf("Success\n"); } else { printf("Failure\n"); From 403d3325553e7a4caa22b02df0c9331862836251 Mon Sep 17 00:00:00 2001 From: kkrentz Date: Thu, 17 Dec 2015 05:55:13 -0800 Subject: [PATCH 154/374] llsec: Make decorated framer configurable --- core/net/llsec/noncoresec/noncoresec.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/core/net/llsec/noncoresec/noncoresec.c b/core/net/llsec/noncoresec/noncoresec.c index c55128336..a14e71e52 100644 --- a/core/net/llsec/noncoresec/noncoresec.c +++ b/core/net/llsec/noncoresec/noncoresec.c @@ -47,7 +47,6 @@ #include "net/llsec/llsec802154.h" #include "net/llsec/ccm-star-packetbuf.h" #include "net/mac/frame802154.h" -#include "net/mac/framer-802154.h" #include "net/netstack.h" #include "net/packetbuf.h" #include "net/nbr-table.h" @@ -55,6 +54,14 @@ #include "lib/ccm-star.h" #include +#ifdef NONCORESEC_CONF_DECORATED_FRAMER +#define DECORATED_FRAMER NONCORESEC_CONF_DECORATED_FRAMER +#else /* NONCORESEC_CONF_DECORATED_FRAMER */ +#define DECORATED_FRAMER framer_802154 +#endif /* NONCORESEC_CONF_DECORATED_FRAMER */ + +extern const struct framer DECORATED_FRAMER; + #ifdef NONCORESEC_CONF_SEC_LVL #define SEC_LVL NONCORESEC_CONF_SEC_LVL #else /* NONCORESEC_CONF_SEC_LVL */ @@ -155,7 +162,7 @@ create(void) int result; add_security_header(); - result = framer_802154.create(); + result = DECORATED_FRAMER.create(); if(result == FRAMER_FAILED) { return result; } @@ -172,7 +179,7 @@ parse(void) const linkaddr_t *sender; struct anti_replay_info* info; - result = framer_802154.parse(); + result = DECORATED_FRAMER.parse(); if(result == FRAMER_FAILED) { return result; } @@ -242,7 +249,7 @@ static int length(void) { add_security_header(); - return framer_802154.length() + MIC_LEN; + return DECORATED_FRAMER.length() + MIC_LEN; } /*---------------------------------------------------------------------------*/ static void From b3f2bba3ecd4d0284dc57467164762ac5c1521ee Mon Sep 17 00:00:00 2001 From: Hardy Date: Wed, 13 Apr 2016 18:12:47 +0200 Subject: [PATCH 155/374] Removed some unnecessary statics in do_event() and process_post(). This allows the optimizer to put the corresponding variables into registers. See also discussion about other static variables: https://sourceforge.net/p/contiki/mailman/message/35010460/ --- core/sys/process.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core/sys/process.c b/core/sys/process.c index b2ed5701c..f98057cd3 100644 --- a/core/sys/process.c +++ b/core/sys/process.c @@ -245,10 +245,10 @@ do_poll(void) static void do_event(void) { - static process_event_t ev; - static process_data_t data; - static struct process *receiver; - static struct process *p; + process_event_t ev; + process_data_t data; + struct process *receiver; + struct process *p; /* * If there are any events in the queue, take the first one and walk @@ -321,7 +321,7 @@ process_nevents(void) int process_post(struct process *p, process_event_t ev, process_data_t data) { - static process_num_events_t snum; + process_num_events_t snum; if(PROCESS_CURRENT() == NULL) { PRINTF("process_post: NULL process posts event %d to process '%s', nevents %d\n", From 431530bf6bfd2445fd558d8b22ba11555aae2b18 Mon Sep 17 00:00:00 2001 From: kkrentz Date: Thu, 15 Oct 2015 01:39:42 -0700 Subject: [PATCH 156/374] llsec: Added READMEs --- core/net/llsec/README.md | 5 +++++ core/net/llsec/noncoresec/README.md | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 core/net/llsec/README.md create mode 100644 core/net/llsec/noncoresec/README.md diff --git a/core/net/llsec/README.md b/core/net/llsec/README.md new file mode 100644 index 000000000..a5ac5854e --- /dev/null +++ b/core/net/llsec/README.md @@ -0,0 +1,5 @@ +Link layer security is implemented as a new netstack layer, which is located in between the MAC and the NETWORK layer. The interface of LLSEC drivers is defined in [llsec.h](llsec.h). Additionally, LLSEC drivers may define a special [FRAMER](../mac/framer.h), which calls the actual FRAMER underneath. By default, the LLSEC driver `nullsec` is used, which does nothing. + +# TODO + +* Most main files do not call LLSEC.init, yet \ No newline at end of file diff --git a/core/net/llsec/noncoresec/README.md b/core/net/llsec/noncoresec/README.md new file mode 100644 index 000000000..00ca46f15 --- /dev/null +++ b/core/net/llsec/noncoresec/README.md @@ -0,0 +1,21 @@ +`noncoresec` is a noncompromise-resilient 802.15.4 security implementation, which uses a network-wide key. Add these lines to your `project_conf.h` to enable `noncoresec`: + +```c +#undef LLSEC802154_CONF_ENABLED +#define LLSEC802154_CONF_ENABLED 1 +#undef NETSTACK_CONF_FRAMER +#define NETSTACK_CONF_FRAMER noncoresec_framer +#undef NETSTACK_CONF_LLSEC +#define NETSTACK_CONF_LLSEC noncoresec_driver +#undef NONCORESEC_CONF_SEC_LVL +#define NONCORESEC_CONF_SEC_LVL 1 +``` +`NONCORESEC_CONF_SEC_LVL` defines the length of MICs and whether encryption is enabled or not. + +Setting the network-wide key works as follows: +```c +#define NONCORESEC_CONF_KEY { 0x00 , 0x01 , 0x02 , 0x03 , \ + 0x04 , 0x05 , 0x06 , 0x07 , \ + 0x08 , 0x09 , 0x0A , 0x0B , \ + 0x0C , 0x0D , 0x0E , 0x0F } +``` From 4a88e9e537dbbe297f9271062917094978394e60 Mon Sep 17 00:00:00 2001 From: kkrentz Date: Fri, 18 Dec 2015 06:52:18 -0800 Subject: [PATCH 157/374] llsec: Removed TSCH_SECURITY_CONF_LEVEL and TSCH_SECURITY_LEVEL --- core/net/mac/tsch/README.md | 2 -- core/net/mac/tsch/tsch-security.h | 13 ------------- examples/ipv6/rpl-tsch/node.c | 6 +++--- examples/ipv6/rpl-tsch/project-conf.h | 2 -- 4 files changed, 3 insertions(+), 20 deletions(-) diff --git a/core/net/mac/tsch/README.md b/core/net/mac/tsch/README.md index a70b4806d..02fe0cb05 100644 --- a/core/net/mac/tsch/README.md +++ b/core/net/mac/tsch/README.md @@ -130,8 +130,6 @@ To include TSCH standard-compliant security, set the following: /* Enable security */ #undef LLSEC802154_CONF_ENABLED #define LLSEC802154_CONF_ENABLED 1 -#undef TSCH_SECURITY_CONF_LEVEL -#define TSCH_SECURITY_CONF_LEVEL 1 /* TSCH uses explicit keys to identify k1 and k2 */ #undef LLSEC802154_CONF_USES_EXPLICIT_KEYS #define LLSEC802154_CONF_USES_EXPLICIT_KEYS 1 diff --git a/core/net/mac/tsch/tsch-security.h b/core/net/mac/tsch/tsch-security.h index c01e7ea6b..42f18e8d9 100644 --- a/core/net/mac/tsch/tsch-security.h +++ b/core/net/mac/tsch/tsch-security.h @@ -46,23 +46,10 @@ /* To enable TSCH security: * - set LLSEC802154_CONF_ENABLED - * - set TSCH_SECURITY_CONF_LEVEL * - set LLSEC802154_CONF_USES_EXPLICIT_KEYS * - unset LLSEC802154_CONF_USES_FRAME_COUNTER * */ -#ifdef TSCH_SECURITY_CONF_LEVEL -#define TSCH_SECURITY_LEVEL TSCH_SECURITY_CONF_LEVEL -#else /* TSCH_SECURITY_CONF_LEVEL */ -#define TSCH_SECURITY_LEVEL FRAME802154_SECURITY_LEVEL_NONE -#endif /* TSCH_SECURITY_CONF_LEVEL */ - -#if LLSEC802154_ENABLED && !TSCH_SECURITY_LEVEL -#error LLSEC802154_ENABLED set but TSCH_SECURITY_LEVEL unset -#endif /* LLSEC802154_ENABLED */ -#if !LLSEC802154_ENABLED && TSCH_SECURITY_LEVEL -#error TSCH_SECURITY_LEVEL set but LLSEC802154_ENABLED unset -#endif /* LLSEC802154_ENABLED */ #if LLSEC802154_ENABLED && !LLSEC802154_USES_EXPLICIT_KEYS #error LLSEC802154_ENABLED set but LLSEC802154_USES_EXPLICIT_KEYS unset #endif /* LLSEC802154_ENABLED */ diff --git a/examples/ipv6/rpl-tsch/node.c b/examples/ipv6/rpl-tsch/node.c index 79f8719ea..af0db8845 100644 --- a/examples/ipv6/rpl-tsch/node.c +++ b/examples/ipv6/rpl-tsch/node.c @@ -144,7 +144,7 @@ PROCESS_THREAD(node_process, ev, data) /* Set node with ID == 1 as coordinator, convenient in Cooja. */ if(node_id == 1) { - if(TSCH_SECURITY_LEVEL) { + if(LLSEC802154_ENABLED) { node_role = role_6dr_sec; } else { node_role = role_6dr; @@ -169,7 +169,7 @@ PROCESS_THREAD(node_process, ev, data) || etimer_expired(&et)); if(ev == sensors_event && data == &button_sensor && button_sensor.value(0) > 0) { node_role = (node_role + 1) % 3; - if(TSCH_SECURITY_LEVEL == 0 && node_role == role_6dr_sec) { + if(LLSEC802154_ENABLED == 0 && node_role == role_6dr_sec) { node_role = (node_role + 1) % 3; } etimer_restart(&et); @@ -182,7 +182,7 @@ PROCESS_THREAD(node_process, ev, data) printf("Init: node starting with role %s\n", node_role == role_6ln ? "6ln" : (node_role == role_6dr) ? "6dr" : "6dr-sec"); - tsch_set_pan_secured(TSCH_SECURITY_LEVEL && (node_role == role_6dr_sec)); + tsch_set_pan_secured(LLSEC802154_ENABLED && (node_role == role_6dr_sec)); is_coordinator = node_role > role_6ln; if(is_coordinator) { diff --git a/examples/ipv6/rpl-tsch/project-conf.h b/examples/ipv6/rpl-tsch/project-conf.h index 11c882c43..30f638bb4 100644 --- a/examples/ipv6/rpl-tsch/project-conf.h +++ b/examples/ipv6/rpl-tsch/project-conf.h @@ -100,8 +100,6 @@ #if WITH_SECURITY /* Enable security */ -#undef TSCH_SECURITY_CONF_LEVEL -#define TSCH_SECURITY_CONF_LEVEL 1 #undef LLSEC802154_CONF_ENABLED #define LLSEC802154_CONF_ENABLED 1 /* TSCH uses explicit keys to identify k1 and k2 */ From 7353829c72fd6a499942fdb9f946f62780e5a4ac Mon Sep 17 00:00:00 2001 From: kkrentz Date: Wed, 2 Mar 2016 01:58:19 -0800 Subject: [PATCH 158/374] llsec: Fix for Issue #1537 --- core/net/llsec/noncoresec/noncoresec.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/core/net/llsec/noncoresec/noncoresec.c b/core/net/llsec/noncoresec/noncoresec.c index a14e71e52..71a1cb82a 100644 --- a/core/net/llsec/noncoresec/noncoresec.c +++ b/core/net/llsec/noncoresec/noncoresec.c @@ -143,16 +143,15 @@ aead(uint8_t hdrlen, int forward) static void add_security_header(void) { - if(!packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL)) { - packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME); - packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, SEC_LVL); - anti_replay_set_counter(); - } + packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME); + packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, SEC_LVL); } /*---------------------------------------------------------------------------*/ static void send(mac_callback_t sent, void *ptr) { + add_security_header(); + anti_replay_set_counter(); NETSTACK_MAC.send(sent, ptr); } /*---------------------------------------------------------------------------*/ @@ -161,7 +160,6 @@ create(void) { int result; - add_security_header(); result = DECORATED_FRAMER.create(); if(result == FRAMER_FAILED) { return result; From d478c0f7f15fc884914c2cfc164588e43152f882 Mon Sep 17 00:00:00 2001 From: Konrad Krentz Date: Fri, 17 Jul 2015 05:40:45 -0700 Subject: [PATCH 159/374] packetbuf: Deleted functions that are never called --- core/net/packetbuf.c | 29 ----------------------------- core/net/packetbuf.h | 31 ------------------------------- 2 files changed, 60 deletions(-) diff --git a/core/net/packetbuf.c b/core/net/packetbuf.c index c7e2a9898..3cc2e1ac7 100644 --- a/core/net/packetbuf.c +++ b/core/net/packetbuf.c @@ -83,12 +83,6 @@ packetbuf_clear(void) packetbuf_attr_clear(); } /*---------------------------------------------------------------------------*/ -void -packetbuf_clear_hdr(void) -{ - hdrptr = PACKETBUF_HDR_SIZE; -} -/*---------------------------------------------------------------------------*/ int packetbuf_copyfrom(const void *from, uint16_t len) { @@ -117,23 +111,6 @@ packetbuf_compact(void) } /*---------------------------------------------------------------------------*/ int -packetbuf_copyto_hdr(uint8_t *to) -{ -#if DEBUG_LEVEL > 0 - { - int i; - PRINTF("packetbuf_write_hdr: header:\n"); - for(i = hdrptr; i < PACKETBUF_HDR_SIZE; ++i) { - PRINTF("0x%02x, ", packetbuf[i]); - } - PRINTF("\n"); - } -#endif /* DEBUG_LEVEL */ - memcpy(to, packetbuf + hdrptr, PACKETBUF_HDR_SIZE - hdrptr); - return PACKETBUF_HDR_SIZE - hdrptr; -} -/*---------------------------------------------------------------------------*/ -int packetbuf_copyto(void *to) { #if DEBUG_LEVEL > 0 @@ -176,12 +153,6 @@ packetbuf_hdralloc(int size) return 0; } /*---------------------------------------------------------------------------*/ -void -packetbuf_hdr_remove(int size) -{ - hdrptr += size; -} -/*---------------------------------------------------------------------------*/ int packetbuf_hdrreduce(int size) { diff --git a/core/net/packetbuf.h b/core/net/packetbuf.h index 12b0d9dce..fe3472536 100644 --- a/core/net/packetbuf.h +++ b/core/net/packetbuf.h @@ -92,21 +92,6 @@ */ void packetbuf_clear(void); -/** - * \brief Clear and reset the header of the packetbuf - * - * This function clears the header of the packetbuf and - * resets all the internal state pointers pertaining to - * the header (header size, header pointer, but not - * external data pointer). It is used before after sending - * a packet in the packetbuf, to be able to reuse the - * packet buffer for a later retransmission. - * - */ -void packetbuf_clear_hdr(void); - -void packetbuf_hdr_remove(int bytes); - /** * \brief Get a pointer to the data in the packetbuf * \return Pointer to the packetbuf data @@ -235,22 +220,6 @@ int packetbuf_copyfrom(const void *from, uint16_t len); */ int packetbuf_copyto(void *to); -/** - * \brief Copy the header portion of the packetbuf to an external buffer - * \param to A pointer to the buffer to which the data is to be copied - * \retval The number of bytes that was copied to the external buffer - * - * This function copies the header portion of the packetbuf - * to an external buffer. - * - * The external buffer to which the packetbuf is to be - * copied must be able to accomodate at least - * PACKETBUF_HDR_SIZE bytes. The number of bytes that was - * copied to the external buffer is returned. - * - */ -int packetbuf_copyto_hdr(uint8_t *to); - /** * \brief Extend the header of the packetbuf, for outbound packets * \param size The number of bytes the header should be extended From a1b91d8b59398249816e67f89fc8553e194cff16 Mon Sep 17 00:00:00 2001 From: kkrentz Date: Wed, 3 Feb 2016 06:41:15 -0800 Subject: [PATCH 160/374] packetbuf: Removed commented code --- core/net/packetbuf.c | 2 -- core/net/packetbuf.h | 4 ---- 2 files changed, 6 deletions(-) diff --git a/core/net/packetbuf.c b/core/net/packetbuf.c index 3cc2e1ac7..774ff2f60 100644 --- a/core/net/packetbuf.c +++ b/core/net/packetbuf.c @@ -243,7 +243,6 @@ packetbuf_attr_copyfrom(struct packetbuf_attr *attrs, int packetbuf_set_attr(uint8_t type, const packetbuf_attr_t val) { -/* packetbuf_attrs[type].type = type; */ packetbuf_attrs[type].val = val; return 1; } @@ -257,7 +256,6 @@ packetbuf_attr(uint8_t type) int packetbuf_set_addr(uint8_t type, const linkaddr_t *addr) { -/* packetbuf_addrs[type - PACKETBUF_ADDR_FIRST].type = type; */ linkaddr_copy(&packetbuf_addrs[type - PACKETBUF_ADDR_FIRST].addr, addr); return 1; } diff --git a/core/net/packetbuf.h b/core/net/packetbuf.h index fe3472536..cca365f6e 100644 --- a/core/net/packetbuf.h +++ b/core/net/packetbuf.h @@ -253,11 +253,9 @@ int packetbuf_hdrreduce(int size); typedef uint16_t packetbuf_attr_t; struct packetbuf_attr { -/* uint8_t type; */ packetbuf_attr_t val; }; struct packetbuf_addr { -/* uint8_t type; */ linkaddr_t addr; }; @@ -380,7 +378,6 @@ static const linkaddr_t *packetbuf_addr(uint8_t type); static inline int packetbuf_set_attr(uint8_t type, const packetbuf_attr_t val) { -/* packetbuf_attrs[type].type = type; */ packetbuf_attrs[type].val = val; return 1; } @@ -393,7 +390,6 @@ packetbuf_attr(uint8_t type) static inline int packetbuf_set_addr(uint8_t type, const linkaddr_t *addr) { -/* packetbuf_addrs[type - PACKETBUF_ADDR_FIRST].type = type; */ linkaddr_copy(&packetbuf_addrs[type - PACKETBUF_ADDR_FIRST].addr, addr); return 1; } From 11c03eef797ed03820374fc307010c0d76eb636e Mon Sep 17 00:00:00 2001 From: kkrentz Date: Wed, 3 Feb 2016 06:42:18 -0800 Subject: [PATCH 161/374] packetbuf: Removed function prototypes --- core/net/packetbuf.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/core/net/packetbuf.h b/core/net/packetbuf.h index cca365f6e..0afd02a74 100644 --- a/core/net/packetbuf.h +++ b/core/net/packetbuf.h @@ -370,11 +370,6 @@ enum { extern struct packetbuf_attr packetbuf_attrs[]; extern struct packetbuf_addr packetbuf_addrs[]; -static int packetbuf_set_attr(uint8_t type, const packetbuf_attr_t val); -static packetbuf_attr_t packetbuf_attr(uint8_t type); -static int packetbuf_set_addr(uint8_t type, const linkaddr_t *addr); -static const linkaddr_t *packetbuf_addr(uint8_t type); - static inline int packetbuf_set_attr(uint8_t type, const packetbuf_attr_t val) { From 1014018c2d5fa4a61b57f7ba6f56f7ffc18f6029 Mon Sep 17 00:00:00 2001 From: kkrentz Date: Wed, 3 Feb 2016 08:08:12 -0800 Subject: [PATCH 162/374] packetbuf: Removed debugging stuff --- core/net/packetbuf.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/core/net/packetbuf.c b/core/net/packetbuf.c index 774ff2f60..cfc831fd8 100644 --- a/core/net/packetbuf.c +++ b/core/net/packetbuf.c @@ -113,26 +113,6 @@ packetbuf_compact(void) int packetbuf_copyto(void *to) { -#if DEBUG_LEVEL > 0 - { - int i; - char buffer[1000]; - char *bufferptr = buffer; - int bufferlen = 0; - - bufferptr[0] = 0; - for(i = hdrptr; i < PACKETBUF_HDR_SIZE; ++i) { - bufferptr += sprintf(bufferptr, "0x%02x, ", packetbuf[i]); - } - PRINTF("packetbuf_write: header: %s\n", buffer); - bufferptr = buffer; - bufferptr[0] = 0; - for(i = bufptr; ((i < buflen + bufptr) && (bufferlen < (sizeof(buffer) - 10))); ++i) { - bufferlen += sprintf(bufferptr + bufferlen, "0x%02x, ", packetbufptr[i]); - } - PRINTF("packetbuf_write: data: %s\n", buffer); - } -#endif /* DEBUG_LEVEL */ if(PACKETBUF_HDR_SIZE - hdrptr + buflen > PACKETBUF_SIZE) { /* Too large packet */ return 0; From 3d79292e441fe66e78b161f8963481f0eb6c2067 Mon Sep 17 00:00:00 2001 From: kkrentz Date: Wed, 3 Feb 2016 07:59:22 -0800 Subject: [PATCH 163/374] packetbuf: Simplified packetbuf_attr_clear --- core/net/packetbuf.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/net/packetbuf.c b/core/net/packetbuf.c index cfc831fd8..1e6b9a57f 100644 --- a/core/net/packetbuf.c +++ b/core/net/packetbuf.c @@ -195,9 +195,7 @@ void packetbuf_attr_clear(void) { int i; - for(i = 0; i < PACKETBUF_NUM_ATTRS; ++i) { - packetbuf_attrs[i].val = 0; - } + memset(packetbuf_attrs, 0, sizeof(packetbuf_attrs)); for(i = 0; i < PACKETBUF_NUM_ADDRS; ++i) { linkaddr_copy(&packetbuf_addrs[i].addr, &linkaddr_null); } From 0af4a18c09d6759f8285e017c216b04b8c2414ac Mon Sep 17 00:00:00 2001 From: kkrentz Date: Wed, 3 Feb 2016 08:09:13 -0800 Subject: [PATCH 164/374] packetbuf: Use MIN macro --- core/net/packetbuf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/net/packetbuf.c b/core/net/packetbuf.c index 1e6b9a57f..a2f295816 100644 --- a/core/net/packetbuf.c +++ b/core/net/packetbuf.c @@ -47,6 +47,7 @@ #include "contiki-net.h" #include "net/packetbuf.h" #include "net/rime/rime.h" +#include "sys/cc.h" struct packetbuf_attr packetbuf_attrs[PACKETBUF_NUM_ATTRS]; struct packetbuf_addr packetbuf_addrs[PACKETBUF_NUM_ADDRS]; @@ -89,7 +90,7 @@ packetbuf_copyfrom(const void *from, uint16_t len) uint16_t l; packetbuf_clear(); - l = len > PACKETBUF_SIZE? PACKETBUF_SIZE: len; + l = MIN(PACKETBUF_SIZE, len); memcpy(packetbufptr, from, l); buflen = l; return l; From f1110bf6df176cdc61a284030021c67f314cb7df Mon Sep 17 00:00:00 2001 From: Marko Gucanin Date: Thu, 14 Apr 2016 16:52:32 +0200 Subject: [PATCH 165/374] removed NETSTACK_LLSEC.init --- platform/jn516x/contiki-jn516x-main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/platform/jn516x/contiki-jn516x-main.c b/platform/jn516x/contiki-jn516x-main.c index 171b94a2a..9a64365e6 100644 --- a/platform/jn516x/contiki-jn516x-main.c +++ b/platform/jn516x/contiki-jn516x-main.c @@ -409,7 +409,6 @@ main(void) #endif /* NETSTACK_CONF_WITH_IPV4 */ watchdog_start(); - NETSTACK_LLSEC.init(); #if NETSTACK_CONF_WITH_IPV6 start_uip6(); From d8db093eb256641e3c131e4803c1ae9d591fe246 Mon Sep 17 00:00:00 2001 From: Marko Gucanin Date: Thu, 14 Apr 2016 16:55:48 +0200 Subject: [PATCH 166/374] renamed ccm-star.c to jn516x-ccm-star.c, adapted Makefile accordingly --- platform/jn516x/Makefile.jn516x | 2 +- platform/jn516x/dev/{ccm-star.c => jn516x-ccm-star.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename platform/jn516x/dev/{ccm-star.c => jn516x-ccm-star.c} (100%) diff --git a/platform/jn516x/Makefile.jn516x b/platform/jn516x/Makefile.jn516x index 27587ccaf..ca41ce3ae 100644 --- a/platform/jn516x/Makefile.jn516x +++ b/platform/jn516x/Makefile.jn516x @@ -80,7 +80,7 @@ SIZE:=$(CROSS_COMPILE)-size OBJCOPY:=$(CROSS_COMPILE)-objcopy OBJDUMP:=$(CROSS_COMPILE)-objdump -ARCH = ccm-star.c exceptions.c rtimer-arch.c rtimer-arch-slow.c \ +ARCH = jn516x-ccm-star.c exceptions.c rtimer-arch.c rtimer-arch-slow.c \ slip_uart0.c clock.c micromac-radio.c \ mtarch.c node-id.c watchdog.c log.c slip.c sprintf.c # Default uart0 for printf and slip diff --git a/platform/jn516x/dev/ccm-star.c b/platform/jn516x/dev/jn516x-ccm-star.c similarity index 100% rename from platform/jn516x/dev/ccm-star.c rename to platform/jn516x/dev/jn516x-ccm-star.c From 6fb6fd5bb9639941d141028ac205f89b9d4a7c8a Mon Sep 17 00:00:00 2001 From: kkrentz Date: Thu, 4 Feb 2016 03:25:47 -0800 Subject: [PATCH 167/374] packetbuf: No more splitting of header and data --- core/net/packetbuf.c | 62 ++++++++++++---------------- core/net/packetbuf.h | 46 +-------------------- platform/avr-raven/contiki-conf.h | 3 -- platform/avr-ravenusb/contiki-conf.h | 5 --- platform/avr-rcb/contiki-conf.h | 1 - platform/avr-zigbit/contiki-conf.h | 3 -- 6 files changed, 28 insertions(+), 92 deletions(-) diff --git a/core/net/packetbuf.c b/core/net/packetbuf.c index a2f295816..4869263cf 100644 --- a/core/net/packetbuf.c +++ b/core/net/packetbuf.c @@ -54,17 +54,15 @@ struct packetbuf_addr packetbuf_addrs[PACKETBUF_NUM_ADDRS]; static uint16_t buflen, bufptr; -static uint8_t hdrptr; +static uint8_t hdrlen; /* The declarations below ensure that the packet buffer is aligned on an even 32-bit boundary. On some platforms (most notably the msp430 or OpenRISC), having a potentially misaligned packet buffer may lead to problems when accessing words. */ -static uint32_t packetbuf_aligned[(PACKETBUF_SIZE + PACKETBUF_HDR_SIZE + 3) / 4]; +static uint32_t packetbuf_aligned[(PACKETBUF_SIZE + 3) / 4]; static uint8_t *packetbuf = (uint8_t *)packetbuf_aligned; -static uint8_t *packetbufptr; - #define DEBUG 0 #if DEBUG #include @@ -78,9 +76,8 @@ void packetbuf_clear(void) { buflen = bufptr = 0; - hdrptr = PACKETBUF_HDR_SIZE; + hdrlen = 0; - packetbufptr = &packetbuf[PACKETBUF_HDR_SIZE]; packetbuf_attr_clear(); } /*---------------------------------------------------------------------------*/ @@ -91,7 +88,7 @@ packetbuf_copyfrom(const void *from, uint16_t len) packetbuf_clear(); l = MIN(PACKETBUF_SIZE, len); - memcpy(packetbufptr, from, l); + memcpy(packetbuf, from, l); buflen = l; return l; } @@ -99,14 +96,13 @@ packetbuf_copyfrom(const void *from, uint16_t len) void packetbuf_compact(void) { - int i, len; + int16_t i; - if(bufptr > 0) { - len = packetbuf_datalen() + PACKETBUF_HDR_SIZE; - for(i = PACKETBUF_HDR_SIZE; i < len; i++) { - packetbuf[i] = packetbuf[bufptr + i]; + if(bufptr) { + /* shift data to the left */ + for(i = 0; i < buflen; i++) { + packetbuf[hdrlen + i] = packetbuf[packetbuf_hdrlen() + i]; } - bufptr = 0; } } @@ -114,24 +110,29 @@ packetbuf_compact(void) int packetbuf_copyto(void *to) { - if(PACKETBUF_HDR_SIZE - hdrptr + buflen > PACKETBUF_SIZE) { - /* Too large packet */ + if(hdrlen + buflen > PACKETBUF_SIZE) { return 0; } - memcpy(to, packetbuf + hdrptr, PACKETBUF_HDR_SIZE - hdrptr); - memcpy((uint8_t *)to + PACKETBUF_HDR_SIZE - hdrptr, packetbufptr + bufptr, - buflen); - return PACKETBUF_HDR_SIZE - hdrptr + buflen; + memcpy(to, packetbuf_hdrptr(), hdrlen); + memcpy((uint8_t *)to + hdrlen, packetbuf_dataptr(), buflen); + return hdrlen + buflen; } /*---------------------------------------------------------------------------*/ int packetbuf_hdralloc(int size) { - if(hdrptr >= size && packetbuf_totlen() + size <= PACKETBUF_SIZE) { - hdrptr -= size; - return 1; + int16_t i; + + if(size + packetbuf_totlen() > PACKETBUF_SIZE) { + return 0; } - return 0; + + /* shift data to the right */ + for(i = packetbuf_totlen() - 1; i >= 0; i--) { + packetbuf[i + size] = packetbuf[i]; + } + hdrlen += size; + return 1; } /*---------------------------------------------------------------------------*/ int @@ -156,13 +157,13 @@ packetbuf_set_datalen(uint16_t len) void * packetbuf_dataptr(void) { - return (void *)(&packetbuf[bufptr + PACKETBUF_HDR_SIZE]); + return packetbuf + packetbuf_hdrlen(); } /*---------------------------------------------------------------------------*/ void * packetbuf_hdrptr(void) { - return (void *)(&packetbuf[hdrptr]); + return packetbuf; } /*---------------------------------------------------------------------------*/ uint16_t @@ -174,16 +175,7 @@ packetbuf_datalen(void) uint8_t packetbuf_hdrlen(void) { - uint8_t hdrlen; - - hdrlen = PACKETBUF_HDR_SIZE - hdrptr; - if(hdrlen) { - /* outbound packet */ - return hdrlen; - } else { - /* inbound packet */ - return bufptr; - } + return bufptr + hdrlen; } /*---------------------------------------------------------------------------*/ uint16_t diff --git a/core/net/packetbuf.h b/core/net/packetbuf.h index 0afd02a74..3d6386d26 100644 --- a/core/net/packetbuf.h +++ b/core/net/packetbuf.h @@ -66,15 +66,6 @@ #define PACKETBUF_SIZE 128 #endif -/** - * \brief The size of the packetbuf header, in bytes - */ -#ifdef PACKETBUF_CONF_HDR_SIZE -#define PACKETBUF_HDR_SIZE PACKETBUF_CONF_HDR_SIZE -#else -#define PACKETBUF_HDR_SIZE 48 -#endif - #ifdef PACKETBUF_CONF_WITH_PACKET_TYPE #define PACKETBUF_WITH_PACKET_TYPE PACKETBUF_CONF_WITH_PACKET_TYPE #else @@ -100,15 +91,6 @@ void packetbuf_clear(void); * the packetbuf. The data is either stored in the packetbuf, * or referenced to an external location. * - * For outbound packets, the packetbuf consists of two - * parts: header and data. The header is accessed with the - * packetbuf_hdrptr() function. - * - * For incoming packets, both the packet header and the - * packet data is stored in the data portion of the - * packetbuf. Thus this function is used to get a pointer to - * the header for incoming packets. - * */ void *packetbuf_dataptr(void); @@ -116,11 +98,6 @@ void *packetbuf_dataptr(void); * \brief Get a pointer to the header in the packetbuf, for outbound packets * \return Pointer to the packetbuf header * - * For outbound packets, the packetbuf consists of two - * parts: header and data. This function is used to get a - * pointer to the header in the packetbuf. The header is - * stored in the packetbuf. - * */ void *packetbuf_hdrptr(void); @@ -128,12 +105,6 @@ void *packetbuf_hdrptr(void); * \brief Get the length of the header in the packetbuf * \return Length of the header in the packetbuf * - * For outbound packets, the packetbuf consists of two - * parts: header and data. This function is used to get - * the length of the header in the packetbuf. The header is - * stored in the packetbuf and accessed via the - * packetbuf_hdrptr() function. - * */ uint8_t packetbuf_hdrlen(void); @@ -142,17 +113,6 @@ uint8_t packetbuf_hdrlen(void); * \brief Get the length of the data in the packetbuf * \return Length of the data in the packetbuf * - * For outbound packets, the packetbuf consists of two - * parts: header and data. This function is used to get - * the length of the data in the packetbuf. The data is - * stored in the packetbuf and accessed via the - * packetbuf_dataptr() function. - * - * For incoming packets, both the packet header and the - * packet data is stored in the data portion of the - * packetbuf. This function is then used to get the total - * length of the packet - both header and data. - * */ uint16_t packetbuf_datalen(void); @@ -166,10 +126,6 @@ uint16_t packetbuf_totlen(void); /** * \brief Set the length of the data in the packetbuf * \param len The length of the data - * - * For outbound packets, the packetbuf consists of two - * parts: header and data. This function is used to set - * the length of the data in the packetbuf. */ void packetbuf_set_datalen(uint16_t len); @@ -213,7 +169,7 @@ int packetbuf_copyfrom(const void *from, uint16_t len); * * The external buffer to which the packetbuf is to be * copied must be able to accomodate at least - * (PACKETBUF_SIZE + PACKETBUF_HDR_SIZE) bytes. The number of + * PACKETBUF_SIZE bytes. The number of * bytes that was copied to the external buffer is * returned. * diff --git a/platform/avr-raven/contiki-conf.h b/platform/avr-raven/contiki-conf.h index ab770540d..45ea5fb22 100644 --- a/platform/avr-raven/contiki-conf.h +++ b/platform/avr-raven/contiki-conf.h @@ -138,15 +138,12 @@ typedef unsigned short uip_stats_t; /* Network setup. The new NETSTACK interface requires RF230BB (as does ip4) */ #if RF230BB -#undef PACKETBUF_CONF_HDR_SIZE //Use the packetbuf default for header size /* TX routine passes the cca/ack result in the return parameter */ #define RDC_CONF_HARDWARE_ACK 1 /* TX routine does automatic cca and optional backoff */ #define RDC_CONF_HARDWARE_CSMA 1 /* Allow MCU sleeping between channel checks */ #define RDC_CONF_MCU_SLEEP 0 -#else -#define PACKETBUF_CONF_HDR_SIZE 0 //RF230 combined driver/mac handles headers internally #endif /*RF230BB */ #if NETSTACK_CONF_WITH_IPV6 diff --git a/platform/avr-ravenusb/contiki-conf.h b/platform/avr-ravenusb/contiki-conf.h index 71d56e248..8eab7cce9 100644 --- a/platform/avr-ravenusb/contiki-conf.h +++ b/platform/avr-ravenusb/contiki-conf.h @@ -204,11 +204,6 @@ extern void mac_log_802_15_4_rx(const uint8_t* buffer, size_t total_len); /* Network setup. The new NETSTACK interface requires RF230BB (as does ip4) */ /* These mostly have no effect when the Jackdaw is a repeater (CONTIKI_NO_NET=1 using fakeuip.c) */ -#if RF230BB -#else -#define PACKETBUF_CONF_HDR_SIZE 0 //RF230 combined driver/mac handles headers internally -#endif /*RF230BB */ - #if NETSTACK_CONF_WITH_IPV6 #define LINKADDR_CONF_SIZE 8 #define UIP_CONF_ICMP6 1 diff --git a/platform/avr-rcb/contiki-conf.h b/platform/avr-rcb/contiki-conf.h index 298a33cd0..68ce8f3b6 100644 --- a/platform/avr-rcb/contiki-conf.h +++ b/platform/avr-rcb/contiki-conf.h @@ -85,7 +85,6 @@ void clock_adjust_ticks(clock_time_t howmany); #define CLIF #define LINKADDR_CONF_SIZE 8 -#define PACKETBUF_CONF_HDR_SIZE 48 /* Choose a buffersize != 0 for the messages which should be sended over the wireless interface */ /* Uncomment this lines to activate the specific drivers */ //#define NETSTACK_CONF_NETWORK rime_driver diff --git a/platform/avr-zigbit/contiki-conf.h b/platform/avr-zigbit/contiki-conf.h index f84df8863..c01c6555c 100644 --- a/platform/avr-zigbit/contiki-conf.h +++ b/platform/avr-zigbit/contiki-conf.h @@ -88,7 +88,6 @@ void clock_adjust_ticks(clock_time_t howmany); #endif #define LINKADDR_CONF_SIZE 8 -#define PACKETBUF_CONF_HDR_SIZE 0 //define NETSTACK_CONF_WITH_IPV6 1 //Let the makefile do this, allows hello-world to compile #if NETSTACK_CONF_WITH_IPV6 @@ -100,7 +99,6 @@ void clock_adjust_ticks(clock_time_t howmany); /* The new NETSTACK interface requires RF230BB */ #if RF230BB #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 -#undef PACKETBUF_CONF_HDR_SIZE //RF230BB takes the packetbuf default for header size #define UIP_CONF_LLH_LEN 0 /* No radio cycling */ @@ -126,7 +124,6 @@ void clock_adjust_ticks(clock_time_t howmany); #else /* Original combined RF230/mac code will not compile with current contiki stack */ -//#define PACKETBUF_CONF_HDR_SIZE 0 //RF230 handles headers internally //FTH081105 #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 #define SICSLOWPAN_CONF_MAXAGE 5 From 3bf05d664e77b6e6e43b3f7bd34e3b1f4d3fc715 Mon Sep 17 00:00:00 2001 From: thomas-ha Date: Fri, 15 Apr 2016 15:50:01 +0200 Subject: [PATCH 168/374] moving macros to .c --- cpu/cc2538/dev/cc2538-rf.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/cpu/cc2538/dev/cc2538-rf.h b/cpu/cc2538/dev/cc2538-rf.h index 287147a92..5edb478ba 100644 --- a/cpu/cc2538/dev/cc2538-rf.h +++ b/cpu/cc2538/dev/cc2538-rf.h @@ -129,15 +129,6 @@ REG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHTX; \ REG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHTX; \ } while(0) -/*--------------------------------------------------------------------------- - * MAC timer - *---------------------------------------------------------------------------*/ -/* Timer conversion */ -#define RADIO_TO_RTIMER(X) ((X) * RTIMER_ARCH_SECOND / SYS_CTRL_32MHZ) - -#define CLOCK_STABLE() do { \ - while ( !(REG(SYS_CTRL_CLOCK_STA) & (SYS_CTRL_CLOCK_STA_XOSC_STB))); \ - } while(0) /*---------------------------------------------------------------------------*/ /** The NETSTACK data structure for the cc2538 RF driver */ extern const struct radio_driver cc2538_rf_driver; From 6262025ef3befe7afc0b653444c3d7276d6c5aaa Mon Sep 17 00:00:00 2001 From: thomas-ha Date: Fri, 15 Apr 2016 15:50:20 +0200 Subject: [PATCH 169/374] code style fixes and insert macros from .h --- cpu/cc2538/dev/cc2538-rf.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/cpu/cc2538/dev/cc2538-rf.c b/cpu/cc2538/dev/cc2538-rf.c index 12fe9ffae..652480a9e 100644 --- a/cpu/cc2538/dev/cc2538-rf.c +++ b/cpu/cc2538/dev/cc2538-rf.c @@ -119,6 +119,15 @@ static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 }; /** Snif */ #else #define CC2538_RF_AUTOACK 1 #endif +/*--------------------------------------------------------------------------- + * MAC timer + *---------------------------------------------------------------------------*/ +/* Timer conversion */ +#define RADIO_TO_RTIMER(X) ((X) * RTIMER_ARCH_SECOND / SYS_CTRL_32MHZ) + +#define CLOCK_STABLE() do { \ + while ( !(REG(SYS_CTRL_CLOCK_STA) & (SYS_CTRL_CLOCK_STA_XOSC_STB))); \ + } while(0) /*---------------------------------------------------------------------------*/ /* Are we currently in poll mode? Disabled by default */ static uint8_t volatile poll_mode = 0; @@ -427,7 +436,7 @@ off(void) /* Wait for ongoing TX to complete (e.g. this could be an outgoing ACK) */ while(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); - if (!(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFOP)) { + if(!(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFOP)) { CC2538_RF_CSP_ISFLUSHRX(); } @@ -1071,7 +1080,7 @@ cc2538_rf_rx_tx_isr(void) process_poll(&cc2538_rf_process); } - /* We only acknowledge FIFOP or SFD so we can safely wipe out the entire SFR */ + /* We only acknowledge FIFOP so we can safely wipe out the entire SFR */ REG(RFCORE_SFR_RFIRQF0) = 0; ENERGEST_OFF(ENERGEST_TYPE_IRQ); @@ -1149,7 +1158,8 @@ void mac_timer_init(void) while(!(REG(RFCORE_SFR_MTCTRL) & RFCORE_SFR_MTCTRL_STATE)); REG(RFCORE_SFR_MTCTRL) &= ~RFCORE_SFR_MTCTRL_RUN; while(REG(RFCORE_SFR_MTCTRL) & RFCORE_SFR_MTCTRL_STATE); - REG(RFCORE_SFR_MTCTRL) |= (RFCORE_SFR_MTCTRL_RUN | RFCORE_SFR_MTCTRL_SYNC); + REG(RFCORE_SFR_MTCTRL) |= RFCORE_SFR_MTCTRL_SYNC; + REG(RFCORE_SFR_MTCTRL) |= (RFCORE_SFR_MTCTRL_RUN); while(!(REG(RFCORE_SFR_MTCTRL) & RFCORE_SFR_MTCTRL_STATE)); } /*---------------------------------------------------------------------------*/ From 2a07dc0e0a7f3d87073ab19331f5d2fb5349fe1a Mon Sep 17 00:00:00 2001 From: Phil Rhinehart Date: Mon, 18 Apr 2016 17:02:07 +0800 Subject: [PATCH 170/374] This fixes an event handling issue in the cc26xx BLE driver. Currently, the rf_ble_beacon_process triggers the BLE beacon upon receiving any event, rather than verifying that the event timer has expired. This means that any PROCESS_BROADCAST (e.g. any sensor event) will fire the beacon. This commit adds logic to prevent this. --- cpu/cc26xx-cc13xx/rf-core/rf-ble.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpu/cc26xx-cc13xx/rf-core/rf-ble.c b/cpu/cc26xx-cc13xx/rf-core/rf-ble.c index b8af55ff8..48daba69f 100644 --- a/cpu/cc26xx-cc13xx/rf-core/rf-ble.c +++ b/cpu/cc26xx-cc13xx/rf-core/rf-ble.c @@ -256,7 +256,7 @@ PROCESS_THREAD(rf_ble_beacon_process, ev, data) while(1) { etimer_set(&ble_adv_et, beacond_config.interval); - PROCESS_WAIT_EVENT(); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&ble_adv_et) || ev == PROCESS_EVENT_EXIT); if(ev == PROCESS_EVENT_EXIT) { PROCESS_EXIT(); @@ -374,7 +374,7 @@ PROCESS_THREAD(rf_ble_beacon_process, ev, data) /* Wait unless this is the last burst */ if(i < BLE_ADV_MESSAGES - 1) { - PROCESS_WAIT_EVENT(); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&ble_adv_et)); } } From 5d5544151f3a7bf993c0692778a1583ec918f78c Mon Sep 17 00:00:00 2001 From: Phil Rhinehart Date: Mon, 18 Apr 2016 16:36:33 +0800 Subject: [PATCH 171/374] Fixed bug in cc26xx-cc13xx rf-core. When running BLE in conjunction with ContikiMAC, oscillators were modified from an interrupt state causing occasional bus faults and infinite loops. We now check if BLE is active prior to modifiying the oscillators to avoid these conditions. --- cpu/cc26xx-cc13xx/rf-core/ieee-mode.c | 12 ++++++------ cpu/cc26xx-cc13xx/rf-core/prop-mode.c | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c index fc0ef7cbb..f26d57939 100644 --- a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c +++ b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c @@ -1048,12 +1048,6 @@ pending_packet(void) static int on(void) { - /* - * Request the HF XOSC as the source for the HF clock. Needed before we can - * use the FS. This will only request, it will _not_ perform the switch. - */ - oscillators_request_hf_xosc(); - /* * If we are in the middle of a BLE operation, we got called by ContikiMAC * from within an interrupt context. Abort, but pretend everything is OK. @@ -1063,6 +1057,12 @@ on(void) return RF_CORE_CMD_OK; } + /* + * Request the HF XOSC as the source for the HF clock. Needed before we can + * use the FS. This will only request, it will _not_ perform the switch. + */ + oscillators_request_hf_xosc(); + if(rf_is_on()) { PRINTF("on: We were on. PD=%u, RX=0x%04x \n", rf_core_is_accessible(), RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf)); diff --git a/cpu/cc26xx-cc13xx/rf-core/prop-mode.c b/cpu/cc26xx-cc13xx/rf-core/prop-mode.c index 7515d79b4..419a7b9d2 100644 --- a/cpu/cc26xx-cc13xx/rf-core/prop-mode.c +++ b/cpu/cc26xx-cc13xx/rf-core/prop-mode.c @@ -893,12 +893,6 @@ pending_packet(void) static int on(void) { - /* - * Request the HF XOSC as the source for the HF clock. Needed before we can - * use the FS. This will only request, it will _not_ perform the switch. - */ - oscillators_request_hf_xosc(); - /* * If we are in the middle of a BLE operation, we got called by ContikiMAC * from within an interrupt context. Abort, but pretend everything is OK. @@ -907,6 +901,12 @@ on(void) return RF_CORE_CMD_OK; } + /* + * Request the HF XOSC as the source for the HF clock. Needed before we can + * use the FS. This will only request, it will _not_ perform the switch. + */ + oscillators_request_hf_xosc(); + if(rf_is_on()) { PRINTF("on: We were on. PD=%u, RX=0x%04x \n", rf_core_is_accessible(), smartrf_settings_cmd_prop_rx_adv.status); From 3a76207b5958d34c587ee83b7a46d54cf7cd4a3e Mon Sep 17 00:00:00 2001 From: thomas-ha Date: Mon, 18 Apr 2016 11:40:52 +0200 Subject: [PATCH 172/374] Use 64 bit values for MAC timer --- cpu/cc2538/dev/cc2538-rf.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cpu/cc2538/dev/cc2538-rf.c b/cpu/cc2538/dev/cc2538-rf.c index 652480a9e..52708e0ca 100644 --- a/cpu/cc2538/dev/cc2538-rf.c +++ b/cpu/cc2538/dev/cc2538-rf.c @@ -123,7 +123,7 @@ static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 }; /** Snif */ * MAC timer *---------------------------------------------------------------------------*/ /* Timer conversion */ -#define RADIO_TO_RTIMER(X) ((X) * RTIMER_ARCH_SECOND / SYS_CTRL_32MHZ) +#define RADIO_TO_RTIMER(X) ((uint32_t)((uint64_t)(X) * RTIMER_ARCH_SECOND / SYS_CTRL_32MHZ)) #define CLOCK_STABLE() do { \ while ( !(REG(SYS_CTRL_CLOCK_STA) & (SYS_CTRL_CLOCK_STA_XOSC_STB))); \ @@ -1129,7 +1129,7 @@ cc2538_rf_set_promiscous_mode(char p) /*---------------------------------------------------------------------------*/ uint32_t get_sfd_timestamp(void) { - uint32_t sfd, timer_val; + uint64_t sfd, timer_val, buffer; REG(RFCORE_SFR_MTMSEL) = (REG(RFCORE_SFR_MTMSEL) & ~RFCORE_SFR_MTMSEL_MTMSEL) | 0x00000000; REG(RFCORE_SFR_MTCTRL) |= RFCORE_SFR_MTCTRL_LATCH_MODE; @@ -1138,6 +1138,8 @@ uint32_t get_sfd_timestamp(void) REG(RFCORE_SFR_MTMSEL) = (REG(RFCORE_SFR_MTMSEL) & ~RFCORE_SFR_MTMSEL_MTMOVFSEL) | 0x00000000; timer_val |= ((REG(RFCORE_SFR_MTMOVF0) & RFCORE_SFR_MTMOVF0_MTMOVF0) << 16); timer_val |= ((REG(RFCORE_SFR_MTMOVF1) & RFCORE_SFR_MTMOVF1_MTMOVF1) << 24); + buffer = REG(RFCORE_SFR_MTMOVF2) & RFCORE_SFR_MTMOVF2_MTMOVF2; + timer_val |= (buffer << 32); REG(RFCORE_SFR_MTMSEL) = (REG(RFCORE_SFR_MTMSEL) & ~RFCORE_SFR_MTMSEL_MTMSEL) | 0x00000001; REG(RFCORE_SFR_MTCTRL) |= RFCORE_SFR_MTCTRL_LATCH_MODE; @@ -1146,6 +1148,8 @@ uint32_t get_sfd_timestamp(void) REG(RFCORE_SFR_MTMSEL) = (REG(RFCORE_SFR_MTMSEL) & ~RFCORE_SFR_MTMSEL_MTMOVFSEL) | 0x00000010; sfd |= ((REG(RFCORE_SFR_MTMOVF0) & RFCORE_SFR_MTMOVF0_MTMOVF0) << 16); sfd |= ((REG(RFCORE_SFR_MTMOVF1) & RFCORE_SFR_MTMOVF1_MTMOVF1) << 24); + buffer = REG(RFCORE_SFR_MTMOVF2) & RFCORE_SFR_MTMOVF2_MTMOVF2; + sfd |= (buffer << 32); return (RTIMER_NOW() - RADIO_TO_RTIMER(timer_val - sfd)); } From 3e00ea55d1fce8a76df2ee2850541cac1fec65b4 Mon Sep 17 00:00:00 2001 From: Pere Tuset Date: Mon, 11 Apr 2016 15:32:29 +0200 Subject: [PATCH 173/374] Updated the OpenMote-CC2538 platform and examples. --- examples/openmote-cc2538/Makefile | 2 +- examples/openmote-cc2538/openmote-demo.c | 130 +++++++----- examples/openmote-cc2538/openmote-demo.gdb | 10 + examples/openmote-cc2538/project-conf.h | 8 +- examples/openmote-cc2538/test-adxl346.c | 86 -------- examples/openmote-cc2538/test-max44009.c | 86 -------- examples/openmote-cc2538/test-sht21.c | 92 --------- examples/openmote-cc2538/test-timer.c | 188 ----------------- .../openmote-cc2538/Makefile.openmote-cc2538 | 4 +- platform/openmote-cc2538/README.md | 189 ++++++++++++++++++ platform/openmote-cc2538/board.c | 5 +- platform/openmote-cc2538/board.h | 69 ++++--- platform/openmote-cc2538/contiki-conf.h | 75 +++++-- platform/openmote-cc2538/contiki-main.c | 38 ++-- platform/openmote-cc2538/dev/adxl346.c | 58 ++---- platform/openmote-cc2538/dev/adxl346.h | 46 ++++- platform/openmote-cc2538/dev/antenna.c | 56 ++---- platform/openmote-cc2538/dev/antenna.h | 31 ++- platform/openmote-cc2538/dev/button-sensor.c | 143 ++++++++----- platform/openmote-cc2538/dev/button-sensor.h | 41 ++-- platform/openmote-cc2538/dev/leds-arch.c | 20 +- platform/openmote-cc2538/dev/max44009.c | 71 +++---- platform/openmote-cc2538/dev/max44009.h | 42 +++- .../{smartrf-sensors.c => openmote-sensors.c} | 23 ++- .../openmote-cc2538/dev/openmote-sensors.h | 59 ++++++ platform/openmote-cc2538/dev/sht21.c | 81 ++++---- platform/openmote-cc2538/dev/sht21.h | 50 ++++- platform/openmote-cc2538/dev/tps62730.c | 27 +-- platform/openmote-cc2538/dev/tps62730.h | 32 ++- .../18-compile-arm-ports/Makefile | 1 + 30 files changed, 895 insertions(+), 868 deletions(-) create mode 100644 examples/openmote-cc2538/openmote-demo.gdb delete mode 100644 examples/openmote-cc2538/test-adxl346.c delete mode 100644 examples/openmote-cc2538/test-max44009.c delete mode 100644 examples/openmote-cc2538/test-sht21.c delete mode 100644 examples/openmote-cc2538/test-timer.c rename platform/openmote-cc2538/dev/{smartrf-sensors.c => openmote-sensors.c} (82%) create mode 100644 platform/openmote-cc2538/dev/openmote-sensors.h diff --git a/examples/openmote-cc2538/Makefile b/examples/openmote-cc2538/Makefile index 9f925fb70..e5e5eb4f3 100644 --- a/examples/openmote-cc2538/Makefile +++ b/examples/openmote-cc2538/Makefile @@ -1,6 +1,6 @@ DEFINES+=PROJECT_CONF_H=\"project-conf.h\" -CONTIKI_PROJECT = openmote-demo test-timer test-adxl346 test-max44009 test-sht21 +CONTIKI_PROJECT = openmote-demo all: $(CONTIKI_PROJECT) diff --git a/examples/openmote-cc2538/openmote-demo.c b/examples/openmote-cc2538/openmote-demo.c index 10a1c0762..f36c3a0b4 100644 --- a/examples/openmote-cc2538/openmote-demo.c +++ b/examples/openmote-cc2538/openmote-demo.c @@ -29,7 +29,7 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** * \addtogroup openmote-cc2538 * @{ @@ -37,65 +37,42 @@ * \defgroup openmote-examples OpenMote-CC2538 Example Projects * @{ * - * \defgroup openmote-demo OpenMote-CC2538 Demo Project - * - * Example project demonstrating the OpenMote-CC2538 functionality - * - * This assumes that you are using an OpenMote-CC2538 - * - * - Boot sequence: LEDs flashing, LED2 followed by LED3 then LED4 - * - etimer/clock : Every LOOP_INTERVAL clock ticks the LED defined as - * LEDS_PERIODIC will turn on - * - rtimer : Exactly LEDS_OFF_HYSTERISIS rtimer ticks later, - * LEDS_PERIODIC will turn back off - * - UART : Every LOOP_INTERVAL the EM will print something over the - * UART. Receiving an entire line of text over UART (ending - * in \\r) will cause LEDS_SERIAL_IN to toggle - * - Radio comms : BTN_SELECT sends a rime broadcast. Reception of a rime - * packet will toggle LEDs defined as LEDS_RF_RX + * Example project demonstrating the OpenMote-CC2538 functionality * * @{ * * \file - * Example demonstrating the OpenMote platform. + * Example demonstrating the OpenMote-CC2538 platform * \author - * Pere Tuset + * Pere Tuset */ +/*---------------------------------------------------------------------------*/ #include "contiki.h" #include "cpu.h" #include "sys/etimer.h" -#include "sys/rtimer.h" #include "dev/leds.h" #include "dev/uart.h" #include "dev/button-sensor.h" -#include "dev/watchdog.h" #include "dev/serial-line.h" #include "dev/sys-ctrl.h" #include "net/rime/broadcast.h" +#include "dev/adxl346.h" +#include "dev/max44009.h" +#include "dev/sht21.h" + #include #include /*---------------------------------------------------------------------------*/ -#define LOOP_INTERVAL CLOCK_SECOND -#define LEDS_OFF_HYSTERISIS (RTIMER_SECOND >> 1) -#define LEDS_PERIODIC LEDS_YELLOW -#define LEDS_BUTTON LEDS_RED -#define LEDS_SERIAL_IN LEDS_ORANGE -#define LEDS_REBOOT LEDS_ALL -#define LEDS_RF_RX (LEDS_YELLOW | LEDS_ORANGE) #define BROADCAST_CHANNEL 129 /*---------------------------------------------------------------------------*/ -static struct etimer et; -static struct rtimer rt; -static uint16_t counter; -/*---------------------------------------------------------------------------*/ PROCESS(openmote_demo_process, "OpenMote-CC2538 demo process"); AUTOSTART_PROCESSES(&openmote_demo_process); /*---------------------------------------------------------------------------*/ static void broadcast_recv(struct broadcast_conn *c, const linkaddr_t *from) { - leds_toggle(LEDS_RF_RX); + leds_toggle(LEDS_GREEN); printf("Received %u bytes: '0x%04x'\n", packetbuf_datalen(), *(uint16_t *)packetbuf_dataptr()); } @@ -103,43 +80,92 @@ broadcast_recv(struct broadcast_conn *c, const linkaddr_t *from) static const struct broadcast_callbacks bc_rx = { broadcast_recv }; static struct broadcast_conn bc; /*---------------------------------------------------------------------------*/ -void -rt_callback(struct rtimer *t, void *ptr) -{ - leds_off(LEDS_PERIODIC); -} -/*---------------------------------------------------------------------------*/ PROCESS_THREAD(openmote_demo_process, ev, data) { + static struct etimer et; + static unsigned int raw, counter; + static uint8_t adxl346_present, max44009_present, sht21_present; + static float light, temperature, humidity; PROCESS_EXITHANDLER(broadcast_close(&bc)) PROCESS_BEGIN(); + adxl346_init(); + adxl346_present = adxl346_is_present(); + if(!adxl346_present) { + printf("ADXL346 sensor is NOT present!\n"); + leds_on(LEDS_YELLOW); + } + + max44009_init(); + max44009_present = max44009_is_present(); + if(!max44009_present) { + printf("MAX44009 sensor is NOT present!\n"); + leds_on(LEDS_ORANGE); + } + + sht21_init(); + sht21_present = sht21_is_present(); + if(!sht21_present) { + printf("SHT21 sensor is NOT present!\n"); + leds_on(LEDS_RED); + } + counter = 0; broadcast_open(&bc, BROADCAST_CHANNEL, &bc_rx); + printf("****************************************\n"); + while(1) { etimer_set(&et, CLOCK_SECOND); PROCESS_YIELD(); if(ev == PROCESS_EVENT_TIMER) { - leds_on(LEDS_PERIODIC); - printf("Counter = 0x%08x\n", counter); - - etimer_set(&et, CLOCK_SECOND); - rtimer_set(&rt, RTIMER_NOW() + LEDS_OFF_HYSTERISIS, 1, - rt_callback, NULL); - } else if(ev == sensors_event) { - if(data == &button_user_sensor) { - packetbuf_copyfrom(&counter, sizeof(counter)); - broadcast_send(&bc); + if(adxl346_present) { + leds_on(LEDS_YELLOW); + raw = adxl346_read_x(); + printf("X Acceleration: %u\n", raw); + raw = adxl346_read_y(); + printf("Y Acceleration: %u\n", raw); + raw = adxl346_read_z(); + printf("Z Acceleration: %u\n", raw); + leds_off(LEDS_YELLOW); + } + + if(max44009_present) { + leds_on(LEDS_ORANGE); + raw = max44009_read_light(); + light = max44009_convert_light(raw); + printf("Light: %u.%ulux\n", (unsigned int)light, (unsigned int)(light * 100) % 100); + leds_off(LEDS_ORANGE); + } + + if(sht21_present) { + leds_on(LEDS_RED); + raw = sht21_read_temperature(); + temperature = sht21_convert_temperature(raw); + printf("Temperature: %u.%uC\n", (unsigned int)temperature, (unsigned int)(temperature * 100) % 100); + raw = sht21_read_humidity(); + humidity = sht21_convert_humidity(raw); + printf("Rel. humidity: %u.%u%%\n", (unsigned int)humidity, (unsigned int)(humidity * 100) % 100); + leds_off(LEDS_RED); + } + + printf("****************************************\n"); + } + + if(ev == sensors_event) { + if(data == &button_sensor) { + if(button_sensor.value(BUTTON_SENSOR_VALUE_TYPE_LEVEL) == + BUTTON_SENSOR_PRESSED_LEVEL) { + leds_toggle(LEDS_GREEN); + packetbuf_copyfrom(&counter, sizeof(counter)); + broadcast_send(&bc); + } } - } else if(ev == serial_line_event_message) { - leds_toggle(LEDS_SERIAL_IN); } - counter++; } PROCESS_END(); diff --git a/examples/openmote-cc2538/openmote-demo.gdb b/examples/openmote-cc2538/openmote-demo.gdb new file mode 100644 index 000000000..43cbb5530 --- /dev/null +++ b/examples/openmote-cc2538/openmote-demo.gdb @@ -0,0 +1,10 @@ +target remote localhost:2331 +monitor interface JTAG +monitor endian little +monitor speed auto +monitor flash device = CC2538SF53 +monitor flash breakpoints = 1 +monitor flash download = 1 +monitor reset +load +continue diff --git a/examples/openmote-cc2538/project-conf.h b/examples/openmote-cc2538/project-conf.h index 126ea1058..718ce668d 100644 --- a/examples/openmote-cc2538/project-conf.h +++ b/examples/openmote-cc2538/project-conf.h @@ -10,7 +10,6 @@ * 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 copyright holder nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. @@ -35,12 +34,13 @@ * \file * Project specific configuration defines for the basic RE-Mote examples */ +/*---------------------------------------------------------------------------*/ #ifndef PROJECT_CONF_H_ #define PROJECT_CONF_H_ - +/*---------------------------------------------------------------------------*/ #define BROADCAST_CHANNEL 129 #define NETSTACK_CONF_RDC nullrdc_driver - +/*---------------------------------------------------------------------------*/ #endif /* PROJECT_CONF_H_ */ - +/*---------------------------------------------------------------------------*/ /** @} */ diff --git a/examples/openmote-cc2538/test-adxl346.c b/examples/openmote-cc2538/test-adxl346.c deleted file mode 100644 index 1a750a67c..000000000 --- a/examples/openmote-cc2538/test-adxl346.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2014, OpenMote Technologies, S.L. - * 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. - * - */ - -/** - * \addtogroup openmote-examples - * @{ - * - * \defgroup openmote-adxl346 - * - * This example tests the correct functionality of the ADXL346 acceleration - * sensor using the I2C bus. - * - * @{ - * - * \file - * Testing the ADXL346 sensor on the OpenMote-CC2538 platform. - * \author - * Pere Tuset - */ - -#include "contiki.h" -#include "dev/adxl346.h" - -#include - -PROCESS(test_adxl346_process, "ADXL346 test"); -AUTOSTART_PROCESSES(&test_adxl346_process); - -PROCESS_THREAD(test_adxl346_process, ev, data) -{ - static struct etimer et; - static unsigned acceleration; - - PROCESS_BEGIN(); - adxl346_init(); - - if (!adxl346_is_present()) { - leds_on(LEDS_ORANGE); - } - - while(1) { - etimer_set(&et, CLOCK_SECOND); - - PROCESS_YIELD(); - - if (ev == PROCESS_EVENT_TIMER) { - acceleration = adxl346_read_x(); - printf("X Acceleration: %u\n", acceleration); - acceleration = adxl346_read_y(); - printf("Y Acceleration: %u\n", acceleration); - acceleration = adxl346_read_z(); - printf("Z Acceleration: %u\n", acceleration); - } - } - - PROCESS_END(); -} diff --git a/examples/openmote-cc2538/test-max44009.c b/examples/openmote-cc2538/test-max44009.c deleted file mode 100644 index 8085283ca..000000000 --- a/examples/openmote-cc2538/test-max44009.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2014, OpenMote Technologies, S.L. - * 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. - * - */ - -/** - * \addtogroup openmote-examples - * @{ - * - * \defgroup openmote-max44009 - * - * This example tests the correct functionality of the MAX44009 light - * sensor using the I2C bus. - * - * @{ - * - * \file - * Testing the MAX44009 sensor on the OpenMote-CC2538 platform. - * \author - * Pere Tuset - */ - -#include "contiki.h" -#include "dev/max44009.h" -#include "dev/leds.h" -#include - -PROCESS(test_max44009_process, "MAX44009 test"); -AUTOSTART_PROCESSES(&test_max44009_process); - -PROCESS_THREAD(test_max44009_process, ev, data) -{ - static struct etimer et; - static unsigned raw; - static float light; - - PROCESS_BEGIN(); - max44009_init(); - -if (!max44009_is_present()) { - leds_on(LEDS_ORANGE); - } - - while(1) { - etimer_set(&et, CLOCK_SECOND); - - PROCESS_YIELD(); - - if (ev == PROCESS_EVENT_TIMER) { - leds_on(LEDS_YELLOW); - raw = max44009_read_light(); - light = max44009_convert_light(raw); - printf("Light: %u.%u\n", (unsigned int) light, (unsigned int) (light * 100) % 100); - leds_off(LEDS_YELLOW); - } - } - - PROCESS_END(); -} diff --git a/examples/openmote-cc2538/test-sht21.c b/examples/openmote-cc2538/test-sht21.c deleted file mode 100644 index cefdb3266..000000000 --- a/examples/openmote-cc2538/test-sht21.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2014, OpenMote Technologies, S.L. - * 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. - * - */ - -/** - * \addtogroup openmote-examples - * @{ - * - * \defgroup openmote-sht21 - * - * This example tests the correct functionality of the SHT21 temperature - * and humidity sensor using the I2C bus. - * - * @{ - * - * \file - * Testing the SHT21 sensor on the OpenMote-CC2538 platform. - * \author - * Pere Tuset - */ - -#include "contiki.h" -#include "dev/sht21.h" -#include "dev/leds.h" -#include "sys/etimer.h" - -#include - -PROCESS(test_sht21_process, "SHT21 test"); -AUTOSTART_PROCESSES(&test_sht21_process); - -PROCESS_THREAD(test_sht21_process, ev, data) -{ - static struct etimer et; - static unsigned raw; - static float temperature; - static float humidity; - - PROCESS_BEGIN(); - sht21_init(); - - if (!sht21_is_present()) { - leds_on(LEDS_ORANGE); - } - - while(1) { - etimer_set(&et, CLOCK_SECOND); - - PROCESS_YIELD(); - - if (ev == PROCESS_EVENT_TIMER) { - leds_on(LEDS_YELLOW); - raw = sht21_read_temperature(); - temperature = sht21_convert_temperature(raw); - printf("Temperature: %u.%u degrees Celsius\n", (unsigned int) temperature, (unsigned int) (temperature * 100) % 100); - raw = sht21_read_humidity(); - humidity = sht21_convert_humidity(raw); - printf("Rel. humidity: %u.%u%%\n", (unsigned int) humidity, (unsigned int) (humidity * 100) % 100); - leds_off(LEDS_YELLOW ); - } - } - - PROCESS_END(); -} diff --git a/examples/openmote-cc2538/test-timer.c b/examples/openmote-cc2538/test-timer.c deleted file mode 100644 index 3eb8ff2ff..000000000 --- a/examples/openmote-cc2538/test-timer.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2014, OpenMote Technologies, S.L. - * 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. - * - */ - -/** - * \addtogroup openmote-examples - * @{ - * - * \defgroup openmote-timers OpenMote-CC2538 Timer Test Project - * - * This example tests the correct functionality of clocks and timers. - * - * More specifically, it tests clock_seconds, rtimers, etimers and - * clock_delay_usec. - * - * This is largely-based on the same example of the cc2530 port. - * @{ - * - * \file - * Tests related to clocks and timers. - * \author - * Pere Tuset - */ - -#include "contiki.h" -#include "sys/clock.h" -#include "sys/rtimer.h" -#include "dev/leds.h" - -#include -/*---------------------------------------------------------------------------*/ -#define TIMER_TEST_CONF_TEST_CLOCK_DELAY_USEC 1 -#define TIMER_TEST_CONF_TEST_RTIMER 1 -#define TIMER_TEST_CONF_TEST_ETIMER 1 -#define TIMER_TEST_CONF_TEST_CLOCK_SECONDS 1 -/*---------------------------------------------------------------------------*/ -static struct etimer et; - -#if TIMER_TEST_CONF_TEST_CLOCK_DELAY_USEC -static rtimer_clock_t start_count, end_count, diff; -#endif - -#if TIMER_TEST_CONF_TEST_CLOCK_SECONDS -static unsigned long sec; -#endif - -#if TIMER_TEST_CONF_TEST_ETIMER -static clock_time_t count; -#endif - -#if TIMER_TEST_CONF_TEST_RTIMER -static struct rtimer rt; -rtimer_clock_t rt_now, rt_for; -static clock_time_t ct; -#endif - -static uint8_t i; -/*---------------------------------------------------------------------------*/ -PROCESS(timer_test_process, "Timer test process"); -AUTOSTART_PROCESSES(&timer_test_process); -/*---------------------------------------------------------------------------*/ -#if TIMER_TEST_CONF_TEST_RTIMER -void -rt_callback(struct rtimer *t, void *ptr) -{ - rt_now = RTIMER_NOW(); - ct = clock_time(); - printf("Task called at %lu (clock = %lu)\n", rt_now, ct); -} -#endif -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(timer_test_process, ev, data) -{ - - PROCESS_BEGIN(); - - etimer_set(&et, 2 * CLOCK_SECOND); - - PROCESS_YIELD(); - -#if TIMER_TEST_CONF_TEST_CLOCK_DELAY_USEC - printf("-----------------------------------------\n"); - printf("clock_delay_usec test, (10,000 x i) usec:\n"); - printf("N.B. clock_delay_usec is more accurate than rtimers\n"); - i = 1; - while(i < 7) { - start_count = RTIMER_NOW(); - clock_delay_usec(10000 * i); - end_count = RTIMER_NOW(); - diff = end_count - start_count; - printf("Requested: %u usec, Real: %lu rtimer ticks = ~%lu us\n", - 10000 * i, diff, diff * 1000000 / RTIMER_SECOND); - i++; - } -#endif - -#if TIMER_TEST_CONF_TEST_RTIMER - printf("-----------------------------------------\n"); - printf("Rtimer Test, 1 sec (%u rtimer ticks):\n", RTIMER_SECOND); - i = 0; - while(i < 5) { - etimer_set(&et, 2 * CLOCK_SECOND); - printf("=======================\n"); - ct = clock_time(); - rt_now = RTIMER_NOW(); - rt_for = rt_now + RTIMER_SECOND; - printf("Now=%lu (clock = %lu) - For=%lu\n", rt_now, ct, rt_for); - if(rtimer_set(&rt, rt_for, 1, rt_callback, NULL) != RTIMER_OK) { - printf("Error setting\n"); - } - - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - i++; - } -#endif - -#if TIMER_TEST_CONF_TEST_ETIMER - printf("-----------------------------------------\n"); - printf("Clock tick and etimer test, 1 sec (%u clock ticks):\n", - CLOCK_SECOND); - i = 0; - while(i < 10) { - etimer_set(&et, CLOCK_SECOND); - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - etimer_reset(&et); - - count = clock_time(); - printf("%lu ticks\n", count); - - leds_toggle(LEDS_RED); - i++; - } -#endif - -#if TIMER_TEST_CONF_TEST_CLOCK_SECONDS - printf("-----------------------------------------\n"); - printf("Clock seconds test (5s):\n"); - i = 0; - while(i < 10) { - etimer_set(&et, 5 * CLOCK_SECOND); - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - etimer_reset(&et); - - sec = clock_seconds(); - printf("%lu seconds\n", sec); - - leds_toggle(LEDS_GREEN); - i++; - } -#endif - - printf("Done!\n"); - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ -/** - * @} - * @} - */ diff --git a/platform/openmote-cc2538/Makefile.openmote-cc2538 b/platform/openmote-cc2538/Makefile.openmote-cc2538 index 878b81877..3439a3211 100644 --- a/platform/openmote-cc2538/Makefile.openmote-cc2538 +++ b/platform/openmote-cc2538/Makefile.openmote-cc2538 @@ -10,7 +10,7 @@ PLATFORM_ROOT_DIR = $(CONTIKI)/platform/$(TARGET) ### Include CONTIKI_TARGET_SOURCEFILES += contiki-main.c board.c -CONTIKI_TARGET_SOURCEFILES += leds-arch.c button-sensor.c smartrf-sensors.c +CONTIKI_TARGET_SOURCEFILES += leds-arch.c button-sensor.c openmote-sensors.c CONTIKI_TARGET_SOURCEFILES += antenna.c adxl346.c max44009.c sht21.c tps62730.c CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) @@ -31,7 +31,7 @@ MODULES += core/net core/net/mac \ core/net/llsec core/net/llsec/noncoresec PYTHON = python -BSL_FLAGS += -e -w --bootloader-invert-lines -b 115200 -v +BSL_FLAGS += -e -w -v -b 450000 ifdef PORT BSL_FLAGS += -p $(PORT) diff --git a/platform/openmote-cc2538/README.md b/platform/openmote-cc2538/README.md index e69de29bb..2f3ee7d07 100644 --- a/platform/openmote-cc2538/README.md +++ b/platform/openmote-cc2538/README.md @@ -0,0 +1,189 @@ +OpenMote-CC2538 platform +======================== +The OpenMote-CC2538 is based on TI's CC2538 SoC (System on Chip), featuring an ARM Cortex-M3 running at 16/32 MHz and with 32 kbytes of RAM and 512 kbytes of FLASH. It has the following key features: + + * Standard Cortex M3 peripherals (NVIC, SCB, SysTick) + * Sleep Timer (underpins rtimers) + * SysTick (underpins the platform clock and Contiki's timers infrastructure) + * RF (2.4 GHz) + * UART + * Watchdog (in watchdog mode) + * USB (in CDC-ACM) + * uDMA Controller (RAM to/from USB and RAM to/from RF) + * Random number generator + * Low Power Modes + * General-Purpose Timers + * ADC + * Cryptoprocessor (AES-ECB/CBC/CTR/CBC-MAC/GCM/CCM-128/192/256, SHA-256) + * Public Key Accelerator (ECDH, ECDSA) + * Flash-based port of Coffee + * PWM + * Built-in core temperature and battery sensor + +Requirements +============ +To start using Contiki with the OpenMote-CC2538, the following is required: + + * An OpenMote-CC2538 board. + * A toolchain to compile Contiki for the CC2538. + * Drivers so that your OS can communicate with your hardware. + * Software to upload images to the CC2538. + +Install a Toolchain +------------------- +The toolchain used to build contiki is arm-gcc, also used by other arm-based Contiki ports. If you are using Instant Contiki, you may have a version pre-installed in your system. + +The platform is currently being used/tested with "GNU Tools for ARM Embedded Processors" (). The current recommended version and the one being used by Contiki's regression tests on Travis is shown below. + + $ arm-none-eabi-gcc --version + arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 5.2.1 20151202 (release) [ARM/embedded-5-branch revision 231848] + Copyright (C) 2015 Free Software Foundation, Inc. + This is free software; see the source for copying conditions. There is NO + warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Software to Program the Nodes +----------------------------- +The OpenMote-CC2538 can be programmed via the jtag interface or via the serial boot loader on the chip. + +The OpenMote-CC2538 has a mini JTAG 10-pin male header, compatible with the `SmartRF06` development board, which can be used to flash and debug the platforms. Alternatively one could use the `JLink` programmer with a 20-to-10 pin converter like the following: . + +The serial boot loader on the chip is exposed to the user via the USB interface. To activate the bootloader short the ON/SLEEP pin to GND and then press the reset button. + +Instructions to flash for different OS are given below. + +* On Windows: + * Nodes can be programmed with TI's ArmProgConsole or the SmartRF Flash Programmer 2. The README should be self-explanatory. With ArmProgConsole, upload the file with a `.bin` extension. + * Nodes can also be programmed via the serial boot loader in the cc2538. In `tools/cc2538-bsl/` you can find `cc2538-bsl.py` python script, which can download firmware to your node via a serial connection. If you use this option you just need to make sure you have a working version of python installed. You can read the README in the same directory for more info. + +* On Linux: + * Nodes can be programmed with TI's [UniFlash] tool. With UniFlash, use the file with `.elf` extension. + * Nodes can also be programmed via the serial boot loader in the cc2538. No extra software needs to be installed. + +* On OSX: + * The `cc2538-bsl.py` script in `tools/cc2538-bsl/` is the only option. No extra software needs to be installed. + +Use the Port +============ +The following examples are intended to work off-the-shelf: + +* Examples under `examples/openmote-cc2538` +* MQTT example `examples/cc2538dk/mqtt-demo` +* Border router: `examples/ipv6/rpl-border-router` +* Webserver: `examples/webserver-ipv6` +* CoAP example: `examples/er-rest-example` + +Build your First Examples +------------------------- +It is recommended to start with the `openmote-demo`, it is a simple example that demonstrates the OpenMote-CC2538 features, such as the built-in sensors, LEDs, user button and radio (using RIME broadcast). + +The `Makefile.target` includes the `TARGET=` argument, predefining which is the target platform to compile for, it is automatically included at compilation. + +To generate or override an existing one, you can run: + +`make TARGET=openmote-cc2538 savetarget` + +Then you can just run `make` to compile an application, otherwise you will need to do `make TARGET=openmote-cc2538`. + +If you want to upload the compiled firmware to a node via the serial boot loader you need first to either manually enable the boot loader. + +Then use `make openmote-demo.upload`. + +The `PORT` argument could be used to specify in which port the device is connected, in case we have multiple devices connected at the same time. + +To generate an assembly listing of the compiled firmware, run `make openmote-demo.lst`. This may be useful for debugging or optimizing your application code. To intersperse the C source code within the assembly listing, you must instruct the compiler to include debugging information by adding `CFLAGS += -g` to the project Makefile and rebuild by running `make clean openmote-demo.lst`. + +To enable printing debug output to your console, use the `make login` to get the information over the USB programming/debugging port, or alternatively use `make serialview` to also add a timestamp in each print. + +Node IEEE/RIME/IPv6 Addresses +----------------------------- + +Nodes will generally autoconfigure their IPv6 address based on their IEEE address. The IEEE address can be read directly from the CC2538 Info Page, or it can be hard-coded. Additionally, the user may specify a 2-byte value at build time, which will be used as the IEEE address' 2 LSBs. + +To configure the IEEE address source location (Info Page or hard-coded), use the `IEEE_ADDR_CONF_HARDCODED` define in contiki-conf.h: + +* 0: Info Page +* 1: Hard-coded + +If `IEEE_ADDR_CONF_HARDCODED` is defined as 1, the IEEE address will take its value from the `IEEE_ADDR_CONF_ADDRESS` define. If `IEEE_ADDR_CONF_HARDCODED` is defined as 0, the IEEE address can come from either the primary or secondary location in the Info Page. To use the secondary address, define `IEEE_ADDR_CONF_USE_SECONDARY_LOCATION` as 1. + +Additionally, you can override the IEEE's 2 LSBs, by using the `NODEID` make variable. The value of `NODEID` will become the value of the `IEEE_ADDR_NODE_ID` pre-processor define. If `NODEID` is not defined, `IEEE_ADDR_NODE_ID` will not get defined either. For example: + + make NODEID=0x79ab + +This will result in the 2 last bytes of the IEEE address getting set to 0x79 0xAB + +Note: Some early production devices do not have am IEEE address written on the Info Page. For those devices, using value 0 above will result in a Rime address of all 0xFFs. If your device is in this category, define `IEEE_ADDR_CONF_HARDCODED` to 1 and specify `NODEID` to differentiate between devices. + +Low-Power Modes +--------------- +The CC2538 port supports power modes for low energy consumption. The SoC will enter a low power mode as part of the main loop when there are no more events to service. + +LPM support can be disabled in its entirety by setting `LPM_CONF_ENABLE` to 0 in `contiki-conf.h` or `project-conf.h`. + +The Low-Power module uses a simple heuristic to determine the best power mode, depending on anticipated Deep Sleep duration and the state of various peripherals. + +In a nutshell, the algorithm first answers the following questions: + +* Is the RF off? +* Are all registered peripherals permitting PM1+? +* Is the Sleep Timer scheduled to fire an interrupt? + +If the answer to any of the above question is "No", the SoC will enter PM0. If the answer to all questions is "Yes", the SoC will enter one of PMs 0/1/2 depending on the expected Deep Sleep duration and subject to user configuration and application requirements. + +At runtime, the application may enable/disable some Power Modes by making calls to `lpm_set_max_pm()`. For example, to avoid PM2 an application could call `lpm_set_max_pm(1)`. Subsequently, to re-enable PM2 the application would call `lpm_set_max_pm(2)`. + +The LPM module can be configured with a hard maximum permitted power mode. + + #define LPM_CONF_MAX_PM N + +Where N corresponds to the PM number. Supported values are 0, 1, 2. PM3 is not supported. Thus, if the value of the define is 1, the SoC will only ever enter PMs 0 or 1 but never 2 and so on. + +The configuration directive `LPM_CONF_MAX_PM` sets a hard upper boundary. For instance, if `LPM_CONF_MAX_PM` is defined as 1, calls to `lpm_set_max_pm()` can only enable/disable PM1. In this scenario, PM2 can not be enabled at runtime. + +When setting `LPM_CONF_MAX_PM` to 0 or 1, the entire SRAM will be available. Crucially, when value 2 is used the linker will automatically stop using the SoC's SRAM non-retention area, resulting in a total available RAM of 16 kbytes instead of 32 kbytes. + +### LPM and Duty Cycling Driver +LPM is highly related to the operations of the Radio Duty Cycling (RDC) driver of the Contiki network stack and will work correctly with ContikiMAC and NullRDC. + +* With ContikiMAC, PMs 0/1/2 are supported subject to user configuration. +* When NullRDC is in use, the radio will be always on. As a result, the algorithm discussed above will always choose PM0 and will never attempt to drop to PM1/2. + +Build headless nodes +-------------------- +It is possible to turn off all character I/O for nodes not connected to a PC. Doing this will entirely disable the UART as well as the USB controller, preserving energy in the long term. The define used to achieve this is (1: Quiet, 0: Normal output): + + #define CC2538_CONF_QUIET 0 + +Setting this define to 1 will automatically set the following to 0: + +* `USB_SERIAL_CONF_ENABLE` +* `UART_CONF_ENABLE` +* `STARTUP_CONF_VERBOSE` + +Code Size Optimisations +----------------------- +The build system currently uses optimization level `-Os`, which is controlled indirectly through the value of the `SMALL` make variable. This value can be overridden by example makefiles, or it can be changed directly in `platform/openmote-cc2538/Makefile.openmote-cc2538`. + +Historically, the `-Os` flag has caused problems with some toolchains. If you are using one of the toolchains documented in this README, you should be able to use it without issues. If for whatever reason you do come across problems, try setting `SMALL=0` or replacing `-Os` with `-O2` in `cpu/cc2538/Makefile.cc2538`. + +Doxygen Documentation +===================== +This port's code has been documented with doxygen. To build the documentation, navigate to `$(CONTIKI)/doc` and run `make`. This will build the entire contiki documentation and may take a while. + +If you want to build this platform's documentation only and skip the remaining platforms, run this: + + make basedirs="platform/openmote-cc2538 core cpu/cc2538 examples/openmote-cc2538 examples/openmote-cc2538" + +Once you've built the docs, open `$(CONTIKI)/doc/html/index.html` and enjoy. + +Other Versions of this Guide +============================ +If you prefer this guide in other formats, use the excellent [pandoc] to convert it. + +* **pdf**: `pandoc -s --toc README.md -o README.pdf` +* **html**: `pandoc -s --toc README.md -o README.html` + +Maintainers +=========== +The OpenMote-CC2538 is maintained by OpenMote Technologies. +Main contributor: Pere Tuset diff --git a/platform/openmote-cc2538/board.c b/platform/openmote-cc2538/board.c index 0b565b43c..c27812a9a 100644 --- a/platform/openmote-cc2538/board.c +++ b/platform/openmote-cc2538/board.c @@ -26,6 +26,9 @@ * 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. + * */ /*---------------------------------------------------------------------------*/ /** @@ -34,7 +37,6 @@ * * \file * Board-initialisation for the OpenMote-CC2538 platform - * */ /*---------------------------------------------------------------------------*/ #include "contiki-conf.h" @@ -58,4 +60,3 @@ board_init() /** * @} */ - diff --git a/platform/openmote-cc2538/board.h b/platform/openmote-cc2538/board.h index 08538a995..9c9a62bc1 100644 --- a/platform/openmote-cc2538/board.h +++ b/platform/openmote-cc2538/board.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -10,7 +10,6 @@ * 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 copyright holder nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. @@ -27,22 +26,24 @@ * 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. + * */ - +/* -------------------------------------------------------------------------- */ /** - * \addtogroup platform + * \addtogroup openmote-cc2538 * @{ * - * \defgroup openmote - * * \file - * Header file with definitions related to the I/O connections on the - * OpenMote-CC2538 platform. This file provides connectivity information on - * LEDs, Buttons, UART and other peripherals. + * This file provides connectivity information on LEDs, Buttons, UART and + * other OpenMote-CC2538 peripherals. * - * \note - * Do not include this file directly. It gets included by contiki-conf - * after all relevant directives have been set. + * This file can be used as the basis to configure other platforms using the + * cc2538 SoC. + * + * \note Do not include this file directly. It gets included by contiki-conf + * after all relevant directives have been set. */ #ifndef BOARD_H_ @@ -69,7 +70,7 @@ #undef LEDS_RED #undef LEDS_CONF_ALL -#define LEDS_RED 16 /**< LED1 (Red) -> PC4 */ +#define LEDS_RED 16 /**< LED1 (Red) -> PC4 */ #define LEDS_YELLOW 64 /**< LED2 (Yellow) -> PC6 */ #define LEDS_GREEN 128 /**< LED3 (Green) -> PC7 */ #define LEDS_ORANGE 32 /**< LED4 (Orange) -> PC5 */ @@ -102,15 +103,17 @@ */ #define UART0_RX_PORT GPIO_A_NUM #define UART0_RX_PIN 0 - #define UART0_TX_PORT GPIO_A_NUM #define UART0_TX_PIN 1 -#define UART1_CTS_PORT GPIO_B_NUM -#define UART1_CTS_PIN 0 - -#define UART1_RTS_PORT GPIO_D_NUM -#define UART1_RTS_PIN 3 +#define UART1_RX_PORT GPIO_B_NUM +#define UART1_RX_PIN 0 +#define UART1_TX_PORT GPIO_D_NUM +#define UART1_TX_PIN 3 +#define UART1_CTS_PORT (-1) +#define UART1_CTS_PIN (-1) +#define UART1_RTS_PORT (-1) +#define UART1_RTS_PIN (-1) /** @} */ /*---------------------------------------------------------------------------*/ /** \name OpenMote-CC2538 Button configuration @@ -128,9 +131,11 @@ /** @} */ /*---------------------------------------------------------------------------*/ /** - * \name SPI configuration + * \name SPI (SSI0) configuration * - * These values configure which CC2538 pins to use for the SPI lines. + * These values configure which CC2538 pins to use for the SPI (SSI0) lines. + * The SSI0 is currently used to interface with the Ethernet driver (ENC28J60) + * on the OpenBase board. * @{ */ #define SPI_CLK_PORT GPIO_A_NUM @@ -139,8 +144,21 @@ #define SPI_MOSI_PIN 5 #define SPI_MISO_PORT GPIO_A_NUM #define SPI_MISO_PIN 4 -#define SPI_SEL_PORT GPIO_A_NUM -#define SPI_SEL_PIN 3 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SPI (SSI1) configuration + * + * These values configure which CC2538 pins to use for the SPI (SSI1) lines. + * The SSI1 is currently not used. + * @{ + */ +#define SPI1_CLK_PORT GPIO_C_NUM +#define SPI1_CLK_PIN 4 +#define SPI1_TX_PORT GPIO_C_NUM +#define SPI1_TX_PIN 5 +#define SPI1_RX_PORT GPIO_C_NUM +#define SPI1_RX_PIN 6 /** @} */ /*---------------------------------------------------------------------------*/ /** @@ -163,4 +181,7 @@ /** @} */ /*---------------------------------------------------------------------------*/ #endif /* BOARD_H_ */ -/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/platform/openmote-cc2538/contiki-conf.h b/platform/openmote-cc2538/contiki-conf.h index 44a15e539..6c0349025 100644 --- a/platform/openmote-cc2538/contiki-conf.h +++ b/platform/openmote-cc2538/contiki-conf.h @@ -1,9 +1,48 @@ +/* + * Copyright (c) 2014, OpenMote Technologies, S.L. + * 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. + * + */ +/*---------------------------------------------------------------------------*/ /** - * \addtogroup openmote + * \addtogroup openmote-cc2538 * @{ * + * \defgroup openmote-cc2538-platforms OpenMote-CC2538 platform + * + * The OpenMote-CC2538 platform was designed at UC Berkeley in 2013 and + * is comercialized by OpenMote Technologies since 2014. It is the first + * commercial platform based on the powerful TI CC2538 SoC. It uses a + * XBee form-factor to ease prototyping. + * * \file - * Configuration for the OpenMote-CC2538 platform. + * Configuration for the OpenMote-CC2538 platform */ #ifndef CONTIKI_CONF_H_ #define CONTIKI_CONF_H_ @@ -48,7 +87,7 @@ typedef uint32_t rtimer_clock_t; #ifndef FLASH_CCA_CONF_BOOTLDR_BACKDOOR #define FLASH_CCA_CONF_BOOTLDR_BACKDOOR 1 /** 0); - /* We have serviced all pending events. Enter a Low-Power mode. */ lpm_enter(); } } /*---------------------------------------------------------------------------*/ - /** * @} * @} diff --git a/platform/openmote-cc2538/dev/adxl346.c b/platform/openmote-cc2538/dev/adxl346.c index bdb934d2d..650b7cfda 100644 --- a/platform/openmote-cc2538/dev/adxl346.c +++ b/platform/openmote-cc2538/dev/adxl346.c @@ -29,29 +29,33 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** - * \addtogroup platform + * \addtogroup openmote-adxl346-sensor * @{ * - * \defgroup openmote - * * \file - * Driver for the ADXL346 acceleration sensor in OpenMote-CC2538. + * Driver for the ADXL346 acceleration sensor * * \author * Pere Tuset */ - /*---------------------------------------------------------------------------*/ #include "dev/i2c.h" #include "dev/adxl346.h" /*---------------------------------------------------------------------------*/ -/* ADDRESS AND IDENTIFIER */ +/** + * \name ADXL346 address and device identifier + * @{ + */ #define ADXL346_ADDRESS (0x53) #define ADXL346_DEVID_VALUE (0xE6) - -/* REGISTER ADDRESSES */ +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name ADXL346 register addresses + * @{ + */ #define ADXL346_DEVID_ADDR (0x00) #define ADXL346_THRES_TAP_ADDR (0x1D) #define ADXL346_OFSX_ADDR (0x1E) @@ -85,8 +89,12 @@ #define ADXL346_TAP_SIGN_ADDR (0x3A) #define ADXL346_ORIENT_CONF_ADDR (0x3B) #define ADXL346_ORIENT_ADDR (0x3C) - -/* INT_ENABLE/INT_MAP/INT_SOURCE */ +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name ADXL346 register values + * @{ + */ #define ADXL346_INT_ENABLE_DATA_READY (1 << 7) #define ADXL346_INT_ENABLE_SINGLE_TAP (1 << 6) #define ADXL346_INT_ENABLE_DOUBLE_TAP (1 << 5) @@ -96,7 +104,6 @@ #define ADXL346_INT_ENABLE_WATERMARK (1 << 1) #define ADXL346_INT_ENABLE_OVERRUN (1 << 0) -/* ACT_INACT_CONTROL */ #define ADXL346_ACT_INACT_CTL_ACT_ACDC (1 << 7) #define ADXL346_ACT_INACT_CTL_ACT_X_EN (1 << 6) #define ADXL346_ACT_INACT_CTL_ACT_Y_EN (1 << 5) @@ -106,13 +113,11 @@ #define ADXL346_ACT_INACT_CTL_INACT_Y_EN (1 << 1) #define ADXL346_ACT_INACT_CTL_INACT_Z_EN (1 << 0) -/* TAP_AXES */ #define ADXL346_TAP_AXES_SUPPRESS (1 << 3) #define ADXL346_TAP_AXES_TAP_X_EN (1 << 2) #define ADXL346_TAP_AXES_TAP_Y_EN (1 << 1) #define ADXL346_TAP_AXES_TAP_Z_EN (1 << 0) -/* ACT_TAP_STATUS */ #define ADXL346_ACT_TAP_STATUS_ACT_X_SRC (1 << 6) #define ADXL346_ACT_TAP_STATUS_ACT_Y_SRC (1 << 5) #define ADXL346_ACT_TAP_STATUS_ACT_Z_SRC (1 << 4) @@ -121,18 +126,15 @@ #define ADXL346_ACT_TAP_STATUS_TAP_Y_SRC (1 << 1) #define ADXL346_ACT_TAP_STATUS_TAP_Z_SRC (1 << 0) -/* BW_RATE */ #define ADXL346_BW_RATE_POWER (1 << 4) #define ADXL346_BW_RATE_RATE(x) ((x) & 0x0F) -/* POWER CONTROL */ #define ADXL346_POWER_CTL_LINK (1 << 5) #define ADXL346_POWER_CTL_AUTO_SLEEP (1 << 4) #define ADXL346_POWER_CTL_MEASURE (1 << 3) #define ADXL346_POWER_CTL_SLEEP (1 << 2) #define ADXL346_POWER_CTL_WAKEUP(x) ((x) & 0x03) -/* DATA_FORMAT */ #define ADXL346_DATA_FORMAT_SELF_TEST (1 << 7) #define ADXL346_DATA_FORMAT_SPI (1 << 6) #define ADXL346_DATA_FORMAT_INT_INVERT (1 << 5) @@ -143,18 +145,13 @@ #define ADXL346_DATA_FORMAT_RANGE_PM_4g (1) #define ADXL346_DATA_FORMAT_RANGE_PM_8g (2) #define ADXL346_DATA_FORMAT_RANGE_PM_16g (3) +/** @} */ /*---------------------------------------------------------------------------*/ -/** - * - */ void adxl346_init(void) { uint8_t config[2]; - i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, - I2C_SCL_NORMAL_BUS_SPEED); - config[0] = ADXL346_BW_RATE_ADDR; config[1] = (ADXL346_BW_RATE_RATE(11)); i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); @@ -170,17 +167,11 @@ adxl346_init(void) i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); } /*---------------------------------------------------------------------------*/ -/** - * - */ void adxl346_reset(void) { } /*---------------------------------------------------------------------------*/ -/** - * - */ uint8_t adxl346_is_present(void) { @@ -192,9 +183,6 @@ adxl346_is_present(void) return is_present == ADXL346_DEVID_VALUE; } /*---------------------------------------------------------------------------*/ -/** - * - */ uint16_t adxl346_read_x(void) { @@ -211,9 +199,6 @@ adxl346_read_x(void) return x; } /*---------------------------------------------------------------------------*/ -/** - * - */ uint16_t adxl346_read_y(void) { @@ -230,9 +215,6 @@ adxl346_read_y(void) return y; } /*---------------------------------------------------------------------------*/ -/** - * - */ uint16_t adxl346_read_z(void) { diff --git a/platform/openmote-cc2538/dev/adxl346.h b/platform/openmote-cc2538/dev/adxl346.h index d5e9eac76..d5751ce70 100644 --- a/platform/openmote-cc2538/dev/adxl346.h +++ b/platform/openmote-cc2538/dev/adxl346.h @@ -29,29 +29,57 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** - * \addtogroup platform + * \addtogroup openmote-sensors * @{ * - * \defgroup openmote + * \defgroup openmote-adxl346-sensor ADXL346 acceleration sensor + * @{ * * \file - * Header for the ADXL346 acceleration sensor in OpenMote-CC2538. + * ADXL346 acceleration sensor driver header file * * \author * Pere Tuset */ - -#ifndef __ADXL346_H__ -#define __ADXL346_H__ /*---------------------------------------------------------------------------*/ +#ifndef ADXL346_H_ +#define ADXL346_H_ +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize the ADXL346 sensor + */ void adxl346_init(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Reset the ADXL346 sensor + */ void adxl346_reset(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Check if the ADXL346 sensor is present + */ uint8_t adxl346_is_present(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Read the x-axis from the ADXL346 sensor + */ uint16_t adxl346_read_x(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Read the y-axis from the ADXL346 sensor + */ uint16_t adxl346_read_y(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Read the z-axis from the ADXL346 sensor + */ uint16_t adxl346_read_z(void); /*---------------------------------------------------------------------------*/ -#endif /* ifndef __ADXL346_H__ */ -/** @} */ +#endif /* ADXL346_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/dev/antenna.c b/platform/openmote-cc2538/dev/antenna.c index b0ad7b07e..3672258f9 100644 --- a/platform/openmote-cc2538/dev/antenna.c +++ b/platform/openmote-cc2538/dev/antenna.c @@ -27,44 +27,31 @@ * 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. + * */ - +/*---------------------------------------------------------------------------*/ /** - * \addtogroup platform + * \addtogroup openmote-antenna * @{ * - * \defgroup openmote + * Driver for the OpenMote-CC2538 RF switch. + * INT is the internal antenna (chip) configured through ANT1_SEL (V1) + * EXT is the external antenna (connector) configured through ANT2_SEL (V2) + * @{ * * \file - * Driver for the antenna selection on the OpenMote-CC2538 platform. + * Driver implementation for the OpenMote-CC2538 antenna switch */ - /*---------------------------------------------------------------------------*/ #include "contiki-conf.h" #include "dev/gpio.h" #include "dev/antenna.h" /*---------------------------------------------------------------------------*/ -#define BSP_RADIO_BASE (GPIO_D_BASE) -#define BSP_RADIO_INT (1 << 5) -#define BSP_RADIO_EXT (1 << 4) +#define BSP_RADIO_BASE GPIO_PORT_TO_BASE(GPIO_D_NUM) +#define BSP_RADIO_INT GPIO_PIN_MASK(5) +#define BSP_RADIO_EXT GPIO_PIN_MASK(4) /*---------------------------------------------------------------------------*/ -static void -gpio_set(int port, int bit) -{ - REG((port | GPIO_DATA) + (bit << 2)) = bit; -} -/*---------------------------------------------------------------------------*/ -static void -gpio_reset(int port, int bit) -{ - REG((port | GPIO_DATA) + (bit << 2)) = 0; -} -/*---------------------------------------------------------------------------*/ -/** - * Configure the antenna using the RF switch - * INT is the internal antenna (chip) configured through ANT1_SEL (V1) - * EXT is the external antenna (connector) configured through ANT2_SEL (V2) - */ void antenna_init(void) { @@ -76,24 +63,21 @@ antenna_init(void) antenna_external(); } /*---------------------------------------------------------------------------*/ -/** - * Select the external (connector) antenna - */ void antenna_external(void) { - gpio_reset(BSP_RADIO_BASE, BSP_RADIO_INT); - gpio_set(BSP_RADIO_BASE, BSP_RADIO_EXT); + GPIO_WRITE_PIN(BSP_RADIO_BASE, BSP_RADIO_INT, 0); + GPIO_WRITE_PIN(BSP_RADIO_BASE, BSP_RADIO_EXT, 1); } /*---------------------------------------------------------------------------*/ -/** - * Select the internal (chip) antenna - */ void antenna_internal(void) { - gpio_reset(BSP_RADIO_BASE, BSP_RADIO_EXT); - gpio_set(BSP_RADIO_BASE, BSP_RADIO_INT); + GPIO_WRITE_PIN(BSP_RADIO_BASE, BSP_RADIO_EXT, 0); + GPIO_WRITE_PIN(BSP_RADIO_BASE, BSP_RADIO_INT, 1); } /*---------------------------------------------------------------------------*/ -/** @} */ +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/dev/antenna.h b/platform/openmote-cc2538/dev/antenna.h index 8b14df4b0..9c42bf885 100644 --- a/platform/openmote-cc2538/dev/antenna.h +++ b/platform/openmote-cc2538/dev/antenna.h @@ -27,24 +27,43 @@ * 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. + * */ - +/*--------------------------------------------------------------------------*/ /** - * \addtogroup platform + * \addtogroup openmote-cc2538 * @{ * - * \defgroup openmote + * \defgroup openmote-antenna OpenMote-CC2538 antenna switch + * + * Driver for the OpenMote-CC2538 antenna switch + * @{ * * \file - * Header for the antenna selection on the OpenMote-CC2538 platform. + * Header for the OpenMote-CC2538 antenna switch */ - +/*---------------------------------------------------------------------------*/ #ifndef ANTENNA_H_ #define ANTENNA_H_ /*---------------------------------------------------------------------------*/ +/** + * \brief Initialize the antenna switch, by default it uses the external + */ void antenna_init(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Select the external (connector) antenna + */ void antenna_internal(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Select the internal (chip) antenna + */ void antenna_external(void); /*---------------------------------------------------------------------------*/ #endif /* ANTENNA_H_ */ -/** @} */ +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/dev/button-sensor.c b/platform/openmote-cc2538/dev/button-sensor.c index 6d85400d7..6477045c5 100644 --- a/platform/openmote-cc2538/dev/button-sensor.c +++ b/platform/openmote-cc2538/dev/button-sensor.c @@ -27,19 +27,18 @@ * 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. + * */ - +/*---------------------------------------------------------------------------*/ /** - * \addtogroup platform + * \addtogroup openmote-button-sensor * @{ * - * \defgroup openmote - * * \file - * Driver for the OpenMote-CC2538 buttons - * + * Driver for for the OpenMote-CC2538 user button */ - /*---------------------------------------------------------------------------*/ #include "contiki.h" #include "dev/nvic.h" @@ -47,6 +46,8 @@ #include "dev/gpio.h" #include "dev/button-sensor.h" #include "sys/timer.h" +#include "sys/ctimer.h" +#include "sys/process.h" #include #include @@ -54,32 +55,44 @@ #define BUTTON_USER_PORT_BASE GPIO_PORT_TO_BASE(BUTTON_USER_PORT) #define BUTTON_USER_PIN_MASK GPIO_PIN_MASK(BUTTON_USER_PIN) /*---------------------------------------------------------------------------*/ +#define DEBOUNCE_DURATION (CLOCK_SECOND >> 4) + static struct timer debouncetimer; /*---------------------------------------------------------------------------*/ -/** - * \brief Common initialiser for all buttons - * \param port_base GPIO port's register offset - * \param pin_mask Pin mask corresponding to the button's pin - */ +static clock_time_t press_duration = 0; +static struct ctimer press_counter; +static uint8_t press_event_counter; + +process_event_t button_press_duration_exceeded; +/*---------------------------------------------------------------------------*/ static void -config(uint32_t port_base, uint32_t pin_mask) +duration_exceeded_callback(void *data) { - /* Software controlled */ - GPIO_SOFTWARE_CONTROL(port_base, pin_mask); + press_event_counter++; + process_post(PROCESS_BROADCAST, button_press_duration_exceeded, + &press_event_counter); + ctimer_set(&press_counter, press_duration, duration_exceeded_callback, + NULL); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Retrieves the value of the button pin + * \param type Returns the pin level or the counter of press duration events. + * type == BUTTON_SENSOR_VALUE_TYPE_LEVEL or + * type == BUTTON_SENSOR_VALUE_TYPE_PRESS_DURATION + * respectively + */ +static int +value(int type) +{ + switch(type) { + case BUTTON_SENSOR_VALUE_TYPE_LEVEL: + return GPIO_READ_PIN(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + case BUTTON_SENSOR_VALUE_TYPE_PRESS_DURATION: + return press_event_counter; + } - /* Set pin to input */ - GPIO_SET_INPUT(port_base, pin_mask); - - /* Enable edge detection */ - GPIO_DETECT_EDGE(port_base, pin_mask); - - /* Single edge */ - GPIO_TRIGGER_SINGLE_EDGE(port_base, pin_mask); - - /* Trigger interrupt on Falling edge */ - GPIO_DETECT_RISING(port_base, pin_mask); - - GPIO_ENABLE_INTERRUPT(port_base, pin_mask); + return 0; } /*---------------------------------------------------------------------------*/ /** @@ -95,42 +108,72 @@ btn_callback(uint8_t port, uint8_t pin) if(!timer_expired(&debouncetimer)) { return; } - timer_set(&debouncetimer, CLOCK_SECOND / 8); - if(port == GPIO_C_NUM) { - sensors_changed(&button_user_sensor); + + timer_set(&debouncetimer, DEBOUNCE_DURATION); + + if(press_duration) { + press_event_counter = 0; + if(value(BUTTON_SENSOR_VALUE_TYPE_LEVEL) == BUTTON_SENSOR_PRESSED_LEVEL) { + ctimer_set(&press_counter, press_duration, duration_exceeded_callback, + NULL); + } else { + ctimer_stop(&press_counter); + } } + + sensors_changed(&button_sensor); } /*---------------------------------------------------------------------------*/ /** - * \brief Init function for the select button. + * \brief Init function for the User button. + * \param type SENSORS_ACTIVE: Activate / Deactivate the sensor (value == 1 + * or 0 respectively) * - * Parameters are ignored. They have been included because the prototype is - * dictated by the core sensor api. The return value is also not required by - * the API but otherwise ignored. - * - * \param type ignored - * \param value ignored - * \return ignored + * \param value Depends on the value of the type argument + * \return Depends on the value of the type argument */ static int config_user(int type, int value) { - config(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + switch(type) { + case SENSORS_HW_INIT: + button_press_duration_exceeded = process_alloc_event(); - ioc_set_over(BUTTON_USER_PORT, BUTTON_USER_PIN, IOC_OVERRIDE_PUE); + /* Software controlled */ + GPIO_SOFTWARE_CONTROL(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); - nvic_interrupt_enable(BUTTON_USER_VECTOR); + /* Set pin to input */ + GPIO_SET_INPUT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + + /* Enable edge detection */ + GPIO_DETECT_EDGE(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + + /* Both Edges */ + GPIO_TRIGGER_BOTH_EDGES(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + + ioc_set_over(BUTTON_USER_PORT, BUTTON_USER_PIN, IOC_OVERRIDE_PUE); + + gpio_register_callback(btn_callback, BUTTON_USER_PORT, BUTTON_USER_PIN); + break; + case SENSORS_ACTIVE: + if(value) { + GPIO_ENABLE_INTERRUPT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + nvic_interrupt_enable(BUTTON_USER_VECTOR); + } else { + GPIO_DISABLE_INTERRUPT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + nvic_interrupt_disable(BUTTON_USER_VECTOR); + } + return value; + case BUTTON_SENSOR_CONFIG_TYPE_INTERVAL: + press_duration = (clock_time_t)value; + break; + default: + break; + } - gpio_register_callback(btn_callback, BUTTON_USER_PORT, BUTTON_USER_PIN); return 1; } /*---------------------------------------------------------------------------*/ -void -button_sensor_init() -{ - timer_set(&debouncetimer, 0); -} -/*---------------------------------------------------------------------------*/ -SENSORS_SENSOR(button_user_sensor, BUTTON_SENSOR, NULL, config_user, NULL); +SENSORS_SENSOR(button_sensor, BUTTON_SENSOR, value, config_user, NULL); /*---------------------------------------------------------------------------*/ /** @} */ diff --git a/platform/openmote-cc2538/dev/button-sensor.h b/platform/openmote-cc2538/dev/button-sensor.h index ec7849ee1..9a08634ae 100644 --- a/platform/openmote-cc2538/dev/button-sensor.h +++ b/platform/openmote-cc2538/dev/button-sensor.h @@ -27,33 +27,48 @@ * 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. + * */ - +/*---------------------------------------------------------------------------*/ /** - * \addtogroup platform + * \addtogroup openmote-cc2538 * @{ * - * \defgroup openmote + * \defgroup openmote-button-sensor OpenMote-CC2538 user button driver + * + * The user button will generate a sensors_changed event on press as + * well as on release. + * + * @{ * * \file - * Header for the OpenMote-CC2538 buttons - * + * Header for the OpenMote-CC2538 button driver */ - +/*---------------------------------------------------------------------------*/ #ifndef BUTTON_SENSOR_H_ #define BUTTON_SENSOR_H_ /*---------------------------------------------------------------------------*/ #include "lib/sensors.h" -#include "dev/gpio.h" /*---------------------------------------------------------------------------*/ #define BUTTON_SENSOR "Button" + +extern const struct sensors_sensor button_sensor; /*---------------------------------------------------------------------------*/ -#define button_sensor button_user_sensor -extern const struct sensors_sensor button_user_sensor; +extern process_event_t button_press_duration_exceeded; +/*---------------------------------------------------------------------------*/ +#define BUTTON_SENSOR_CONFIG_TYPE_INTERVAL 0x0100 + +#define BUTTON_SENSOR_VALUE_TYPE_LEVEL 0 +#define BUTTON_SENSOR_VALUE_TYPE_PRESS_DURATION 1 + +#define BUTTON_SENSOR_PRESSED_LEVEL 0 +#define BUTTON_SENSOR_RELEASED_LEVEL 8 /*---------------------------------------------------------------------------*/ #endif /* BUTTON_SENSOR_H_ */ - -/** \brief Common initialiser for all SmartRF Buttons */ -void button_sensor_init(); /*---------------------------------------------------------------------------*/ -/** @} */ +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/dev/leds-arch.c b/platform/openmote-cc2538/dev/leds-arch.c index 13a4c1347..28454dacf 100644 --- a/platform/openmote-cc2538/dev/leds-arch.c +++ b/platform/openmote-cc2538/dev/leds-arch.c @@ -10,7 +10,6 @@ * 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 copyright holder nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. @@ -27,19 +26,21 @@ * 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. + * */ - +/*---------------------------------------------------------------------------*/ /** - * \addtogroup platform + * \addtogroup openmote-cc2538 * @{ * - * \defgroup openmote + * \defgroup openmote-leds OpenMote-CC2538 LED driver + * @{ * * \file - * Driver for the OpenMote-CC2538 LEDs - * + * LED driver implementation for the OpenMote-CC2538 platform */ - /*---------------------------------------------------------------------------*/ #include "contiki.h" #include "reg.h" @@ -66,4 +67,7 @@ leds_arch_set(unsigned char leds) GPIO_WRITE_PIN(GPIO_C_BASE, LEDS_GPIO_PIN_MASK, leds); } /*---------------------------------------------------------------------------*/ -/** @} */ +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/dev/max44009.c b/platform/openmote-cc2538/dev/max44009.c index 34bce89ab..233b07d13 100644 --- a/platform/openmote-cc2538/dev/max44009.c +++ b/platform/openmote-cc2538/dev/max44009.c @@ -29,29 +29,33 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** - * \addtogroup platform + * \addtogroup openmote-max44009-sensor * @{ * - * \defgroup openmote - * * \file - * Driver for the MAX44009 light sensor in OpenMote-CC2538. + * Driver for the MAX44009 light sensor * * \author * Pere Tuset */ - /*---------------------------------------------------------------------------*/ #include "dev/i2c.h" #include "dev/max44009.h" /*---------------------------------------------------------------------------*/ -/* ADDRESS AND NOT_FOUND VALUE */ +/** + * \name MAX44009 address and device identifier + * @{ + */ #define MAX44009_ADDRESS (0x4A) #define MAX44009_NOT_FOUND (0x00) - -/* REGISTER ADDRESSES */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name MAX44009 register addresses + * @{ + */ #define MAX44009_INT_STATUS_ADDR (0x00) /* R */ #define MAX44009_INT_ENABLE_ADDR (0x01) /* R/W */ #define MAX44009_CONFIG_ADDR (0x02) /* R/W */ @@ -60,14 +64,17 @@ #define MAX44009_THR_HIGH_ADDR (0x05) /* R/W */ #define MAX44009_THR_LOW_ADDR (0x06) /* R/W */ #define MAX44009_THR_TIMER_ADDR (0x07) /* R/W */ - -/* INTERRUPT VALUES */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name MAX44009 register values + * @{ + */ #define MAX44009_INT_STATUS_OFF (0x00) #define MAX44009_INT_STATUS_ON (0x01) #define MAX44009_INT_DISABLED (0x00) #define MAX44009_INT_ENABLED (0x01) -/* CONFIGURATION VALUES */ #define MAX44009_CONFIG_DEFAULT (0 << 7) #define MAX44009_CONFIG_CONTINUOUS (1 << 7) #define MAX44009_CONFIG_AUTO (0 << 6) @@ -83,15 +90,12 @@ #define MAX44009_CONFIG_INTEGRATION_12ms (6 << 0) #define MAX44009_CONFIG_INTEGRATION_6ms (7 << 0) -/* DEFAULT CONFIGURATION */ #define MAX44009_DEFAULT_CONFIGURATION (MAX44009_CONFIG_DEFAULT | \ MAX44009_CONFIG_AUTO | \ MAX44009_CONFIG_CDR_NORMAL | \ MAX44009_CONFIG_INTEGRATION_100ms) +/** @} */ /*---------------------------------------------------------------------------*/ -/** - * - */ void max44009_init(void) { @@ -108,19 +112,13 @@ max44009_init(void) max44009_value[3] = (0x00); max44009_value[4] = (0xFF); - i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, - I2C_SCL_NORMAL_BUS_SPEED); - - for(i = 0; i < sizeof(max44009_address); i++) { - max44009_data[0] = max44009_value[i]; - max44009_data[1] = max44009_data[i]; + for(i = 0; i < sizeof(max44009_address) / sizeof(max44009_address[0]); i++) { + max44009_data[0] = max44009_address[i]; + max44009_data[1] = max44009_value[i]; i2c_burst_send(MAX44009_ADDRESS, max44009_data, 2); } } /*---------------------------------------------------------------------------*/ -/** - * - */ void max44009_reset(void) { @@ -131,30 +129,28 @@ max44009_reset(void) uint8_t max44009_data[2]; uint8_t i; - for(i = 0; i < sizeof(max44009_address); i++) { - max44009_data[0] = max44009_value[i]; - max44009_data[1] = max44009_data[i]; + for(i = 0; i < sizeof(max44009_address) / sizeof(max44009_address[0]); i++) { + max44009_data[0] = max44009_address[i]; + max44009_data[1] = max44009_value[i]; i2c_burst_send(MAX44009_ADDRESS, max44009_data, 2); } } /*---------------------------------------------------------------------------*/ -/** - * - */ uint8_t max44009_is_present(void) { + uint8_t status; uint8_t is_present; i2c_single_send(MAX44009_ADDRESS, MAX44009_CONFIG_ADDR); - i2c_single_receive(MAX44009_ADDRESS, &is_present); + status = i2c_single_receive(MAX44009_ADDRESS, &is_present); + if(status != I2C_MASTER_ERR_NONE) { + return 0; + } return is_present != MAX44009_NOT_FOUND; } /*---------------------------------------------------------------------------*/ -/** - * - */ uint16_t max44009_read_light(void) { @@ -175,9 +171,6 @@ max44009_read_light(void) return result; } /*---------------------------------------------------------------------------*/ -/** - * - */ float max44009_convert_light(uint16_t lux) { @@ -186,7 +179,7 @@ max44009_convert_light(uint16_t lux) exponent = (lux >> 8) & 0xFF; exponent = (exponent == 0x0F ? exponent & 0x0E : exponent); - + mantissa = (lux >> 0) & 0xFF; result *= 2 ^ exponent * mantissa; diff --git a/platform/openmote-cc2538/dev/max44009.h b/platform/openmote-cc2538/dev/max44009.h index dbc40775d..e94a91fca 100644 --- a/platform/openmote-cc2538/dev/max44009.h +++ b/platform/openmote-cc2538/dev/max44009.h @@ -29,28 +29,52 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** - * \addtogroup platform + * \addtogroup openmote-sensors * @{ * - * \defgroup openmote + * \defgroup openmote-max44009-sensor MAX4009 light sensor + * @{ * * \file - * Header for the MAX44009 light sensor in OpenMote-CC2538. + * Header file for the MAX44009 light sensor driver * * \author * Pere Tuset */ - -#ifndef __MAX44009_H__ -#define __MAX44009_H__ /*---------------------------------------------------------------------------*/ +#ifndef MAX44009_H_ +#define MAX44009_H_ +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize the MAX44009 sensor + */ void max44009_init(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Reset the MAX44009 sensor + */ void max44009_reset(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Check if the MAX44009 sensor is present + */ uint8_t max44009_is_present(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Read the light from the MAX44009 sensor + */ uint16_t max44009_read_light(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Convert the light from the MAX44009 sensor + */ float max44009_convert_light(uint16_t light); /*---------------------------------------------------------------------------*/ -#endif /* ifndef __MAX44009_H__ */ -/** @} */ +#endif /* MAX44009_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/dev/smartrf-sensors.c b/platform/openmote-cc2538/dev/openmote-sensors.c similarity index 82% rename from platform/openmote-cc2538/dev/smartrf-sensors.c rename to platform/openmote-cc2538/dev/openmote-sensors.c index d8948a017..3b55e4cbb 100644 --- a/platform/openmote-cc2538/dev/smartrf-sensors.c +++ b/platform/openmote-cc2538/dev/openmote-sensors.c @@ -27,27 +27,34 @@ * 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. + * */ - +/*---------------------------------------------------------------------------*/ /** - * \addtogroup platform + * \addtogroup openmote-sensors * @{ * - * \defgroup openmote + * Generic module controlling sensors on the OpenMote-CC2538 platform + * @{ * * \file - * Implementation of a generic module controlling OpenMote-CC2538 sensors. + * Implementation of a generic module controlling OpenMote-CC2538 sensors */ - /*---------------------------------------------------------------------------*/ #include "contiki.h" +#include "dev/cc2538-sensors.h" #include "dev/button-sensor.h" #include /*---------------------------------------------------------------------------*/ /** - *\brief Exports a global symbol to be used by the sensor API + * \brief Exports a global symbol to be used by the sensor API */ -SENSORS(&button_user_sensor); +SENSORS(&button_sensor, &cc2538_temp_sensor); /*---------------------------------------------------------------------------*/ -/** @} */ +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/dev/openmote-sensors.h b/platform/openmote-cc2538/dev/openmote-sensors.h new file mode 100644 index 000000000..a765dbd3d --- /dev/null +++ b/platform/openmote-cc2538/dev/openmote-sensors.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup openmote-cc2538 + * @{ + * + * \defgroup openmote-sensors OpenMote-CC2538 sensors + * + * Generic module controlling sensors on the OpenMote-CC2538 platform + * @{ + * + * \file + * Implementation of a generic module controlling OpenMote-CC2538 sensors + */ +/*---------------------------------------------------------------------------*/ +#ifndef OPENMOTE_SENSORS_H_ +#define OPENMOTE_SENSORS_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +#include "dev/cc2538-sensors.h" +#include "dev/button-sensor.h" +/*---------------------------------------------------------------------------*/ +#endif /* OPENMOTE_SENSORS_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/dev/sht21.c b/platform/openmote-cc2538/dev/sht21.c index 1ad07836f..989fe2905 100644 --- a/platform/openmote-cc2538/dev/sht21.c +++ b/platform/openmote-cc2538/dev/sht21.c @@ -29,30 +29,43 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** - * \addtogroup platform + * \addtogroup openmote-sht21-sensor * @{ * - * \defgroup openmote - * * \file - * Driver for the SHT21 temperature and humidity sensor in OpenMote-CC2538. + * Driver for the SHT21 temperature and relative humidity sensor * * \author * Pere Tuset */ - /*---------------------------------------------------------------------------*/ #include "i2c.h" #include "sht21.h" /*---------------------------------------------------------------------------*/ +/** + * \name SHT21 address + */ #define SHT21_ADDRESS (0x40) - +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SHT21 register addresses and values + * @{ + */ #define SHT21_USER_REG_READ (0xE7) #define SHT21_USER_REG_WRITE (0xE6) #define SHT21_USER_REG_RESERVED_BITS (0x38) +#define SHT21_TEMPERATURE_HM_CMD (0xE3) +#define SHT21_HUMIDITY_HM_CMD (0xE5) +#define SHT21_TEMPERATURE_NHM_CMD (0xF3) +#define SHT21_HUMIDITY_NHM_CMD (0xF5) +#define SHT21_RESET_CMD (0xFE) + +#define SHT21_STATUS_MASK (0xFC) + #define SHT21_RESOLUTION_12b_14b ((0 << 7) | (0 << 0)) #define SHT21_RESOLUTION_8b_12b ((0 << 7) | (1 << 0)) #define SHT21_RESOLUTION_10b_13b ((1 << 7) | (0 << 0)) @@ -63,15 +76,12 @@ #define SHT21_ONCHIP_HEATER_DISABLE (0 << 2) #define SHT21_OTP_RELOAD_ENABLE (0 << 1) #define SHT21_OTP_RELOAD_DISABLE (1 << 1) - -#define SHT21_TEMPERATURE_HM_CMD (0xE3) -#define SHT21_HUMIDITY_HM_CMD (0xE5) -#define SHT21_TEMPERATURE_NHM_CMD (0xF3) -#define SHT21_HUMIDITY_NHM_CMD (0xF5) -#define SHT21_RESET_CMD (0xFE) - -#define SHT21_STATUS_MASK ( 0xFC ) - +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SHT21 configuration values + * @{ + */ #define SHT21_DEFAULT_CONFIG (SHT21_RESOLUTION_12b_14b | \ SHT21_ONCHIP_HEATER_DISABLE | \ SHT21_BATTERY_ABOVE_2V25 | \ @@ -81,18 +91,13 @@ SHT21_ONCHIP_HEATER_DISABLE | \ SHT21_BATTERY_ABOVE_2V25 | \ SHT21_OTP_RELOAD_DISABLE) +/** @} */ /*---------------------------------------------------------------------------*/ -/** - * - */ void sht21_init(void) { uint8_t config[2]; - i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, - I2C_SCL_NORMAL_BUS_SPEED); - /* Setup the configuration vector, the first position holds address */ /* and the second position holds the actual configuration */ config[0] = SHT21_USER_REG_WRITE; @@ -111,9 +116,6 @@ sht21_init(void) i2c_burst_send(SHT21_ADDRESS, config, sizeof(config)); } /*---------------------------------------------------------------------------*/ -/** - * - */ void sht21_reset(void) { @@ -121,29 +123,25 @@ sht21_reset(void) i2c_single_send(SHT21_ADDRESS, SHT21_RESET_CMD); } /*---------------------------------------------------------------------------*/ -/** - * - */ uint8_t sht21_is_present(void) { + uint8_t status; uint8_t is_present; /* Read the current configuration according to the datasheet (pag. 9, fig. 18) */ i2c_single_send(SHT21_ADDRESS, SHT21_USER_REG_READ); - i2c_single_receive(SHT21_ADDRESS, &is_present); + status = i2c_single_receive(SHT21_ADDRESS, &is_present); + if(status != I2C_MASTER_ERR_NONE) { + return 0; + } /* Clear the reserved bits according to the datasheet (pag. 9, tab. 8) */ is_present &= ~SHT21_USER_REG_RESERVED_BITS; - is_present = ((is_present == SHT21_USER_CONFIG) || (is_present == SHT21_DEFAULT_CONFIG)); - - return is_present; + return (is_present == SHT21_USER_CONFIG) || (is_present == SHT21_DEFAULT_CONFIG); } /*---------------------------------------------------------------------------*/ -/** - * - */ uint16_t sht21_read_temperature(void) { @@ -159,23 +157,17 @@ sht21_read_temperature(void) return temperature; } /*---------------------------------------------------------------------------*/ -/** - * - */ float sht21_convert_temperature(uint16_t temperature) { float result; result = -46.85; - result += 175.72 * (float) temperature / 65536.0; + result += 175.72 * (float)temperature / 65536.0; return result; } /*---------------------------------------------------------------------------*/ -/** - * - */ uint16_t sht21_read_humidity(void) { @@ -191,16 +183,13 @@ sht21_read_humidity(void) return humidity; } /*---------------------------------------------------------------------------*/ -/** - * - */ float sht21_convert_humidity(uint16_t humidity) { float result; result = -6.0; - result += 125.0 * (float) humidity / 65536.0; + result += 125.0 * (float)humidity / 65536.0; return result; } diff --git a/platform/openmote-cc2538/dev/sht21.h b/platform/openmote-cc2538/dev/sht21.h index c95e02edf..1483a70a9 100644 --- a/platform/openmote-cc2538/dev/sht21.h +++ b/platform/openmote-cc2538/dev/sht21.h @@ -29,30 +29,62 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** - * \addtogroup platform + * \addtogroup openmote-sensors * @{ * - * \defgroup openmote + * \defgroup openmote-sht21-sensor SHT21 sensor + * @{ * * \file - * Header for the SHT21 temperature and humidity sensor in OpenMote-CC2538. + * Header file for the SHT21 temperature and humidity sensor driver * * \author * Pere Tuset */ - -#ifndef __SHT21_H__ -#define __SHT21_H__ /*---------------------------------------------------------------------------*/ +#ifndef SHT21_H_ +#define SHT21_H_ +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize the SHT21 sensor + */ void sht21_init(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Reset the SHT21 sensor + */ void sht21_reset(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Check if the SHT21 sensor is present + */ uint8_t sht21_is_present(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Read the temperature from the SHT21 sensor + */ uint16_t sht21_read_temperature(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Convert the temperature from the SHT21 sensor + */ float sht21_convert_temperature(uint16_t temperature); +/*---------------------------------------------------------------------------*/ +/** + * \brief Read the relative humidity from the SHT21 sensor + */ uint16_t sht21_read_humidity(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Convert the relative humidity from the SHT21 sensor + */ float sht21_convert_humidity(uint16_t humidity); /*---------------------------------------------------------------------------*/ -#endif /* ifndef __SHT21_H__ */ -/** @} */ +#endif /* SHT21_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/dev/tps62730.c b/platform/openmote-cc2538/dev/tps62730.c index 0356077f9..f90c0e097 100644 --- a/platform/openmote-cc2538/dev/tps62730.c +++ b/platform/openmote-cc2538/dev/tps62730.c @@ -29,20 +29,22 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** - * \addtogroup platform + * \addtogroup openmote-tps62730 * @{ * - * \defgroup openmote + * Driver for the TPS62730 voltage regulator, to enable power from + * the battery voltage (bypass, Vout=Vin, Iq < 1uA) or through the + * buck regulator (on, Vout=2.1V, Iq = 30uA) + * @{ * * \file - * Driver for the TPS62730 voltage regulator on the OpenMote-CC2538. + * Driver for the TPS62730 voltage regulator * * \author * Pere Tuset */ - /*---------------------------------------------------------------------------*/ #include "contiki-conf.h" #include "dev/gpio.h" @@ -64,10 +66,6 @@ gpio_reset(int port, int bit) REG((port | GPIO_DATA) + (bit << 2)) = 0; } /*---------------------------------------------------------------------------*/ -/** - * Initializes the TPS62730 voltage regulator - * By default it is in bypass mode, Vout = Vin, Iq < 1 uA - */ void tps62730_init(void) { @@ -77,22 +75,19 @@ tps62730_init(void) tps62730_bypass(); } /*---------------------------------------------------------------------------*/ -/** - * Enables the TPS62730, Vout = 2.2V, Iq = 30 uA - */ void tps62730_on(void) { gpio_set(BSP_TPS62730_BASE, BSP_TPS62730_ON); } /*---------------------------------------------------------------------------*/ -/** - * Disables the TPS62730, Vout = Vin, Iq < 1 uA - */ void tps62730_bypass(void) { gpio_reset(BSP_TPS62730_BASE, BSP_TPS62730_ON); } /*---------------------------------------------------------------------------*/ -/** @} */ +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/dev/tps62730.h b/platform/openmote-cc2538/dev/tps62730.h index b3e99bc8d..00518c9c7 100644 --- a/platform/openmote-cc2538/dev/tps62730.h +++ b/platform/openmote-cc2538/dev/tps62730.h @@ -29,26 +29,46 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** - * \addtogroup platform + * \addtogroup openmote-cc2538 * @{ * - * \defgroup openmote + * \defgroup openmote-tps62730 TPS62730 voltage regulator + * + * Driver for the TPS62730 voltage regulator, to enable power from + * the battery voltage (bypass, Vout=Vin, Iq < 1uA) or through the + * buck regulator (on, Vout=2.1V, Iq = 30uA) + * @{ * * \file - * Header for the TPS62730 voltage regulator on the OpenMote-CC2538. + * Driver for the TPS62730 voltage regulator * * \author * Pere Tuset */ - +/*---------------------------------------------------------------------------*/ #ifndef TPS62730_H_ #define TPS62730_H_ /*---------------------------------------------------------------------------*/ +/** + * \brief Initialize the TPS62730 voltage regulator in bypass mode + */ void tps62730_init(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Set TPS62730 to on, Vout = 2.2V, Iq = 30 uA + */ void tps62730_on(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Set TPS62730 to bypass, Vout = Vin, Iq < 1 uA + */ void tps62730_bypass(void); /*---------------------------------------------------------------------------*/ #endif /* TPS62730_H_ */ -/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/regression-tests/18-compile-arm-ports/Makefile b/regression-tests/18-compile-arm-ports/Makefile index dbac11d43..19bd7d63e 100644 --- a/regression-tests/18-compile-arm-ports/Makefile +++ b/regression-tests/18-compile-arm-ports/Makefile @@ -32,6 +32,7 @@ cc2538-common/crypto/zoul \ cc2538-common/pka/zoul \ zolertia/zoul/zoul \ zolertia/zoul/cc1200-demo/zoul \ +openmote-cc2538/openmote-cc2538 \ er-rest-example/zoul \ ipso-objects/zoul \ hello-world/zoul \ From 510fc9e51edf1f8818e0ed488f88f7983b714b5d Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Tue, 24 Nov 2015 11:35:20 +0100 Subject: [PATCH 174/374] removed memcpy that cause inconsistency in nbr-table when adding nd6 neighbor with NS/NA. --- core/net/ipv6/uip-nd6.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/core/net/ipv6/uip-nd6.c b/core/net/ipv6/uip-nd6.c index 107e66369..a6b8931ad 100644 --- a/core/net/ipv6/uip-nd6.c +++ b/core/net/ipv6/uip-nd6.c @@ -492,10 +492,11 @@ na_input(void) } else { uip_lladdr_t *lladdr; nbr = uip_ds6_nbr_lookup(&UIP_ND6_NA_BUF->tgtipaddr); - lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr); if(nbr == NULL) { goto discard; } + lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr); + if(nd6_opt_llao != 0) { is_llchange = memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], (void *)lladdr, @@ -505,8 +506,16 @@ na_input(void) if(nd6_opt_llao == NULL) { goto discard; } - memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], - UIP_LLADDR_LEN); + + /* Remove this neighbor - since it has a NULL MAC address */ + uip_ds6_nbr_rm(nbr); + /* Re-add this neighbor - now with a correct MAC address */ + nbr = uip_ds6_nbr_add(&UIP_ND6_NA_BUF->tgtipaddr, + (const uip_lladdr_t *) &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], + is_router, NBR_STALE); + if(nbr == NULL) { + goto discard; + } if(is_solicited) { nbr->state = NBR_REACHABLE; nbr->nscount = 0; From b2f72fc99634a28258d98078c3a7a228cd818bdf Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Tue, 24 Nov 2015 23:00:50 +0100 Subject: [PATCH 175/374] replaces with aligned lladdress and also fixed the second memcpy to avoid risk of inconsistency when nodes change MAC address --- core/net/ipv6/uip-nd6.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/core/net/ipv6/uip-nd6.c b/core/net/ipv6/uip-nd6.c index a6b8931ad..1d354d384 100644 --- a/core/net/ipv6/uip-nd6.c +++ b/core/net/ipv6/uip-nd6.c @@ -490,16 +490,16 @@ na_input(void) PRINTF("NA received is bad\n"); goto discard; } else { - uip_lladdr_t *lladdr; + uip_lladdr_t lladdr_aligned; nbr = uip_ds6_nbr_lookup(&UIP_ND6_NA_BUF->tgtipaddr); if(nbr == NULL) { goto discard; } - lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr); + extract_lladdr_aligned(&lladdr_aligned); if(nd6_opt_llao != 0) { is_llchange = - memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], (void *)lladdr, + memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], (void *)&lladdr_aligned, UIP_LLADDR_LEN); } if(nbr->state == NBR_INCOMPLETE) { @@ -511,7 +511,7 @@ na_input(void) uip_ds6_nbr_rm(nbr); /* Re-add this neighbor - now with a correct MAC address */ nbr = uip_ds6_nbr_add(&UIP_ND6_NA_BUF->tgtipaddr, - (const uip_lladdr_t *) &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], + &lladdr_aligned, is_router, NBR_STALE); if(nbr == NULL) { goto discard; @@ -537,8 +537,15 @@ na_input(void) if(is_override || (!is_override && nd6_opt_llao != 0 && !is_llchange) || nd6_opt_llao == 0) { if(nd6_opt_llao != 0) { - memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], - UIP_LLADDR_LEN); + /* Remove this neighbor - since it has updated its MAC address */ + uip_ds6_nbr_rm(nbr); + /* Re-add this neighbor - now with a correct (new) MAC address */ + nbr = uip_ds6_nbr_add(&UIP_ND6_NA_BUF->tgtipaddr, + &lladdr_aligned, + is_router, NBR_STALE); + if(nbr == NULL) { + goto discard; + } } if(is_solicited) { nbr->state = NBR_REACHABLE; From 6f271bf8531aca07383e6cb8221963d9a073db59 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Wed, 25 Nov 2015 15:01:46 +0100 Subject: [PATCH 176/374] fixed so that the comparison of old lladdr and llao lladdr is compared instead of two llaos - and improved code style on surrounding code --- core/net/ipv6/uip-nd6.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/core/net/ipv6/uip-nd6.c b/core/net/ipv6/uip-nd6.c index 1d354d384..0eac94c4f 100644 --- a/core/net/ipv6/uip-nd6.c +++ b/core/net/ipv6/uip-nd6.c @@ -490,22 +490,22 @@ na_input(void) PRINTF("NA received is bad\n"); goto discard; } else { - uip_lladdr_t lladdr_aligned; nbr = uip_ds6_nbr_lookup(&UIP_ND6_NA_BUF->tgtipaddr); if(nbr == NULL) { goto discard; } - extract_lladdr_aligned(&lladdr_aligned); - if(nd6_opt_llao != 0) { + if(nd6_opt_llao != NULL) { is_llchange = - memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], (void *)&lladdr_aligned, + memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], uip_ds6_nbr_get_ll(nbr), UIP_LLADDR_LEN); } if(nbr->state == NBR_INCOMPLETE) { + uip_lladdr_t lladdr_aligned; if(nd6_opt_llao == NULL) { goto discard; } + extract_lladdr_aligned(&lladdr_aligned); /* Remove this neighbor - since it has a NULL MAC address */ uip_ds6_nbr_rm(nbr); @@ -534,9 +534,12 @@ na_input(void) } goto discard; } else { - if(is_override || (!is_override && nd6_opt_llao != 0 && !is_llchange) - || nd6_opt_llao == 0) { - if(nd6_opt_llao != 0) { + if(is_override || (!is_override && nd6_opt_llao != NULL && !is_llchange) + || nd6_opt_llao == NULL) { + if(nd6_opt_llao != NULL) { + uip_lladdr_t lladdr_aligned; + extract_lladdr_aligned(&lladdr_aligned); + /* Remove this neighbor - since it has updated its MAC address */ uip_ds6_nbr_rm(nbr); /* Re-add this neighbor - now with a correct (new) MAC address */ @@ -552,7 +555,7 @@ na_input(void) /* reachable time is stored in ms */ stimer_set(&(nbr->reachable), uip_ds6_if.reachable_time / 1000); } else { - if(nd6_opt_llao != 0 && is_llchange) { + if(nd6_opt_llao != NULL && is_llchange) { nbr->state = NBR_STALE; } } From 223f002676829f6df15f6aa10e35f39b8de5d1d1 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Thu, 26 Nov 2015 14:10:16 +0100 Subject: [PATCH 177/374] fixed the case when the lladdr did not change but the LLAO is there and it is not an override. --- core/net/ipv6/uip-nd6.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/core/net/ipv6/uip-nd6.c b/core/net/ipv6/uip-nd6.c index 0eac94c4f..316172fb2 100644 --- a/core/net/ipv6/uip-nd6.c +++ b/core/net/ipv6/uip-nd6.c @@ -534,9 +534,12 @@ na_input(void) } goto discard; } else { - if(is_override || (!is_override && nd6_opt_llao != NULL && !is_llchange) - || nd6_opt_llao == NULL) { - if(nd6_opt_llao != NULL) { + /** + * If this is an cache override, or same lladdr, or no llao - + * do updates of nbr states. + */ + if(is_override || !is_llchange || nd6_opt_llao == NULL) { + if(nd6_opt_llao != NULL && is_llchange) { uip_lladdr_t lladdr_aligned; extract_lladdr_aligned(&lladdr_aligned); @@ -554,10 +557,6 @@ na_input(void) nbr->state = NBR_REACHABLE; /* reachable time is stored in ms */ stimer_set(&(nbr->reachable), uip_ds6_if.reachable_time / 1000); - } else { - if(nd6_opt_llao != NULL && is_llchange) { - nbr->state = NBR_STALE; - } } } } From 2e852f758b3fbc18ad30ec75d8c62b5d5238e70a Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Thu, 26 Nov 2015 14:19:12 +0100 Subject: [PATCH 178/374] added a null check on the lladdr before the memcmp. --- core/net/ipv6/uip-nd6.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/net/ipv6/uip-nd6.c b/core/net/ipv6/uip-nd6.c index 316172fb2..62b3a64cb 100644 --- a/core/net/ipv6/uip-nd6.c +++ b/core/net/ipv6/uip-nd6.c @@ -490,14 +490,16 @@ na_input(void) PRINTF("NA received is bad\n"); goto discard; } else { + const uip_lladdr_t *lladdr; nbr = uip_ds6_nbr_lookup(&UIP_ND6_NA_BUF->tgtipaddr); if(nbr == NULL) { goto discard; } + lladdr = uip_ds6_nbr_get_ll(nbr); if(nd6_opt_llao != NULL) { - is_llchange = - memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], uip_ds6_nbr_get_ll(nbr), + is_llchange = lladdr == NULL || + memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], lladdr, UIP_LLADDR_LEN); } if(nbr->state == NBR_INCOMPLETE) { From e9e31e9fd11070d04cec5e37fd47c3c145bb82df Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Thu, 26 Nov 2015 20:26:10 +0100 Subject: [PATCH 179/374] replaced add/remove ds6-nbr with an nbr-module controlled update of lladdress to avoid loss of other state information --- core/net/ipv6/uip-nd6.c | 77 ++++++++++++++++++++++++++--------------- core/net/nbr-table.c | 69 ++++++++++++++++++++++++++++-------- core/net/nbr-table.h | 1 + 3 files changed, 104 insertions(+), 43 deletions(-) diff --git a/core/net/ipv6/uip-nd6.c b/core/net/ipv6/uip-nd6.c index 62b3a64cb..d160392ed 100644 --- a/core/net/ipv6/uip-nd6.c +++ b/core/net/ipv6/uip-nd6.c @@ -136,7 +136,7 @@ static uip_ds6_prefix_t *prefix; /** Pointer to a prefix list entry */ /*------------------------------------------------------------------*/ /* Copy link-layer address from LLAO option to a word-aligned uip_lladdr_t */ static void -extract_lladdr_aligned(uip_lladdr_t *dest) { +extract_lladdr_from_llao_aligned(uip_lladdr_t *dest) { if(dest != NULL && nd6_opt_llao != NULL) { memcpy(dest, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN); } @@ -199,17 +199,29 @@ ns_input(void) goto discard; } else { #endif /*UIP_CONF_IPV6_CHECKS */ + uip_lladdr_t lladdr_aligned; + extract_lladdr_from_llao_aligned(&lladdr_aligned); nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr); if(nbr == NULL) { +<<<<<<< 2e852f758b3fbc18ad30ec75d8c62b5d5238e70a uip_lladdr_t lladdr_aligned; extract_lladdr_aligned(&lladdr_aligned); uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL); +======= + uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE); +>>>>>>> replaced add/remove ds6-nbr with an nbr-module controlled update of lladdress to avoid loss of other state information } else { - uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr); + const uip_lladdr_t *lladdr = uip_ds6_nbr_get_ll(nbr); + if(lladdr == NULL) { + goto discard; + } if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], lladdr, UIP_LLADDR_LEN) != 0) { - memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN); + if(nbr_table_update_lladdr((const linkaddr_t *)lladdr, (const linkaddr_t *)&lladdr_aligned, 1) == 0) { + /* failed to update the lladdr */ + goto discard; + } nbr->state = NBR_STALE; } else { if(nbr->state == NBR_INCOMPLETE) { @@ -495,10 +507,12 @@ na_input(void) if(nbr == NULL) { goto discard; } - lladdr = uip_ds6_nbr_get_ll(nbr); + if(lladdr == NULL) { + goto discard; + } if(nd6_opt_llao != NULL) { - is_llchange = lladdr == NULL || + is_llchange = memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], lladdr, UIP_LLADDR_LEN); } @@ -507,17 +521,13 @@ na_input(void) if(nd6_opt_llao == NULL) { goto discard; } - extract_lladdr_aligned(&lladdr_aligned); - /* Remove this neighbor - since it has a NULL MAC address */ - uip_ds6_nbr_rm(nbr); - /* Re-add this neighbor - now with a correct MAC address */ - nbr = uip_ds6_nbr_add(&UIP_ND6_NA_BUF->tgtipaddr, - &lladdr_aligned, - is_router, NBR_STALE); - if(nbr == NULL) { + extract_lladdr_from_llao_aligned(&lladdr_aligned); + if(nbr_table_update_lladdr((const linkaddr_t *)lladdr, (const linkaddr_t *)&lladdr_aligned, 1) == 0) { + /* failed to update the lladdr */ goto discard; } + if(is_solicited) { nbr->state = NBR_REACHABLE; nbr->nscount = 0; @@ -529,7 +539,7 @@ na_input(void) nbr->state = NBR_STALE; } nbr->isrouter = is_router; - } else { + } else { /* NBR is not INCOMPLETE */ if(!is_override && is_llchange) { if(nbr->state == NBR_REACHABLE) { nbr->state = NBR_STALE; @@ -543,15 +553,9 @@ na_input(void) if(is_override || !is_llchange || nd6_opt_llao == NULL) { if(nd6_opt_llao != NULL && is_llchange) { uip_lladdr_t lladdr_aligned; - extract_lladdr_aligned(&lladdr_aligned); - - /* Remove this neighbor - since it has updated its MAC address */ - uip_ds6_nbr_rm(nbr); - /* Re-add this neighbor - now with a correct (new) MAC address */ - nbr = uip_ds6_nbr_add(&UIP_ND6_NA_BUF->tgtipaddr, - &lladdr_aligned, - is_router, NBR_STALE); - if(nbr == NULL) { + extract_lladdr_from_llao_aligned(&lladdr_aligned); + if(nbr_table_update_lladdr((const linkaddr_t *) lladdr, (const linkaddr_t *) &lladdr_aligned, 1) == 0) { + /* failed to update the lladdr */ goto discard; } } @@ -652,15 +656,19 @@ rs_input(void) } else { #endif /*UIP_CONF_IPV6_CHECKS */ uip_lladdr_t lladdr_aligned; - extract_lladdr_aligned(&lladdr_aligned); + extract_lladdr_from_llao_aligned(&lladdr_aligned); if((nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr)) == NULL) { /* we need to add the neighbor */ uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL); } else { /* If LL address changed, set neighbor state to stale */ + const uip_lladdr_t *lladdr = uip_ds6_nbr_get_ll(nbr); + if(lladdr == NULL) { + goto discard; + } if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], - uip_ds6_nbr_get_ll(nbr), UIP_LLADDR_LEN) != 0) { + lladdr, UIP_LLADDR_LEN) != 0) { uip_ds6_nbr_t nbr_data = *nbr; uip_ds6_nbr_rm(nbr); nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, @@ -892,18 +900,31 @@ ra_input(void) nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr); if(nbr == NULL) { uip_lladdr_t lladdr_aligned; +<<<<<<< 2e852f758b3fbc18ad30ec75d8c62b5d5238e70a extract_lladdr_aligned(&lladdr_aligned); nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 1, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL); +======= + extract_lladdr_from_llao_aligned(&lladdr_aligned); + nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 1, NBR_STALE); +>>>>>>> replaced add/remove ds6-nbr with an nbr-module controlled update of lladdress to avoid loss of other state information } else { - uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr); + uip_lladdr_t lladdr_aligned; + extract_lladdr_from_llao_aligned(&lladdr_aligned); + const uip_lladdr_t *lladdr = uip_ds6_nbr_get_ll(nbr); + if(lladdr == NULL) { + goto discard; + } if(nbr->state == NBR_INCOMPLETE) { nbr->state = NBR_STALE; } if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], lladdr, UIP_LLADDR_LEN) != 0) { - memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], - UIP_LLADDR_LEN); + /* change of link layer address */ + if(nbr_table_update_lladdr((const linkaddr_t *)lladdr, (const linkaddr_t *)&lladdr_aligned, 1) == 0) { + /* failed to update the lladdr */ + goto discard; + } nbr->state = NBR_STALE; } nbr->isrouter = 1; diff --git a/core/net/nbr-table.c b/core/net/nbr-table.c index ddae06fca..4a3518475 100644 --- a/core/net/nbr-table.c +++ b/core/net/nbr-table.c @@ -178,6 +178,26 @@ nbr_set_bit(uint8_t *bitmap, nbr_table_t *table, nbr_table_item_t *item, int val return 0; } /*---------------------------------------------------------------------------*/ +static void +remove_key(nbr_table_key_t *least_used_key) +{ + int i; + for(i = 0; i < MAX_NUM_TABLES; i++) { + if(all_tables[i] != NULL && all_tables[i]->callback != NULL) { + /* Call table callback for each table that uses this item */ + nbr_table_item_t *removed_item = item_from_key(all_tables[i], least_used_key); + if(nbr_get_bit(used_map, all_tables[i], removed_item) == 1) { + all_tables[i]->callback(removed_item); + } + } + } + /* Empty used map */ + used_map[index_from_key(least_used_key)] = 0; + /* Remove neighbor from list */ + list_remove(nbr_table_keys, least_used_key); + /* Return associated key */ +} + static nbr_table_key_t * nbr_table_allocate(nbr_table_reason_t reason, void *data) { @@ -253,21 +273,7 @@ nbr_table_allocate(nbr_table_reason_t reason, void *data) return NULL; } else { /* Reuse least used item */ - int i; - for(i = 0; icallback != NULL) { - /* Call table callback for each table that uses this item */ - nbr_table_item_t *removed_item = item_from_key(all_tables[i], least_used_key); - if(nbr_get_bit(used_map, all_tables[i], removed_item) == 1) { - all_tables[i]->callback(removed_item); - } - } - } - /* Empty used map */ - used_map[index_from_key(least_used_key)] = 0; - /* Remove neighbor from list */ - list_remove(nbr_table_keys, least_used_key); - /* Return associated key */ + remove_key(least_used_key); return least_used_key; } } @@ -416,6 +422,39 @@ nbr_table_get_lladdr(nbr_table_t *table, const void *item) return key != NULL ? &key->lladdr : NULL; } /*---------------------------------------------------------------------------*/ +/* Update link-layer address of an item */ +int +nbr_table_update_lladdr(const linkaddr_t *old_addr, const linkaddr_t *new_addr, + int remove_if_duplicate) +{ + int index; + int new_index; + nbr_table_key_t *key; + index = index_from_lladdr(old_addr); + if(index == -1) { + /* Failure to change since there is nothing to change. */ + return 0; + } + if((new_index = index_from_lladdr(new_addr)) != -1) { + /* check if it is a change or not - do not remove / fail if same */ + if(new_index == index) { + return 1; + } + /* This new entry already exists - failure! - remove if requested. */ + if(remove_if_duplicate) { + remove_key(key_from_index(index)); + } + return 0; + } + key = key_from_index(index); + /** + * Copy the new lladdr into the key - since we know that there is no + * conflicting entry. + */ + memcpy(&key->lladdr, new_addr, sizeof(linkaddr_t)); + return 1; +} +/*---------------------------------------------------------------------------*/ #if DEBUG static void print_table() diff --git a/core/net/nbr-table.h b/core/net/nbr-table.h index 88a90a46c..c797a44ec 100644 --- a/core/net/nbr-table.h +++ b/core/net/nbr-table.h @@ -109,6 +109,7 @@ int nbr_table_unlock(nbr_table_t *table, nbr_table_item_t *item); /** \name Neighbor tables: address manipulation */ /** @{ */ linkaddr_t *nbr_table_get_lladdr(nbr_table_t *table, const nbr_table_item_t *item); +int nbr_table_update_lladdr(const linkaddr_t *old_addr, const linkaddr_t *new_addr, int remove_if_duplicate); /** @} */ #endif /* NBR_TABLE_H_ */ From d9f4d97a41496d0bd7f92cc6e5856adcceffc87d Mon Sep 17 00:00:00 2001 From: Pere Tuset Date: Tue, 19 Apr 2016 22:35:31 +0200 Subject: [PATCH 180/374] Adapted OpenMote-CC2538 sensor drivers to Contiki sensor API. --- examples/openmote-cc2538/openmote-demo.c | 55 +++++------ platform/openmote-cc2538/dev/adxl346.c | 111 ++++++++++++--------- platform/openmote-cc2538/dev/adxl346.h | 36 ++----- platform/openmote-cc2538/dev/max44009.c | 97 ++++++++++++++++--- platform/openmote-cc2538/dev/max44009.h | 31 ++---- platform/openmote-cc2538/dev/sht21.c | 117 +++++++++++++++++++---- platform/openmote-cc2538/dev/sht21.h | 43 +++------ 7 files changed, 304 insertions(+), 186 deletions(-) diff --git a/examples/openmote-cc2538/openmote-demo.c b/examples/openmote-cc2538/openmote-demo.c index f36c3a0b4..46a301511 100644 --- a/examples/openmote-cc2538/openmote-demo.c +++ b/examples/openmote-cc2538/openmote-demo.c @@ -83,31 +83,29 @@ static struct broadcast_conn bc; PROCESS_THREAD(openmote_demo_process, ev, data) { static struct etimer et; - static unsigned int raw, counter; - static uint8_t adxl346_present, max44009_present, sht21_present; - static float light, temperature, humidity; + static int16_t counter; + static uint16_t adxl346_present, sht21_present, max44009_present; + static uint16_t accel, light, temperature, humidity; PROCESS_EXITHANDLER(broadcast_close(&bc)) PROCESS_BEGIN(); - adxl346_init(); - adxl346_present = adxl346_is_present(); - if(!adxl346_present) { + /* Initialize and activate the ADXL346 sensor */ + adxl346_present = SENSORS_ACTIVATE(adxl346); + if(adxl346_present == ADXL346_ERROR) { printf("ADXL346 sensor is NOT present!\n"); leds_on(LEDS_YELLOW); } - max44009_init(); - max44009_present = max44009_is_present(); - if(!max44009_present) { + max44009_present = SENSORS_ACTIVATE(max44009); + if(max44009_present == MAX44009_ERROR) { printf("MAX44009 sensor is NOT present!\n"); leds_on(LEDS_ORANGE); } - sht21_init(); - sht21_present = sht21_is_present(); - if(!sht21_present) { + sht21_present = SENSORS_ACTIVATE(sht21); + if(sht21_present == SHT21_ERROR) { printf("SHT21 sensor is NOT present!\n"); leds_on(LEDS_RED); } @@ -123,33 +121,30 @@ PROCESS_THREAD(openmote_demo_process, ev, data) PROCESS_YIELD(); if(ev == PROCESS_EVENT_TIMER) { - if(adxl346_present) { + if(adxl346_present != ADXL346_ERROR) { leds_on(LEDS_YELLOW); - raw = adxl346_read_x(); - printf("X Acceleration: %u\n", raw); - raw = adxl346_read_y(); - printf("Y Acceleration: %u\n", raw); - raw = adxl346_read_z(); - printf("Z Acceleration: %u\n", raw); + accel = adxl346.value(ADXL346_READ_X); + printf("X Acceleration: %u\n", accel); + accel = adxl346.value(ADXL346_READ_Y); + printf("Y Acceleration: %u\n", accel); + accel = adxl346.value(ADXL346_READ_Z); + printf("Z Acceleration: %u\n", accel); leds_off(LEDS_YELLOW); } - if(max44009_present) { + if(max44009_present != MAX44009_ERROR) { leds_on(LEDS_ORANGE); - raw = max44009_read_light(); - light = max44009_convert_light(raw); - printf("Light: %u.%ulux\n", (unsigned int)light, (unsigned int)(light * 100) % 100); + light = max44009.value(MAX44009_READ_LIGHT); + printf("Light: %u.%ulux\n", light / 100, light % 100); leds_off(LEDS_ORANGE); } - if(sht21_present) { + if(sht21_present != SHT21_ERROR) { leds_on(LEDS_RED); - raw = sht21_read_temperature(); - temperature = sht21_convert_temperature(raw); - printf("Temperature: %u.%uC\n", (unsigned int)temperature, (unsigned int)(temperature * 100) % 100); - raw = sht21_read_humidity(); - humidity = sht21_convert_humidity(raw); - printf("Rel. humidity: %u.%u%%\n", (unsigned int)humidity, (unsigned int)(humidity * 100) % 100); + temperature = sht21.value(SHT21_READ_TEMP); + printf("Temperature: %u.%uC\n", temperature / 100, temperature % 100); + humidity = sht21.value(SHT21_READ_RHUM); + printf("Rel. humidity: %u.%u%%\n", humidity / 100, humidity % 100); leds_off(LEDS_RED); } diff --git a/platform/openmote-cc2538/dev/adxl346.c b/platform/openmote-cc2538/dev/adxl346.c index 650b7cfda..7fb406051 100644 --- a/platform/openmote-cc2538/dev/adxl346.c +++ b/platform/openmote-cc2538/dev/adxl346.c @@ -43,6 +43,14 @@ /*---------------------------------------------------------------------------*/ #include "dev/i2c.h" #include "dev/adxl346.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif /*---------------------------------------------------------------------------*/ /** * \name ADXL346 address and device identifier @@ -147,7 +155,9 @@ #define ADXL346_DATA_FORMAT_RANGE_PM_16g (3) /** @} */ /*---------------------------------------------------------------------------*/ -void +static uint8_t enabled; +/*---------------------------------------------------------------------------*/ +static void adxl346_init(void) { uint8_t config[2]; @@ -167,12 +177,7 @@ adxl346_init(void) i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); } /*---------------------------------------------------------------------------*/ -void -adxl346_reset(void) -{ -} -/*---------------------------------------------------------------------------*/ -uint8_t +static uint8_t adxl346_is_present(void) { uint8_t is_present; @@ -183,47 +188,15 @@ adxl346_is_present(void) return is_present == ADXL346_DEVID_VALUE; } /*---------------------------------------------------------------------------*/ -uint16_t -adxl346_read_x(void) -{ - uint8_t acceleration[2]; - uint16_t x; - - i2c_single_send(ADXL346_ADDRESS, ADXL346_DATAX0_ADDR); - i2c_single_receive(ADXL346_ADDRESS, &acceleration[0]); - i2c_single_send(ADXL346_ADDRESS, ADXL346_DATAX1_ADDR); - i2c_single_receive(ADXL346_ADDRESS, &acceleration[1]); - - x = (acceleration[0] << 8) | acceleration[1]; - - return x; -} -/*---------------------------------------------------------------------------*/ -uint16_t -adxl346_read_y(void) -{ - uint8_t acceleration[2]; - uint16_t y; - - i2c_single_send(ADXL346_ADDRESS, ADXL346_DATAY0_ADDR); - i2c_single_receive(ADXL346_ADDRESS, &acceleration[0]); - i2c_single_send(ADXL346_ADDRESS, ADXL346_DATAY1_ADDR); - i2c_single_receive(ADXL346_ADDRESS, &acceleration[1]); - - y = (acceleration[0] << 8) | acceleration[1]; - - return y; -} -/*---------------------------------------------------------------------------*/ -uint16_t -adxl346_read_z(void) +static uint16_t +adxl346_read_accel(uint8_t addr1, uint8_t addr2) { uint8_t acceleration[2]; uint16_t z; - i2c_single_send(ADXL346_ADDRESS, ADXL346_DATAZ0_ADDR); + i2c_single_send(ADXL346_ADDRESS, addr1); i2c_single_receive(ADXL346_ADDRESS, &acceleration[0]); - i2c_single_send(ADXL346_ADDRESS, ADXL346_DATAZ1_ADDR); + i2c_single_send(ADXL346_ADDRESS, addr2); i2c_single_receive(ADXL346_ADDRESS, &acceleration[1]); z = (acceleration[0] << 8) | acceleration[1]; @@ -231,4 +204,56 @@ adxl346_read_z(void) return z; } /*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + if(!enabled) { + PRINTF("ADXL346: sensor not started\n"); + return ADXL346_ERROR; + } + + if(type == ADXL346_READ_X) { + return adxl346_read_accel(ADXL346_DATAX0_ADDR, ADXL346_DATAX1_ADDR); + } else if(type == ADXL346_READ_Y) { + return adxl346_read_accel(ADXL346_DATAY0_ADDR, ADXL346_DATAY1_ADDR); + } else if(type == ADXL346_READ_Z) { + return adxl346_read_accel(ADXL346_DATAZ0_ADDR, ADXL346_DATAZ1_ADDR); + } else { + PRINTF("ADXL346: invalid value requested\n"); + return ADXL346_ERROR; + } + + return ADXL346_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type == ADXL346_ACTIVATE) { + if(!adxl346_is_present()) { + PRINTF("ADXL346: is not present\n"); + return ADXL346_ERROR; + } else { + adxl346_init(); + enabled = 1; + return ADXL346_SUCCESS; + } + } + + return ADXL346_ERROR; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(adxl346, ADXL346_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ /** @} */ diff --git a/platform/openmote-cc2538/dev/adxl346.h b/platform/openmote-cc2538/dev/adxl346.h index d5751ce70..acd0d21f5 100644 --- a/platform/openmote-cc2538/dev/adxl346.h +++ b/platform/openmote-cc2538/dev/adxl346.h @@ -47,35 +47,17 @@ #ifndef ADXL346_H_ #define ADXL346_H_ /*---------------------------------------------------------------------------*/ -/** - * \brief Initialize the ADXL346 sensor - */ -void adxl346_init(void); +#define ADXL346_ERROR (-1) +#define ADXL346_SUCCESS (0) +#define ADXL346_ACTIVATE (SENSORS_ACTIVE) +#define ADXL346_READ_X (2) +#define ADXL346_READ_Y (3) +#define ADXL346_READ_Z (4) +#define ADXL346_NONE (5) /*---------------------------------------------------------------------------*/ -/** - * \brief Reset the ADXL346 sensor - */ -void adxl346_reset(void); +#define ADXL346_SENSOR "ADXL346 Sensor" /*---------------------------------------------------------------------------*/ -/** - * \brief Check if the ADXL346 sensor is present - */ -uint8_t adxl346_is_present(void); -/*---------------------------------------------------------------------------*/ -/** - * \brief Read the x-axis from the ADXL346 sensor - */ -uint16_t adxl346_read_x(void); -/*---------------------------------------------------------------------------*/ -/** - * \brief Read the y-axis from the ADXL346 sensor - */ -uint16_t adxl346_read_y(void); -/*---------------------------------------------------------------------------*/ -/** - * \brief Read the z-axis from the ADXL346 sensor - */ -uint16_t adxl346_read_z(void); +extern const struct sensors_sensor adxl346; /*---------------------------------------------------------------------------*/ #endif /* ADXL346_H_ */ /*---------------------------------------------------------------------------*/ diff --git a/platform/openmote-cc2538/dev/max44009.c b/platform/openmote-cc2538/dev/max44009.c index 233b07d13..d7f4e90d9 100644 --- a/platform/openmote-cc2538/dev/max44009.c +++ b/platform/openmote-cc2538/dev/max44009.c @@ -43,6 +43,14 @@ /*---------------------------------------------------------------------------*/ #include "dev/i2c.h" #include "dev/max44009.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 1 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif /*---------------------------------------------------------------------------*/ /** * \name MAX44009 address and device identifier @@ -94,9 +102,17 @@ MAX44009_CONFIG_AUTO | \ MAX44009_CONFIG_CDR_NORMAL | \ MAX44009_CONFIG_INTEGRATION_100ms) + +#define MAX44009_USER_CONFIGURATION (MAX44009_CONFIG_DEFAULT | \ + MAX44009_CONFIG_AUTO | \ + MAX44009_CONFIG_CDR_NORMAL | \ + MAX44009_CONFIG_INTEGRATION_800ms) + /** @} */ /*---------------------------------------------------------------------------*/ -void +static uint8_t enabled; +/*---------------------------------------------------------------------------*/ +static void max44009_init(void) { uint8_t max44009_address[5] = { MAX44009_INT_ENABLE_ADDR, MAX44009_CONFIG_ADDR, \ @@ -106,8 +122,8 @@ max44009_init(void) uint8_t max44009_data[2]; uint8_t i; - max44009_value[0] = (MAX44009_INT_STATUS_ON); - max44009_value[1] = (MAX44009_DEFAULT_CONFIGURATION); + max44009_value[0] = (MAX44009_INT_STATUS_OFF); + max44009_value[1] = (MAX44009_USER_CONFIGURATION); max44009_value[2] = (0xFF); max44009_value[3] = (0x00); max44009_value[4] = (0xFF); @@ -119,7 +135,7 @@ max44009_init(void) } } /*---------------------------------------------------------------------------*/ -void +static void max44009_reset(void) { uint8_t max44009_address[5] = { MAX44009_INT_ENABLE_ADDR, MAX44009_CONFIG_ADDR, \ @@ -136,7 +152,7 @@ max44009_reset(void) } } /*---------------------------------------------------------------------------*/ -uint8_t +static uint8_t max44009_is_present(void) { uint8_t status; @@ -151,12 +167,12 @@ max44009_is_present(void) return is_present != MAX44009_NOT_FOUND; } /*---------------------------------------------------------------------------*/ -uint16_t +static uint16_t max44009_read_light(void) { uint8_t exponent, mantissa; uint8_t max44009_data[2]; - uint16_t result; + uint32_t result; i2c_single_send(MAX44009_ADDRESS, MAX44009_LUX_HIGH_ADDR); i2c_single_receive(MAX44009_ADDRESS, &max44009_data[0]); @@ -171,20 +187,77 @@ max44009_read_light(void) return result; } /*---------------------------------------------------------------------------*/ -float +static uint16_t max44009_convert_light(uint16_t lux) { uint8_t exponent, mantissa; - float result = 0.045; + uint32_t result; exponent = (lux >> 8) & 0xFF; exponent = (exponent == 0x0F ? exponent & 0x0E : exponent); - mantissa = (lux >> 0) & 0xFF; - result *= 2 ^ exponent * mantissa; + result = 45 * (2 ^ exponent * mantissa) / 10; - return result; + return (uint16_t)result; } /*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + uint16_t value; + + if(!enabled) { + PRINTF("MAX44009: sensor not started\n"); + return MAX44009_ERROR; + } + + if(type == MAX44009_READ_RAW_LIGHT) { + return max44009_read_light(); + } else if(type == MAX44009_READ_LIGHT) { + value = max44009_read_light(); + return max44009_convert_light(value); + } else { + PRINTF("MAX44009: invalid value requested\n"); + return MAX44009_ERROR; + } +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type == MAX44009_ACTIVATE) { + if(!max44009_is_present()) { + return MAX44009_ERROR; + } else { + max44009_init(); + enabled = 1; + return MAX44009_SUCCESS; + } + } + + if((type == MAX44009_RESET) && enabled) { + max44009_reset(); + return MAX44009_SUCCESS; + } else { + PRINTF("MAX44009: is not enabled\n"); + return MAX44009_ERROR; + } + + return MAX44009_ERROR; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(max44009, MAX44009_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ /** @} */ diff --git a/platform/openmote-cc2538/dev/max44009.h b/platform/openmote-cc2538/dev/max44009.h index e94a91fca..32ba101e8 100644 --- a/platform/openmote-cc2538/dev/max44009.h +++ b/platform/openmote-cc2538/dev/max44009.h @@ -47,30 +47,17 @@ #ifndef MAX44009_H_ #define MAX44009_H_ /*---------------------------------------------------------------------------*/ -/** - * \brief Initialize the MAX44009 sensor - */ -void max44009_init(void); +#define MAX44009_ERROR (-1) +#define MAX44009_SUCCESS (0) +#define MAX44009_ACTIVATE (SENSORS_ACTIVE) +#define MAX44009_READ_RAW_LIGHT (2) +#define MAX44009_READ_LIGHT (3) +#define MAX44009_RESET (4) +#define MAX44009_NONE (5) /*---------------------------------------------------------------------------*/ -/** - * \brief Reset the MAX44009 sensor - */ -void max44009_reset(void); +#define MAX44009_SENSOR "MAX44009 Sensor" /*---------------------------------------------------------------------------*/ -/** - * \brief Check if the MAX44009 sensor is present - */ -uint8_t max44009_is_present(void); -/*---------------------------------------------------------------------------*/ -/** - * \brief Read the light from the MAX44009 sensor - */ -uint16_t max44009_read_light(void); -/*---------------------------------------------------------------------------*/ -/** - * \brief Convert the light from the MAX44009 sensor - */ -float max44009_convert_light(uint16_t light); +extern const struct sensors_sensor max44009; /*---------------------------------------------------------------------------*/ #endif /* MAX44009_H_ */ /*---------------------------------------------------------------------------*/ diff --git a/platform/openmote-cc2538/dev/sht21.c b/platform/openmote-cc2538/dev/sht21.c index 989fe2905..4fd577e01 100644 --- a/platform/openmote-cc2538/dev/sht21.c +++ b/platform/openmote-cc2538/dev/sht21.c @@ -41,8 +41,16 @@ * Pere Tuset */ /*---------------------------------------------------------------------------*/ -#include "i2c.h" -#include "sht21.h" +#include "dev/i2c.h" +#include "dev/sht21.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif /*---------------------------------------------------------------------------*/ /** * \name SHT21 address @@ -87,13 +95,15 @@ SHT21_BATTERY_ABOVE_2V25 | \ SHT21_OTP_RELOAD_DISABLE) -#define SHT21_USER_CONFIG (SHT21_RESOLUTION_8b_12b | \ +#define SHT21_USER_CONFIG (SHT21_RESOLUTION_12b_14b | \ SHT21_ONCHIP_HEATER_DISABLE | \ SHT21_BATTERY_ABOVE_2V25 | \ SHT21_OTP_RELOAD_DISABLE) /** @} */ /*---------------------------------------------------------------------------*/ -void +static uint8_t enabled; +/*---------------------------------------------------------------------------*/ +static void sht21_init(void) { uint8_t config[2]; @@ -116,14 +126,14 @@ sht21_init(void) i2c_burst_send(SHT21_ADDRESS, config, sizeof(config)); } /*---------------------------------------------------------------------------*/ -void +static void sht21_reset(void) { /* Send a soft-reset command according to the datasheet (pag. 9, fig. 17) */ i2c_single_send(SHT21_ADDRESS, SHT21_RESET_CMD); } /*---------------------------------------------------------------------------*/ -uint8_t +static uint8_t sht21_is_present(void) { uint8_t status; @@ -142,7 +152,7 @@ sht21_is_present(void) return (is_present == SHT21_USER_CONFIG) || (is_present == SHT21_DEFAULT_CONFIG); } /*---------------------------------------------------------------------------*/ -uint16_t +static uint32_t sht21_read_temperature(void) { uint8_t sht21_temperature[2]; @@ -152,23 +162,24 @@ sht21_read_temperature(void) i2c_single_send(SHT21_ADDRESS, SHT21_TEMPERATURE_HM_CMD); i2c_burst_receive(SHT21_ADDRESS, sht21_temperature, sizeof(sht21_temperature)); - temperature = (sht21_temperature[0] << 8) | (sht21_temperature[1] & SHT21_STATUS_MASK); + temperature = (sht21_temperature[0] << 8) | ((sht21_temperature[1] & SHT21_STATUS_MASK)); return temperature; } /*---------------------------------------------------------------------------*/ -float -sht21_convert_temperature(uint16_t temperature) +static int16_t +sht21_convert_temperature(uint32_t temperature) { - float result; + int16_t result; - result = -46.85; - result += 175.72 * (float)temperature / 65536.0; + temperature *= 17572; + temperature = temperature >> 16; + result = (int16_t)temperature - 4685; return result; } /*---------------------------------------------------------------------------*/ -uint16_t +static uint32_t sht21_read_humidity(void) { uint8_t sht21_humidity[2]; @@ -178,20 +189,86 @@ sht21_read_humidity(void) i2c_single_send(SHT21_ADDRESS, SHT21_HUMIDITY_HM_CMD); i2c_burst_receive(SHT21_ADDRESS, sht21_humidity, sizeof(sht21_humidity)); - humidity = (sht21_humidity[0] << 8) | (sht21_humidity[1] & SHT21_STATUS_MASK); + humidity = (sht21_humidity[0] << 8) | ((sht21_humidity[1] & SHT21_STATUS_MASK)); return humidity; } /*---------------------------------------------------------------------------*/ -float -sht21_convert_humidity(uint16_t humidity) +static int16_t +sht21_convert_humidity(uint32_t humidity) { - float result; + int16_t result; - result = -6.0; - result += 125.0 * (float)humidity / 65536.0; + humidity *= 12500; + humidity = humidity >> 16; + result = (int16_t)humidity - 600; + result = (result > 10000) ? 10000 : result; return result; } /*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + uint32_t value; + + if(!enabled) { + PRINTF("SHT21: sensor not started\n"); + return SHT21_ERROR; + } + + if(type == SHT21_READ_RAW_TEMP) { + return sht21_read_temperature(); + } else if(type == SHT21_READ_RAW_RHUM) { + return sht21_read_humidity(); + } else if(type == SHT21_READ_TEMP) { + value = sht21_read_temperature(); + return sht21_convert_temperature(value); + } else if(type == SHT21_READ_RHUM) { + value = sht21_read_humidity(); + return sht21_convert_humidity(value); + } else { + PRINTF("SHT21: invalid value requested\n"); + return SHT21_ERROR; + } +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type == SHT21_ACTIVATE) { + if(!sht21_is_present()) { + PRINTF("SHT21: is not present\n"); + return SHT21_ERROR; + } else { + sht21_init(); + enabled = 1; + return SHT21_SUCCESS; + } + } + + if(type == SHT21_RESET && enabled) { + sht21_reset(); + return SHT21_SUCCESS; + } else { + PRINTF("SHT21: is not enabled\n"); + return SHT21_ERROR; + } + + return SHT21_ERROR; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(sht21, SHT21_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ /** @} */ diff --git a/platform/openmote-cc2538/dev/sht21.h b/platform/openmote-cc2538/dev/sht21.h index 1483a70a9..3304d915e 100644 --- a/platform/openmote-cc2538/dev/sht21.h +++ b/platform/openmote-cc2538/dev/sht21.h @@ -47,40 +47,19 @@ #ifndef SHT21_H_ #define SHT21_H_ /*---------------------------------------------------------------------------*/ -/** - * \brief Initialize the SHT21 sensor - */ -void sht21_init(void); +#define SHT21_ERROR (-1) +#define SHT21_SUCCESS (0) +#define SHT21_ACTIVATE (SENSORS_ACTIVE) +#define SHT21_READ_RAW_TEMP (2) +#define SHT21_READ_RAW_RHUM (3) +#define SHT21_READ_TEMP (4) +#define SHT21_READ_RHUM (5) +#define SHT21_RESET (6) +#define SHT21_NONE (7) /*---------------------------------------------------------------------------*/ -/** - * \brief Reset the SHT21 sensor - */ -void sht21_reset(void); +#define SHT21_SENSOR "SHT21 Sensor" /*---------------------------------------------------------------------------*/ -/** - * \brief Check if the SHT21 sensor is present - */ -uint8_t sht21_is_present(void); -/*---------------------------------------------------------------------------*/ -/** - * \brief Read the temperature from the SHT21 sensor - */ -uint16_t sht21_read_temperature(void); -/*---------------------------------------------------------------------------*/ -/** - * \brief Convert the temperature from the SHT21 sensor - */ -float sht21_convert_temperature(uint16_t temperature); -/*---------------------------------------------------------------------------*/ -/** - * \brief Read the relative humidity from the SHT21 sensor - */ -uint16_t sht21_read_humidity(void); -/*---------------------------------------------------------------------------*/ -/** - * \brief Convert the relative humidity from the SHT21 sensor - */ -float sht21_convert_humidity(uint16_t humidity); +extern const struct sensors_sensor sht21; /*---------------------------------------------------------------------------*/ #endif /* SHT21_H_ */ /*---------------------------------------------------------------------------*/ From 2ad3d85d412b765bb6415ae96f937172f44aa6fa Mon Sep 17 00:00:00 2001 From: Bernhard Hackl Date: Wed, 20 Apr 2016 08:14:08 +0000 Subject: [PATCH 181/374] Fix slip config switch statement --- examples/ipv6/native-border-router/slip-config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ipv6/native-border-router/slip-config.c b/examples/ipv6/native-border-router/slip-config.c index 782259f8c..d6b6e0660 100644 --- a/examples/ipv6/native-border-router/slip-config.c +++ b/examples/ipv6/native-border-router/slip-config.c @@ -67,7 +67,7 @@ int slip_config_handle_arguments(int argc, char **argv) { const char *prog; - char c; + int c; int baudrate = 115200; slip_config_verbose = 0; From 7f700c9564dfb6ec0b3308412187fc04579b8ae5 Mon Sep 17 00:00:00 2001 From: Nicolas Tsiftes Date: Wed, 20 Apr 2016 12:47:37 +0200 Subject: [PATCH 182/374] Remove the protected memory code associated with sensornet checkpointing because this functionality has been removed from Contiki. --- core/cfs/cfs-coffee.c | 49 ++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 31 deletions(-) diff --git a/core/cfs/cfs-coffee.c b/core/cfs/cfs-coffee.c index 4b08d4544..ea158dfb9 100644 --- a/core/cfs/cfs-coffee.c +++ b/core/cfs/cfs-coffee.c @@ -201,21 +201,13 @@ struct log_param { }; /* - * The protected memory consists of structures that should not be - * overwritten during system checkpointing because they may be used by - * the checkpointing implementation. These structures need not be - * protected if checkpointing is not used. + * Variables that keep track of opened files and internal + * optimization information for Coffee. */ -static struct protected_mem_t { - struct file coffee_files[COFFEE_MAX_OPEN_FILES]; - struct file_desc coffee_fd_set[COFFEE_FD_SET_SIZE]; - coffee_page_t next_free; - char gc_wait; -} protected_mem; -static struct file *const coffee_files = protected_mem.coffee_files; -static struct file_desc *const coffee_fd_set = protected_mem.coffee_fd_set; -static coffee_page_t *const next_free = &protected_mem.next_free; -static char *const gc_wait = &protected_mem.gc_wait; +static struct file coffee_files[COFFEE_MAX_OPEN_FILES]; +static struct file_desc coffee_fd_set[COFFEE_FD_SET_SIZE]; +static coffee_page_t next_free; +static char gc_wait; /*---------------------------------------------------------------------------*/ static void @@ -387,8 +379,8 @@ collect_garbage(int mode) if((mode == GC_RELUCTANT && stats.free == 0) || (mode == GC_GREEDY && stats.obsolete > 0)) { first_page = sector * COFFEE_PAGES_PER_SECTOR; - if(first_page < *next_free) { - *next_free = first_page; + if(first_page < next_free) { + next_free = first_page; } if(isolation_count > 0) { @@ -539,7 +531,7 @@ find_contiguous_pages(coffee_page_t amount) struct file_header hdr; start = INVALID_PAGE; - for(page = *next_free; page < COFFEE_PAGE_COUNT;) { + for(page = next_free; page < COFFEE_PAGE_COUNT;) { read_header(&hdr, page); if(HDR_FREE(hdr)) { if(start == INVALID_PAGE) { @@ -555,8 +547,8 @@ find_contiguous_pages(coffee_page_t amount) page = next_file(page, &hdr); if(start + amount <= page) { - if(start == *next_free) { - *next_free = start + amount; + if(start == next_free) { + next_free = start + amount; } return start; } @@ -589,7 +581,7 @@ remove_by_page(coffee_page_t page, int remove_log, int close_fds, hdr.flags |= HDR_FLAG_OBSOLETE; write_header(&hdr, page); - *gc_wait = 0; + gc_wait = 0; /* Close all file descriptors that reference the removed file. */ if(close_fds) { @@ -638,13 +630,13 @@ reserve(const char *name, coffee_page_t pages, page = find_contiguous_pages(pages); if(page == INVALID_PAGE) { - if(*gc_wait) { + if(gc_wait) { return NULL; } collect_garbage(GC_GREEDY); page = find_contiguous_pages(pages); if(page == INVALID_PAGE) { - *gc_wait = 1; + gc_wait = 1; return NULL; } } @@ -1346,24 +1338,19 @@ cfs_coffee_format(void) PRINTF("Coffee: Formatting %u sectors", COFFEE_SECTOR_COUNT); - *next_free = 0; - for(i = 0; i < COFFEE_SECTOR_COUNT; i++) { COFFEE_ERASE(i); PRINTF("."); } /* Formatting invalidates the file information. */ - memset(&protected_mem, 0, sizeof(protected_mem)); + memset(&coffee_files, 0, sizeof(coffee_files)); + memset(&coffee_fd_set, 0, sizeof(coffee_fd_set)); + next_free = 0; + gc_wait = 1; PRINTF(" done!\n"); return 0; } /*---------------------------------------------------------------------------*/ -void * -cfs_coffee_get_protected_mem(unsigned *size) -{ - *size = sizeof(protected_mem); - return &protected_mem; -} From 86733e87020686306fd16bdb191ad4c64759dd1c Mon Sep 17 00:00:00 2001 From: Nicolas Tsiftes Date: Wed, 20 Apr 2016 14:30:20 +0200 Subject: [PATCH 183/374] Clarified and cleaned up Coffee's documentation and the debug statements. Formatted some source code for easier reading. --- core/cfs/cfs-coffee.c | 77 ++++++++++++++++++++++--------------------- core/cfs/cfs-coffee.h | 41 ++++++++++------------- 2 files changed, 56 insertions(+), 62 deletions(-) diff --git a/core/cfs/cfs-coffee.c b/core/cfs/cfs-coffee.c index ea158dfb9..6391e173c 100644 --- a/core/cfs/cfs-coffee.c +++ b/core/cfs/cfs-coffee.c @@ -114,41 +114,41 @@ #define GC_RELUCTANT 1 /* File descriptor macros. */ -#define FD_VALID(fd) \ - ((fd) >= 0 && (fd) < COFFEE_FD_SET_SIZE && \ - coffee_fd_set[(fd)].flags != COFFEE_FD_FREE) +#define FD_VALID(fd) ((fd) >= 0 && (fd) < COFFEE_FD_SET_SIZE && \ + coffee_fd_set[(fd)].flags != COFFEE_FD_FREE) #define FD_READABLE(fd) (coffee_fd_set[(fd)].flags & CFS_READ) #define FD_WRITABLE(fd) (coffee_fd_set[(fd)].flags & CFS_WRITE) #define FD_APPENDABLE(fd) (coffee_fd_set[(fd)].flags & CFS_APPEND) /* File object macros. */ -#define FILE_MODIFIED(file) ((file)->flags & COFFEE_FILE_MODIFIED) -#define FILE_FREE(file) ((file)->max_pages == 0) +#define FILE_MODIFIED(file) ((file)->flags & COFFEE_FILE_MODIFIED) +#define FILE_FREE(file) ((file)->max_pages == 0) #define FILE_UNREFERENCED(file) ((file)->references == 0) /* File header flags. */ -#define HDR_FLAG_VALID 0x1 /* Completely written header. */ -#define HDR_FLAG_ALLOCATED 0x2 /* Allocated file. */ -#define HDR_FLAG_OBSOLETE 0x4 /* File marked for GC. */ -#define HDR_FLAG_MODIFIED 0x8 /* Modified file, log exists. */ -#define HDR_FLAG_LOG 0x10 /* Log file. */ -#define HDR_FLAG_ISOLATED 0x20 /* Isolated page. */ +#define HDR_FLAG_VALID 0x01 /* Completely written header. */ +#define HDR_FLAG_ALLOCATED 0x02 /* Allocated file. */ +#define HDR_FLAG_OBSOLETE 0x04 /* File marked for GC. */ +#define HDR_FLAG_MODIFIED 0x08 /* Modified file, log exists. */ +#define HDR_FLAG_LOG 0x10 /* Log file. */ +#define HDR_FLAG_ISOLATED 0x20 /* Isolated page. */ /* File header macros. */ #define CHECK_FLAG(hdr, flag) ((hdr).flags & (flag)) -#define HDR_VALID(hdr) CHECK_FLAG(hdr, HDR_FLAG_VALID) -#define HDR_ALLOCATED(hdr) CHECK_FLAG(hdr, HDR_FLAG_ALLOCATED) -#define HDR_FREE(hdr) !HDR_ALLOCATED(hdr) -#define HDR_LOG(hdr) CHECK_FLAG(hdr, HDR_FLAG_LOG) -#define HDR_MODIFIED(hdr) CHECK_FLAG(hdr, HDR_FLAG_MODIFIED) -#define HDR_ISOLATED(hdr) CHECK_FLAG(hdr, HDR_FLAG_ISOLATED) -#define HDR_OBSOLETE(hdr) CHECK_FLAG(hdr, HDR_FLAG_OBSOLETE) -#define HDR_ACTIVE(hdr) (HDR_ALLOCATED(hdr) && \ - !HDR_OBSOLETE(hdr) && \ - !HDR_ISOLATED(hdr)) +#define HDR_VALID(hdr) CHECK_FLAG(hdr, HDR_FLAG_VALID) +#define HDR_ALLOCATED(hdr) CHECK_FLAG(hdr, HDR_FLAG_ALLOCATED) +#define HDR_FREE(hdr) !HDR_ALLOCATED(hdr) +#define HDR_LOG(hdr) CHECK_FLAG(hdr, HDR_FLAG_LOG) +#define HDR_MODIFIED(hdr) CHECK_FLAG(hdr, HDR_FLAG_MODIFIED) +#define HDR_ISOLATED(hdr) CHECK_FLAG(hdr, HDR_FLAG_ISOLATED) +#define HDR_OBSOLETE(hdr) CHECK_FLAG(hdr, HDR_FLAG_OBSOLETE) +#define HDR_ACTIVE(hdr) (HDR_ALLOCATED(hdr) && \ + !HDR_OBSOLETE(hdr) && \ + !HDR_ISOLATED(hdr)) /* Shortcuts derived from the hardware-dependent configuration of Coffee. */ -#define COFFEE_SECTOR_COUNT (unsigned)(COFFEE_SIZE / COFFEE_SECTOR_SIZE) +#define COFFEE_SECTOR_COUNT \ + (coffee_page_t)(COFFEE_SIZE / COFFEE_SECTOR_SIZE) #define COFFEE_PAGE_COUNT \ ((coffee_page_t)(COFFEE_SIZE / COFFEE_PAGE_SIZE)) #define COFFEE_PAGES_PER_SECTOR \ @@ -235,7 +235,7 @@ absolute_offset(coffee_page_t page, cfs_offset_t offset) } /*---------------------------------------------------------------------------*/ static coffee_page_t -get_sector_status(uint16_t sector, struct sector_status *stats) +get_sector_status(coffee_page_t sector, struct sector_status *stats) { static coffee_page_t skip_pages; static char last_pages_are_active; @@ -305,7 +305,7 @@ get_sector_status(uint16_t sector, struct sector_status *stats) /* * Determine the amount of pages in the following sectors that * should be remembered for the next iteration. This is necessary - * because no page except the first of a file contains information + * because no file page except the first contains information * about what type of page it is. A side effect of remembering this * amount is that there is no need to read in the headers of each * of these pages from the storage. @@ -356,11 +356,11 @@ isolate_pages(coffee_page_t start, coffee_page_t skip_pages) static void collect_garbage(int mode) { - uint16_t sector; + coffee_page_t sector; struct sector_status stats; coffee_page_t first_page, isolation_count; - PRINTF("Coffee: Running the file system garbage collector in %s mode\n", + PRINTF("Coffee: Running the garbage collector in %s mode\n", mode == GC_RELUCTANT ? "reluctant" : "greedy"); /* * The garbage collector erases as many sectors as possible. A sector is @@ -369,7 +369,7 @@ collect_garbage(int mode) for(sector = 0; sector < COFFEE_SECTOR_COUNT; sector++) { isolation_count = get_sector_status(sector, &stats); PRINTF("Coffee: Sector %u has %u active, %u obsolete, and %u free pages.\n", - sector, (unsigned)stats.active, + (unsigned)sector, (unsigned)stats.active, (unsigned)stats.obsolete, (unsigned)stats.free); if(stats.active > 0) { @@ -402,7 +402,7 @@ next_file(coffee_page_t page, struct file_header *hdr) { /* * The quick-skip algorithm for finding file extents is the most - * essential part of Coffee. The file allocation rules enables this + * essential part of Coffee. The file allocation rules enable this * algorithm to quickly jump over free areas and allocated extents * after reading single headers and determining their status. * @@ -648,7 +648,7 @@ reserve(const char *name, coffee_page_t pages, write_header(&hdr, page); PRINTF("Coffee: Reserved %u pages starting from %u for file %s\n", - pages, page, name); + (unsigned)pages, (unsigned)page, name); file = load_file(page, &hdr); if(file != NULL) { @@ -843,7 +843,7 @@ merge_log(coffee_page_t file_page, int extend) return -1; } - /* Copy the log configuration and the EOF hint. */ + /* Copy the log configuration. */ read_header(&hdr2, new_file->page); hdr2.log_record_size = hdr.log_record_size; hdr2.log_records = hdr.log_records; @@ -1102,7 +1102,7 @@ cfs_read(int fd, void *buf, unsigned size) size = file->end - fdp->offset; } - /* If the file is allocated, read directly in the file. */ + /* If the file is not modified, read directly from the file extent. */ if(!FILE_MODIFIED(file)) { COFFEE_READ(buf, size, absolute_offset(file->page, fdp->offset)); fdp->offset += size; @@ -1113,8 +1113,9 @@ cfs_read(int fd, void *buf, unsigned size) read_header(&hdr, file->page); /* - * Fill the buffer by copying from the log in first hand, or the - * ordinary file if the page has no log record. + * Copy the contents of the most recent log record. If there is + * no log record for the file area to read from, we simply read + * from the original file extent. */ for(bytes_left = size; bytes_left > 0; bytes_left -= r) { lp.offset = fdp->offset; @@ -1242,8 +1243,8 @@ int cfs_opendir(struct cfs_dir *dir, const char *name) { /* - * Coffee is only guaranteed to support "/" and ".", but it does not - * currently enforce this. + * Coffee is only guaranteed to support the directory names "/" and ".", + * but it does not enforce this currently. */ memset(dir->dummy_space, 0, sizeof(coffee_page_t)); return 0; @@ -1254,13 +1255,13 @@ cfs_readdir(struct cfs_dir *dir, struct cfs_dirent *record) { struct file_header hdr; coffee_page_t page; + coffee_page_t next_page; memcpy(&page, dir->dummy_space, sizeof(coffee_page_t)); while(page < COFFEE_PAGE_COUNT) { read_header(&hdr, page); if(HDR_ACTIVE(hdr) && !HDR_LOG(hdr)) { - coffee_page_t next_page; memcpy(record->name, hdr.name, sizeof(record->name)); record->name[sizeof(record->name) - 1] = '\0'; record->size = file_end(page); @@ -1334,9 +1335,9 @@ cfs_coffee_set_io_semantics(int fd, unsigned flags) int cfs_coffee_format(void) { - unsigned i; + coffee_page_t i; - PRINTF("Coffee: Formatting %u sectors", COFFEE_SECTOR_COUNT); + PRINTF("Coffee: Formatting %u sectors", (unsigned)COFFEE_SECTOR_COUNT); for(i = 0; i < COFFEE_SECTOR_COUNT; i++) { COFFEE_ERASE(i); diff --git a/core/cfs/cfs-coffee.h b/core/cfs/cfs-coffee.h index a227792a1..2c62f2512 100644 --- a/core/cfs/cfs-coffee.h +++ b/core/cfs/cfs-coffee.h @@ -46,15 +46,15 @@ * invoke its own micro logs when file modifications occur. * * This semantical I/O setting is useful when implementing flash storage - * algorithms on top of Coffee. + * algorithms such as database indices on top of Coffee. * * \sa cfs_coffee_set_io_semantics() */ #define CFS_COFFEE_IO_FLASH_AWARE 0x1 /** - * Instruct Coffee not to attempt to extend the file when there is - * an attempt to write past the reserved file size. + * Instruct Coffee not to attempt to extend the file upon a request + * to write past the reserved file size. * * A case when this is necessary is when the file has a firm size limit, * and a safeguard is needed to protect against writes beyond this limit. @@ -75,8 +75,8 @@ /** * \brief Reserve space for a file. - * \param name The filename. - * \param size The size of the file. + * \param name The file name. + * \param size The initial size to be reserved for the file. * \return 0 on success, -1 on failure. * * Coffee uses sequential page structures for files. The sequential @@ -88,15 +88,15 @@ int cfs_coffee_reserve(const char *name, cfs_offset_t size); /** * \brief Configure the on-demand log file. - * \param file The filename. - * \param log_size The total log size. + * \param file The file name. + * \param log_size The total log file size. * \param log_entry_size The log entry size. * \return 0 on success, -1 on failure. * * When file data is first modified, Coffee creates a micro log for the - * file. The micro log stores a table of modifications whose - * parameters--the log size and the log entry size--can be modified - * through the cfs_coffee_configure_log function. + * file. The micro log stores a table of modifications whose parameters -- + * the log size and the log entry size -- can be modified through the + * cfs_coffee_configure_log function. */ int cfs_coffee_configure_log(const char *file, unsigned log_size, unsigned log_entry_size); @@ -109,8 +109,8 @@ int cfs_coffee_configure_log(const char *file, unsigned log_size, * * Coffee is used on a wide range of storage types, and the default * I/O file semantics may not be optimal for the access pattern - * of a certain file. Hence, this functions allows programmers to - * switch the /O semantics on a file that is accessed through a + * of a certain file. Hence, this function allows programmers to + * switch the I/O semantics on a file that is accessed through a * particular file descriptor. * */ @@ -123,21 +123,14 @@ int cfs_coffee_set_io_semantics(int fd, unsigned flags); * Coffee formats the underlying storage by setting all bits to zero. * Formatting must be done before using Coffee for the first time in * a mote. + * + * Notice that the erased bits may be set to 1 on the physical storage + * when using flash memory. In this case, Coffee requires that the + * COFFEE_READ and COFFEE_WRITE functions used to access the flash memory + * invert all bits. */ int cfs_coffee_format(void); -/** - * \brief Points out a memory region that may not be altered during - * checkpointing operations that use the file system. - * \param size - * \return A pointer to the protected memory. - * - * This function returns the protected memory pointer and writes its size - * to the given parameter. Mainly used by sensornet checkpointing to protect - * the coffee state during CFS-based checkpointing operations. - */ -void *cfs_coffee_get_protected_mem(unsigned *size); - /** @} */ /** @} */ From fb5f0f66dd035463a54968b82711a9974abcb81f Mon Sep 17 00:00:00 2001 From: Nicolas Tsiftes Date: Thu, 21 Apr 2016 13:24:16 +0200 Subject: [PATCH 184/374] Removed Deluge and associated test files. --- apps/deluge/Makefile.deluge | 1 - apps/deluge/deluge.c | 698 ------------------ apps/deluge/deluge.h | 159 ---- examples/sky/test-deluge.c | 115 --- regression-tests/04-rime/04-sky-deluge.csc | 155 ---- ...5-sky-runicast.csc => 04-sky-runicast.csc} | 0 ...{06-sky-trickle.csc => 05-sky-trickle.csc} | 0 regression-tests/04-rime/06-sky-collect.csc | 245 ++++++ regression-tests/04-rime/07-sky-collect.csc | 388 +++++++--- ...cooja-trickle.csc => 08-cooja-trickle.csc} | 0 regression-tests/04-rime/08-sky-collect.csc | 447 ----------- .../{10-cooja-mesh.csc => 09-cooja-mesh.csc} | 0 12 files changed, 540 insertions(+), 1668 deletions(-) delete mode 100644 apps/deluge/Makefile.deluge delete mode 100644 apps/deluge/deluge.c delete mode 100644 apps/deluge/deluge.h delete mode 100644 examples/sky/test-deluge.c delete mode 100644 regression-tests/04-rime/04-sky-deluge.csc rename regression-tests/04-rime/{05-sky-runicast.csc => 04-sky-runicast.csc} (100%) rename regression-tests/04-rime/{06-sky-trickle.csc => 05-sky-trickle.csc} (100%) create mode 100644 regression-tests/04-rime/06-sky-collect.csc rename regression-tests/04-rime/{09-cooja-trickle.csc => 08-cooja-trickle.csc} (100%) delete mode 100644 regression-tests/04-rime/08-sky-collect.csc rename regression-tests/04-rime/{10-cooja-mesh.csc => 09-cooja-mesh.csc} (100%) diff --git a/apps/deluge/Makefile.deluge b/apps/deluge/Makefile.deluge deleted file mode 100644 index abadf18d0..000000000 --- a/apps/deluge/Makefile.deluge +++ /dev/null @@ -1 +0,0 @@ -deluge_src = deluge.c diff --git a/apps/deluge/deluge.c b/apps/deluge/deluge.c deleted file mode 100644 index 9e3235b25..000000000 --- a/apps/deluge/deluge.c +++ /dev/null @@ -1,698 +0,0 @@ -/* - * Copyright (c) 2007, 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. - * - */ - -/** - * \file - * An implementation of the Deluge protocol. - * (Hui and Culler: The dynamic behavior of a data - * dissemination protocol for network programming at scale, - * ACM SenSys 2004) - * \author - * Nicolas Tsiftes - */ - -#include "contiki.h" -#include "net/rime/rime.h" -#include "cfs/cfs.h" -#include "loader/elfloader.h" -#include "lib/crc16.h" -#include "lib/random.h" -#include "sys/node-id.h" -#include "deluge.h" - -#if NETSIM -#include "ether.h" -#include -#endif - -#include "dev/leds.h" -#include -#include - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif - -/* Implementation-specific variables. */ -static struct broadcast_conn deluge_broadcast; -static struct unicast_conn deluge_uc; -static struct deluge_object current_object; -static process_event_t deluge_event; - -/* Deluge variables. */ -static int deluge_state; -static int old_summary; -static int neighbor_inconsistency; -static unsigned r_interval; -static unsigned recv_adv; -static int broadcast_profile; - -/* Deluge timers. */ -static struct ctimer rx_timer; -static struct ctimer tx_timer; -static struct ctimer summary_timer; -static struct ctimer profile_timer; - -/* Deluge objects will get an ID that defaults to the current value of - the next_object_id parameter. */ -static deluge_object_id_t next_object_id; - -/* Rime callbacks. */ -static void broadcast_recv(struct broadcast_conn *, const linkaddr_t *); -static void unicast_recv(struct unicast_conn *, const linkaddr_t *); - -static const struct broadcast_callbacks broadcast_call = {broadcast_recv, NULL}; -static const struct unicast_callbacks unicast_call = {unicast_recv, NULL}; - -/* The Deluge process manages the main Deluge timer. */ -PROCESS(deluge_process, "Deluge"); - -static void -transition(int state) -{ - if(state != deluge_state) { - switch(deluge_state) { - case DELUGE_STATE_MAINTAIN: - ctimer_stop(&summary_timer); - ctimer_stop(&profile_timer); - break; - case DELUGE_STATE_RX: - ctimer_stop(&rx_timer); - break; - case DELUGE_STATE_TX: - ctimer_stop(&tx_timer); - break; - } - deluge_state = state; - } -} - -static int -write_page(struct deluge_object *obj, unsigned pagenum, unsigned char *data) -{ - cfs_offset_t offset; - - offset = pagenum * S_PAGE; - - if(cfs_seek(obj->cfs_fd, offset, CFS_SEEK_SET) != offset) { - return -1; - } - return cfs_write(obj->cfs_fd, (char *)data, S_PAGE); -} - -static int -read_page(struct deluge_object *obj, unsigned pagenum, unsigned char *buf) -{ - cfs_offset_t offset; - - offset = pagenum * S_PAGE; - - if(cfs_seek(obj->cfs_fd, offset, CFS_SEEK_SET) != offset) { - return -1; - } - return cfs_read(obj->cfs_fd, (char *)buf, S_PAGE); -} - -static void -init_page(struct deluge_object *obj, int pagenum, int have) -{ - struct deluge_page *page; - unsigned char buf[S_PAGE]; - - page = &obj->pages[pagenum]; - - page->flags = 0; - page->last_request = 0; - page->last_data = 0; - - if(have) { - page->version = obj->version; - page->packet_set = ALL_PACKETS; - page->flags |= PAGE_COMPLETE; - read_page(obj, pagenum, buf); - page->crc = crc16_data(buf, S_PAGE, 0); - } else { - page->version = 0; - page->packet_set = 0; - } -} - -static cfs_offset_t -file_size(const char *file) -{ - int fd; - cfs_offset_t size; - - fd = cfs_open(file, CFS_READ); - if(fd < 0) { - return (cfs_offset_t)-1; - } - - size = cfs_seek(fd, 0, CFS_SEEK_END); - cfs_close(fd); - - return size; -} - -static int -init_object(struct deluge_object *obj, char *filename, unsigned version) -{ - static struct deluge_page *page; - int i; - - obj->cfs_fd = cfs_open(filename, CFS_READ | CFS_WRITE); - if(obj->cfs_fd < 0) { - return -1; - } - - obj->filename = filename; - obj->object_id = next_object_id++; - obj->size = file_size(filename); - obj->version = obj->update_version = version; - obj->current_rx_page = 0; - obj->nrequests = 0; - obj->tx_set = 0; - - obj->pages = malloc(OBJECT_PAGE_COUNT(*obj) * sizeof(*obj->pages)); - if(obj->pages == NULL) { - cfs_close(obj->cfs_fd); - return -1; - } - - for(i = 0; i < OBJECT_PAGE_COUNT(current_object); i++) { - page = ¤t_object.pages[i]; - init_page(¤t_object, i, 1); - } - - memset(obj->current_page, 0, sizeof(obj->current_page)); - - return 0; -} - -static int -highest_available_page(struct deluge_object *obj) -{ - int i; - - for(i = 0; i < OBJECT_PAGE_COUNT(*obj); i++) { - if(!(obj->pages[i].flags & PAGE_COMPLETE)) { - break; - } - } - - return i; -} - -static void -send_request(void *arg) -{ - struct deluge_object *obj; - struct deluge_msg_request request; - - obj = (struct deluge_object *)arg; - - request.cmd = DELUGE_CMD_REQUEST; - request.pagenum = obj->current_rx_page; - request.version = obj->pages[request.pagenum].version; - request.request_set = ~obj->pages[obj->current_rx_page].packet_set; - request.object_id = obj->object_id; - - PRINTF("Sending request for page %d, version %u, request_set %u\n", - request.pagenum, request.version, request.request_set); - packetbuf_copyfrom(&request, sizeof(request)); - unicast_send(&deluge_uc, &obj->summary_from); - - /* Deluge R.2 */ - if(++obj->nrequests == CONST_LAMBDA) { - /* XXX check rate here too. */ - obj->nrequests = 0; - transition(DELUGE_STATE_MAINTAIN); - } else { - ctimer_reset(&rx_timer); - } -} - -static void -advertise_summary(struct deluge_object *obj) -{ - struct deluge_msg_summary summary; - - if(recv_adv >= CONST_K) { - ctimer_stop(&summary_timer); - return; - } - - summary.cmd = DELUGE_CMD_SUMMARY; - summary.version = obj->update_version; - summary.highest_available = highest_available_page(obj); - summary.object_id = obj->object_id; - - PRINTF("Advertising summary for object id %u: version=%u, available=%u\n", - (unsigned)obj->object_id, summary.version, summary.highest_available); - - packetbuf_copyfrom(&summary, sizeof(summary)); - broadcast_send(&deluge_broadcast); -} - -static void -handle_summary(struct deluge_msg_summary *msg, const linkaddr_t *sender) -{ - int highest_available, i; - clock_time_t oldest_request, oldest_data, now; - struct deluge_page *page; - - highest_available = highest_available_page(¤t_object); - - if(msg->version != current_object.version || - msg->highest_available != highest_available) { - neighbor_inconsistency = 1; - } else { - recv_adv++; - } - - if(msg->version < current_object.version) { - old_summary = 1; - broadcast_profile = 1; - } - - /* Deluge M.5 */ - if(msg->version == current_object.update_version && - msg->highest_available > highest_available) { - if(msg->highest_available > OBJECT_PAGE_COUNT(current_object)) { - PRINTF("Error: highest available is above object page count!\n"); - return; - } - - oldest_request = oldest_data = now = clock_time(); - for(i = 0; i < msg->highest_available; i++) { - page = ¤t_object.pages[i]; - if(page->last_request < oldest_request) { - oldest_request = page->last_request; - } - if(page->last_request < oldest_data) { - oldest_data = page->last_data; - } - } - - if(((now - oldest_request) / CLOCK_SECOND) <= 2 * r_interval || - ((now - oldest_data) / CLOCK_SECOND) <= r_interval) { - return; - } - - linkaddr_copy(¤t_object.summary_from, sender); - transition(DELUGE_STATE_RX); - - if(ctimer_expired(&rx_timer)) { - ctimer_set(&rx_timer, - CONST_OMEGA * ESTIMATED_TX_TIME + ((unsigned)random_rand() % T_R), - send_request, ¤t_object); - } - } -} - -static void -send_page(struct deluge_object *obj, unsigned pagenum) -{ - unsigned char buf[S_PAGE]; - struct deluge_msg_packet pkt; - unsigned char *cp; - - pkt.cmd = DELUGE_CMD_PACKET; - pkt.pagenum = pagenum; - pkt.version = obj->pages[pagenum].version; - pkt.packetnum = 0; - pkt.object_id = obj->object_id; - pkt.crc = 0; - - read_page(obj, pagenum, buf); - - /* Divide the page into packets and send them one at a time. */ - for(cp = buf; cp + S_PKT <= (unsigned char *)&buf[S_PAGE]; cp += S_PKT) { - if(obj->tx_set & (1 << pkt.packetnum)) { - pkt.crc = crc16_data(cp, S_PKT, 0); - memcpy(pkt.payload, cp, S_PKT); - packetbuf_copyfrom(&pkt, sizeof(pkt)); - broadcast_send(&deluge_broadcast); - } - pkt.packetnum++; - } - obj->tx_set = 0; -} - -static void -tx_callback(void *arg) -{ - struct deluge_object *obj; - - obj = (struct deluge_object *)arg; - if(obj->current_tx_page >= 0 && obj->tx_set) { - send_page(obj, obj->current_tx_page); - /* Deluge T.2. */ - if(obj->tx_set) { - packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, - PACKETBUF_ATTR_PACKET_TYPE_STREAM); - ctimer_reset(&tx_timer); - } else { - packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, - PACKETBUF_ATTR_PACKET_TYPE_STREAM_END); - obj->current_tx_page = -1; - transition(DELUGE_STATE_MAINTAIN); - } - } -} - -static void -handle_request(struct deluge_msg_request *msg) -{ - int highest_available; - - if(msg->pagenum >= OBJECT_PAGE_COUNT(current_object)) { - return; - } - - if(msg->version != current_object.version) { - neighbor_inconsistency = 1; - } - - highest_available = highest_available_page(¤t_object); - - /* Deluge M.6 */ - if(msg->version == current_object.version && - msg->pagenum <= highest_available) { - current_object.pages[msg->pagenum].last_request = clock_time(); - - /* Deluge T.1 */ - if(msg->pagenum == current_object.current_tx_page) { - current_object.tx_set |= msg->request_set; - } else { - current_object.current_tx_page = msg->pagenum; - current_object.tx_set = msg->request_set; - } - - transition(DELUGE_STATE_TX); - ctimer_set(&tx_timer, CLOCK_SECOND, tx_callback, ¤t_object); - } -} - -static void -handle_packet(struct deluge_msg_packet *msg) -{ - struct deluge_page *page; - uint16_t crc; - struct deluge_msg_packet packet; - - memcpy(&packet, msg, sizeof(packet)); - - PRINTF("Incoming packet for object id %u, version %u, page %u, packet num %u!\n", - (unsigned)packet.object_id, (unsigned)packet.version, - (unsigned)packet.pagenum, (unsigned)packet.packetnum); - - if(packet.pagenum != current_object.current_rx_page) { - return; - } - - if(packet.version != current_object.version) { - neighbor_inconsistency = 1; - } - - page = ¤t_object.pages[packet.pagenum]; - if(packet.version == page->version && !(page->flags & PAGE_COMPLETE)) { - memcpy(¤t_object.current_page[S_PKT * packet.packetnum], - packet.payload, S_PKT); - - crc = crc16_data(packet.payload, S_PKT, 0); - if(packet.crc != crc) { - PRINTF("packet crc: %hu, calculated crc: %hu\n", packet.crc, crc); - return; - } - - page->last_data = clock_time(); - page->packet_set |= (1 << packet.packetnum); - - if(page->packet_set == ALL_PACKETS) { - /* This is the last packet of the requested page; stop streaming. */ - packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, - PACKETBUF_ATTR_PACKET_TYPE_STREAM_END); - - write_page(¤t_object, packet.pagenum, current_object.current_page); - page->version = packet.version; - page->flags = PAGE_COMPLETE; - PRINTF("Page %u completed\n", packet.pagenum); - - current_object.current_rx_page++; - - if(packet.pagenum == OBJECT_PAGE_COUNT(current_object) - 1) { - current_object.version = current_object.update_version; - leds_on(LEDS_RED); - PRINTF("Update completed for object %u, version %u\n", - (unsigned)current_object.object_id, packet.version); - } else if(current_object.current_rx_page < OBJECT_PAGE_COUNT(current_object)) { - if(ctimer_expired(&rx_timer)) { - ctimer_set(&rx_timer, - CONST_OMEGA * ESTIMATED_TX_TIME + (random_rand() % T_R), - send_request, ¤t_object); - } - } - /* Deluge R.3 */ - transition(DELUGE_STATE_MAINTAIN); - } else { - /* More packets to come. Put lower layers in streaming mode. */ - packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, - PACKETBUF_ATTR_PACKET_TYPE_STREAM); - } - } -} - -static void -send_profile(struct deluge_object *obj) -{ - struct deluge_msg_profile *msg; - unsigned char buf[sizeof(*msg) + OBJECT_PAGE_COUNT(*obj)]; - int i; - - if(broadcast_profile && recv_adv < CONST_K) { - broadcast_profile = 0; - - msg = (struct deluge_msg_profile *)buf; - msg->cmd = DELUGE_CMD_PROFILE; - msg->version = obj->version; - msg->npages = OBJECT_PAGE_COUNT(*obj); - msg->object_id = obj->object_id; - for(i = 0; i < msg->npages; i++) { - msg->version_vector[i] = obj->pages[i].version; - } - - packetbuf_copyfrom(buf, sizeof(buf)); - broadcast_send(&deluge_broadcast); - } -} - -static void -handle_profile(struct deluge_msg_profile *msg) -{ - int i; - int npages; - struct deluge_object *obj; - char *p; - - obj = ¤t_object; - if(msg->version <= current_object.update_version) { - return; - } - - PRINTF("Received profile of version %u with a vector of %u pages.\n", - msg->version, msg->npages); - - leds_off(LEDS_RED); - current_object.tx_set = 0; - - npages = OBJECT_PAGE_COUNT(*obj); - obj->size = msg->npages * S_PAGE; - - p = malloc(OBJECT_PAGE_COUNT(*obj) * sizeof(*obj->pages)); - if(p == NULL) { - PRINTF("Failed to reallocate memory for pages!\n"); - return; - } - - memcpy(p, obj->pages, npages * sizeof(*obj->pages)); - free(obj->pages); - obj->pages = (struct deluge_page *)p; - - if(msg->npages < npages) { - npages = msg->npages; - } - - for(i = 0; i < npages; i++) { - if(msg->version_vector[i] > obj->pages[i].version) { - obj->pages[i].packet_set = 0; - obj->pages[i].flags &= ~PAGE_COMPLETE; - obj->pages[i].version = msg->version_vector[i]; - } - } - - for(; i < msg->npages; i++) { - init_page(obj, i, 0); - } - - obj->current_rx_page = highest_available_page(obj); - obj->update_version = msg->version; - - transition(DELUGE_STATE_RX); - - ctimer_set(&rx_timer, - CONST_OMEGA * ESTIMATED_TX_TIME + ((unsigned)random_rand() % T_R), - send_request, obj); -} - -static void -command_dispatcher(const linkaddr_t *sender) -{ - char *msg; - int len; - struct deluge_msg_profile *profile; - - msg = packetbuf_dataptr(); - len = packetbuf_datalen(); - if(len < 1) - return; - - switch(msg[0]) { - case DELUGE_CMD_SUMMARY: - if(len >= sizeof(struct deluge_msg_summary)) - handle_summary((struct deluge_msg_summary *)msg, sender); - break; - case DELUGE_CMD_REQUEST: - if(len >= sizeof(struct deluge_msg_request)) - handle_request((struct deluge_msg_request *)msg); - break; - case DELUGE_CMD_PACKET: - if(len >= sizeof(struct deluge_msg_packet)) - handle_packet((struct deluge_msg_packet *)msg); - break; - case DELUGE_CMD_PROFILE: - profile = (struct deluge_msg_profile *)msg; - if(len >= sizeof(*profile) && - len >= sizeof(*profile) + profile->npages * profile->version_vector[0]) - handle_profile((struct deluge_msg_profile *)msg); - break; - default: - PRINTF("Incoming packet with unknown command: %d\n", msg[0]); - } -} - -static void -unicast_recv(struct unicast_conn *c, const linkaddr_t *sender) -{ - command_dispatcher(sender); -} - -static void -broadcast_recv(struct broadcast_conn *c, const linkaddr_t *sender) -{ - command_dispatcher(sender); -} - -int -deluge_disseminate(char *file, unsigned version) -{ - /* This implementation disseminates at most one object. */ - if(next_object_id > 0 || init_object(¤t_object, file, version) < 0) { - return -1; - } - process_start(&deluge_process, (void *)file); - - return 0; -} - -PROCESS_THREAD(deluge_process, ev, data) -{ - static struct etimer et; - static unsigned time_counter; - static unsigned r_rand; - - PROCESS_EXITHANDLER(goto exit); - - PROCESS_BEGIN(); - - deluge_event = process_alloc_event(); - - broadcast_open(&deluge_broadcast, DELUGE_BROADCAST_CHANNEL, &broadcast_call); - unicast_open(&deluge_uc, DELUGE_UNICAST_CHANNEL, &unicast_call); - r_interval = T_LOW; - - PRINTF("Maintaining state for object %s of %d pages\n", - current_object.filename, OBJECT_PAGE_COUNT(current_object)); - - deluge_state = DELUGE_STATE_MAINTAIN; - - for(r_interval = T_LOW;;) { - if(neighbor_inconsistency) { - /* Deluge M.2 */ - r_interval = T_LOW; - neighbor_inconsistency = 0; - } else { - /* Deluge M.3 */ - r_interval = (2 * r_interval >= T_HIGH) ? T_HIGH : 2 * r_interval; - } - - r_rand = r_interval / 2 + ((unsigned)random_rand() % (r_interval / 2)); - recv_adv = 0; - old_summary = 0; - - /* Deluge M.1 */ - ctimer_set(&summary_timer, r_rand * CLOCK_SECOND, - (void *)(void *)advertise_summary, ¤t_object); - - /* Deluge M.4 */ - ctimer_set(&profile_timer, r_rand * CLOCK_SECOND, - (void *)(void *)send_profile, ¤t_object); - - LONG_TIMER(et, time_counter, r_interval); - } - -exit: - unicast_close(&deluge_uc); - broadcast_close(&deluge_broadcast); - if(current_object.cfs_fd >= 0) { - cfs_close(current_object.cfs_fd); - } - if(current_object.pages != NULL) { - free(current_object.pages); - } - - PROCESS_END(); -} diff --git a/apps/deluge/deluge.h b/apps/deluge/deluge.h deleted file mode 100644 index 11bdd0a96..000000000 --- a/apps/deluge/deluge.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2007, 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. - * - */ - -/** - * \file - * Header for Deluge. - * \author - * Nicolas Tsiftes - */ - -#ifndef DELUGE_H -#define DELUGE_H - -#include "net/rime/rime.h" - -PROCESS_NAME(deluge_process); - -#define LONG_TIMER(et, counter, time) \ - do { \ - for (counter = 0; counter < time; counter++) { \ - etimer_set(&et, CLOCK_SECOND); \ - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); \ - } \ - } while (0) - -#define DELUGE_UNICAST_CHANNEL 55 -#define DELUGE_BROADCAST_CHANNEL 56 - -/* All the packets in a page have been received. */ -#define PAGE_COMPLETE 1 -/* All pages up to, and including, this page are complete. */ -#define PAGE_AVAILABLE 1 - -#define S_PKT 64 /* Deluge packet size. */ -#define N_PKT 4 /* Packets per page. */ -#define S_PAGE (S_PKT * N_PKT) /* Fixed page size. */ - -/* Bounds for the round time in seconds. */ -#define T_LOW 2 -#define T_HIGH 64 - -/* Random interval for request transmissions in jiffies. */ -#define T_R (CLOCK_SECOND * 2) - -/* Bound for the number of advertisements. */ -#define CONST_K 1 - -/* The number of pages in this object. */ -#define OBJECT_PAGE_COUNT(obj) (((obj).size + (S_PAGE - 1)) / S_PAGE) - -#define ALL_PACKETS ((1 << N_PKT) - 1) - -#define DELUGE_CMD_SUMMARY 1 -#define DELUGE_CMD_REQUEST 2 -#define DELUGE_CMD_PACKET 3 -#define DELUGE_CMD_PROFILE 4 - -#define DELUGE_STATE_MAINTAIN 1 -#define DELUGE_STATE_RX 2 -#define DELUGE_STATE_TX 3 - -#define CONST_LAMBDA 2 -#define CONST_ALPHA 0.5 - -#define CONST_OMEGA 8 -#define ESTIMATED_TX_TIME (CLOCK_SECOND) - -typedef uint8_t deluge_object_id_t; - -struct deluge_msg_summary { - uint8_t cmd; - uint8_t version; - uint8_t highest_available; - deluge_object_id_t object_id; -}; - -struct deluge_msg_request { - uint8_t cmd; - uint8_t version; - uint8_t pagenum; - uint8_t request_set; - deluge_object_id_t object_id; -}; - -struct deluge_msg_packet { - uint8_t cmd; - uint8_t version; - uint8_t pagenum; - uint8_t packetnum; - uint16_t crc; - deluge_object_id_t object_id; - unsigned char payload[S_PKT]; -}; - -struct deluge_msg_profile { - uint8_t cmd; - uint8_t version; - uint8_t npages; - deluge_object_id_t object_id; - uint8_t version_vector[]; -}; - -struct deluge_object { - char *filename; - uint16_t object_id; - uint16_t size; - uint8_t version; - uint8_t update_version; - struct deluge_page *pages; - uint8_t current_rx_page; - int8_t current_tx_page; - uint8_t nrequests; - uint8_t current_page[S_PAGE]; - uint8_t tx_set; - int cfs_fd; - linkaddr_t summary_from; -}; - -struct deluge_page { - uint32_t packet_set; - uint16_t crc; - clock_time_t last_request; - clock_time_t last_data; - uint8_t flags; - uint8_t version; -}; - -int deluge_disseminate(char *file, unsigned version); - -#endif diff --git a/examples/sky/test-deluge.c b/examples/sky/test-deluge.c deleted file mode 100644 index 3bb9bb5e8..000000000 --- a/examples/sky/test-deluge.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2007, 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. - * - */ - -/** - * \file - * A test program for Deluge. - * \author - * Nicolas Tsiftes - */ - -#include "contiki.h" -#include "cfs/cfs.h" -#include "deluge.h" -#include "sys/node-id.h" - -#include -#include - -#ifndef SINK_ID -#define SINK_ID 1 -#endif - -#ifndef FILE_SIZE -#define FILE_SIZE 1000 -#endif - -PROCESS(deluge_test_process, "Deluge test process"); -AUTOSTART_PROCESSES(&deluge_test_process); -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(deluge_test_process, ev, data) -{ - int fd, r; - char buf[32]; - static struct etimer et; - - PROCESS_BEGIN(); - - memset(buf, 0, sizeof(buf)); - if(node_id == SINK_ID) { - strcpy(buf, "This is version 1 of the file"); - } else { - strcpy(buf, "This is version 0 of the file"); - } - - cfs_remove("test"); - fd = cfs_open("test", CFS_WRITE); - if(fd < 0) { - process_exit(NULL); - } - if(cfs_write(fd, buf, sizeof(buf)) != sizeof(buf)) { - cfs_close(fd); - process_exit(NULL); - } - - if(cfs_seek(fd, FILE_SIZE, CFS_SEEK_SET) != FILE_SIZE) { - printf("failed to seek to the end\n"); - } - - deluge_disseminate("test", node_id == SINK_ID); - cfs_close(fd); - - etimer_set(&et, CLOCK_SECOND * 5); - for(;;) { - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - if(node_id != SINK_ID) { - fd = cfs_open("test", CFS_READ); - if(fd < 0) { - printf("failed to open the test file\n"); - } else { - r = cfs_read(fd, buf, sizeof(buf)); - buf[sizeof(buf) - 1] = '\0'; - if(r <= 0) { - printf("failed to read data from the file\n"); - } else { - printf("File contents: %s\n", buf); - } - cfs_close(fd); - } - } - etimer_reset(&et); - } - - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/regression-tests/04-rime/04-sky-deluge.csc b/regression-tests/04-rime/04-sky-deluge.csc deleted file mode 100644 index f62d87145..000000000 --- a/regression-tests/04-rime/04-sky-deluge.csc +++ /dev/null @@ -1,155 +0,0 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - Deluge - generated - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - Sky Mote Type #1 - [CONTIKI_DIR]/examples/sky/test-deluge.c - make clean TARGET=sky -make APPS=deluge test-deluge.sky TARGET=sky - [CONTIKI_DIR]/examples/sky/test-deluge.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - - - - - org.contikios.cooja.interfaces.Position - 22.464792491653174 - 11.3235347656354 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 16.167564578306468 - 29.89745599030348 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 63.42409596590043 - 12.470791515046386 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 5 - - sky1 - - - - org.contikios.cooja.plugins.SimControl - 282 - 4 - 212 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 4.405003166995177 0.0 0.0 4.405003166995177 -40.3007583818182 -45.78929741329485 - - 283 - 2 - 144 - -1 - 212 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 600 - 1 - 357 - 281 - 1 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - 2 - - 500.0 - - 882 - 3 - 149 - -1 - 357 - - - org.contikios.cooja.plugins.LogListener - - - - - - 882 - 0 - 195 - -1 - 504 - - - diff --git a/regression-tests/04-rime/05-sky-runicast.csc b/regression-tests/04-rime/04-sky-runicast.csc similarity index 100% rename from regression-tests/04-rime/05-sky-runicast.csc rename to regression-tests/04-rime/04-sky-runicast.csc diff --git a/regression-tests/04-rime/06-sky-trickle.csc b/regression-tests/04-rime/05-sky-trickle.csc similarity index 100% rename from regression-tests/04-rime/06-sky-trickle.csc rename to regression-tests/04-rime/05-sky-trickle.csc diff --git a/regression-tests/04-rime/06-sky-collect.csc b/regression-tests/04-rime/06-sky-collect.csc new file mode 100644 index 000000000..3fe71e180 --- /dev/null +++ b/regression-tests/04-rime/06-sky-collect.csc @@ -0,0 +1,245 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + generated + 10000000 + + org.contikios.cooja.radiomediums.UDGM + 30.0 + 40.0 + 0.9 + 0.9 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + Sky Mote Type #1 + [CONTIKI_DIR]/examples/sky/sky-collect.c + make clean TARGET=sky +make sky-collect.sky TARGET=sky + [CONTIKI_DIR]/examples/sky/sky-collect.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + + + + + org.contikios.cooja.interfaces.Position + 9.333811152651393 + 89.28114548870677 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 33.040227185226826 + 54.184283361563054 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + -2.2559922410521516 + 50.71648775308175 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 12.959353575718179 + 43.874396471224806 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 15.917348901177405 + 66.93526904376517 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 26.735174243053933 + 35.939375910459084 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 41.5254792748469 + 28.370611308140152 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + sky1 + + + + org.contikios.cooja.plugins.SimControl + 265 + 3 + 200 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 1.9551775516837413 0.0 0.0 1.9551775516837413 87.61059024269439 -50.01503690267507 + + 264 + 1 + 185 + 0 + 200 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 600 + 2 + 385 + 266 + 0 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + + 500.0 + + 866 + 0 + 152 + 0 + 384 + + + diff --git a/regression-tests/04-rime/07-sky-collect.csc b/regression-tests/04-rime/07-sky-collect.csc index 3fe71e180..5184bf959 100644 --- a/regression-tests/04-rime/07-sky-collect.csc +++ b/regression-tests/04-rime/07-sky-collect.csc @@ -9,25 +9,25 @@ My simulation generated - 10000000 + 1000000 org.contikios.cooja.radiomediums.UDGM - 30.0 - 40.0 - 0.9 - 0.9 + 50.0 + 50.0 + 1.0 + 1.0 - 40000 + 400000 org.contikios.cooja.mspmote.SkyMoteType sky1 Sky Mote Type #1 - [CONTIKI_DIR]/examples/sky/sky-collect.c + [CONTIKI_DIR]/examples/rime/example-collect.c make clean TARGET=sky -make sky-collect.sky TARGET=sky - [CONTIKI_DIR]/examples/sky/sky-collect.sky +make example-collect.sky TARGET=sky + [CONTIKI_DIR]/examples/rime/example-collect.sky org.contikios.cooja.interfaces.Position org.contikios.cooja.interfaces.IPAddress org.contikios.cooja.interfaces.Mote2MoteRelations @@ -38,13 +38,18 @@ make sky-collect.sky TARGET=sky org.contikios.cooja.mspmote.interfaces.Msp802154Radio org.contikios.cooja.mspmote.interfaces.MspSerial org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature org.contikios.cooja.interfaces.Position - 9.333811152651393 - 89.28114548870677 + 87.29845932913939 + 60.286214311723164 0.0 @@ -57,8 +62,8 @@ make sky-collect.sky TARGET=sky org.contikios.cooja.interfaces.Position - 33.040227185226826 - 54.184283361563054 + 94.30809966340686 + 22.50388779326399 0.0 @@ -71,8 +76,8 @@ make sky-collect.sky TARGET=sky org.contikios.cooja.interfaces.Position - -2.2559922410521516 - 50.71648775308175 + 82.40423567500785 + 39.56979106929553 0.0 @@ -85,8 +90,8 @@ make sky-collect.sky TARGET=sky org.contikios.cooja.interfaces.Position - 12.959353575718179 - 43.874396471224806 + 26.185019854469438 + 4.800834369523899 0.0 @@ -99,8 +104,8 @@ make sky-collect.sky TARGET=sky org.contikios.cooja.interfaces.Position - 15.917348901177405 - 66.93526904376517 + 1.9530156130507015 + 78.3175061800706 0.0 @@ -113,8 +118,8 @@ make sky-collect.sky TARGET=sky org.contikios.cooja.interfaces.Position - 26.735174243053933 - 35.939375910459084 + 48.35216700543414 + 80.36988713780997 0.0 @@ -127,8 +132,8 @@ make sky-collect.sky TARGET=sky org.contikios.cooja.interfaces.Position - 41.5254792748469 - 28.370611308140152 + 24.825985087266833 + 74.27809432062487 0.0 @@ -137,12 +142,194 @@ make sky-collect.sky TARGET=sky sky1 + + + + org.contikios.cooja.interfaces.Position + 8.356165164293616 + 94.33967355724187 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 8 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 45.11740613004886 + 31.7059041432301 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 9 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 68.9908548386292 + 55.01991960639596 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 10 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 13.181122543889046 + 55.9636533130127 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 11 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 2.1749985906538427 + 78.39666095789707 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 12 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 37.79795217518357 + 7.164284163506062 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 13 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 64.4595177394984 + 72.115414337433 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 14 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 81.85663737096085 + 89.31412706434035 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 15 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 44.74952276297882 + 18.78566116347574 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 16 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 96.11333426285873 + 90.64560410751824 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 17 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 21.651464136783527 + 7.1381043251259495 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 18 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 83.6006916200628 + 26.97170140682981 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 19 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 1.3446070721664705 + 7.340373220385176 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 20 + + sky1 + org.contikios.cooja.plugins.SimControl - 265 - 3 - 200 + 247 + 0 + 227 0 0 @@ -151,95 +338,110 @@ make sky-collect.sky TARGET=sky org.contikios.cooja.plugins.skins.IDVisualizerSkin org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 1.9551775516837413 0.0 0.0 1.9551775516837413 87.61059024269439 -50.01503690267507 + 1.685403700540615 0.0 0.0 1.685403700540615 23.872012513439184 -0.545889466623605 - 264 + 224 + 3 + 225 + 247 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 469 1 - 185 + 473 0 - 200 + 226 org.contikios.cooja.plugins.ScriptRunner - + if(num_reported == num_nodes) { + print_stats(); + log.testOK(); + } + } true 600 2 - 385 - 266 + 700 + 469 0 - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - - 500.0 - - 866 - 0 - 152 - 0 - 384 - diff --git a/regression-tests/04-rime/09-cooja-trickle.csc b/regression-tests/04-rime/08-cooja-trickle.csc similarity index 100% rename from regression-tests/04-rime/09-cooja-trickle.csc rename to regression-tests/04-rime/08-cooja-trickle.csc diff --git a/regression-tests/04-rime/08-sky-collect.csc b/regression-tests/04-rime/08-sky-collect.csc deleted file mode 100644 index 5184bf959..000000000 --- a/regression-tests/04-rime/08-sky-collect.csc +++ /dev/null @@ -1,447 +0,0 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - generated - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 400000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - Sky Mote Type #1 - [CONTIKI_DIR]/examples/rime/example-collect.c - make clean TARGET=sky -make example-collect.sky TARGET=sky - [CONTIKI_DIR]/examples/rime/example-collect.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 87.29845932913939 - 60.286214311723164 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 94.30809966340686 - 22.50388779326399 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 82.40423567500785 - 39.56979106929553 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 26.185019854469438 - 4.800834369523899 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 4 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 1.9530156130507015 - 78.3175061800706 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 5 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 48.35216700543414 - 80.36988713780997 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 6 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 24.825985087266833 - 74.27809432062487 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 7 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 8.356165164293616 - 94.33967355724187 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 8 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 45.11740613004886 - 31.7059041432301 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 9 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 68.9908548386292 - 55.01991960639596 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 10 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 13.181122543889046 - 55.9636533130127 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 11 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 2.1749985906538427 - 78.39666095789707 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 12 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 37.79795217518357 - 7.164284163506062 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 13 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 64.4595177394984 - 72.115414337433 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 14 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 81.85663737096085 - 89.31412706434035 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 15 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 44.74952276297882 - 18.78566116347574 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 16 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 96.11333426285873 - 90.64560410751824 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 17 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 21.651464136783527 - 7.1381043251259495 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 18 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 83.6006916200628 - 26.97170140682981 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 19 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 1.3446070721664705 - 7.340373220385176 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 20 - - sky1 - - - - org.contikios.cooja.plugins.SimControl - 247 - 0 - 227 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 1.685403700540615 0.0 0.0 1.685403700540615 23.872012513439184 -0.545889466623605 - - 224 - 3 - 225 - 247 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - - 469 - 1 - 473 - 0 - 226 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 600 - 2 - 700 - 469 - 0 - - - diff --git a/regression-tests/04-rime/10-cooja-mesh.csc b/regression-tests/04-rime/09-cooja-mesh.csc similarity index 100% rename from regression-tests/04-rime/10-cooja-mesh.csc rename to regression-tests/04-rime/09-cooja-mesh.csc From 186138f6af940877dea8e6824f9e24d2247ef8f4 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Fri, 4 Mar 2016 14:20:23 +0100 Subject: [PATCH 185/374] added error check for extraction of aligned llao --- core/net/ipv6/uip-nd6.c | 36 +++++++++++++----------------------- core/net/nbr-table.c | 3 +-- 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/core/net/ipv6/uip-nd6.c b/core/net/ipv6/uip-nd6.c index d160392ed..218507228 100644 --- a/core/net/ipv6/uip-nd6.c +++ b/core/net/ipv6/uip-nd6.c @@ -135,11 +135,13 @@ static uip_ds6_prefix_t *prefix; /** Pointer to a prefix list entry */ #if UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER /*------------------------------------------------------------------*/ /* Copy link-layer address from LLAO option to a word-aligned uip_lladdr_t */ -static void +static int extract_lladdr_from_llao_aligned(uip_lladdr_t *dest) { if(dest != NULL && nd6_opt_llao != NULL) { memcpy(dest, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN); + return 1; } + return 0; } #endif /* UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER */ /*------------------------------------------------------------------*/ @@ -203,14 +205,8 @@ ns_input(void) extract_lladdr_from_llao_aligned(&lladdr_aligned); nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr); if(nbr == NULL) { -<<<<<<< 2e852f758b3fbc18ad30ec75d8c62b5d5238e70a - uip_lladdr_t lladdr_aligned; - extract_lladdr_aligned(&lladdr_aligned); uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL); -======= - uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE); ->>>>>>> replaced add/remove ds6-nbr with an nbr-module controlled update of lladdress to avoid loss of other state information } else { const uip_lladdr_t *lladdr = uip_ds6_nbr_get_ll(nbr); if(lladdr == NULL) { @@ -440,6 +436,7 @@ na_input(void) uint8_t is_router; uint8_t is_solicited; uint8_t is_override; + uip_lladdr_t lladdr_aligned; PRINTF("Received NA from "); PRINT6ADDR(&UIP_IP_BUF->srcipaddr); @@ -517,12 +514,9 @@ na_input(void) UIP_LLADDR_LEN); } if(nbr->state == NBR_INCOMPLETE) { - uip_lladdr_t lladdr_aligned; - if(nd6_opt_llao == NULL) { + if(nd6_opt_llao == NULL || !extract_lladdr_from_llao_aligned(&lladdr_aligned)) { goto discard; } - - extract_lladdr_from_llao_aligned(&lladdr_aligned); if(nbr_table_update_lladdr((const linkaddr_t *)lladdr, (const linkaddr_t *)&lladdr_aligned, 1) == 0) { /* failed to update the lladdr */ goto discard; @@ -552,9 +546,8 @@ na_input(void) */ if(is_override || !is_llchange || nd6_opt_llao == NULL) { if(nd6_opt_llao != NULL && is_llchange) { - uip_lladdr_t lladdr_aligned; - extract_lladdr_from_llao_aligned(&lladdr_aligned); - if(nbr_table_update_lladdr((const linkaddr_t *) lladdr, (const linkaddr_t *) &lladdr_aligned, 1) == 0) { + if(!extract_lladdr_from_llao_aligned(&lladdr_aligned) || + nbr_table_update_lladdr((const linkaddr_t *) lladdr, (const linkaddr_t *) &lladdr_aligned, 1) == 0) { /* failed to update the lladdr */ goto discard; } @@ -854,6 +847,8 @@ uip_nd6_rs_output(void) void ra_input(void) { + uip_lladdr_t lladdr_aligned; + PRINTF("Received RA from "); PRINT6ADDR(&UIP_IP_BUF->srcipaddr); PRINTF(" to "); @@ -898,19 +893,14 @@ ra_input(void) PRINTF("Processing SLLAO option in RA\n"); nd6_opt_llao = (uint8_t *) UIP_ND6_OPT_HDR_BUF; nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr); + if(!extract_lladdr_from_llao_aligned(&lladdr_aligned)) { + /* failed to extract llao - discard packet */ + goto discard; + } if(nbr == NULL) { - uip_lladdr_t lladdr_aligned; -<<<<<<< 2e852f758b3fbc18ad30ec75d8c62b5d5238e70a - extract_lladdr_aligned(&lladdr_aligned); nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 1, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL); -======= - extract_lladdr_from_llao_aligned(&lladdr_aligned); - nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 1, NBR_STALE); ->>>>>>> replaced add/remove ds6-nbr with an nbr-module controlled update of lladdress to avoid loss of other state information } else { - uip_lladdr_t lladdr_aligned; - extract_lladdr_from_llao_aligned(&lladdr_aligned); const uip_lladdr_t *lladdr = uip_ds6_nbr_get_ll(nbr); if(lladdr == NULL) { goto discard; diff --git a/core/net/nbr-table.c b/core/net/nbr-table.c index 4a3518475..4893a99ca 100644 --- a/core/net/nbr-table.c +++ b/core/net/nbr-table.c @@ -195,9 +195,8 @@ remove_key(nbr_table_key_t *least_used_key) used_map[index_from_key(least_used_key)] = 0; /* Remove neighbor from list */ list_remove(nbr_table_keys, least_used_key); - /* Return associated key */ } - +/*---------------------------------------------------------------------------*/ static nbr_table_key_t * nbr_table_allocate(nbr_table_reason_t reason, void *data) { From 4cdb7ba9b606c4308b9ae5d5206f4c0b0e0ffd82 Mon Sep 17 00:00:00 2001 From: Michael LeMay Date: Fri, 7 Aug 2015 15:43:10 -0700 Subject: [PATCH 186/374] x86: Add TSS-based protection domain support This patch extends the protection domain framework with an additional plugin to use Task-State Segment (TSS) structures to offload much of the work of switching protection domains to the CPU. This can save space compared to paging, since paging requires two 4KiB page tables and one 32-byte page table plus one whole-system TSS and an additional 32-byte data structure for each protection domain, whereas the approach implemented by this patch just requires a 128-byte data structure for each protection domain. Only a small number of protection domains will typically be used, so n * 128 < 8328 + (n * 32). For additional information, please refer to cpu/x86/mm/README.md. GCC 6 is introducing named address spaces for the FS and GS segments [1]. LLVM Clang also provides address spaces for the FS and GS segments [2]. This patch also adds support to the multi-segment X86 memory management subsystem for using these features instead of inline assembly blocks, which enables type checking to detect some address space mismatches. [1] https://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html [2] http://llvm.org/releases/3.3/tools/clang/docs/LanguageExtensions.html#target-specific-extensions --- cpu/x86/Makefile.x86_quarkX1000 | 19 + cpu/x86/bootstrap_quarkX1000.S | 12 + cpu/x86/dma.h | 2 +- cpu/x86/drivers/legacy_pc/pci.c | 10 +- cpu/x86/drivers/legacy_pc/pci.h | 12 +- cpu/x86/drivers/legacy_pc/uart-16x50.c | 45 ++- cpu/x86/drivers/legacy_pc/uart-16x50.h | 2 +- cpu/x86/drivers/quarkX1000/eth.c | 116 ++++-- cpu/x86/drivers/quarkX1000/gpio.c | 8 + cpu/x86/drivers/quarkX1000/i2c.c | 8 + cpu/x86/drivers/quarkX1000/uart.c | 8 +- cpu/x86/init/common/cpu.c | 10 +- cpu/x86/init/common/gdt.c | 26 +- cpu/x86/init/common/gdt.h | 24 +- cpu/x86/init/common/idt.c | 50 ++- cpu/x86/init/common/idt.h | 2 +- cpu/x86/mm/README.md | 363 ++++++++++++++++-- cpu/x86/mm/gdt-layout.h | 28 ++ cpu/x86/mm/ldt-layout.h | 59 +++ cpu/x86/mm/multi-segment.c | 239 ++++++++++++ cpu/x86/mm/multi-segment.h | 195 ++++++++++ cpu/x86/mm/prot-domains.c | 6 +- cpu/x86/mm/prot-domains.h | 113 +++++- cpu/x86/mm/segmentation.h | 19 +- cpu/x86/mm/stacks.h | 11 + cpu/x86/mm/syscalls.h | 47 ++- cpu/x86/mm/tss-prot-domains-asm.S | 88 +++++ cpu/x86/mm/tss-prot-domains.c | 161 ++++++++ cpu/x86/mm/tss-prot-domains.h | 130 +++++++ cpu/x86/quarkX1000.ld | 2 + cpu/x86/quarkX1000_dma.ld | 28 +- cpu/x86/quarkX1000_multi_seg.ld | 190 +++++++++ cpu/x86/quarkX1000_paging.ld | 4 +- platform/galileo/Makefile.customrules-galileo | 12 +- 34 files changed, 1883 insertions(+), 166 deletions(-) create mode 100644 cpu/x86/mm/ldt-layout.h create mode 100644 cpu/x86/mm/multi-segment.c create mode 100644 cpu/x86/mm/multi-segment.h create mode 100644 cpu/x86/mm/tss-prot-domains-asm.S create mode 100644 cpu/x86/mm/tss-prot-domains.c create mode 100644 cpu/x86/mm/tss-prot-domains.h create mode 100644 cpu/x86/quarkX1000_multi_seg.ld diff --git a/cpu/x86/Makefile.x86_quarkX1000 b/cpu/x86/Makefile.x86_quarkX1000 index 4a7668cc6..13a9c686f 100644 --- a/cpu/x86/Makefile.x86_quarkX1000 +++ b/cpu/x86/Makefile.x86_quarkX1000 @@ -20,6 +20,11 @@ CFLAGS += -DX86_CONF_USE_INVLPG endif # This matches the definition of X86_CONF_PROT_DOMAINS__PAGING in prot-domains.h: CFLAGS += -DX86_CONF_PROT_DOMAINS=1 +else ifeq ($(X86_CONF_PROT_DOMAINS),tss) +# This matches the definition of X86_CONF_PROT_DOMAINS__TSS in prot-domains.h: +CFLAGS += -DX86_CONF_PROT_DOMAINS=2 +X86_CONF_MULTI_SEG = 1 +CONTIKI_SOURCEFILES += tss-prot-domains-asm.S else $(error Unrecognized setting for X86_CONF_PROT_DOMAINS: \ $(X86_CONF_PROT_DOMAINS). See cpu/x86/mm/README.md for \ @@ -30,6 +35,20 @@ ifeq ($(X86_CONF_SYSCALLS_INT),1) CONTIKI_SOURCEFILES += syscalls-int-asm.S tss.c endif +ifeq ($(X86_CONF_MULTI_SEG),1) +LINKERSCRIPT_SFX = _multi_seg +CONTIKI_SOURCEFILES += multi-segment.c +# Due to the way the multi-segment implementation of protection domains define +# tightly-bounded stack segments, the base pointer register cannot be used as +# a general-purpose register in all circumstances. The stack segment is used +# by default for a data access that uses the base pointer as the base register +# to compute the address. If the data referenced by the base pointer is not +# on the stack, then the access will fail. Thus, it is necessary to disable +# the omit-frame-pointer optimization. See mm/README.md for more details of +# how multi-segment protection domains are implemented. +CFLAGS += -fno-omit-frame-pointer +endif + endif CFLAGS += -m32 -march=i586 -mtune=i586 diff --git a/cpu/x86/bootstrap_quarkX1000.S b/cpu/x86/bootstrap_quarkX1000.S index 4211e51a3..622c9dab8 100644 --- a/cpu/x86/bootstrap_quarkX1000.S +++ b/cpu/x86/bootstrap_quarkX1000.S @@ -45,5 +45,17 @@ .global start start: cli +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__TSS + /* TSS-based protection domains use a multi-segment model that defines + * tight bounds around stacks. That means that the bottom of the stack + * has an offset of 0, which is the address of the stacks_main symbol. + * The following code computes the physical load address of the top of + * the stack, which is what should be initially used as the stack + * pointer while the flat memory model is in use. + */ + lea _sdata_addr, %eax + lea (stacks_main + STACKS_SIZE_MAIN)(%eax), %esp +#else mov $(stacks_main + STACKS_SIZE_MAIN), %esp +#endif call cpu_boot_stage0 diff --git a/cpu/x86/dma.h b/cpu/x86/dma.h index b0122fcdb..7a8d991b1 100644 --- a/cpu/x86/dma.h +++ b/cpu/x86/dma.h @@ -43,6 +43,6 @@ #endif #endif -extern int _sbss_dma_addr, _ebss_dma_addr; +extern int _ebss_pre_dma_addr, _sbss_dma_addr, _ebss_dma_addr; #endif /* CPU_X86_DMA_H_ */ diff --git a/cpu/x86/drivers/legacy_pc/pci.c b/cpu/x86/drivers/legacy_pc/pci.c index e94c9ecbe..4584d454c 100644 --- a/cpu/x86/drivers/legacy_pc/pci.c +++ b/cpu/x86/drivers/legacy_pc/pci.c @@ -138,7 +138,9 @@ SYSCALLS_DEFINE_SINGLETON(pci_irq_agent_set_pirq, offset = 0x3146; } - value = *(uint16_t*)(rcba_addr + offset); + prot_domains_enable_mmio(); + + MMIO_READW(value, *(uint16_t ATTR_MMIO_ADDR_SPACE *)(rcba_addr + offset)); /* clear interrupt pin route and set corresponding pirq. */ switch(pin) { @@ -159,7 +161,9 @@ SYSCALLS_DEFINE_SINGLETON(pci_irq_agent_set_pirq, value |= (pirq << 12); } - *(uint16_t*)(rcba_addr + offset) = value; + MMIO_WRITEW(*(uint16_t ATTR_MMIO_ADDR_SPACE *)(rcba_addr + offset), value); + + prot_domains_disable_mmio(); } /*---------------------------------------------------------------------------*/ /** @@ -231,7 +235,7 @@ pci_pirq_set_irq(PIRQ pirq, uint8_t irq, uint8_t route_to_legacy) * \param meta_sz Size of optional driver-defined metadata. */ void -pci_init(pci_driver_t *c_this, +pci_init(pci_driver_t ATTR_KERN_ADDR_SPACE *c_this, pci_config_addr_t pci_addr, size_t mmio_sz, uintptr_t meta, diff --git a/cpu/x86/drivers/legacy_pc/pci.h b/cpu/x86/drivers/legacy_pc/pci.h index fff53a048..666b3c29e 100644 --- a/cpu/x86/drivers/legacy_pc/pci.h +++ b/cpu/x86/drivers/legacy_pc/pci.h @@ -102,7 +102,7 @@ void pci_command_enable(pci_config_addr_t addr, uint32_t flags); typedef dom_client_data_t pci_driver_t; -void pci_init(pci_driver_t *c_this, +void pci_init(pci_driver_t ATTR_KERN_ADDR_SPACE *c_this, pci_config_addr_t pci_addr, size_t mmio_sz, uintptr_t meta, @@ -113,10 +113,12 @@ void pci_root_complex_init(void); void pci_root_complex_lock(void); #define PCI_MMIO_READL(c_this, dest, reg_addr) \ - dest = *((volatile uint32_t *) \ - (((uintptr_t)PROT_DOMAINS_MMIO(c_this)) + (reg_addr))) + MMIO_READL(dest, \ + *((volatile uint32_t ATTR_MMIO_ADDR_SPACE *) \ + (((uintptr_t)PROT_DOMAINS_MMIO(c_this)) + (reg_addr)))) #define PCI_MMIO_WRITEL(c_this, reg_addr, src) \ - *((volatile uint32_t *) \ - (((uintptr_t)PROT_DOMAINS_MMIO(c_this)) + (reg_addr))) = (src) + MMIO_WRITEL(*((volatile uint32_t ATTR_MMIO_ADDR_SPACE *) \ + (((uintptr_t)PROT_DOMAINS_MMIO(c_this)) + (reg_addr))), \ + src) #endif /* CPU_X86_DRIVERS_LEGACY_PC_PCI_H_ */ diff --git a/cpu/x86/drivers/legacy_pc/uart-16x50.c b/cpu/x86/drivers/legacy_pc/uart-16x50.c index d1f2c498d..d17e61498 100644 --- a/cpu/x86/drivers/legacy_pc/uart-16x50.c +++ b/cpu/x86/drivers/legacy_pc/uart-16x50.c @@ -74,6 +74,11 @@ typedef struct uart_16x50_regs { */ #define UART_MMIO_SZ MIN_PAGE_SIZE #else +/* Multi-segment protection domain implementations can control memory with + * byte granularity. Thus, only the registers defined in the uart_16x50_regs + * structure are included in the MMIO region allocated for this protection + * domain: + */ #define UART_MMIO_SZ sizeof(uart_16x50_regs_t) #endif @@ -82,24 +87,30 @@ void uart_16x50_setup(uart_16x50_driver_t c_this, uint16_t dl); /*---------------------------------------------------------------------------*/ SYSCALLS_DEFINE(uart_16x50_setup, uart_16x50_driver_t c_this, uint16_t dl) { - uart_16x50_regs_t *regs = (uart_16x50_regs_t *)PROT_DOMAINS_MMIO(c_this); + uart_16x50_regs_t ATTR_MMIO_ADDR_SPACE *regs = + (uart_16x50_regs_t ATTR_MMIO_ADDR_SPACE *)PROT_DOMAINS_MMIO(c_this); + + prot_domains_enable_mmio(); /* Set the DLAB bit to enable access to divisor settings. */ - regs->lcr = UART_LCR_7_DLAB; + MMIO_WRITEL(regs->lcr, UART_LCR_7_DLAB); /* The divisor settings configure the baud rate, and may need to be defined * on a per-device basis. */ - regs->rbr_thr_dll = dl & UINT8_MAX; - regs->ier_dlh = dl >> 8; + MMIO_WRITEL(regs->rbr_thr_dll, dl & UINT8_MAX); + MMIO_WRITEL(regs->ier_dlh, dl >> 8); /* Clear the DLAB bit to enable access to other settings and configure other * UART parameters. */ - regs->lcr = UART_LCR_8BITS; + MMIO_WRITEL(regs->lcr, UART_LCR_8BITS); /* Enable the FIFOs. */ - regs->iir_fcr = UART_FCR_0_FIFOE | UART_FCR_1_RFIFOR | UART_FCR_2_XFIFOR; + MMIO_WRITEL(regs->iir_fcr, + UART_FCR_0_FIFOE | UART_FCR_1_RFIFOR | UART_FCR_2_XFIFOR); + + prot_domains_disable_mmio(); } /*---------------------------------------------------------------------------*/ /** @@ -112,13 +123,21 @@ SYSCALLS_DEFINE(uart_16x50_setup, uart_16x50_driver_t c_this, uint16_t dl) */ SYSCALLS_DEFINE(uart_16x50_tx, uart_16x50_driver_t c_this, uint8_t c) { - uart_16x50_regs_t *regs = (uart_16x50_regs_t *)PROT_DOMAINS_MMIO(c_this); + uint32_t ready; + uart_16x50_regs_t ATTR_MMIO_ADDR_SPACE *regs = + (uart_16x50_regs_t ATTR_MMIO_ADDR_SPACE *)PROT_DOMAINS_MMIO(c_this); + + prot_domains_enable_mmio(); /* Wait for space in TX FIFO. */ - while((regs->lsr & UART_LSR_5_THRE) == 0); + do { + MMIO_READL(ready, regs->lsr); + } while((ready & UART_LSR_5_THRE) == 0); /* Add character to TX FIFO. */ - regs->rbr_thr_dll = c; + MMIO_WRITEL(regs->rbr_thr_dll, c); + + prot_domains_disable_mmio(); } /*---------------------------------------------------------------------------*/ /** @@ -128,10 +147,12 @@ SYSCALLS_DEFINE(uart_16x50_tx, uart_16x50_driver_t c_this, uint8_t c) * \param dl Divisor setting to configure the baud rate. */ void -uart_16x50_init(uart_16x50_driver_t *c_this, +uart_16x50_init(uart_16x50_driver_t ATTR_KERN_ADDR_SPACE *c_this, pci_config_addr_t pci_addr, uint16_t dl) { + uart_16x50_driver_t loc_c_this; + /* This assumes that the UART had an MMIO range assigned to it by the * firmware during boot. */ @@ -141,6 +162,8 @@ uart_16x50_init(uart_16x50_driver_t *c_this, SYSCALLS_INIT(uart_16x50_tx); SYSCALLS_AUTHZ(uart_16x50_tx, *c_this); - uart_16x50_setup(*c_this, dl); + prot_domains_copy_dcd(&loc_c_this, c_this); + + uart_16x50_setup(loc_c_this, dl); } /*---------------------------------------------------------------------------*/ diff --git a/cpu/x86/drivers/legacy_pc/uart-16x50.h b/cpu/x86/drivers/legacy_pc/uart-16x50.h index 615806518..4a038b948 100644 --- a/cpu/x86/drivers/legacy_pc/uart-16x50.h +++ b/cpu/x86/drivers/legacy_pc/uart-16x50.h @@ -35,7 +35,7 @@ typedef pci_driver_t uart_16x50_driver_t; -void uart_16x50_init(uart_16x50_driver_t *c_this, +void uart_16x50_init(uart_16x50_driver_t ATTR_KERN_ADDR_SPACE *c_this, pci_config_addr_t pci_addr, uint16_t dl); diff --git a/cpu/x86/drivers/quarkX1000/eth.c b/cpu/x86/drivers/quarkX1000/eth.c index 5c16b10a5..88782ebc2 100644 --- a/cpu/x86/drivers/quarkX1000/eth.c +++ b/cpu/x86/drivers/quarkX1000/eth.c @@ -216,13 +216,19 @@ SYSCALLS_DEFINE_SINGLETON(quarkX1000_eth_setup, drv, uintptr_t meta_phys_base) { uip_eth_addr mac_addr; uint32_t mac_tmp1, mac_tmp2; - quarkX1000_eth_meta_t *loc_meta = - (quarkX1000_eth_meta_t *)PROT_DOMAINS_META(drv); + quarkX1000_eth_rx_desc_t rx_desc; + quarkX1000_eth_tx_desc_t tx_desc; + quarkX1000_eth_meta_t ATTR_META_ADDR_SPACE *loc_meta = + (quarkX1000_eth_meta_t ATTR_META_ADDR_SPACE *)PROT_DOMAINS_META(drv); + + prot_domains_enable_mmio(); /* Read the MAC address from the device. */ PCI_MMIO_READL(drv, mac_tmp1, REG_ADDR_MACADDR_HI); PCI_MMIO_READL(drv, mac_tmp2, REG_ADDR_MACADDR_LO); + prot_domains_disable_mmio(); + /* Convert the data read from the device into the format expected by * Contiki. */ @@ -245,29 +251,39 @@ SYSCALLS_DEFINE_SINGLETON(quarkX1000_eth_setup, drv, uintptr_t meta_phys_base) uip_setethaddr(mac_addr); /* Initialize transmit descriptor. */ - loc_meta->tx_desc.tdes0 = 0; - loc_meta->tx_desc.tdes1 = 0; + tx_desc.tdes0 = 0; + tx_desc.tdes1 = 0; - loc_meta->tx_desc.buf1_ptr = - (uint8_t *)PROT_DOMAINS_META_OFF_TO_PHYS( - (uintptr_t)&loc_meta->tx_buf, meta_phys_base); - loc_meta->tx_desc.tx_end_of_ring = 1; - loc_meta->tx_desc.first_seg_in_frm = 1; - loc_meta->tx_desc.last_seg_in_frm = 1; - loc_meta->tx_desc.tx_end_of_ring = 1; + tx_desc.tx_end_of_ring = 1; + tx_desc.first_seg_in_frm = 1; + tx_desc.last_seg_in_frm = 1; + tx_desc.tx_end_of_ring = 1; + + META_WRITEL(loc_meta->tx_desc.tdes0, tx_desc.tdes0); + META_WRITEL(loc_meta->tx_desc.tdes1, tx_desc.tdes1); + META_WRITEL(loc_meta->tx_desc.buf1_ptr, + (uint8_t *)PROT_DOMAINS_META_OFF_TO_PHYS( + (uintptr_t)&loc_meta->tx_buf, meta_phys_base)); + META_WRITEL(loc_meta->tx_desc.buf2_ptr, 0); /* Initialize receive descriptor. */ - loc_meta->rx_desc.rdes0 = 0; - loc_meta->rx_desc.rdes1 = 0; + rx_desc.rdes0 = 0; + rx_desc.rdes1 = 0; - loc_meta->rx_desc.buf1_ptr = - (uint8_t *)PROT_DOMAINS_META_OFF_TO_PHYS( - (uintptr_t)&loc_meta->rx_buf, meta_phys_base); - loc_meta->rx_desc.own = 1; - loc_meta->rx_desc.first_desc = 1; - loc_meta->rx_desc.last_desc = 1; - loc_meta->rx_desc.rx_buf1_sz = UIP_BUFSIZE; - loc_meta->rx_desc.rx_end_of_ring = 1; + rx_desc.own = 1; + rx_desc.first_desc = 1; + rx_desc.last_desc = 1; + rx_desc.rx_buf1_sz = UIP_BUFSIZE; + rx_desc.rx_end_of_ring = 1; + + META_WRITEL(loc_meta->rx_desc.rdes0, rx_desc.rdes0); + META_WRITEL(loc_meta->rx_desc.rdes1, rx_desc.rdes1); + META_WRITEL(loc_meta->rx_desc.buf1_ptr, + (uint8_t *)PROT_DOMAINS_META_OFF_TO_PHYS( + (uintptr_t)&loc_meta->rx_buf, meta_phys_base)); + META_WRITEL(loc_meta->rx_desc.buf2_ptr, 0); + + prot_domains_enable_mmio(); /* Install transmit and receive descriptors. */ PCI_MMIO_WRITEL(drv, REG_ADDR_RX_DESC_LIST, @@ -298,8 +314,11 @@ SYSCALLS_DEFINE_SINGLETON(quarkX1000_eth_setup, drv, uintptr_t meta_phys_base) /* Place the receiver state machine in the Running state. */ OP_MODE_1_START_RX); + prot_domains_disable_mmio(); + printf(LOG_PFX "Enabled 100M full-duplex mode.\n"); } + /*---------------------------------------------------------------------------*/ /** * \brief Poll for a received Ethernet frame. @@ -313,33 +332,43 @@ SYSCALLS_DEFINE_SINGLETON(quarkX1000_eth_poll, drv, uint16_t * frame_len) { uint16_t *loc_frame_len; uint16_t frm_len = 0; - quarkX1000_eth_meta_t *loc_meta = - (quarkX1000_eth_meta_t *)PROT_DOMAINS_META(drv); + quarkX1000_eth_rx_desc_t tmp_desc; + quarkX1000_eth_meta_t ATTR_META_ADDR_SPACE *loc_meta = + (quarkX1000_eth_meta_t ATTR_META_ADDR_SPACE *)PROT_DOMAINS_META(drv); PROT_DOMAINS_VALIDATE_PTR(loc_frame_len, frame_len, sizeof(*frame_len)); + META_READL(tmp_desc.rdes0, loc_meta->rx_desc.rdes0); + /* Check whether the RX descriptor is still owned by the device. If not, * process the received frame or an error that may have occurred. */ - if(loc_meta->rx_desc.own == 0) { - if(loc_meta->rx_desc.err_summary) { + if(tmp_desc.own == 0) { + META_READL(tmp_desc.rdes1, loc_meta->rx_desc.rdes1); + if(tmp_desc.err_summary) { fprintf(stderr, LOG_PFX "Error receiving frame: RDES0 = %08x, RDES1 = %08x.\n", - loc_meta->rx_desc.rdes0, loc_meta->rx_desc.rdes1); + tmp_desc.rdes0, tmp_desc.rdes1); assert(0); } - frm_len = loc_meta->rx_desc.frm_len; + frm_len = tmp_desc.frm_len; assert(frm_len <= UIP_BUFSIZE); - memcpy(uip_buf, (void *)loc_meta->rx_buf, frm_len); + MEMCPY_FROM_META(uip_buf, loc_meta->rx_buf, frm_len); /* Return ownership of the RX descriptor to the device. */ - loc_meta->rx_desc.own = 1; + tmp_desc.own = 1; + + META_WRITEL(loc_meta->rx_desc.rdes0, tmp_desc.rdes0); + + prot_domains_enable_mmio(); /* Request that the device check for an available RX descriptor, since * ownership of the descriptor was just transferred to the device. */ PCI_MMIO_WRITEL(drv, REG_ADDR_RX_POLL_DEMAND, 1); + + prot_domains_disable_mmio(); } *loc_frame_len = frm_len; @@ -356,32 +385,45 @@ SYSCALLS_DEFINE_SINGLETON(quarkX1000_eth_poll, drv, uint16_t * frame_len) */ SYSCALLS_DEFINE_SINGLETON(quarkX1000_eth_send, drv) { - quarkX1000_eth_meta_t *loc_meta = - (quarkX1000_eth_meta_t *)PROT_DOMAINS_META(drv); + quarkX1000_eth_tx_desc_t tmp_desc; + quarkX1000_eth_meta_t ATTR_META_ADDR_SPACE *loc_meta = + (quarkX1000_eth_meta_t ATTR_META_ADDR_SPACE *)PROT_DOMAINS_META(drv); /* Wait until the TX descriptor is no longer owned by the device. */ - while(loc_meta->tx_desc.own == 1); + do { + META_READL(tmp_desc.tdes0, loc_meta->tx_desc.tdes0); + } while(tmp_desc.own == 1); + + META_READL(tmp_desc.tdes1, loc_meta->tx_desc.tdes1); /* Check whether an error occurred transmitting the previous frame. */ - if(loc_meta->tx_desc.err_summary) { + if(tmp_desc.err_summary) { fprintf(stderr, LOG_PFX "Error transmitting frame: TDES0 = %08x, TDES1 = %08x.\n", - loc_meta->tx_desc.tdes0, loc_meta->tx_desc.tdes1); + tmp_desc.tdes0, tmp_desc.tdes1); assert(0); } /* Transmit the next frame. */ assert(uip_len <= UIP_BUFSIZE); - memcpy((void *)loc_meta->tx_buf, uip_buf, uip_len); + MEMCPY_TO_META(loc_meta->tx_buf, uip_buf, uip_len); - loc_meta->tx_desc.tx_buf1_sz = uip_len; + tmp_desc.tx_buf1_sz = uip_len; - loc_meta->tx_desc.own = 1; + META_WRITEL(loc_meta->tx_desc.tdes1, tmp_desc.tdes1); + + tmp_desc.own = 1; + + META_WRITEL(loc_meta->tx_desc.tdes0, tmp_desc.tdes0); + + prot_domains_enable_mmio(); /* Request that the device check for an available TX descriptor, since * ownership of the descriptor was just transferred to the device. */ PCI_MMIO_WRITEL(drv, REG_ADDR_TX_POLL_DEMAND, 1); + + prot_domains_disable_mmio(); } /*---------------------------------------------------------------------------*/ /** diff --git a/cpu/x86/drivers/quarkX1000/gpio.c b/cpu/x86/drivers/quarkX1000/gpio.c index 642cad310..ba825c090 100644 --- a/cpu/x86/drivers/quarkX1000/gpio.c +++ b/cpu/x86/drivers/quarkX1000/gpio.c @@ -56,7 +56,11 @@ #define HIGHEST_REG LS_SYNC +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__PAGING #define MMIO_SZ MIN_PAGE_SIZE +#else +#define MMIO_SZ (HIGHEST_REG + 4) +#endif PROT_DOMAINS_ALLOC(pci_driver_t, drv); @@ -77,7 +81,9 @@ SYSCALLS_DEFINE_SINGLETON(quarkX1000_gpio_mmin, drv, halt(); } + prot_domains_enable_mmio(); PCI_MMIO_READL(drv, *loc_res, offset); + prot_domains_disable_mmio(); } static inline uint32_t @@ -96,7 +102,9 @@ SYSCALLS_DEFINE_SINGLETON(quarkX1000_gpio_mmout, drv, halt(); } + prot_domains_enable_mmio(); PCI_MMIO_WRITEL(drv, offset, val); + prot_domains_disable_mmio(); } static inline void diff --git a/cpu/x86/drivers/quarkX1000/i2c.c b/cpu/x86/drivers/quarkX1000/i2c.c index 746e52b96..9e233e89c 100644 --- a/cpu/x86/drivers/quarkX1000/i2c.c +++ b/cpu/x86/drivers/quarkX1000/i2c.c @@ -51,7 +51,11 @@ #define I2C_IRQ 9 +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__PAGING #define MMIO_SZ MIN_PAGE_SIZE +#else +#define MMIO_SZ (QUARKX1000_IC_HIGHEST + 4) +#endif typedef enum { I2C_DIRECTION_READ, @@ -99,7 +103,9 @@ SYSCALLS_DEFINE_SINGLETON(quarkX1000_i2c_mmin, drv, halt(); } + prot_domains_enable_mmio(); PCI_MMIO_READL(drv, *loc_res, offset); + prot_domains_disable_mmio(); } static inline uint32_t @@ -119,7 +125,9 @@ SYSCALLS_DEFINE_SINGLETON(quarkX1000_i2c_mmout, drv, halt(); } + prot_domains_enable_mmio(); PCI_MMIO_WRITEL(drv, offset, val); + prot_domains_disable_mmio(); } static inline void diff --git a/cpu/x86/drivers/quarkX1000/uart.c b/cpu/x86/drivers/quarkX1000/uart.c index dcd0af8f2..341e31cf7 100644 --- a/cpu/x86/drivers/quarkX1000/uart.c +++ b/cpu/x86/drivers/quarkX1000/uart.c @@ -49,7 +49,7 @@ void quarkX1000_uart_init(quarkX1000_uart_dev_t dev) { pci_config_addr_t pci_addr; - uart_16x50_driver_t *drv; + uart_16x50_driver_t ATTR_KERN_ADDR_SPACE *drv; assert((dev == QUARK_X1000_UART_0) || (dev == QUARK_X1000_UART_1)); @@ -78,7 +78,11 @@ quarkX1000_uart_init(quarkX1000_uart_dev_t dev) void quarkX1000_uart_tx(quarkX1000_uart_dev_t dev, uint8_t c) { + uart_16x50_driver_t drv; assert((dev == QUARK_X1000_UART_0) || (dev == QUARK_X1000_UART_1)); - uart_16x50_tx((dev == QUARK_X1000_UART_0) ? quarkX1000_uart0 : quarkX1000_uart1, c); + prot_domains_copy_dcd(&drv, + (dev == QUARK_X1000_UART_0) ? + &quarkX1000_uart0 : &quarkX1000_uart1); + uart_16x50_tx(drv, c); } /*---------------------------------------------------------------------------*/ diff --git a/cpu/x86/init/common/cpu.c b/cpu/x86/init/common/cpu.c index 94ec2ddab..dd58b96d5 100644 --- a/cpu/x86/init/common/cpu.c +++ b/cpu/x86/init/common/cpu.c @@ -42,8 +42,11 @@ double_fault_handler(struct interrupt_context context) halt(); } /*---------------------------------------------------------------------------*/ -/* The OS has switched to its own segment descriptors. However, the protection - * domain support, if enabled, has not yet been fully activated. +/* The OS has switched to its own segment descriptors. When multi-segment + * protection domain support is enabled, this routine runs with the + * necessary address translations configured to invoke other routines that + * require those translations to be in place. However, the protection domain + * support, if enabled, has not yet been fully activated. */ static void boot_stage1(void) @@ -75,7 +78,8 @@ cpu_boot_stage0(void) uintptr_t top_of_stack = STACKS_INIT_TOP; #if X86_CONF_PROT_DOMAINS != X86_CONF_PROT_DOMAINS__NONE - uintptr_t *top_of_stack_ptr = (uintptr_t *)top_of_stack; + uintptr_t *top_of_stack_ptr = + (uintptr_t *)DATA_OFF_TO_PHYS_ADDR(top_of_stack); top_of_stack_ptr[0] = (uintptr_t)prot_domains_launch_kernel; top_of_stack_ptr[1] = (uintptr_t)prot_domains_launch_app; diff --git a/cpu/x86/init/common/gdt.c b/cpu/x86/init/common/gdt.c index f7fa10342..f63767850 100644 --- a/cpu/x86/init/common/gdt.c +++ b/cpu/x86/init/common/gdt.c @@ -72,7 +72,7 @@ set_descriptor(unsigned int index, segment_desc_init(&descriptor, base, len, flag); /* Save descriptor into gdt */ - gdt[index] = descriptor; + gdt_insert_boot(index, descriptor); } /*---------------------------------------------------------------------------*/ void @@ -86,15 +86,17 @@ gdt_copy_desc_change_dpl(unsigned int dest_idx, halt(); } - desc = gdt[src_idx]; + gdt_lookup(src_idx, &desc); SEG_SET_FLAG(desc, DPL, dpl); - gdt[dest_idx] = desc; + gdt_insert(dest_idx, desc); } /*---------------------------------------------------------------------------*/ /* This function initializes the Global Descriptor Table. For simplicity, the - * memory is organized following the flat model. Thus, memory appears to - * Contiki as a single continuous address space. Code, data, and stack + * memory is initially organized following the flat model. Thus, memory appears + * to Contiki as a single continuous address space. Code, data, and stack * are all contained in this address space (so called linear address space). + * Certain protection domain implementations switch to a multi-segment memory + * model later during boot. */ void gdt_init(void) @@ -103,7 +105,7 @@ gdt_init(void) /* Initialize gdtr structure */ gdtr.limit = sizeof(segment_desc_t) * GDT_LEN - 1; - gdtr.base = (uint32_t) &gdt; + gdtr.base = KERN_DATA_OFF_TO_PHYS_ADDR(gdt); /* Initialize descriptors */ set_descriptor(GDT_IDX_NULL, 0, 0, 0); @@ -115,13 +117,20 @@ gdt_init(void) } /*---------------------------------------------------------------------------*/ void +gdt_insert_boot(unsigned int idx, segment_desc_t desc) +{ + ((segment_desc_t *)KERN_DATA_OFF_TO_PHYS_ADDR(gdt))[idx] = desc; +} +/*---------------------------------------------------------------------------*/ +void gdt_insert(unsigned int idx, segment_desc_t desc) { if(GDT_LEN <= idx) { halt(); } - gdt[idx] = desc; + KERN_WRITEL(gdt[idx].raw_lo, desc.raw_lo); + KERN_WRITEL(gdt[idx].raw_hi, desc.raw_hi); } /*---------------------------------------------------------------------------*/ void @@ -131,6 +140,7 @@ gdt_lookup(unsigned int idx, segment_desc_t *desc) halt(); } - *desc = gdt[idx]; + KERN_READL(desc->raw_lo, gdt[idx].raw_lo); + KERN_READL(desc->raw_hi, gdt[idx].raw_hi); } /*---------------------------------------------------------------------------*/ diff --git a/cpu/x86/init/common/gdt.h b/cpu/x86/init/common/gdt.h index 37f1f4dbe..305e32716 100644 --- a/cpu/x86/init/common/gdt.h +++ b/cpu/x86/init/common/gdt.h @@ -35,13 +35,21 @@ #include "prot-domains.h" #include "segmentation.h" -extern segment_desc_t gdt[]; -extern int _ebss_gdt_addr; +extern segment_desc_t ATTR_KERN_ADDR_SPACE gdt[]; +extern int ATTR_KERN_ADDR_SPACE _ebss_gdt_addr; #define GDT_IDX_OF_DESC(ptr) \ ((((uintptr_t)(ptr)) - ((uintptr_t)&gdt))/ \ sizeof(segment_desc_t)) +typedef struct far_pointer { + /** Far pointer offset. */ + uint32_t offset; + /** Far pointer segment/gate selector. */ + uint16_t sel; + uint16_t pad; +} __attribute__((packed)) far_pointer_t; + /** * \brief Compute the selector for a GDT entry allocated somewhere besides gdt.c. * \param ptr Pointer to GDT descriptor. @@ -49,14 +57,22 @@ extern int _ebss_gdt_addr; */ #define GDT_SEL_OF_DESC(ptr, rpl) GDT_SEL(GDT_IDX_OF_DESC(ptr), rpl) -#define ATTR_BSS_GDT __attribute__((section(".gdt_bss"))) -#define ATTR_BSS_GDT_START __attribute__((section(".gdt_bss_start"))) +/* Section for fixed GDT entries */ +#define ATTR_BSS_GDT \ + __attribute__((section(".gdt_bss"))) ATTR_KERN_ADDR_SPACE +/* Section for TSS and LDT descriptors for protection domains */ +#define ATTR_BSS_GDT_MID \ + __attribute__((used, section(".gdt_bss_mid"))) ATTR_KERN_ADDR_SPACE +/* Section for other GDT entries */ +#define ATTR_BSS_GDT_START \ + __attribute__((section(".gdt_bss_start"))) ATTR_KERN_ADDR_SPACE void gdt_copy_desc_change_dpl(unsigned int dest_idx, unsigned int src_idx, unsigned dpl); void gdt_init(void) ATTR_CODE_BOOT; void gdt_insert(unsigned int idx, segment_desc_t desc); +void gdt_insert_boot(unsigned int idx, segment_desc_t desc) ATTR_CODE_BOOT; void gdt_lookup(unsigned int idx, segment_desc_t *desc); #endif /* GDT_H */ diff --git a/cpu/x86/init/common/idt.c b/cpu/x86/init/common/idt.c index 441668a75..c5de5ed25 100644 --- a/cpu/x86/init/common/idt.c +++ b/cpu/x86/init/common/idt.c @@ -43,17 +43,23 @@ typedef struct idtr { uint32_t base; } __attribute__((packed)) idtr_t; -typedef struct intr_gate_desc { - uint16_t offset_low; - uint16_t selector; /* Segment Selector for destination code segment */ - uint16_t fixed:11; - uint16_t d:1; /* Size of gate: 1 = 32 bits; 0 = 16 bits */ - uint16_t pad:1; - uint16_t dpl:2; /* Descriptor Privilege Level */ - uint16_t p:1; /* Segment Present flag */ - uint16_t offset_high; - -} __attribute__((packed)) intr_gate_desc_t; +typedef union intr_gate_desc { + struct __attribute__((packed)) { + uint16_t offset_low; + uint16_t selector; /* Segment Selector for destination code segment */ + uint16_t fixed:11; + uint16_t d:1; /* Size of gate: 1 = 32 bits; 0 = 16 bits */ + uint16_t pad:1; + uint16_t dpl:2; /* Descriptor Privilege Level */ + uint16_t p:1; /* Segment Present flag */ + uint16_t offset_high; + }; + uint64_t raw; + struct { + uint32_t raw_lo; + uint32_t raw_hi; + }; +} intr_gate_desc_t; /* According to Intel Combined Manual, Vol. 3, Section 6.10, the base addresses * of the IDT should be aligned on an 8-byte boundary to maximize performance @@ -73,15 +79,19 @@ idt_set_intr_gate_desc(int intr_num, uint16_t cs, uint16_t dpl) { - intr_gate_desc_t *desc = &idt[intr_num]; + intr_gate_desc_t desc; - desc->offset_low = offset & 0xFFFF; - desc->selector = cs; - desc->fixed = BIT(9) | BIT(10); - desc->d = 1; - desc->dpl = dpl; - desc->p = 1; - desc->offset_high = (offset >> 16) & 0xFFFF; + desc.offset_low = offset & 0xFFFF; + desc.selector = cs; + desc.fixed = BIT(9) | BIT(10); + desc.pad = 0; + desc.d = 1; + desc.dpl = dpl; + desc.p = 1; + desc.offset_high = (offset >> 16) & 0xFFFF; + + KERN_WRITEL(idt[intr_num].raw_hi, desc.raw_hi); + KERN_WRITEL(idt[intr_num].raw_lo, desc.raw_lo); } /*---------------------------------------------------------------------------*/ /* Initialize Interrupt Descriptor Table. The IDT is initialized with @@ -95,7 +105,7 @@ idt_init(void) /* Initialize idtr structure */ idtr.limit = (sizeof(intr_gate_desc_t) * NUM_DESC) - 1; - idtr.base = (uint32_t)&idt; + idtr.base = KERN_DATA_OFF_TO_PHYS_ADDR((uint32_t)idt); /* Load IDTR register */ __asm__("lidt %0\n\t" :: "m" (idtr)); diff --git a/cpu/x86/init/common/idt.h b/cpu/x86/init/common/idt.h index 18f168ad8..059e81705 100644 --- a/cpu/x86/init/common/idt.h +++ b/cpu/x86/init/common/idt.h @@ -34,7 +34,7 @@ #include #include "prot-domains.h" -void idt_init(void) ATTR_CODE_BOOT; +void idt_init(void); void idt_set_intr_gate_desc(int intr_num, uint32_t offset, uint16_t cs, diff --git a/cpu/x86/mm/README.md b/cpu/x86/mm/README.md index 8990beec9..dcd6370b4 100644 --- a/cpu/x86/mm/README.md +++ b/cpu/x86/mm/README.md @@ -5,13 +5,15 @@ Introduction ------------ The X86 port of Contiki implements a simple, lightweight form of -protection domains using a pluggable framework. Currently, the -following plugin is available: +protection domains using a pluggable framework. Currently, there are +two plugins available: - Flat memory model with paging. + - Multi-segment memory model with hardware-switched segments based on + Task-State Segment (TSS) structures. -For an introduction to paging and possible ways in which it can be -used, refer to the following resources: +For an introduction to paging and TSS and possible ways in which they +can be used, refer to the following resources: - Intel Combined Manual (Intel 64 and IA-32 Architectures Software Developer's Manual), Vol. 3, Chapter 4 @@ -28,7 +30,7 @@ idealized principle is balanced against the practical objectives of limiting the number of relatively time-consuming context switches and minimizing changes to existing code. In fact, no changes were made to code outside of the CPU- and platform-specific code directories for -the initial plugin. +the initial plugins. Each protection domain can optionally be associated with a metadata and/or MMIO region. The hardware can support additional regions per @@ -139,7 +141,11 @@ the one that was interrupted. However, interrupts are only actually enabled in the application protection domain. Similarly, register contents may be accessed and modified across -protection domain boundaries. +protection domain boundaries in some protection domain +implementations. The TSS task switching mechanism automatically saves +and restores many registers to and from TSS data structures when +switching tasks, but the paging-based protection domain implementation +does not perform analogous operations. For the reasons described above, each protection domain should only invoke other protection domains that it trusts to properly handle data @@ -186,7 +192,9 @@ disabled. Flat segments each map the whole 4GiB physical memory space. This is the state of the system when the OS enters boot stage 0. This stage is responsible for setting up a new GDT and loading the segment registers with the appropriate descriptors from the new GDT to -enable boot stage 1 to run. +enable boot stage 1 to run. Code in stage 1 for multi-segment +protection domain implementations require that the appropriate +segment-based address translations be configured. #### Boot Stage 1 @@ -258,17 +266,18 @@ Ring level 1 is unused. ### IO and Interrupt Privileges The kernel protection domain cooperative scheduling context needs -access to IO ports, for device initialization. Other protection -domains may also require such access. The IO Privilege Level (IOPL) -that is assigned to a protection domain using the relevant bits in the +access to IO ports, for device initialization. Some other protection +domains also require such access. The IO Privilege Level (IOPL) that +is assigned to a protection domain using the relevant bits in the EFLAGS field could be set according to whether IO port access is -required in that protection domain. However, this would introduce -additional complexity and overhead in the critical system call and -return dispatchers. Instead, the IOPL is always set to block IO -access from the cooperative scheduling context. Port IO instructions -in that context will then generate general protection faults, and the -exception handler decodes and emulates authorized port IO -instructions. +required in that protection domain. This is straightforward for TSS, +which includes separate flags settings for each protection domain. +However, this would introduce additional complexity and overhead in +the critical system call and return dispatchers for other plugins. +Instead, the IOPL is always set to block IO access from the +cooperative scheduling context. Port IO instructions in that context +will then generate general protection faults, and the exception +handler decodes and emulates authorized port IO instructions. Interrupts are handled at ring level 2, since they do not use any privileged instructions. They do cause the interrupt flag to be @@ -307,11 +316,15 @@ pivoting to the main stack and executing the handler. ### Protection Domain Control Structures (PDCSes) Each protection domain is managed by the kernel and privileged -functions using a PDCS. The PDCS structure is entirely -software-defined. The initial protection domain plugin does not -support re-entrant protection domains to simplify the implementation -of the plugin by enabling domain-specific information (e.g. system -call return address) to be trivially stored in each PDCS. +functions using a PDCS. The structure of the PDCS is partially +hardware-imposed in the cases of the two segment-based plugins, since +the PDCS contains the Local Descriptor Table (LDT) and the TSS, if +applicable. In the paging plugin, the PDCS structure is entirely +software-defined. None of the initial protection domain plugins +support re-entrant protection domains due to hardware-imposed +limitations of TSS and to simplify the implementation of the other +plugins by enabling domain-specific information (e.g. system call +return address) to be trivially stored in each PDCS. ### Paging-Based Protection Domains @@ -547,6 +560,293 @@ be possible to improve the robustness of the system by marking that data as read-only. Doing so would introduce additional complexity into the system. +### Hardware-Switched Segment-Based Protection Domains + +Primary implementation sources: + + - cpu/x86/mm/tss-prot-domains.c + - cpu/x86/mm/tss-prot-domains-asm.S + +#### Introduction + +One TSS is allocated for each protection domain. Each one is +associated with its own dedicated LDT. The memory resources assigned +to each protection domain are represented as segment descriptors in +the LDT for the protection domain. Additional shared memory resources +are represented as segment descriptors in the GDT. + +#### System Call and Return Dispatching + +The system call dispatcher runs in the context of the server +protection domain. It is a common piece of code that is shared among +all protection domains. Thus, each TSS, except the application TSS, +has its EIP field initialized to the entrypoint for the system call +dispatcher so that will be the first code to run when the first switch +to that task is performed. + +The overall process of handling a system call can be illustrated at a +high level as follows. Some minor steps are omitted from this +illustration in the interest of clarity and brevity. + +``` + == BEGIN Client protection domain ========================================== + -- BEGIN Caller ------------------------------------------------------------ + 1. Call system call stub. + -- + 13. Continue execution... + -- END Caller -------------------------------------------------------------- + -- BEGIN System call stub -------------------------------------------------- + 2. Already in desired (server) protection domain? + - No: Request task switch to server protection domain. + - Yes: Jump to system call body. + -- + 12. Return to caller. + -- END System call stub ---------------------------------------------------- + == END Client protection domain ============================================ + == BEGIN Server protection domain ========================================== + -- BEGIN System call dispatcher--------------------------------------------- + 3. Check that the requested system call is allowed. Get entrypoint. + 4. Switch to the main stack. + 5. Pop the client return address off the stack to a callee-saved register. + 6. Push the address of the system call return dispatcher onto the stack. + 7. Jump to system call body. + -- + 10. Restore the client return address to the stack. + 11. Request task switch to client protection domain. + -- END System call dispatcher ---------------------------------------------- + -- BEGIN System call body -------------------------------------------------- + 8. Execute the work for the requested system call. + 9. Return (to system call return stub, unless invoked from server + protection domain, in which case return is to caller). + -- END System call body ---------------------------------------------------- + == END Server protection domain ============================================ +``` + +An additional exception handler is needed, for the "Device Not +Available" exception. The handler comprises just a CLTS and an IRET +instruction. The CLTS instruction is privileged, which is why it must +be run at ring level 0. This exception handler is invoked when a +floating point instruction is used following a task switch, and its +sole purpose is to enable the floating point instruction to execute +after the exception handler returns. See the TSS resources listed +above for more details regarding interactions between task switching +and floating point instructions. + +Each segment register may represent a different data region within +each protection domain, although the FS register is used for two +separate purposes at different times. The segments are defined as +follows: + + - CS (code segment) maps all non-startup code with execute-only + permissions in all protection domains. Limiting the code that is + executable within each protection domain to just the code that is + actually needed within that protection domain could improve the + robustness of the system, but it is challenging to determine all + code that may be needed in a given protection domain (e.g. all + needed library routines). Furthermore, that code may not all be + contiguous, and each segment descriptor can only map a contiguous + memory region. Finally, segment-based memory addressing is + relative to an offset of zero from the beginning of each segment, + introducing additional complexity if such fine-grained memory + management were to be used. + - DS (default data segment) typically maps the main stack and all + non-stack data memory that is accessible from all protection + domains. Limiting the data that is accessible via DS within each + protection domain to just the subset of the data that is actually + needed within that protection domain could improve the robustness + of the system, but it is challenging for similar reasons to those + that apply to CS. Access to the main stack via DS is supported so + that code that copies the stack pointer to a register and attempts + to access stack entries via DS works correctly. Disallowing access + to the main stack via DS could improve the robustness of the + system, but that may require modifying code that expects to be able + to access the stack via DS. + - ES is loaded with the same segment descriptor as DS so that string + operations (e.g. the MOVS instruction) work correctly. + - FS usually maps the kernel-owned data region. That region can only + be written via FS in the kernel protection domain. FS contains a + descriptor specifying a read-only mapping in all other protection + domains except the application protection domain, in which FS is + nullified. Requiring that code specifically request access to the + kernel-owned data region by using the FS segment may improve the + robustness of the system by blocking undesired accesses to the + kernel-owned data region via memory access instructions within the + kernel protection domain that implicitly access DS. The reason for + granting read-only access to the kernel-owned data region from most + protection domains is that the system call dispatcher runs in the + context of the server protection domain to minimize overhead, and + it requires access to the kernel-owned data region. It may improve + the robustness of the system to avoid this by running the system + call dispatcher in a more-privileged ring level (e.g. ring 1) + within the protection domain and just granting access to the + kernel-owned data region from that ring. However, that would + necessitate a ring level transition to ring 3 when dispatching the + system call, which would increase overhead. The application + protection domain does not export any system calls, so it does not + require access to the kernel-owned data region. + - FS is temporarily loaded with a segment descriptor that maps just + an MMIO region used by a driver protection domain when such a + driver needs to perform MMIO accesses. + - GS maps an optional region of readable and writable metadata that + can be associated with a protection domain. In protection domains + that are not associated with metadata, GS is nullified. + - SS usually maps just the main stack. This may improve the + robustness of the system by enabling immediate detection of stack + underflows and overflows rather than allowing such a condition to + result in silent data corruption. Interrupt handlers use a stack + segment that covers the main stack and also includes a region above + the main stack that is specifically for use by interrupt handlers. + In like manner, exception handlers use a stack segment that covers + both of the other stacks and includes an additional region. This + is to support the interrupt dispatchers that copy parameters from + the interrupt-specific stack region to the main stack prior to + pivoting to the main stack to execute an interrupt handler body. + +The approximate memory layout of the system is depicted below, +starting with the highest physical addresses and proceeding to lower +physical addresses. The memory ranges that are mapped at various +times by each of the segment registers are also depicted. Read the +descriptions of each segment above for more information about what +memory range may be mapped by each segment register at various times +with various protection domain configurations. Parenthetical notes +indicate the protection domains that can use each mapping. The suffix +[L] indicates that the descriptor is loaded from LDT. Optional +mappings are denoted by a '?' after the protection domain label. The +'other' protection domain label refers to protection domains other +than the application and kernel domains. + +``` + ... + +------------------------------------------+ \ + | Domain X MMIO | +- FS[L] + +------------------------------------------+ / (other?) + ... + +------------------------------------------+ \ + | Domain X DMA-accessible metadata | +- GS[L] (other?) + | (section .dma_bss) | | + +------------------------------------------+ / + +------------------------------------------+ \ + | Domain X metadata (section .meta_bss) | +- GS[L] (other?) + +------------------------------------------+ / + ... + +------------------------------------------+ \ + | Kernel-private data | | + | (sections .prot_dom_bss, .gdt_bss, etc.) | +- FS[L] (kern) + +------------------------------------------+ | + +------------------------------------------+ \ + | System call data (section .syscall_bss) | | + +------------------------------------------+ +- FS[L] (all) + +------------------------------------------+ | + | Kernel-owned data (section .kern_bss) | | + +------------------------------------------+ / + +------------------------------------------+ \ + | Common data | | + | (sections .data, .rodata*, .bss, etc.) | | + +------------------------------------------+ +- DS, ES + +------------------------------------------+ \ | (all) + | Exception stack (section .exc_stack) | | | + |+----------------------------------------+| \ | + || Interrupt stack (section .int_stack) || | | + ||+--------------------------------------+|| \ | + ||| Main stack (section .main_stack) ||| +- SS (all) | + +++--------------------------------------+++ / / + +------------------------------------------+ \ + | Main code (.text) | +- CS (all) + +------------------------------------------+ / + +------------------------------------------+ + | Bootstrap code (section .boot_text) | + +------------------------------------------+ + +------------------------------------------+ + | Multiboot header | + +------------------------------------------+ + ... +``` + +This memory layout is more efficient than the layout that is possible +with paging-based protection domains, since segments have byte +granularity, whereas the minimum unit of control supported by paging +is a 4KiB page. For example, this means that metadata may need to be +padded to be a multiple of the page size. This may also permit +potentially-undesirable accesses to padded areas of code and data +regions that do not entirely fill the pages that they occupy. + +Kernel data structure access, including to the descriptor tables +themselves, is normally restricted to the code running at ring level +0, specifically the exception handlers and the system call and return +dispatchers. It is also accessible from the cooperative scheduling +context in the kernel protection domain. Interrupt delivery is +disabled in the kernel protection domain, so the preemptive scheduling +context is not used. + +SS, DS, and ES all have the same base address, since the compiler may +assume that a flat memory model is in use. Memory accesses that use a +base register of SP/ESP or BP/EBP or that are generated by certain +other instructions (e.g. PUSH, RET, etc.) are directed to SS by +default, whereas other accesses are directed to DS or ES by default. +The compiler may use an instruction that directs an access to DS or ES +even if the data being accessed is on the stack, which is why these +three segments must use the same base address. However, it is +possible to use a lower limit for SS than for DS and ES for the +following reasons. Compilers commonly provide an option for +preventing the frame pointer, EBP, from being omitted and possibly +used to point to non-stack data. In our tests, compilers never used +ESP to point to non-stack data. + +Each task switch ends up saving and restoring more state than is +actually useful to us, but the implementation attempts to minimize +overhead by configuring the register values in each TSS to reduce the +number of register loads that are needed in the system call +dispatcher. Specifically, two callee-saved registers are populated +with base addresses used when computing addresses in the entrypoint +information table as well as a mask corresponding to the ID of the +server protection domain that is used to check whether the requested +system call is exported by the server protection domain. Callee-saved +registers are used, since the task return will update the saved +register values. + +Note that this implies that the intervening code run between the task +call and return can modify critical data used by the system call +dispatcher. However, this is analogous to the considerations +associated with sharing a single stack amongst all protection domains +and should be addressed similarly, by only invoking protection domains +that are trusted by the caller to not modify the saved critical +values. This consideration is specific to the TSS-based dispatcher +and is not shared by the ring 0 dispatcher used in the other +plugins. + +Data in the .rodata sections is marked read/write, even though it may +be possible to improve the robustness of the system by marking that +data as read-only. Doing so would introduce even more complexity into +the system than would be the case with paging-based protection +domains, since it would require allocating different segment +descriptors for the read-only vs. the read/write data. + +#### Supporting Null-Pointer Checks + +A lot of code considers a pointer value of 0 to be invalid. However, +segment offsets always start at 0. To accommodate the common software +behavior, at least the first byte of each segment is marked as +unusable. An exception to this is that the first byte of the stack +segments is usable. + +#### Interrupt and Exception Dispatching + +A distinctive challenge that occurs during interrupt and exception +dispatching is that the state of the segment registers when an +interrupt or exception occurs is somewhat unpredictable. For example, +an exception may occur while MMIO is being performed, meaning that FS +is loaded with the MMIO descriptor instead of the kernel descriptor. +Leaving the segment registers configured in that way could cause +incorrect interrupt or exception handler behavior. Thus, the +interrupt or exception dispatcher must save the current segment +configuration, switch to a configuration that is suitable for the +handler body, and then restore the saved segment configuration after +the handler body returns. Another motivation for this is that the +interrupted code may have corrupted the segment register configuration +in an unexpected manner, since segment register load instructions are +unprivileged. Similar segment register updates must be performed for +similar reasons when dispatching system calls. + ### Pointer Validation Primary implementation sources: @@ -563,10 +863,14 @@ an unintended manner. For example, if an incoming pointer referenced the return address, it could potentially redirect execution with the privileges of the callee protection domain. -It is also necessary to check that the pointer is either within the -stack region or the shared data region (or a guard band region, since -that will generate a fault) to prevent redirection of data accesses to -MMIO or metadata regions. +When the paging-based plugin is in use, it is also necessary to check +that the pointer is either within the stack region or the shared data +region (or a guard band region, since that will generate a fault) to +prevent redirection of data accesses to MMIO or metadata regions. The +other plugins already configure segments to restrict accesses to DS to +just those regions. Pointers provided as inputs to system calls as +defined above should never be dereferenced in any segment other than +DS. The pointer is both validated and copied to a new storage location, which must be within the callee's local stack region (excluding the @@ -648,8 +952,11 @@ The following steps are required: Usage ----- -To enable protection domain support, add -"X86_CONF_PROT_DOMAINS=paging" to the command line. +To enable protection domain support, add "X86_CONF_PROT_DOMAINS=" to +the command line and specify one of the following options: + + - paging + - tss The paging option accepts a sub-option to determine whether the TLB is fully- or selectively-invalidated during protection domain switches. diff --git a/cpu/x86/mm/gdt-layout.h b/cpu/x86/mm/gdt-layout.h index 8a5af6cbf..5dddd3a4d 100644 --- a/cpu/x86/mm/gdt-layout.h +++ b/cpu/x86/mm/gdt-layout.h @@ -39,6 +39,8 @@ * outside of gdt.c. */ #define GDT_NUM_FIXED_DESC 7 +#elif X86_CONF_PROT_DOMAINS_MULTI_SEG +#define GDT_NUM_FIXED_DESC 11 #else #define GDT_NUM_FIXED_DESC 3 #endif @@ -66,12 +68,34 @@ /** Stack segment for interrupt handlers */ #define GDT_IDX_STK_INT 5 +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__PAGING #define GDT_IDX_CODE_EXC GDT_IDX_CODE_FLAT /** Default data segment used by code at all privilege levels */ #define GDT_IDX_DATA 6 #define GDT_IDX_STK GDT_IDX_DATA #define GDT_IDX_STK_EXC GDT_IDX_DATA_FLAT #else +/** + * Same bounds and permissions as default code segment, but at the exception + * handler privilege level + */ +#define GDT_IDX_CODE_EXC 6 +/** R/W kernel data descriptor used during boot stage 1 */ +#define GDT_IDX_DATA_KERN_EXC 7 +/** Default data segment used by code at all privilege levels */ +#define GDT_IDX_DATA 8 +/** + * Default stack segment, which overlaps with the beginning of the default data + * segment + */ +#define GDT_IDX_STK 9 +/** Stack segment for exception handlers */ +#define GDT_IDX_STK_EXC 10 + +#define GDT_IDX_TSS(dom_id) (GDT_NUM_FIXED_DESC + (2 * (dom_id))) +#define GDT_IDX_LDT(dom_id) (GDT_NUM_FIXED_DESC + (2 * (dom_id)) + 1) +#endif +#else #define GDT_IDX_CODE GDT_IDX_CODE_FLAT #define GDT_IDX_CODE_INT GDT_IDX_CODE_FLAT #define GDT_IDX_CODE_EXC GDT_IDX_CODE_FLAT @@ -96,10 +120,14 @@ #define GDT_SEL_CODE_EXC GDT_SEL(GDT_IDX_CODE_EXC, PRIV_LVL_EXC) #define GDT_SEL_DATA GDT_SEL(GDT_IDX_DATA, PRIV_LVL_EXC) +#define GDT_SEL_DATA_KERN_EXC GDT_SEL(GDT_IDX_DATA_KERN_EXC, PRIV_LVL_EXC) #define GDT_SEL_STK GDT_SEL(GDT_IDX_STK, PRIV_LVL_USER) #define GDT_SEL_STK_INT GDT_SEL(GDT_IDX_STK_INT, PRIV_LVL_INT) #define GDT_SEL_STK_EXC GDT_SEL(GDT_IDX_STK_EXC, PRIV_LVL_EXC) +#define GDT_SEL_TSS(dom_id) GDT_SEL(GDT_IDX_TSS(dom_id), PRIV_LVL_USER) +#define GDT_SEL_LDT(dom_id) GDT_SEL(GDT_IDX_LDT(dom_id), PRIV_LVL_USER) + #endif /* CPU_X86_MM_GDT_LAYOUT_H_ */ diff --git a/cpu/x86/mm/ldt-layout.h b/cpu/x86/mm/ldt-layout.h new file mode 100644 index 000000000..7c61054a5 --- /dev/null +++ b/cpu/x86/mm/ldt-layout.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2015, Intel Corporation. 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +#ifndef CPU_X86_MM_LDT_LAYOUT_H_ +#define CPU_X86_MM_LDT_LAYOUT_H_ + +#include "gdt-layout.h" + +/* Each LDT can contain up to this many descriptors, but some protection + * domains may not use all of the slots. + */ +#define LDT_NUM_DESC 3 + +/** + * Provides access to kernel data. Most protection domains are granted at most + * read-only access, but the kernel protection domain is granted read/write + * access. + */ +#define LDT_IDX_KERN 0 +/** Maps a device MMIO range */ +#define LDT_IDX_MMIO 1 +/** Maps domain-defined metadata */ +#define LDT_IDX_META 2 + +#define LDT_SEL(idx, rpl) (GDT_SEL(idx, rpl) | (1 << 2)) + +#define LDT_SEL_KERN LDT_SEL(LDT_IDX_KERN, PRIV_LVL_USER) +#define LDT_SEL_MMIO LDT_SEL(LDT_IDX_MMIO, PRIV_LVL_USER) +#define LDT_SEL_META LDT_SEL(LDT_IDX_META, PRIV_LVL_USER) +#define LDT_SEL_STK LDT_SEL(LDT_IDX_STK, PRIV_LVL_USER) + +#endif /* CPU_X86_MM_LDT_LAYOUT_H_ */ diff --git a/cpu/x86/mm/multi-segment.c b/cpu/x86/mm/multi-segment.c new file mode 100644 index 000000000..f60a2c8bb --- /dev/null +++ b/cpu/x86/mm/multi-segment.c @@ -0,0 +1,239 @@ +/* + * Copyright (C) 2015, Intel Corporation. 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +#include "gdt.h" +#include "helpers.h" +#include "prot-domains.h" +#include "segmentation.h" +#include "stacks.h" + +/*---------------------------------------------------------------------------*/ +static uint32_t +segment_desc_compute_base(segment_desc_t desc) +{ + return (desc.base_hi << 24) | (desc.base_mid << 16) | desc.base_lo; +} +/*---------------------------------------------------------------------------*/ +void +prot_domains_reg_multi_seg(volatile struct dom_kern_data ATTR_KERN_ADDR_SPACE *dkd, + uintptr_t mmio, size_t mmio_sz, + uintptr_t meta, size_t meta_sz) +{ + segment_desc_t desc; + dom_id_t dom_id = PROT_DOMAINS_GET_DOM_ID(dkd); + uint32_t kern_data_len; + uint32_t tmp; + + if((dkd < prot_domains_kern_data) || + (prot_domains_kern_data_end <= dkd) || + (((((uintptr_t)dkd) - (uintptr_t)prot_domains_kern_data) % + sizeof(dom_kern_data_t)) != 0)) { + halt(); + } + + KERN_READL(tmp, dkd->ldt[DT_SEL_GET_IDX(LDT_SEL_KERN)].raw_hi); + if(tmp != 0) { + /* This PDCS was previously initialized, which is disallowed. */ + halt(); + } + + /* Initialize descriptors */ + + if(dom_id == DOM_ID_kern) { + kern_data_len = (uint32_t)&_ebss_kern_addr; + } else { + /* Non-kernel protection domains do not need to access the protection + * domain control structures, and they may contain saved register values + * that are private to each domain. + */ + kern_data_len = (uint32_t)&_ebss_syscall_addr; + } + kern_data_len -= (uint32_t)&_sbss_kern_addr; + + segment_desc_init(&desc, (uint32_t)&_sbss_kern_addr, kern_data_len, + /* Every protection domain requires at least read-only access to kernel + data to read dom_client_data structures and to support the system call + dispatcher, if applicable. Only the kernel protection domain is granted + read/write access to the kernel data. */ + ((dom_id == DOM_ID_kern) ? + SEG_TYPE_DATA_RDWR : + SEG_TYPE_DATA_RDONLY) | + SEG_FLAG(DPL, PRIV_LVL_USER) | + SEG_GRAN_BYTE | SEG_DESCTYPE_NSYS); + + KERN_WRITEL(dkd->ldt[LDT_IDX_KERN].raw_lo, desc.raw_lo); + KERN_WRITEL(dkd->ldt[LDT_IDX_KERN].raw_hi, desc.raw_hi); + + if(mmio_sz != 0) { + if(SEG_MAX_BYTE_GRAN_LEN < mmio_sz) { + halt(); + } + + segment_desc_init(&desc, mmio, mmio_sz, + SEG_FLAG(DPL, PRIV_LVL_USER) | SEG_GRAN_BYTE | + SEG_DESCTYPE_NSYS | SEG_TYPE_DATA_RDWR); + } else { + desc.raw = SEG_DESC_NOT_PRESENT; + } + + KERN_WRITEL(dkd->ldt[LDT_IDX_MMIO].raw_lo, desc.raw_lo); + KERN_WRITEL(dkd->ldt[LDT_IDX_MMIO].raw_hi, desc.raw_hi); + + if(meta_sz != 0) { + if(SEG_MAX_BYTE_GRAN_LEN < meta_sz) { + halt(); + } + + segment_desc_init(&desc, meta, meta_sz, + SEG_FLAG(DPL, PRIV_LVL_USER) | SEG_GRAN_BYTE | + SEG_DESCTYPE_NSYS | SEG_TYPE_DATA_RDWR); + } else { + desc.raw = SEG_DESC_NOT_PRESENT; + } + + KERN_WRITEL(dkd->ldt[LDT_IDX_META].raw_lo, desc.raw_lo); + KERN_WRITEL(dkd->ldt[LDT_IDX_META].raw_hi, desc.raw_hi); + + segment_desc_init(&desc, + KERN_DATA_OFF_TO_PHYS_ADDR(dkd->ldt), + sizeof(dkd->ldt), + SEG_FLAG(DPL, PRIV_LVL_USER) | SEG_GRAN_BYTE | + SEG_DESCTYPE_SYS | SEG_TYPE_LDT); + gdt_insert(GDT_IDX_LDT(dom_id), desc); +} +/*---------------------------------------------------------------------------*/ +void +prot_domains_gdt_init() +{ + int i; + segment_desc_t desc; + + segment_desc_init(&desc, + (uint32_t)&_stext_addr, + ((uint32_t)&_etext_addr) - (uint32_t)&_stext_addr, + SEG_FLAG(DPL, PRIV_LVL_EXC) | SEG_GRAN_BYTE | + SEG_DESCTYPE_NSYS | SEG_TYPE_CODE_EX); + gdt_insert_boot(GDT_IDX_CODE_EXC, desc); + + segment_desc_init(&desc, + (uint32_t)&_sdata_addr, + ((uint32_t)&_edata_addr) - (uint32_t)&_sdata_addr, + SEG_FLAG(DPL, PRIV_LVL_USER) | SEG_GRAN_BYTE | + SEG_DESCTYPE_NSYS | SEG_TYPE_DATA_RDWR); + gdt_insert_boot(GDT_IDX_DATA, desc); + + segment_desc_init(&desc, + (uint32_t)&_sbss_kern_addr, + ((uint32_t)&_ebss_kern_addr) - + (uint32_t)&_sbss_kern_addr, + SEG_FLAG(DPL, PRIV_LVL_EXC) | SEG_GRAN_BYTE | + SEG_DESCTYPE_NSYS | SEG_TYPE_DATA_RDWR); + gdt_insert_boot(GDT_IDX_DATA_KERN_EXC, desc); + + segment_desc_init(&desc, + (uint32_t)DATA_OFF_TO_PHYS_ADDR(stacks_main), + STACKS_SIZE_MAIN, + SEG_FLAG(DPL, PRIV_LVL_USER) | SEG_GRAN_BYTE | + SEG_DESCTYPE_NSYS | SEG_TYPE_DATA_RDWR); + gdt_insert_boot(GDT_IDX_STK, desc); + + segment_desc_set_limit(&desc, STACKS_SIZE_MAIN + STACKS_SIZE_INT); + SEG_SET_FLAG(desc, DPL, PRIV_LVL_INT); + gdt_insert_boot(GDT_IDX_STK_INT, desc); + + segment_desc_set_limit(&desc, + STACKS_SIZE_MAIN + + STACKS_SIZE_INT + + STACKS_SIZE_EXC); + SEG_SET_FLAG(desc, DPL, PRIV_LVL_EXC); + gdt_insert_boot(GDT_IDX_STK_EXC, desc); + + /* Not all domains will necessarily be initialized, so this initially marks + * all per-domain descriptors not-present. + */ + desc.raw = SEG_DESC_NOT_PRESENT; + for(i = 0; i < PROT_DOMAINS_ACTUAL_CNT; i++) { + gdt_insert_boot(GDT_IDX_TSS(i), desc); + gdt_insert_boot(GDT_IDX_LDT(i), desc); + } + + __asm__ __volatile__ ( + "mov %[_default_data_], %%ds\n\t" + "mov %[_default_data_], %%es\n\t" + "mov %[_kern_data_], %%" SEG_KERN "s\n\t" + : + : [_default_data_] "r"(GDT_SEL_DATA), + [_kern_data_] "r"(GDT_SEL_DATA_KERN_EXC)); +} +/*---------------------------------------------------------------------------*/ +void +multi_segment_launch_kernel(void) +{ + /* Update segment registers. */ + __asm__ __volatile__ ( + "mov %[_data_seg_], %%ds\n\t" + "mov %[_data_seg_], %%es\n\t" + "mov %[_kern_seg_], %%" SEG_KERN "s\n\t" + "mov %[_data_seg_], %%" SEG_META "s\n\t" + : + : [_data_seg_] "r" (GDT_SEL_DATA), + [_kern_seg_] "r" (LDT_SEL_KERN) + ); +} +/*---------------------------------------------------------------------------*/ +void +prot_domains_enable_mmio(void) +{ + __asm__ __volatile__ ("mov %0, %%" SEG_MMIO "s" :: "r" (LDT_SEL_MMIO)); +} +/*---------------------------------------------------------------------------*/ +void +prot_domains_disable_mmio(void) +{ + __asm__ __volatile__ ("mov %0, %%" SEG_KERN "s" :: "r" (LDT_SEL_KERN)); +} +/*---------------------------------------------------------------------------*/ +uintptr_t +prot_domains_lookup_meta_phys_base(dom_client_data_t ATTR_KERN_ADDR_SPACE *drv) +{ + dom_id_t dom_id; + segment_desc_t desc; + volatile dom_kern_data_t ATTR_KERN_ADDR_SPACE *dkd; + + KERN_READL(dom_id, drv->dom_id); + + dkd = prot_domains_kern_data + dom_id; + + KERN_READL(desc.raw_lo, dkd->ldt[DT_SEL_GET_IDX(LDT_SEL_META)].raw_lo); + KERN_READL(desc.raw_hi, dkd->ldt[DT_SEL_GET_IDX(LDT_SEL_META)].raw_hi); + + return segment_desc_compute_base(desc); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/x86/mm/multi-segment.h b/cpu/x86/mm/multi-segment.h new file mode 100644 index 000000000..baa28002b --- /dev/null +++ b/cpu/x86/mm/multi-segment.h @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2015, Intel Corporation. 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +#ifndef CPU_X86_MM_MULTI_SEGMENT_H_ +#define CPU_X86_MM_MULTI_SEGMENT_H_ + +#include +#include +#include "helpers.h" +#include "ldt-layout.h" + +#ifdef __clang__ +#define __SEG_FS +#define __seg_fs __attribute__((address_space(257))) +#define __SEG_GS +#define __seg_gs __attribute__((address_space(256))) +#endif + +#ifdef __SEG_FS +#define ATTR_MMIO_ADDR_SPACE __seg_fs +#define ATTR_KERN_ADDR_SPACE __seg_fs +#else +#define ATTR_KERN_ADDR_SPACE +#endif +#ifdef __SEG_GS +#define ATTR_META_ADDR_SPACE __seg_gs +#endif + +void prot_domains_reg_multi_seg(volatile struct dom_kern_data ATTR_KERN_ADDR_SPACE *dkd, + uintptr_t mmio, size_t mmio_sz, + uintptr_t meta, size_t meta_sz); +void multi_segment_launch_kernel(void); + +#define MULTI_SEGMENT_ENTER_ISR(exc) \ + "mov $" EXP_STRINGIFY(GDT_SEL_DATA) ", %%eax\n\t" \ + /* Refresh DS and ES in case the userspace code corrupted them. */ \ + "mov %%eax, %%ds\n\t" \ + "mov %%eax, %%es\n\t" \ + /* Refresh SEG_KERN. */ \ + "mov $" EXP_STRINGIFY(LDT_SEL_KERN) ", %%eax\n\t" \ + "mov %%eax, %%" SEG_KERN "s\n\t" \ + ".if " #exc "\n\t" \ + /* It is possible that a routine performing MMIO is being interrupted. */ \ + /* Thus, it is necessary to save and restore the MMIO segment register */ \ + /* (in a callee-saved register). */ \ + "mov %%" SEG_MMIO "s, %%ebp\n\t" \ + "mov $" EXP_STRINGIFY(GDT_SEL_DATA_KERN_EXC) ", %%eax\n\t" \ + "mov %%eax, %%" SEG_KERN "s\n\t" \ + ".endif\n\t" +#define MULTI_SEGMENT_LEAVE_ISR(exc) \ + ".if " #exc "\n\t" \ + "mov %%ebp, %%" SEG_MMIO "s\n\t" \ + ".endif\n\t" + +/** + * The MMIO region is tightly bounded within a segment, so its base offset is + * always 0. + */ +#define PROT_DOMAINS_MMIO(dcd) 0 +/** + * The metadata region is tightly bounded within a segment, so its base offset + * is always 0. + */ +#define PROT_DOMAINS_META(dcd) 0 + +#define SEG_MMIO "f" /**< For MMIO accesses, when enabled. */ +#define SEG_KERN "f" /**< For kernel data accesses */ +#define SEG_META "g" /**< For metadata accesses */ + +#define _SEG_READL(seg, dst, src) \ + __asm__ __volatile__ ( \ + "movl %%" seg "s:%[src_], %[dst_]" : [dst_]"=r"(dst) : [src_]"m"(src)) + +#define _SEG_READW(seg, dst, src) \ + __asm__ __volatile__ ( \ + "movw %%" seg "s:%[src_], %[dst_]" : [dst_]"=r"(dst) : [src_]"m"(src)) + +#define _SEG_READB(seg, dst, src) \ + __asm__ __volatile__ ( \ + "movb %%" seg "s:%[src_], %[dst_]" : [dst_]"=q"(dst) : [src_]"m"(src)) + +#define _SEG_WRITEL(seg, dst, src) \ + __asm__ __volatile__ ( \ + "movl %[src_], %%" seg "s:%[dst_]" \ + : [dst_]"=m"(dst) : [src_]"r"((uint32_t)(src))) + +#define _SEG_WRITEW(seg, dst, src) \ + __asm__ __volatile__ ( \ + "movw %[src_], %%" seg "s:%[dst_]" \ + : [dst_]"=m"(dst) : [src_]"r"((uint16_t)(src))) + +#define _SEG_WRITEB(seg, dst, src) \ + __asm__ __volatile__ ( \ + "movb %[src_], %%" seg "s:%[dst_]" \ + : [dst_]"=m"(dst) : [src_]"q"((uint8_t)(src))) + +#ifndef __SEG_FS +#define MMIO_READL(dst, src) _SEG_READL(SEG_MMIO, dst, src) +#define MMIO_READW(dst, src) _SEG_READW(SEG_MMIO, dst, src) +#define MMIO_READB(dst, src) _SEG_READB(SEG_MMIO, dst, src) +#define MMIO_WRITEL(dst, src) _SEG_WRITEL(SEG_MMIO, dst, src) +#define MMIO_WRITEW(dst, src) _SEG_WRITEW(SEG_MMIO, dst, src) +#define MMIO_WRITEB(dst, src) _SEG_WRITEB(SEG_MMIO, dst, src) + +#define KERN_READL(dst, src) _SEG_READL(SEG_KERN, dst, src) +#define KERN_READW(dst, src) _SEG_READW(SEG_KERN, dst, src) +#define KERN_READB(dst, src) _SEG_READB(SEG_KERN, dst, src) +#define KERN_WRITEL(dst, src) _SEG_WRITEL(SEG_KERN, dst, src) +#define KERN_WRITEW(dst, src) _SEG_WRITEW(SEG_KERN, dst, src) +#define KERN_WRITEB(dst, src) _SEG_WRITEB(SEG_KERN, dst, src) +#endif + +#ifndef __SEG_GS +#define META_READL(dst, src) _SEG_READL(SEG_META, dst, src) +#define META_READW(dst, src) _SEG_READW(SEG_META, dst, src) +#define META_READB(dst, src) _SEG_READB(SEG_META, dst, src) +#define META_WRITEL(dst, src) _SEG_WRITEL(SEG_META, dst, src) +#define META_WRITEW(dst, src) _SEG_WRITEW(SEG_META, dst, src) +#define META_WRITEB(dst, src) _SEG_WRITEB(SEG_META, dst, src) +#endif + +#define MEMCPY_FROM_META(dst, src, sz) \ + { \ + uintptr_t __dst = (uintptr_t)(dst); \ + uintptr_t __src = (uintptr_t)(src); \ + size_t __sz = (size_t)(sz); \ + __asm__ __volatile__ ( \ + "rep movsb %%" SEG_META "s:(%%esi), %%es:(%%edi)\n\t" \ + : "+D"(__dst), "+S"(__src), "+c"(__sz)); \ + } + +#define MEMCPY_TO_META(dst, src, sz) \ + { \ + uintptr_t __dst = (uintptr_t)(dst); \ + uintptr_t __src = (uintptr_t)(src); \ + size_t __sz = (size_t)(sz); \ + __asm__ __volatile__ ( \ + "push %%es\n\t" \ + "push %%" SEG_META "s\n\t" \ + "pop %%es\n\t" \ + "rep movsb\n\t" \ + "pop %%es\n\t" \ + : "+D"(__dst), "+S"(__src), "+c"(__sz)); \ + } + +/** Compute physical address from offset into kernel data space */ +#define KERN_DATA_OFF_TO_PHYS_ADDR(x) \ + (((uintptr_t)&_sbss_kern_addr) + (uintptr_t)(x)) +/** Compute physical address from offset into default data space */ +#define DATA_OFF_TO_PHYS_ADDR(x) \ + (((uintptr_t)&_sdata_addr) + (uintptr_t)(x)) +/** Compute kernel data offset from physical address in kernel data space */ +#define PHYS_ADDR_TO_KERN_DATA_OFF(x) \ + (((uintptr_t)(x)) - (uintptr_t)&_sbss_kern_addr) + +/** + * In multi-segment protection domain implementations, it is sufficient to just + * compare incoming pointers against the frame pointer. All incoming pointers + * are dereferenced in the main data segment, which only maps the stacks and + * the shared data section. Since the shared data section is at a higher + * address range than the stacks, the frame pointer check is sufficient. + */ +#define PROT_DOMAINS_CHECK_INCOMING_PTR PROT_DOMAINS_CHECK_INCOMING_PTR_EBP + +void prot_domains_enable_mmio(void); +void prot_domains_disable_mmio(void); + +#endif /* CPU_X86_MM_MULTI_SEGMENT_H_ */ diff --git a/cpu/x86/mm/prot-domains.c b/cpu/x86/mm/prot-domains.c index 593da98e2..8bbeb4d83 100644 --- a/cpu/x86/mm/prot-domains.c +++ b/cpu/x86/mm/prot-domains.c @@ -39,10 +39,12 @@ #include "stacks.h" static dom_kern_data_t __attribute__((section(".kern_prot_dom_bss"))) - PROT_DOMAINS_PDCS_NM(kern_dcd); + ATTR_KERN_ADDR_SPACE PROT_DOMAINS_PDCS_NM(kern_dcd); +PROT_DOMAINS_ALLOC_IMPL(kern_dcd); static dom_client_data_t ATTR_BSS_KERN kern_dcd; static dom_kern_data_t __attribute__((section(".app_prot_dom_bss"))) - PROT_DOMAINS_PDCS_NM(app_dcd); + ATTR_KERN_ADDR_SPACE PROT_DOMAINS_PDCS_NM(app_dcd); +PROT_DOMAINS_ALLOC_IMPL(app_dcd); static dom_client_data_t ATTR_BSS_KERN app_dcd; /*---------------------------------------------------------------------------*/ diff --git a/cpu/x86/mm/prot-domains.h b/cpu/x86/mm/prot-domains.h index f7dc84e3c..a1fbca130 100644 --- a/cpu/x86/mm/prot-domains.h +++ b/cpu/x86/mm/prot-domains.h @@ -40,6 +40,10 @@ #define X86_CONF_PROT_DOMAINS__NONE 0 #define X86_CONF_PROT_DOMAINS__PAGING 1 +#define X86_CONF_PROT_DOMAINS__TSS 2 + +#define X86_CONF_PROT_DOMAINS_MULTI_SEG \ + (X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__TSS) /** Privilege level (ring) for exception handlers and other supervisory code */ #define PRIV_LVL_EXC 0 @@ -68,6 +72,49 @@ typedef uint32_t dom_id_t; #if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__PAGING #include "paging-prot-domains.h" +#elif X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__TSS +#include "tss-prot-domains.h" +#endif + +#ifndef ATTR_META_ADDR_SPACE +#define ATTR_META_ADDR_SPACE +#endif +#ifndef ATTR_MMIO_ADDR_SPACE +#define ATTR_MMIO_ADDR_SPACE +#endif +#ifndef ATTR_KERN_ADDR_SPACE +#define ATTR_KERN_ADDR_SPACE +#endif + +#ifndef MMIO_READL +#define MMIO_READL(dst, src) dst = (src) +#define MMIO_READW(dst, src) dst = (src) +#define MMIO_READB(dst, src) dst = (src) +#define MMIO_WRITEL(dst, src) MMIO_READL(dst, src) +#define MMIO_WRITEW(dst, src) MMIO_READW(dst, src) +#define MMIO_WRITEB(dst, src) MMIO_READB(dst, src) +#endif +#ifndef KERN_READL +#define KERN_READL(dst, src) dst = (src) +#define KERN_READW(dst, src) dst = (src) +#define KERN_READB(dst, src) dst = (src) +#define KERN_WRITEL(dst, src) KERN_READL(dst, src) +#define KERN_WRITEW(dst, src) KERN_READW(dst, src) +#define KERN_WRITEB(dst, src) KERN_READB(dst, src) +#endif +#ifndef META_READL +#define META_READL(dst, src) dst = (src) +#define META_READW(dst, src) dst = (src) +#define META_READB(dst, src) dst = (src) +#define META_WRITEL(dst, src) META_READL(dst, src) +#define META_WRITEW(dst, src) META_READw(dst, src) +#define META_WRITEB(dst, src) META_READB(dst, src) +#endif + +#ifndef MEMCPY_FROM_META +#define MEMCPY_FROM_META(dst, src, sz) \ + memcpy((void *)(dst), (const void *)(src), (sz)) +#define MEMCPY_TO_META(dst, src, sz) MEMCPY_FROM_META(dst, src, sz) #endif /* The following symbols are defined in the linker script */ @@ -77,9 +124,9 @@ extern uint32_t _stext_addr, _etext_addr; #if X86_CONF_PROT_DOMAINS != X86_CONF_PROT_DOMAINS__NONE /** Metadata that should not be DMA-accessible */ -#define ATTR_BSS_META __attribute__((section(".meta_bss"))) +#define ATTR_BSS_META __attribute__((section(".meta_bss"))) ATTR_META_ADDR_SPACE /** Kernel-owned data */ -#define ATTR_BSS_KERN __attribute__((section(".kern_bss"))) +#define ATTR_BSS_KERN __attribute__((section(".kern_bss"))) ATTR_KERN_ADDR_SPACE /** Code that should only be executable during bootup */ #define ATTR_CODE_BOOT __attribute__((section(".boot_text"))) @@ -97,6 +144,10 @@ extern uint32_t _ebss_syscall_addr; /** Bounds for other data sections */ extern uint32_t _sdata_addr, _edata_addr; +#ifndef SEG_KERN +#define SEG_KERN "d" +#endif + /** * If set, this protection domain is already in the call stack and is not * available for nested invocations. @@ -114,8 +165,8 @@ extern uint32_t _sdata_addr, _edata_addr; */ typedef struct dom_kern_data dom_kern_data_t; -extern volatile dom_kern_data_t prot_domains_kern_data[]; -extern volatile dom_kern_data_t prot_domains_kern_data_end[]; +extern volatile dom_kern_data_t ATTR_KERN_ADDR_SPACE prot_domains_kern_data[]; +extern volatile dom_kern_data_t ATTR_KERN_ADDR_SPACE prot_domains_kern_data_end[]; #define PROT_DOMAINS_ACTUAL_CNT \ (prot_domains_kern_data_end - prot_domains_kern_data) @@ -125,6 +176,7 @@ extern volatile dom_kern_data_t prot_domains_kern_data_end[]; void prot_domains_syscall_dispatcher(void); +#if X86_CONF_PROT_DOMAINS != X86_CONF_PROT_DOMAINS__TSS /** * Data associated with each protection domain that is owned by clients of that * domain and used to identify the domain. @@ -132,15 +184,21 @@ void prot_domains_syscall_dispatcher(void); struct dom_client_data { dom_id_t dom_id; } __attribute__((packed)); +#endif + +#ifndef PROT_DOMAINS_ALLOC_IMPL +#define PROT_DOMAINS_ALLOC_IMPL(nm) +#endif /** Allocate the client-owned protection domain data structure. */ #define PROT_DOMAINS_PDCS_NM(nm) _pdcs_##nm #define PROT_DOMAINS_ALLOC(typ, nm) \ static dom_kern_data_t __attribute__((section(".prot_dom_bss"))) \ - PROT_DOMAINS_PDCS_NM(nm); \ + ATTR_KERN_ADDR_SPACE PROT_DOMAINS_PDCS_NM(nm); \ + PROT_DOMAINS_ALLOC_IMPL(nm); \ static typ ATTR_BSS_KERN nm #define PROT_DOMAINS_INIT_ID(nm) \ - (nm).dom_id = PROT_DOMAINS_GET_DOM_ID(&PROT_DOMAINS_PDCS_NM(nm)) + KERN_WRITEL((nm).dom_id, PROT_DOMAINS_GET_DOM_ID(&PROT_DOMAINS_PDCS_NM(nm))) /** * Perform early initialization during boot stage 0 to prepare for boot stage 1 @@ -169,8 +227,12 @@ void prot_domains_launch_kernel(void); */ #define PROT_DOMAINS_INIT_RET_ADDR_CNT 2 +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__TSS +void prot_domains_launch_app(void); +#else void app_main(void); #define prot_domains_launch_app app_main +#endif #else @@ -229,7 +291,7 @@ typedef struct dom_client_data dom_client_data_t; * \param meta_sz Size of metadata * \param pio Set to true if protection domain requires port IO access */ -void prot_domains_reg(dom_client_data_t *dcd, +void prot_domains_reg(dom_client_data_t ATTR_KERN_ADDR_SPACE *dcd, uintptr_t mmio, size_t mmio_sz, uintptr_t meta, @@ -237,11 +299,41 @@ void prot_domains_reg(dom_client_data_t *dcd, bool pio); #endif +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__NONE +#define prot_domains_copy_dcd(dst, src) *(dst) = *(src) +#else +static inline void +/** + * It is necessary to make a local copy of a dom_client_data structure when a + * multi-segment protection domain implementation is in use, segment attributes + * are not supported by the compiler, and a dom_client_data structure needs to + * be passed by value into some function. Otherwise, the compiler will not know + * to access the non-default segment in which *src is stored and will attempt + * to copy it out of the default data segment. + */ +prot_domains_copy_dcd(struct dom_client_data *dst, + struct dom_client_data ATTR_KERN_ADDR_SPACE *src) +{ + KERN_READL(dst->dom_id, src->dom_id); +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__TSS + KERN_READL(dst->tss_sel, src->tss_sel); +#endif +} +#endif + +#if !X86_CONF_PROT_DOMAINS_MULTI_SEG +#define prot_domains_enable_mmio() +#define prot_domains_disable_mmio() + +#define KERN_DATA_OFF_TO_PHYS_ADDR(x) ((uintptr_t)(x)) +#define DATA_OFF_TO_PHYS_ADDR(x) ((uintptr_t)(x)) +#endif + #if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__NONE #define prot_domains_lookup_meta_phys_base(drv) 0 #else /** Lookup base physical address of metadata region for specified domain */ -uintptr_t prot_domains_lookup_meta_phys_base(dom_client_data_t *drv); +uintptr_t prot_domains_lookup_meta_phys_base(dom_client_data_t ATTR_KERN_ADDR_SPACE *drv); #endif #if X86_CONF_PROT_DOMAINS != X86_CONF_PROT_DOMAINS__PAGING @@ -270,6 +362,11 @@ uintptr_t prot_domains_lookup_meta_phys_base(dom_client_data_t *drv); ".endif\n\t" #endif +#ifdef X86_CONF_PROT_DOMAINS_MULTI_SEG +/* include GDT section definitions used when allocating protection domains: */ +#include "gdt.h" +#endif + #endif /* !__ASSEMBLER__ */ #endif /* CPU_X86_MM_PROT_DOMAINS_H_ */ diff --git a/cpu/x86/mm/segmentation.h b/cpu/x86/mm/segmentation.h index 57b1b8aea..71cd6beb6 100644 --- a/cpu/x86/mm/segmentation.h +++ b/cpu/x86/mm/segmentation.h @@ -59,8 +59,11 @@ #define SEG_WIDTH_GRAN 1 #define SEG_SHAMT_GRAN 15 +#define SEG_TYPE_DATA_RDONLY SEG_FLAG(TYPE, 0x00) /* Read only */ #define SEG_TYPE_DATA_RDWR SEG_FLAG(TYPE, 0x02) /* Read/Write */ #define SEG_TYPE_CODE_EXRD SEG_FLAG(TYPE, 0x0A) /* Execute/Read */ +#define SEG_TYPE_CODE_EX SEG_FLAG(TYPE, 0x08) /* Execute only */ +#define SEG_TYPE_LDT SEG_FLAG(TYPE, 0x02) #define SEG_TYPE_TSS32_AVAIL SEG_FLAG(TYPE, 0x09) #define SEG_DESCTYPE_SYS SEG_FLAG(DESCTYPE, 0) @@ -73,6 +76,12 @@ #define SEG_GRAN_BYTE SEG_FLAG(GRAN, 0) #define SEG_GRAN_PAGE SEG_FLAG(GRAN, 1) +/** + * Maximum length of segment that can be regulated with a byte-granularity + * segment limit. + */ +#define SEG_MAX_BYTE_GRAN_LEN (1 << 20) + /** * Segment descriptor. See Intel Combined Manual, * Vol. 3, Section 3.4.5 for more details. @@ -91,7 +100,13 @@ typedef union segment_desc { uint64_t raw; } segment_desc_t; -static inline void +#define SEG_DESC_NOT_PRESENT 0 + +/* The next two functions are invoked by boot code, so they must always be + * inlined to avoid being placed in a different address space than the initial, + * flat address space. + */ +static inline void __attribute__((always_inline)) segment_desc_set_limit(segment_desc_t *c_this, uint32_t len) { uint32_t limit = len - 1; @@ -108,7 +123,7 @@ segment_desc_set_limit(segment_desc_t *c_this, uint32_t len) * \param flags Flags to be added to the default flags: present, default * operand size of 32 bits, and high limit bits. */ -static inline void +static inline void __attribute__((always_inline)) segment_desc_init(segment_desc_t *c_this, uint32_t base, uint32_t len, uint16_t flags) { diff --git a/cpu/x86/mm/stacks.h b/cpu/x86/mm/stacks.h index a1005d8e0..96be72cf9 100644 --- a/cpu/x86/mm/stacks.h +++ b/cpu/x86/mm/stacks.h @@ -61,6 +61,17 @@ #else #define STACKS_SIZE_EXC 256 #endif +#elif X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__TSS +/** + * This should be large enough to execute the exception handler with the + * largest stack requirement: double_fault_handler: + * - 1 word for the return address from calling double_fault_handler + * - 1 word for the saved frame pointer in double_fault_handler + * - 2 words that GCC has been observed to skip on the stack to align it + * to a preferred boundary + * - 1 word for the return address for calling halt + */ +#define STACKS_SIZE_EXC (STACKS_SIZE_INT + (6 * 4)) #else #define STACKS_SIZE_EXC STACKS_SIZE_INT #endif diff --git a/cpu/x86/mm/syscalls.h b/cpu/x86/mm/syscalls.h index 83be7a47e..cae8ff2f5 100644 --- a/cpu/x86/mm/syscalls.h +++ b/cpu/x86/mm/syscalls.h @@ -33,6 +33,7 @@ #include "helpers.h" #include "prot-domains.h" +#include typedef uint32_t dom_id_bitmap_t; @@ -40,8 +41,8 @@ typedef struct syscalls_entrypoint { uintptr_t entrypoint; dom_id_bitmap_t doms; } syscalls_entrypoint_t; -extern syscalls_entrypoint_t syscalls_entrypoints[]; -extern syscalls_entrypoint_t syscalls_entrypoints_end[]; +extern syscalls_entrypoint_t ATTR_KERN_ADDR_SPACE syscalls_entrypoints[]; +extern syscalls_entrypoint_t ATTR_KERN_ADDR_SPACE syscalls_entrypoints_end[]; #define SYSCALLS_ACTUAL_CNT (syscalls_entrypoints_end - syscalls_entrypoints) @@ -49,11 +50,11 @@ extern syscalls_entrypoint_t syscalls_entrypoints_end[]; #define SYSCALLS_ALLOC_ENTRYPOINT(nm) \ syscalls_entrypoint_t __attribute__((section(".syscall_bss"))) \ - _syscall_ent_##nm + ATTR_KERN_ADDR_SPACE _syscall_ent_##nm #define SYSCALLS_INIT(nm) \ - _syscall_ent_##nm.entrypoint = (uintptr_t)_syscall_##nm; \ - _syscall_ent_##nm.doms = 0 + KERN_WRITEL(_syscall_ent_##nm.entrypoint, (uintptr_t)_syscall_##nm); \ + KERN_WRITEL(_syscall_ent_##nm.doms, 0) #define SYSCALLS_DEFINE(nm, ...) \ void _syscall_##nm(__VA_ARGS__); \ @@ -65,8 +66,19 @@ extern syscalls_entrypoint_t syscalls_entrypoints_end[]; SYSCALLS_STUB_SINGLETON(nm, dcd); \ void _syscall_##nm(__VA_ARGS__) -#define SYSCALLS_AUTHZ(nm, drv) _syscall_ent_##nm.doms |= BIT((drv).dom_id) -#define SYSCALLS_DEAUTHZ(nm, drv) _syscall_ent_##nm.doms &= ~BIT((drv).dom_id) +#define SYSCALLS_AUTHZ_UPD(nm, drv, set) \ + { \ + dom_id_t _sc_tmp_id; \ + dom_id_bitmap_t _sc_tmp_bm; \ + KERN_READL(_sc_tmp_id, (drv).dom_id); \ + KERN_READL(_sc_tmp_bm, _syscall_ent_##nm.doms); \ + if(set) { \ + _sc_tmp_bm |= BIT(_sc_tmp_id); \ + } else { \ + _sc_tmp_bm &= ~BIT(_sc_tmp_id); \ + } \ + KERN_WRITEL(_syscall_ent_##nm.doms, _sc_tmp_bm); \ + } /** * Check that any untrusted pointer that could have been influenced by a caller @@ -78,7 +90,11 @@ extern syscalls_entrypoint_t syscalls_entrypoints_end[]; * * This also checks that the pointer is either within the stack region or the * shared data region, which is important for preventing redirection of data - * accesses to MMIO or metadata regions. + * accesses to MMIO or metadata regions. This check is omitted for multi- + * segment protection domain implementations, since the segment settings + * already enforce this property for pointers dereferenced in DS. Pointers + * that can be influenced by a caller should not be dereferenced in any other + * segment. * * The pointer is both validated and copied to a new storage location, which * must be within the callee's local stack region (excluding the parameter @@ -92,6 +108,14 @@ extern syscalls_entrypoint_t syscalls_entrypoints_end[]; * references the return address, it could potentially redirect execution with * the privileges of the callee protection domain. */ +#if X86_CONF_PROT_DOMAINS_MULTI_SEG +#define PROT_DOMAINS_VALIDATE_PTR(validated, untrusted, sz) \ + validated = untrusted; \ + if(((uintptr_t)(validated)) < \ + ((2 * sizeof(uintptr_t)) + (uintptr_t)__builtin_frame_address(0))) { \ + halt(); \ + } +#else #define PROT_DOMAINS_VALIDATE_PTR(validated, untrusted, sz) \ validated = untrusted; \ if((((uintptr_t)(validated)) < \ @@ -99,6 +123,7 @@ extern syscalls_entrypoint_t syscalls_entrypoints_end[]; (((uintptr_t)&_edata_addr) <= (((uintptr_t)(validated)) + (sz)))) { \ halt(); \ } +#endif #else @@ -106,10 +131,12 @@ extern syscalls_entrypoint_t syscalls_entrypoints_end[]; #define SYSCALLS_INIT(nm) #define SYSCALLS_DEFINE(nm, ...) void nm(__VA_ARGS__) #define SYSCALLS_DEFINE_SINGLETON(nm, dcd, ...) void nm(__VA_ARGS__) -#define SYSCALLS_AUTHZ(nm, drv) -#define SYSCALLS_DEAUTHZ(nm, drv) +#define SYSCALLS_AUTHZ_UPD(nm, drv, set) #define PROT_DOMAINS_VALIDATE_PTR(validated, untrusted, sz) validated = untrusted #endif +#define SYSCALLS_AUTHZ(nm, drv) SYSCALLS_AUTHZ_UPD(nm, drv, true) +#define SYSCALLS_DEAUTHZ(nm, drv) SYSCALLS_AUTHZ_UPD(nm, drv, false) + #endif /* CPU_X86_MM_SYSCALLS_H_ */ diff --git a/cpu/x86/mm/tss-prot-domains-asm.S b/cpu/x86/mm/tss-prot-domains-asm.S new file mode 100644 index 000000000..45832a62c --- /dev/null +++ b/cpu/x86/mm/tss-prot-domains-asm.S @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2015, Intel Corporation. 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +.text + +/* Initialize the TSS fields in prot_domains_reg accordingly: + * Note: Each of these must be a callee-saved register, so that they are + * restored to their original values prior to the task returning. This will + * result in the same values being loaded when the task is next invoked. + */ +#define CUR_DOM_ID_BITMAP esi + +/* Must match SEG_KERN (plus the trailing 's') in multi-segment.h */ +#define SEG_KERN fs + +.global prot_domains_syscall_dispatcher +prot_domains_syscall_dispatcher: +#define PROT_DOMAINS_SYSCALL eax + mov prot_domains_syscall, %PROT_DOMAINS_SYSCALL + cmp $syscalls_entrypoints, %PROT_DOMAINS_SYSCALL + jl halt + cmp $syscalls_entrypoints_end, %PROT_DOMAINS_SYSCALL + jnl halt +#define SYSCALLS_ENTRYPOINTS_ALIGN_MASK ebp + mov $3, %SYSCALLS_ENTRYPOINTS_ALIGN_MASK + and %PROT_DOMAINS_SYSCALL, %SYSCALLS_ENTRYPOINTS_ALIGN_MASK + jnz halt + + /* Compare allowed domains bitmask against current domain ID bitmap. If + * the check fails, then the current domain ID bitmap value will be zeroed + * out, which could cause incorrect behavior in the future. However, the + * response to a failed check is to halt the system, so destroying the + * current domain ID bitmap value will have no effect. + */ + and %SEG_KERN:4(%PROT_DOMAINS_SYSCALL), %CUR_DOM_ID_BITMAP + jz halt + + mov prot_domains_main_esp, %esp + + /* Must be a callee-saved register: */ +#define ORIG_RET_ADDR edi + /* Update the caller's stack to return back to here */ + pop %ORIG_RET_ADDR + push $sysret_dispatcher + /* Jump to the system call body */ + jmp *%SEG_KERN:(%PROT_DOMAINS_SYSCALL) + +sysret_dispatcher: + push %ORIG_RET_ADDR + + iret + + /* The task will resume here for the next system call, so it is necessary + * to jump back to the top. + */ + jmp prot_domains_syscall_dispatcher + +.global dev_not_avail_isr +dev_not_avail_isr: + clts + iret diff --git a/cpu/x86/mm/tss-prot-domains.c b/cpu/x86/mm/tss-prot-domains.c new file mode 100644 index 000000000..40041a6d1 --- /dev/null +++ b/cpu/x86/mm/tss-prot-domains.c @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +#include +#include +#include "gdt.h" +#include "helpers.h" +#include "idt.h" +#include "prot-domains.h" +#include "stacks.h" +#include "syscalls.h" +#include "tss.h" + +uint32_t prot_domains_main_esp; +syscalls_entrypoint_t ATTR_KERN_ADDR_SPACE *prot_domains_syscall; + +/*---------------------------------------------------------------------------*/ +void app_main(void); +void +prot_domains_reg(dom_client_data_t ATTR_KERN_ADDR_SPACE *dcd, + uintptr_t mmio, size_t mmio_sz, + uintptr_t meta, size_t meta_sz, + bool pio) +{ + segment_desc_t desc; + uint32_t eflags; + dom_id_t dom_id; + volatile struct dom_kern_data ATTR_KERN_ADDR_SPACE *dkd; + + KERN_READL(dom_id, dcd->dom_id); + + dkd = prot_domains_kern_data + dom_id; + + prot_domains_reg_multi_seg(dkd, mmio, mmio_sz, meta, meta_sz); + + /* Only the kernel protection domain requires port I/O access outside of the + * interrupt handlers. + */ + eflags = EFLAGS_IOPL(pio ? PRIV_LVL_USER : PRIV_LVL_INT); + if(dom_id == DOM_ID_app) { + eflags |= EFLAGS_IF; + } + + /* Keep this initialization in sync with the register definitions in + * tss-prot-domains-asm.S. + */ + KERN_WRITEL(dkd->tss.ebp, 0); + KERN_WRITEL(dkd->tss.ebx, 0); + KERN_WRITEL(dkd->tss.esi, BIT(dom_id)); + KERN_WRITEL(dkd->tss.eip, + (dom_id == DOM_ID_app) ? + (uint32_t)app_main : + (uint32_t)prot_domains_syscall_dispatcher); + KERN_WRITEL(dkd->tss.cs, GDT_SEL_CODE); + KERN_WRITEL(dkd->tss.ds, GDT_SEL_DATA); + KERN_WRITEL(dkd->tss.es, GDT_SEL_DATA); + KERN_WRITEL(dkd->tss.fs, LDT_SEL_KERN); + KERN_WRITEL(dkd->tss.gs, + (meta_sz == 0) ? GDT_SEL_NULL : LDT_SEL_META); + KERN_WRITEL(dkd->tss.ss, GDT_SEL_STK); + /* This stack pointer is only actually used in application protection domain. + * Other domains enter at system call dispatcher, which switches to main + * stack. + */ + KERN_WRITEL(dkd->tss.esp, + /* Two return addresses have been consumed: */ + STACKS_INIT_TOP + (2 * sizeof(uintptr_t))); + KERN_WRITEL(dkd->tss.eflags, eflags); + KERN_WRITEL(dkd->tss.ldt, GDT_SEL_LDT(dom_id)); + KERN_WRITEL(dkd->tss.esp2, STACKS_SIZE_MAIN + STACKS_SIZE_INT); + KERN_WRITEL(dkd->tss.ss2, GDT_SEL_STK_INT); + KERN_WRITEL(dkd->tss.esp0, + STACKS_SIZE_MAIN + STACKS_SIZE_INT + STACKS_SIZE_EXC); + KERN_WRITEL(dkd->tss.ss0, GDT_SEL_STK_EXC); + KERN_WRITEW(dkd->tss.t, 0); + KERN_WRITEW(dkd->tss.iomap_base, sizeof(tss_t)); + KERN_WRITEL(dkd->tss.cr3, 0); + + segment_desc_init(&desc, + KERN_DATA_OFF_TO_PHYS_ADDR((uint32_t)&(dkd->tss)), + sizeof(dkd->tss), + /* It should be possible for code at any privilege level to invoke the task's + * system call dispatcher. + */ + SEG_FLAG(DPL, PRIV_LVL_USER) | SEG_TYPE_TSS32_AVAIL); + + gdt_insert(GDT_IDX_TSS(dom_id), desc); + + KERN_WRITEW(dcd->tss_sel, GDT_SEL(GDT_IDX_TSS(dom_id), PRIV_LVL_USER)); +} +/*---------------------------------------------------------------------------*/ +void dev_not_avail_isr(void); +void +prot_domains_impl_init(void) +{ + __asm__ __volatile__ ("ltr %0" :: "r" ((uint16_t)GDT_SEL_TSS(DOM_ID_kern))); + __asm__ __volatile__ ("lldt %0" :: "r" ((uint16_t)GDT_SEL_LDT(DOM_ID_kern))); + + idt_set_intr_gate_desc(7, + (uint32_t)dev_not_avail_isr, + GDT_SEL_CODE_EXC, PRIV_LVL_EXC); +} +/*---------------------------------------------------------------------------*/ +int main(); +void +prot_domains_launch_kernel(void) +{ + multi_segment_launch_kernel(); + + /* Activate kernel protection domain, entering the kernel at main. */ + __asm__ __volatile__ ( + "pushl %[_ss_]\n\t" + "pushl %[_top_of_stk_]\n\t" + "pushl %[_eflags_]\n\t" + "pushl %[_cs_]\n\t" + "pushl %[_kern_start_]\n\t" + "iretl\n\t" + : + : [_ss_] "g" (GDT_SEL_STK), + [_eflags_] "g" (EFLAGS_IOPL(PRIV_LVL_USER)), + [_cs_] "g" (GDT_SEL_CODE), + [_kern_start_] "g" (main), + /* one address has already been consumed */ + [_top_of_stk_] "g" (STACKS_INIT_TOP + sizeof(uint32_t)) + ); +} +/*---------------------------------------------------------------------------*/ +void +prot_domains_launch_app() +{ + far_pointer_t app_ptr = { 0, GDT_SEL_TSS(DOM_ID_app) }; + __asm__ __volatile__ ("ljmp *%0" :: "m" (app_ptr)); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/x86/mm/tss-prot-domains.h b/cpu/x86/mm/tss-prot-domains.h new file mode 100644 index 000000000..d61d97504 --- /dev/null +++ b/cpu/x86/mm/tss-prot-domains.h @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +#ifndef CPU_X86_MM_TSS_PROT_DOMAINS_H_ +#define CPU_X86_MM_TSS_PROT_DOMAINS_H_ + +#include +#include +#include +#include "ldt-layout.h" +#include "segmentation.h" +#include "tss.h" + +struct dom_kern_data { + /** Task State Segment */ + tss_t tss; + /** Local Descriptor Table with per-domain descriptors */ + segment_desc_t ldt[LDT_NUM_DESC]; +} __attribute__((packed)); + +/* relies on dom_kern_data: */ +#include "multi-segment.h" + +/* relies on ATTR_KERN_ADDR_SPACE: */ +#include "syscalls.h" + +/** + * Data associated with each protection domain that is owned by clients of that + * domain and used to identify the domain. + */ +struct dom_client_data { + dom_id_t dom_id; + /** The selector is only 16 bits, but it is padded to 32 bits. */ + uint32_t tss_sel; +}; + +extern uint32_t prot_domains_main_esp; + +#define SYSCALLS_STUB_MIDDLE(nm) \ + /* If already in the callee protection domain, skip the protection */ \ + /* domain switch and directly invoke the system call body */ \ + " je _syscall_" #nm "\n\t" \ + " movl $" EXP_STRINGIFY(_syscall_ent_##nm) ", prot_domains_syscall\n\t" \ + " mov %esp, prot_domains_main_esp\n\t" + +#define SYSCALLS_STUB(nm) \ + SYSCALLS_ALLOC_ENTRYPOINT(nm); \ + asm ( \ + ".text\n\t" \ + ".global " #nm "\n\t" \ + #nm ":\n\t" \ + " str %ax\n\t" \ + /* Compare current Task Register selector to selector for callee */ \ + /* protection domain, in tss_sel field of dom_client_data */ \ + " cmpw %ax, 8(%esp)\n\t" \ + SYSCALLS_STUB_MIDDLE(nm) \ + /* This will treat the dom_id field as the offset for the call, but */ \ + /* that is ignored when performing a far call to a task */ \ + " lcall *4(%esp)\n\t" \ + " ret\n\t") + +#define SYSCALLS_STUB_SINGLETON(nm, dcd) \ + SYSCALLS_ALLOC_ENTRYPOINT(nm); \ + asm ( \ + ".text\n\t" \ + ".global " #nm "\n\t" \ + #nm ":\n\t" \ + " str %ax\n\t" \ + /* Compare current Task Register selector to selector for callee */ \ + /* protection domain, in tss_sel field of dom_client_data */ \ + " cmpw %ax, %" SEG_KERN "s:(4 + " #dcd ")\n\t" \ + SYSCALLS_STUB_MIDDLE(nm) \ + /* This will treat the dom_id field as the offset for the call, but */ \ + /* that is ignored when performing a far call to a task */ \ + " lcall *%" SEG_KERN "s:" #dcd "\n\t" \ + " ret\n\t") + +#define PROT_DOMAINS_ENTER_ISR(exc) \ + MULTI_SEGMENT_ENTER_ISR(exc) \ + /* It is possible that the system call dispatcher is being interrupted, */ \ + /* and some interrupt handlers perform system calls. Thus, it is */ \ + /* necessary to save and restore the system call dispatcher parameters */ \ + /* (in callee-saved registers). */ \ + "mov prot_domains_main_esp, %%esi\n\t" \ + "mov prot_domains_syscall, %%edi\n\t" \ + PROT_DOMAINS_ENTER_ISR_COMMON(exc) +#define PROT_DOMAINS_LEAVE_ISR(exc) \ + PROT_DOMAINS_LEAVE_ISR_COMMON(exc) \ + "mov %%edi, prot_domains_syscall\n\t" \ + "mov %%esi, prot_domains_main_esp\n\t" \ + MULTI_SEGMENT_LEAVE_ISR(exc) + +/* Allocate two additional GDT entries for each protection domain. Note that + * the particular storage allocated by this statement may actually be used for + * some other protection domain, depending on how the linker happens to arrange + * all of the GDT storage. The GDT_IDX_TSS and GDT_IDX_LDT macros in + * gdt-layout.h determine which storage is used for each protection domain. + * Thus, this storage should not be referenced directly by its variable name. + */ +#define PROT_DOMAINS_ALLOC_IMPL(nm) \ + static segment_desc_t ATTR_BSS_GDT_MID _gdt_storage_##nm[2] + +#endif /* CPU_X86_MM_TSS_PROT_DOMAINS_H_ */ diff --git a/cpu/x86/quarkX1000.ld b/cpu/x86/quarkX1000.ld index 2f90b7c70..be91a74c7 100644 --- a/cpu/x86/quarkX1000.ld +++ b/cpu/x86/quarkX1000.ld @@ -87,4 +87,6 @@ SECTIONS { */ _ebss_gdt_addr = .; } + + _ebss_pre_dma_addr = ALIGN(32); } diff --git a/cpu/x86/quarkX1000_dma.ld b/cpu/x86/quarkX1000_dma.ld index fe3b79861..4cecac839 100644 --- a/cpu/x86/quarkX1000_dma.ld +++ b/cpu/x86/quarkX1000_dma.ld @@ -30,26 +30,18 @@ SECTIONS { - /* - It would be more natural to use a 1K alignment for this entire section. - However, the UEFI GenFw program ratchets up its alignment - granularity to the maximum granularity discovered in its input file. - Using 1K-alignment perturbs the symbols, hindering debugging. Thus, - this section is simply padded out to the desired alignment and - declared to have a section alignment of only 32 bytes. - - The alignment directives used here suffice even when paging is in use, - because this is the last section and directly follows one (.bss.meta) - that is 4K-aligned. - */ - .bss.dma (NOLOAD) : ALIGN (32) + .bss.dma (NOLOAD) : AT(_ebss_pre_dma_addr) ALIGN (32) { - /* The IMR feature operates at 1K granularity. */ - . = ALIGN(1K); - _sbss_dma_addr = .; + /* IMRs are used to restrict DMA, and they require 1K physical address alignment. */ + . += ALIGN(_ebss_pre_dma_addr, 1K) - ALIGN(_ebss_pre_dma_addr, 32); *(.dma_bss) - . = ALIGN(1K); - _ebss_dma_addr = .; } + _sbss_dma_addr = LOADADDR(.bss.dma) + ALIGN(_ebss_pre_dma_addr, 1K) - ALIGN(_ebss_pre_dma_addr, 32); + /* + Effectively pointing beyond the end of .bss.dma is acceptable, since + .bss.dma is the last section in memory. + */ + _ebss_dma_addr = ALIGN(LOADADDR(.bss.dma) + SIZEOF(.bss.dma), 1K); + } diff --git a/cpu/x86/quarkX1000_multi_seg.ld b/cpu/x86/quarkX1000_multi_seg.ld new file mode 100644 index 000000000..945650399 --- /dev/null +++ b/cpu/x86/quarkX1000_multi_seg.ld @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2015, Intel Corporation. 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +OUTPUT_FORMAT("elf32-i386") + +ENTRY(start) + +/* + The TSS-based protection domain implementation does not explicitly reference + these symbols, so we list them here to prevent them from being garbage- + collected. +*/ +EXTERN(stacks_int) +EXTERN(stacks_exc) + +PHDRS { + boot_text PT_LOAD; + text PT_LOAD; + data PT_LOAD; +} + +SECTIONS { + /* + OS-Dev Wiki says it is common for kernels to start at 1M. Addresses before that + are used by BIOS/EFI, the bootloader and memory-mapped I/O. + + The UEFI GenFw program inserts a 0x220 byte offset between the image base and + the .text section. We add that same offset here to align the symbols in the + UEFI DLL with those in the final UEFI binary to make debugging easier. + */ + . = 1M + 0x220; + + /* + The GenFw program in the EDK2 UEFI toolchain outputs UEFI images with a + section alignment of at least 32 bytes. Thus, it is desirable to use at + least that alignment granularity to avoid symbols being shifted from the + intermediate DLL to the final UEFI image. Such shifting may make + debugging more difficult by preventing the DLL from being a useful + source of symbol information. The debugging symbols are not included in + the final UEFI image. + */ + .text.boot : ALIGN (32) + { + *(.multiboot) + /* + The initial bootstrap code expects to operate in a flat address + space with an identity mapping between linear and physical + addresses. + */ + *(.boot_text) + } :boot_text + + /* The post-boot code segments define tight bounds around the code + section, so this directive resets the virtual address to 0. */ + . = 0; + + /* The virtual address differs from the load address. */ + .text : AT(LOADADDR(.text.boot) + ALIGN(SIZEOF(.text.boot), 32)) ALIGN (32) + { + /* + These BYTE directives emit a UD2 instruction to cause execution to + halt if the control flow ever deviates to address 0. This also + prevents other code from being placed at address 0. Some code + considers a function pointer to address 0 to be a null function + pointer. + */ + BYTE(0x0F); + BYTE(0x0B); + *(.text*) + + /* + An alternative design to eliminate the need for ALIGN directives + within the AT directives in later sections could have padded + each section out to a 32-byte boundary. However, that would have + enabled unneeded software accesses to the padding past the end of actual + code/data in each section, since segments are also configured based on + the values of the SIZEOF expressions. As a general principle, accesses + should be as restricted as is feasible. + */ + } :text + + _stext_addr = LOADADDR(.text); + _etext_addr = LOADADDR(.text) + SIZEOF(.text); + + . = 0; + + .data : AT(ALIGN(_etext_addr, 32)) ALIGN (32) + { + *(.main_stack) + *(.int_stack) + *(.exc_stack) + *(.rodata*) + *(.data*) + + /* + These could alternatively be treated as read-only data to prevent tampering + from the user privilege level. + */ + _sdata_shared_isr = .; + KEEP(*(.shared_isr_data*)) + _edata_shared_isr = .; + } :data + + .bss : ALIGN (32) + { + *(COMMON) + *(.bss*) + } + + _sdata_addr = LOADADDR(.data); + _edata_addr = LOADADDR(.bss) + SIZEOF(.bss); + + . = 0; + + .bss.kern (NOLOAD) : AT(ALIGN(_edata_addr, 32)) ALIGN (32) + { + /* + This directive prevents any data from being allocated at address + zero, since the address 0 is commonly used to represent null + pointers. + */ + LONG(0); + *(.kern_bss) + + syscalls_entrypoints = .; + *(.syscall_bss) + syscalls_entrypoints_end = .; + } + + _ebss_syscall_addr = LOADADDR(.bss.kern) + SIZEOF(.bss.kern); + + .bss.kern_priv (NOLOAD) : ALIGN (32) + { + prot_domains_kern_data = .; + /* + The kernel and app protection domain control structures must always + be placed in the first two slots in this order, so that they have + well-known protection domain IDs: + */ + *(.kern_prot_dom_bss) + *(.app_prot_dom_bss) + *(.prot_dom_bss) + prot_domains_kern_data_end = .; + + *(.gdt_bss_start) + KEEP(*(.gdt_bss_mid)) + *(.gdt_bss) + _ebss_gdt_addr = .; + } + + _sbss_kern_addr = LOADADDR(.bss.kern); + _ebss_kern_addr = LOADADDR(.bss.kern_priv) + SIZEOF(.bss.kern_priv); + + . = _ebss_kern_addr; + + .bss.meta (NOLOAD) : AT(ALIGN(_ebss_kern_addr, 32)) ALIGN (32) + { + *(.meta_bss) + } + + /* .bss.meta may be empty, so this uses .bss.kern_priv as a base instead: */ + _ebss_pre_dma_addr = ALIGN(ALIGN(_ebss_kern_addr, 32) + SIZEOF(.bss.meta), 32); +} diff --git a/cpu/x86/quarkX1000_paging.ld b/cpu/x86/quarkX1000_paging.ld index 0352cbf64..19e50e1e0 100644 --- a/cpu/x86/quarkX1000_paging.ld +++ b/cpu/x86/quarkX1000_paging.ld @@ -129,7 +129,7 @@ SECTIONS { *(.data*) /* - These could also be treated as read-only data to prevent tampering + These could alternatively be treated as read-only data to prevent tampering from the user privilege level. */ _sdata_shared_isr = .; @@ -201,4 +201,6 @@ SECTIONS { . = ALIGN(4K); } + + _ebss_pre_dma_addr = ALIGN(32); } diff --git a/platform/galileo/Makefile.customrules-galileo b/platform/galileo/Makefile.customrules-galileo index cb5bc26a9..b141ee211 100644 --- a/platform/galileo/Makefile.customrules-galileo +++ b/platform/galileo/Makefile.customrules-galileo @@ -9,7 +9,17 @@ MULTIBOOT = $(CONTIKI_PROJECT).$(MULTIBOOT_SFX) # UEFI binary UEFI_DLL_SFX = $(TARGET).dll UEFI_DLL = $(CONTIKI_PROJECT).$(UEFI_SFX) -UEFI_LDFLAGS += -Xlinker --emit-relocs -Xlinker --entry=uefi_start +# The GenFw program is unable to process absolute symbols like _stext_addr, +# etc., that are defined in quarkX1000_dma.ld and quarkX1000_multi_seg.ld +# and used to configure segments in multi-segment.c, etc. Furthermore, +# relocating the UEFI image during load would result in those symbols not +# pointing to the expected image locations. So, relocation data is omitted +# from the intermediate UEFI DLL. This will only result in a +# correctly-functioning build if the UEFI firmware does not attempt to +# relocate the UEFI image, so it may be desirable in the future to revisit +# this design. To emit relocation data, '-Xlinker --emit-relocs' should be +# appended to the following line. +UEFI_LDFLAGS = -Xlinker --entry=uefi_start UEFI_SFX = $(TARGET).efi UEFI = $(CONTIKI_PROJECT).$(UEFI_SFX) From e0aefd11d94415c5ffc58344201e16c85a4e2e41 Mon Sep 17 00:00:00 2001 From: Michael LeMay Date: Fri, 7 Aug 2015 11:51:04 -0700 Subject: [PATCH 187/374] x86: Add support for SW-switched segment-based protection domains This patch extends the protection domain framework with a third plugin that is a hybrid of the previous two. The hardware task switching mechanism has a strictly-defined format for TSS data structures that causes more space to be consumed than would otherwise be required. This patch defines a smaller data structure that is allocated for each protection domain, only requiring 32 bytes instead of 128 bytes. It uses the same multi-segment memory layout as the TSS-based plugin and leaves paging disabled. However, it uses a similar mechanism as the paging plugin to perform system call dispatches and returns. For additional information, please refer to cpu/x86/mm/README.md. --- cpu/x86/Makefile.x86_quarkX1000 | 5 ++ cpu/x86/mm/README.md | 31 ++++++++++-- cpu/x86/mm/gdt-layout.h | 5 ++ cpu/x86/mm/multi-segment.c | 11 ++++- cpu/x86/mm/prot-domains.c | 7 +++ cpu/x86/mm/prot-domains.h | 6 ++- cpu/x86/mm/stacks.h | 6 +++ cpu/x86/mm/swseg-prot-domains.c | 83 +++++++++++++++++++++++++++++++ cpu/x86/mm/swseg-prot-domains.h | 86 +++++++++++++++++++++++++++++++++ cpu/x86/mm/syscalls-int-asm.S | 48 +++++++++++++++++- cpu/x86/mm/syscalls-int.c | 66 ++++++++++++++++--------- cpu/x86/mm/syscalls-int.h | 2 +- cpu/x86/mm/tss.c | 17 ++++--- 13 files changed, 335 insertions(+), 38 deletions(-) create mode 100644 cpu/x86/mm/swseg-prot-domains.c create mode 100644 cpu/x86/mm/swseg-prot-domains.h diff --git a/cpu/x86/Makefile.x86_quarkX1000 b/cpu/x86/Makefile.x86_quarkX1000 index 13a9c686f..1a8d3ac8e 100644 --- a/cpu/x86/Makefile.x86_quarkX1000 +++ b/cpu/x86/Makefile.x86_quarkX1000 @@ -25,6 +25,11 @@ else ifeq ($(X86_CONF_PROT_DOMAINS),tss) CFLAGS += -DX86_CONF_PROT_DOMAINS=2 X86_CONF_MULTI_SEG = 1 CONTIKI_SOURCEFILES += tss-prot-domains-asm.S +else ifeq ($(X86_CONF_PROT_DOMAINS),swseg) +# This matches the definition of X86_CONF_PROT_DOMAINS__SWSEG in prot-domains.h: +CFLAGS += -DX86_CONF_PROT_DOMAINS=3 +X86_CONF_SYSCALLS_INT = 1 +X86_CONF_MULTI_SEG = 1 else $(error Unrecognized setting for X86_CONF_PROT_DOMAINS: \ $(X86_CONF_PROT_DOMAINS). See cpu/x86/mm/README.md for \ diff --git a/cpu/x86/mm/README.md b/cpu/x86/mm/README.md index dcd6370b4..42c4070a7 100644 --- a/cpu/x86/mm/README.md +++ b/cpu/x86/mm/README.md @@ -6,11 +6,12 @@ Introduction The X86 port of Contiki implements a simple, lightweight form of protection domains using a pluggable framework. Currently, there are -two plugins available: +three plugins available: - Flat memory model with paging. - - Multi-segment memory model with hardware-switched segments based on - Task-State Segment (TSS) structures. + - Multi-segment memory model with either hardware- or + software-switched segments. The hardware-switched segments + approach is based on Task-State Segment (TSS) structures. For an introduction to paging and TSS and possible ways in which they can be used, refer to the following resources: @@ -144,8 +145,8 @@ Similarly, register contents may be accessed and modified across protection domain boundaries in some protection domain implementations. The TSS task switching mechanism automatically saves and restores many registers to and from TSS data structures when -switching tasks, but the paging-based protection domain implementation -does not perform analogous operations. +switching tasks, but the other protection domain implementations do +not perform analogous operations. For the reasons described above, each protection domain should only invoke other protection domains that it trusts to properly handle data @@ -847,6 +848,25 @@ in an unexpected manner, since segment register load instructions are unprivileged. Similar segment register updates must be performed for similar reasons when dispatching system calls. +### Software-Switched Segment-Based Protection Domains + +Primary implementation sources: + + - cpu/x86/mm/swseg-prot-domains.c + +The requirement to allocate a TSS for each protection domain in the +hardware-switched segments plugin may consume a substantial amount of +space, since the size of each TSS is fixed by hardware to be at least +104 bytes. The software-switched segments plugin saves space by +defining a more compact PDCS. However, the layout and definitions of +the segments is identical to what was described above for the +hardware-switched segments plugin. + +The system call and return procedure is mostly identical to that for +paging-based protection domains. However, instead of updating and +invalidating page tables, the dispatchers update the LDT and some of +the segment registers. + ### Pointer Validation Primary implementation sources: @@ -957,6 +977,7 @@ the command line and specify one of the following options: - paging - tss + - swseg The paging option accepts a sub-option to determine whether the TLB is fully- or selectively-invalidated during protection domain switches. diff --git a/cpu/x86/mm/gdt-layout.h b/cpu/x86/mm/gdt-layout.h index 5dddd3a4d..b79c2b9ca 100644 --- a/cpu/x86/mm/gdt-layout.h +++ b/cpu/x86/mm/gdt-layout.h @@ -92,8 +92,13 @@ /** Stack segment for exception handlers */ #define GDT_IDX_STK_EXC 10 +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__TSS #define GDT_IDX_TSS(dom_id) (GDT_NUM_FIXED_DESC + (2 * (dom_id))) #define GDT_IDX_LDT(dom_id) (GDT_NUM_FIXED_DESC + (2 * (dom_id)) + 1) +#else +#define GDT_IDX_LDT(dom_id) (GDT_NUM_FIXED_DESC + (dom_id)) +#endif + #endif #else #define GDT_IDX_CODE GDT_IDX_CODE_FLAT diff --git a/cpu/x86/mm/multi-segment.c b/cpu/x86/mm/multi-segment.c index f60a2c8bb..6d3fd57f1 100644 --- a/cpu/x86/mm/multi-segment.c +++ b/cpu/x86/mm/multi-segment.c @@ -139,7 +139,14 @@ prot_domains_gdt_init() (uint32_t)&_stext_addr, ((uint32_t)&_etext_addr) - (uint32_t)&_stext_addr, SEG_FLAG(DPL, PRIV_LVL_EXC) | SEG_GRAN_BYTE | - SEG_DESCTYPE_NSYS | SEG_TYPE_CODE_EX); + SEG_DESCTYPE_NSYS | +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__SWSEG + /* The general protection fault handler requires read access to CS */ + SEG_TYPE_CODE_EXRD +#else + SEG_TYPE_CODE_EX +#endif + ); gdt_insert_boot(GDT_IDX_CODE_EXC, desc); segment_desc_init(&desc, @@ -180,7 +187,9 @@ prot_domains_gdt_init() */ desc.raw = SEG_DESC_NOT_PRESENT; for(i = 0; i < PROT_DOMAINS_ACTUAL_CNT; i++) { +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__TSS gdt_insert_boot(GDT_IDX_TSS(i), desc); +#endif gdt_insert_boot(GDT_IDX_LDT(i), desc); } diff --git a/cpu/x86/mm/prot-domains.c b/cpu/x86/mm/prot-domains.c index 8bbeb4d83..56461b381 100644 --- a/cpu/x86/mm/prot-domains.c +++ b/cpu/x86/mm/prot-domains.c @@ -54,6 +54,13 @@ prot_domains_init(void) segment_desc_t desc; gdt_lookup(GDT_IDX_CODE_EXC, &desc); +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__SWSEG + /* The exception code segment needs to be readable so that the general + * protection fault handler can decode instructions, but the interrupt and + * user level code segments should not be. + */ + SEG_SET_FLAG(desc, TYPE, SEG_TYPE_CODE_EX); +#endif SEG_SET_FLAG(desc, DPL, PRIV_LVL_INT); gdt_insert(GDT_IDX_CODE_INT, desc); diff --git a/cpu/x86/mm/prot-domains.h b/cpu/x86/mm/prot-domains.h index a1fbca130..13062612b 100644 --- a/cpu/x86/mm/prot-domains.h +++ b/cpu/x86/mm/prot-domains.h @@ -41,9 +41,11 @@ #define X86_CONF_PROT_DOMAINS__NONE 0 #define X86_CONF_PROT_DOMAINS__PAGING 1 #define X86_CONF_PROT_DOMAINS__TSS 2 +#define X86_CONF_PROT_DOMAINS__SWSEG 3 #define X86_CONF_PROT_DOMAINS_MULTI_SEG \ - (X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__TSS) + ((X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__TSS) || \ + (X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__SWSEG)) /** Privilege level (ring) for exception handlers and other supervisory code */ #define PRIV_LVL_EXC 0 @@ -74,6 +76,8 @@ typedef uint32_t dom_id_t; #include "paging-prot-domains.h" #elif X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__TSS #include "tss-prot-domains.h" +#elif X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__SWSEG +#include "swseg-prot-domains.h" #endif #ifndef ATTR_META_ADDR_SPACE diff --git a/cpu/x86/mm/stacks.h b/cpu/x86/mm/stacks.h index 96be72cf9..327e75600 100644 --- a/cpu/x86/mm/stacks.h +++ b/cpu/x86/mm/stacks.h @@ -61,6 +61,12 @@ #else #define STACKS_SIZE_EXC 256 #endif +#elif X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__SWSEG +#ifdef __clang__ +#define STACKS_SIZE_EXC 512 +#else +#define STACKS_SIZE_EXC 256 +#endif #elif X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__TSS /** * This should be large enough to execute the exception handler with the diff --git a/cpu/x86/mm/swseg-prot-domains.c b/cpu/x86/mm/swseg-prot-domains.c new file mode 100644 index 000000000..78a29aaf6 --- /dev/null +++ b/cpu/x86/mm/swseg-prot-domains.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2015, Intel Corporation. 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +#include "gdt.h" +#include "helpers.h" +#include "multi-segment.h" +#include "prot-domains.h" + +/*---------------------------------------------------------------------------*/ +void +prot_domains_reg(dom_client_data_t ATTR_KERN_ADDR_SPACE *dcd, + uintptr_t mmio, size_t mmio_sz, + uintptr_t meta, size_t meta_sz, + bool pio) +{ + volatile dom_kern_data_t ATTR_KERN_ADDR_SPACE *dkd; + dom_id_t dom_id; + + KERN_READL(dom_id, dcd->dom_id); + + if(PROT_DOMAINS_ACTUAL_CNT <= dom_id) { + halt(); + } + + dkd = prot_domains_kern_data + dom_id; + + prot_domains_reg_multi_seg(dkd, mmio, mmio_sz, meta, meta_sz); + + KERN_WRITEL(dkd->flags, pio ? PROT_DOMAINS_FLAG_PIO : 0); +} +/*---------------------------------------------------------------------------*/ +static inline void __attribute__((always_inline)) +prot_domains_switch(dom_id_t from_id, dom_id_t to_id, + interrupt_stack_t *intr_stk) +{ + __asm__ __volatile__ ( + "lldt %[_ldt_]\n\t" + "mov %[_meta_seg_], %%eax\n\t" + "lsl %%eax, %%ecx\n\t" + "jz 1f\n\t" /* ZF will only be set if the segment descriptor is valid. */ + "xor %%eax, %%eax\n\t" /* Nullify metadata selector */ + "1: mov %%eax, %%" SEG_META "s\n\t" + "mov %[_kern_seg_], %%eax\n\t" + "mov %%eax, %%" SEG_KERN "s\n\t" + : + : [_ldt_] "r" ((uint16_t)GDT_SEL_LDT(to_id)), + [_meta_seg_] "i" (LDT_SEL_META), + [_kern_seg_] "i" (LDT_SEL_KERN) + : "cc", "eax", "ecx" + ); +} +/*---------------------------------------------------------------------------*/ + +/* Enable inter-procedural optimization with procedures in the following file: + */ +#include "syscalls-int.c" diff --git a/cpu/x86/mm/swseg-prot-domains.h b/cpu/x86/mm/swseg-prot-domains.h new file mode 100644 index 000000000..a503bc6db --- /dev/null +++ b/cpu/x86/mm/swseg-prot-domains.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2015, Intel Corporation. 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +#ifndef CPU_X86_MM_SWSEG_PROT_DOMAINS_H_ +#define CPU_X86_MM_SWSEG_PROT_DOMAINS_H_ + +#include +#include +#include +#include "ldt-layout.h" +#include "paging.h" +#include "segmentation.h" +#include "syscalls-int.h" + +struct dom_kern_data { + /** Local Descriptor Table with per-domain descriptors */ + segment_desc_t ldt[LDT_NUM_DESC]; + /** Flags are defined with the prefix PROT_DOMAINS_FLAG in prot-domains.h */ + uint32_t flags; + /** + * Original return address from call stack when this protection domain + * invoked some other protection domain. This serves to control the return + * entrypoint. The callee is not permitted to modify this value (unless the + * callee is the kernel protection domain). + */ + uintptr_t orig_ret_addr; + + /* This structure is precisely 32 bytes in length, a power of 2. If its size + * changes, add an alignment attribute to keep it aligned at a power of 2 so + * that dereferencing arrays of these structures uses shift instructions + * instead of multiplication. Shifting is faster than multiplication. + */ +}; + +/* relies on dom_kern_data: */ +#include "multi-segment.h" + +#define PROT_DOMAINS_ENTER_ISR(exc) \ + MULTI_SEGMENT_ENTER_ISR(exc) \ + PROT_DOMAINS_ENTER_ISR_COMMON(exc) +#define PROT_DOMAINS_LEAVE_ISR(exc) \ + PROT_DOMAINS_LEAVE_ISR_COMMON(exc) \ + MULTI_SEGMENT_LEAVE_ISR(exc) + +#define prot_domains_impl_init syscalls_int_init + +#define prot_domains_set_wp(en) + +/* Allocate one additional GDT entry for each protection domain. Note that + * the particular storage allocated by this statement may actually be used for + * some other protection domain, depending on how the linker happens to arrange + * all of the GDT storage. The GDT_IDX_LDT macro in gdt-layout.h determine + * which storage is used for each protection domain. Thus, this storage should + * not be referenced directly by its variable name. + */ +#define PROT_DOMAINS_ALLOC_IMPL(nm) \ + static segment_desc_t ATTR_BSS_GDT_MID _gdt_storage_##nm + +#endif /* CPU_X86_MM_SWSEG_PROT_DOMAINS_H_ */ diff --git a/cpu/x86/mm/syscalls-int-asm.S b/cpu/x86/mm/syscalls-int-asm.S index 1fe80310f..5c88c890b 100644 --- a/cpu/x86/mm/syscalls-int-asm.S +++ b/cpu/x86/mm/syscalls-int-asm.S @@ -33,6 +33,10 @@ #include "gdt-layout.h" #include "stacks.h" +/* Must match definitions (plus the trailing 's') in multi-segment.h */ +#define SEG_MMIO fs +#define SEG_KERN fs + .text /* Invoke the system call return dispatcher from the default privilege @@ -42,21 +46,57 @@ prot_domains_sysret_stub: int $PROT_DOMAINS_SYSRET_DISPATCH_INT +.macro save_segs +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__SWSEG + /* Save (and restore, in restore_segs) MMIO segment register into + * callee-saved register in case a system call was invoked from a region in + * which MMIO is enabled. + */ + push %SEG_MMIO +#endif +.endm + +.macro restore_segs +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__SWSEG + pop %SEG_MMIO +#endif +.endm + +/* Refresh most of the segment registers in case they were corrupted by + * userspace code to prevent that from corrupting the operation of the + * privileged code. + */ +.macro load_kern_segs +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__SWSEG + mov $GDT_SEL_DATA, %eax + mov %eax, %ds + mov %eax, %es + mov $GDT_SEL_DATA_KERN_EXC, %eax + mov %eax, %SEG_KERN +#endif +.endm + /* Invoke the system call dispatcher C routine */ .global prot_domains_syscall_dispatcher prot_domains_syscall_dispatcher: mov %esp, %ecx /*< interrupt_stack_t *intr_stk */ /* EDX already set to "dom_client_data_t to_dcd" by syscall stub */ - push %eax /*< syscalls_id_t syscall_id */ + save_segs + push %eax /*< syscalls_entrypoint_t *syscall */ + load_kern_segs call prot_domains_syscall_dispatcher_impl /* fastcall convention, so callee pops arguments */ + restore_segs iret /* Invoke the system call return dispatcher C routine */ .global prot_domains_sysret_dispatcher prot_domains_sysret_dispatcher: mov %esp, %ecx /*< interrupt_stack_t *intr_stk */ + save_segs + load_kern_segs call prot_domains_sysret_dispatcher_impl + restore_segs /* Zero caller-saved registers in case they contain secrets. The system call * handlers and dispatchers need to preserve the callee-saved registers. */ @@ -67,11 +107,17 @@ prot_domains_sysret_dispatcher: .global prot_domains_launch_kernel prot_domains_launch_kernel: +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__PAGING mov $GDT_SEL_DATA, %eax mov %eax, %ds mov %eax, %es mov %eax, %fs mov %eax, %gs +#else + mov $GDT_SEL_LDT(DOM_ID_kern), %eax + lldt %ax + call multi_segment_launch_kernel +#endif /* init interrupt return stack: */ pushl $GDT_SEL_STK lea stacks_main, %eax diff --git a/cpu/x86/mm/syscalls-int.c b/cpu/x86/mm/syscalls-int.c index 1d1c77efb..6820d3264 100644 --- a/cpu/x86/mm/syscalls-int.c +++ b/cpu/x86/mm/syscalls-int.c @@ -91,7 +91,10 @@ syscall_dispatcher_tail(interrupt_stack_t *intr_stk, uint32_t syscall_eip) { dom_id_t from_id; - volatile dom_kern_data_t *from_dkd, *to_dkd; + uint32_t tmp; + volatile dom_kern_data_t ATTR_KERN_ADDR_SPACE *from_dkd, *to_dkd; + + uint32_t loc_call_stk_ptr; to_dkd = prot_domains_kern_data + to_id; @@ -101,36 +104,40 @@ syscall_dispatcher_tail(interrupt_stack_t *intr_stk, * kernel data associated with that protection domain. That model does not * permit reentrancy. */ - if((to_dkd->flags & PROT_DOMAINS_FLAG_BUSY) == PROT_DOMAINS_FLAG_BUSY) { + KERN_READL(tmp, to_dkd->flags); + if((tmp & PROT_DOMAINS_FLAG_BUSY) == PROT_DOMAINS_FLAG_BUSY) { halt(); } - to_dkd->flags |= PROT_DOMAINS_FLAG_BUSY; + tmp |= PROT_DOMAINS_FLAG_BUSY; + KERN_WRITEL(to_dkd->flags, tmp); /* Update the interrupt stack so that the IRET instruction will return to the * system call entrypoint. */ intr_stk->eip = syscall_eip; + KERN_READL(loc_call_stk_ptr, inter_dom_call_stk_ptr); /* Lookup the information for the caller */ - from_id = inter_dom_call_stk[inter_dom_call_stk_ptr - 1]; + KERN_READL(from_id, inter_dom_call_stk[loc_call_stk_ptr - 1]); from_dkd = prot_domains_kern_data + from_id; /* Save the current return address from the unprivileged stack to a protected * location in the kernel-owned data structure. This enforces return * entrypoint control. */ - from_dkd->orig_ret_addr = *(uintptr_t *)intr_stk->esp; + KERN_WRITEL(from_dkd->orig_ret_addr, *(uintptr_t *)intr_stk->esp); /* Update the unprivileged stack so that when the system call body is * complete, it will invoke the system call return stub. */ *((uintptr_t *)intr_stk->esp) = (uintptr_t)prot_domains_sysret_stub; - if(MAX_INTER_DOM_CALL_STK_SZ <= inter_dom_call_stk_ptr) { + if(MAX_INTER_DOM_CALL_STK_SZ <= loc_call_stk_ptr) { halt(); } - inter_dom_call_stk[inter_dom_call_stk_ptr] = to_id; + KERN_WRITEL(inter_dom_call_stk[loc_call_stk_ptr], to_id); - inter_dom_call_stk_ptr++; + loc_call_stk_ptr++; + KERN_WRITEL(inter_dom_call_stk_ptr, loc_call_stk_ptr); dispatcher_tail(from_id, to_id, intr_stk); } @@ -140,6 +147,7 @@ prot_domains_syscall_dispatcher_impl(interrupt_stack_t *intr_stk, dom_id_t to_id, syscalls_entrypoint_t *syscall) { + uint32_t tmp; uint32_t syscall_eip; if(PROT_DOMAINS_ACTUAL_CNT <= to_id) { @@ -156,11 +164,12 @@ prot_domains_syscall_dispatcher_impl(interrupt_stack_t *intr_stk, halt(); } - if((BIT(to_id) & syscall->doms) == 0) { + KERN_READL(tmp, syscall->doms); + if((BIT(to_id) & tmp) == 0) { halt(); } - syscall_eip = syscall->entrypoint; + KERN_READL(syscall_eip, syscall->entrypoint); prot_domains_set_wp(false); @@ -171,9 +180,9 @@ int main(void); void __attribute__((fastcall)) prot_domains_launch_kernel_impl(interrupt_stack_t *intr_stk) { - inter_dom_call_stk[0] = DOM_ID_app; + KERN_WRITEL(inter_dom_call_stk[0], DOM_ID_app); - inter_dom_call_stk_ptr = 1; + KERN_WRITEL(inter_dom_call_stk_ptr, 1); syscall_dispatcher_tail(intr_stk, DOM_ID_kern, (uint32_t)main); } @@ -182,20 +191,27 @@ void __attribute__((fastcall)) prot_domains_sysret_dispatcher_impl(interrupt_stack_t *intr_stk) { dom_id_t from_id, to_id; - if(inter_dom_call_stk_ptr <= 1) { + uint32_t loc_call_stk_ptr; + uint32_t flags; + + KERN_READL(loc_call_stk_ptr, inter_dom_call_stk_ptr); + if(loc_call_stk_ptr <= 1) { halt(); } - from_id = inter_dom_call_stk[inter_dom_call_stk_ptr - 1]; - to_id = inter_dom_call_stk[inter_dom_call_stk_ptr - 2]; + KERN_READL(from_id, inter_dom_call_stk[loc_call_stk_ptr - 1]); + KERN_READL(to_id, inter_dom_call_stk[loc_call_stk_ptr - 2]); - intr_stk->eip = prot_domains_kern_data[to_id].orig_ret_addr; + KERN_READL(intr_stk->eip, + prot_domains_kern_data[to_id].orig_ret_addr); prot_domains_set_wp(false); - prot_domains_kern_data[from_id].flags &= ~PROT_DOMAINS_FLAG_BUSY; + KERN_READL(flags, prot_domains_kern_data[from_id].flags); + flags &= ~PROT_DOMAINS_FLAG_BUSY; + KERN_WRITEL(prot_domains_kern_data[from_id].flags, flags); - inter_dom_call_stk_ptr--; + KERN_WRITEL(inter_dom_call_stk_ptr, loc_call_stk_ptr - 1); dispatcher_tail(from_id, to_id, intr_stk); } @@ -204,11 +220,13 @@ prot_domains_sysret_dispatcher_impl(interrupt_stack_t *intr_stk) * \brief Lookup the current protection domain. * \return Kernel data structure for the current protection domain. */ -static volatile dom_kern_data_t * +static volatile dom_kern_data_t ATTR_KERN_ADDR_SPACE * get_current_domain(void) { + uint32_t loc_call_stk_ptr; dom_id_t id; - id = inter_dom_call_stk[inter_dom_call_stk_ptr - 1]; + KERN_READL(loc_call_stk_ptr, inter_dom_call_stk_ptr); + KERN_READL(id, inter_dom_call_stk[loc_call_stk_ptr - 1]); return prot_domains_kern_data + id; } /*---------------------------------------------------------------------------*/ @@ -219,9 +237,11 @@ get_current_domain(void) * \return Result of the check as a Boolean value */ static bool -needs_port_io(volatile dom_kern_data_t *dkd) +needs_port_io(volatile dom_kern_data_t ATTR_KERN_ADDR_SPACE *dkd) { - return (dkd->flags & PROT_DOMAINS_FLAG_PIO) == PROT_DOMAINS_FLAG_PIO; + uint32_t dkd_flags; + KERN_READL(dkd_flags, dkd->flags); + return (dkd_flags & PROT_DOMAINS_FLAG_PIO) == PROT_DOMAINS_FLAG_PIO; } /*---------------------------------------------------------------------------*/ /* Mark the context parameter as volatile so that writes to it will not get @@ -236,7 +256,7 @@ gp_fault_handler(volatile struct interrupt_context context) uint32_t cs_lim; uint8_t opcode; - volatile dom_kern_data_t *dkd = get_current_domain(); + volatile dom_kern_data_t ATTR_KERN_ADDR_SPACE *dkd = get_current_domain(); if (needs_port_io(dkd)) { __asm__ __volatile__ ( "mov %%cs, %0\n\t" diff --git a/cpu/x86/mm/syscalls-int.h b/cpu/x86/mm/syscalls-int.h index 7ee4bcb36..a5478d1c5 100644 --- a/cpu/x86/mm/syscalls-int.h +++ b/cpu/x86/mm/syscalls-int.h @@ -74,7 +74,7 @@ extern dom_id_t cur_dom; #nm ":\n\t" \ /* First, load server protection domain ID into EDX, as required by */ \ /* prot_domains_syscall_dispatcher: */ \ - " mov " #dcd ", %edx\n\t" \ + " mov %" SEG_KERN "s:" #dcd ", %edx\n\t" \ SYSCALLS_STUB_EPILOGUE(nm)) void syscalls_int_init(void); diff --git a/cpu/x86/mm/tss.c b/cpu/x86/mm/tss.c index c3628fa8a..b6e0f3deb 100644 --- a/cpu/x86/mm/tss.c +++ b/cpu/x86/mm/tss.c @@ -47,15 +47,20 @@ static segment_desc_t ATTR_BSS_GDT sys_tss_desc; void tss_init(void) { - sys_tss.iomap_base = sizeof(sys_tss); - sys_tss.esp2 = ((uint32_t)stacks_int) + STACKS_SIZE_INT; - sys_tss.ss2 = GDT_SEL_STK_INT; - sys_tss.esp0 = ((uint32_t)stacks_exc) + STACKS_SIZE_EXC; - sys_tss.ss0 = GDT_SEL_STK_EXC; + segment_desc_t seg_desc; - segment_desc_init(&sys_tss_desc, (uint32_t)&sys_tss, sizeof(sys_tss), + /* Initialize TSS */ + KERN_WRITEW(sys_tss.iomap_base, sizeof(sys_tss)); + KERN_WRITEL(sys_tss.esp2, ((uint32_t)stacks_int) + STACKS_SIZE_INT); + KERN_WRITEL(sys_tss.ss2, GDT_SEL_STK_INT); + KERN_WRITEL(sys_tss.esp0, ((uint32_t)stacks_exc) + STACKS_SIZE_EXC); + KERN_WRITEL(sys_tss.ss0, GDT_SEL_STK_EXC); + + segment_desc_init(&seg_desc, + KERN_DATA_OFF_TO_PHYS_ADDR(&sys_tss), sizeof(sys_tss), SEG_FLAG(DPL, PRIV_LVL_EXC) | SEG_DESCTYPE_SYS | SEG_TYPE_TSS32_AVAIL); + gdt_insert(GDT_IDX_OF_DESC(&sys_tss_desc), seg_desc); __asm__ __volatile__ ( "ltr %0" From 73774def6b7c52ce6d3be0e4a41852047e66f46b Mon Sep 17 00:00:00 2001 From: Michael LeMay Date: Sun, 9 Aug 2015 16:38:04 -0700 Subject: [PATCH 188/374] x86, galileo: Add sample non-driver protection domain This patch adds a simple non-driver protection domain sample to serve as an example for defining other non-driver protection domains. It simply performs a ping-pong test of protection domain switching latency during boot, including optional accesses to a private metadata region, and prints out the results. --- cpu/x86/quarkX1000.ld | 4 + cpu/x86/quarkX1000_multi_seg.ld | 4 + cpu/x86/quarkX1000_paging.ld | 4 + cpu/x86/startup.h | 46 ++++++ examples/galileo/Makefile | 8 +- examples/galileo/README.md | 11 ++ examples/galileo/prot-domain-switch-latency.c | 156 ++++++++++++++++++ platform/galileo/contiki-main.c | 11 ++ 8 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 cpu/x86/startup.h create mode 100644 examples/galileo/prot-domain-switch-latency.c diff --git a/cpu/x86/quarkX1000.ld b/cpu/x86/quarkX1000.ld index be91a74c7..d4ea66aa6 100644 --- a/cpu/x86/quarkX1000.ld +++ b/cpu/x86/quarkX1000.ld @@ -63,6 +63,10 @@ SECTIONS { { *(.rodata*) + _sdata_kern_startup_func = .; + KEEP(*(.kern_startup_func)) + _edata_kern_startup_func = .; + _sdata_shared_isr = .; KEEP(*(.shared_isr_data*)) _edata_shared_isr = .; diff --git a/cpu/x86/quarkX1000_multi_seg.ld b/cpu/x86/quarkX1000_multi_seg.ld index 945650399..c4e6293cf 100644 --- a/cpu/x86/quarkX1000_multi_seg.ld +++ b/cpu/x86/quarkX1000_multi_seg.ld @@ -119,6 +119,10 @@ SECTIONS { *(.rodata*) *(.data*) + _sdata_kern_startup_func = .; + KEEP(*(.kern_startup_func)) + _edata_kern_startup_func = .; + /* These could alternatively be treated as read-only data to prevent tampering from the user privilege level. diff --git a/cpu/x86/quarkX1000_paging.ld b/cpu/x86/quarkX1000_paging.ld index 19e50e1e0..87c89ed8b 100644 --- a/cpu/x86/quarkX1000_paging.ld +++ b/cpu/x86/quarkX1000_paging.ld @@ -128,6 +128,10 @@ SECTIONS { *(.rodata*) *(.data*) + _sdata_kern_startup_func = .; + KEEP(*(.kern_startup_func)) + _edata_kern_startup_func = .; + /* These could alternatively be treated as read-only data to prevent tampering from the user privilege level. diff --git a/cpu/x86/startup.h b/cpu/x86/startup.h new file mode 100644 index 000000000..56ad3b482 --- /dev/null +++ b/cpu/x86/startup.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2016, Intel Corporation. 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +#ifndef CPU_X86_STARTUP_H_ +#define CPU_X86_STARTUP_H_ + +/** + * \brief Declare a function that will be automatically invoked from the kernel + * protection domain during boot, after all of the default device + * initialization has been completed. + */ +#define KERN_STARTUP_FUNC(f) \ +static void f(void); \ +static uintptr_t \ + __attribute__((used, section(".kern_startup_func"))) \ + __kern_startup_f = (uintptr_t)f; \ +static void f(void) + +#endif /* CPU_X86_STARTUP_H_ */ diff --git a/examples/galileo/Makefile b/examples/galileo/Makefile index bc7b071ff..0852fe085 100644 --- a/examples/galileo/Makefile +++ b/examples/galileo/Makefile @@ -1,6 +1,6 @@ TARGET=galileo -KNOWN_EXAMPLES = gpio-input gpio-output gpio-interrupt i2c-LSM9DS0 i2c-callbacks print-imr +KNOWN_EXAMPLES = gpio-input gpio-output gpio-interrupt i2c-LSM9DS0 i2c-callbacks print-imr prot-domain-switch-latency ifeq ($(filter $(EXAMPLE),$(KNOWN_EXAMPLES)),) $(info Set the variable EXAMPLE to one of the following Galileo-specific examples:) @@ -12,6 +12,12 @@ ifeq ($(EXAMPLE),print-imr) CFLAGS += -DDBG_IMRS endif +ifeq ($(EXAMPLE),prot-domain-switch-latency) +ifeq ($(SAMPLE_METADATA),1) +CFLAGS += -DSAMPLE_METADATA=1 +endif +endif + CONTIKI_PROJECT = $(EXAMPLE) all: $(CONTIKI_PROJECT) diff --git a/examples/galileo/README.md b/examples/galileo/README.md index 49777a16c..8f3217f05 100644 --- a/examples/galileo/README.md +++ b/examples/galileo/README.md @@ -93,6 +93,17 @@ Intel Quark X1000 SoC Isolated Memory Regions (IMRs), the Host System Management Mode Controls register, and the Host Memory I/O Boundary register. +Protection Domains +------------------ + +### Protection Domain Switch Latency (EXAMPLE=prot-domain-switch-latency) + +This application measures and prints the average latency of repeatedly +switching from one protection domain to another and back, in ping-pong +fashion. It can optionally perform memory accesses to metadata +associated with the destination protection domain. This feature can +be enabled by specifying SAMPLE_METADATA=1 on the build command line. + References ---------- diff --git a/examples/galileo/prot-domain-switch-latency.c b/examples/galileo/prot-domain-switch-latency.c new file mode 100644 index 000000000..9b6908a2f --- /dev/null +++ b/examples/galileo/prot-domain-switch-latency.c @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +#include +#include +#include + +#include "contiki.h" +#include "prot-domains.h" +#include "startup.h" +#include "syscalls.h" + +#define CPU_FREQ (400 * 1000 * 1000) +/* Run the test for approximately eight seconds. + * + * Duration expressed as shift amount to avoid integer overflow. + */ +#define DURATION_SECONDS_SHAMT 3 + +#ifdef SAMPLE_METADATA +typedef struct sample_meta { + int cnt; + +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__PAGING + /** + * See the comment on the padding in the metadata for the Intel Quark X1000 + * Ethernet driver for an explanation of why it is sized and structured like + * this. + */ + uint8_t pad[MIN_PAGE_SIZE - sizeof(int)]; +#endif +} __attribute__((packed)) sample_meta_t; + +static sample_meta_t ATTR_BSS_META meta = { .cnt = 0 }; +#endif + +PROT_DOMAINS_ALLOC(dom_client_data_t, ping_dcd); +PROT_DOMAINS_ALLOC(dom_client_data_t, pong_dcd); + +PROCESS(prot_domain_latency_process, "Ping-Pong Process"); +AUTOSTART_PROCESSES(&prot_domain_latency_process); +/*---------------------------------------------------------------------------*/ +void pong(uint64_t *mid, int *cnt); +SYSCALLS_DEFINE_SINGLETON(pong, pong_dcd, + uint64_t *mid, int *cnt) +{ +#ifdef SAMPLE_METADATA + sample_meta_t *loc_meta = (sample_meta_t *)PROT_DOMAINS_META(pong_dcd); +#endif + + *mid = _rdtsc(); + +#ifdef SAMPLE_METADATA + META_READL(*cnt, loc_meta->cnt); + META_WRITEL(loc_meta->cnt, *cnt + 1); +#endif +} +/*---------------------------------------------------------------------------*/ +void ping(void); +SYSCALLS_DEFINE_SINGLETON(ping, ping_dcd) +{ + uint64_t start, mid, end; + uint64_t diff1 = 0, diff2 = 0; + double diff1_d, diff2_d; + int i = 0; + int cnt; + + while(((diff1 + diff2) >> DURATION_SECONDS_SHAMT) < CPU_FREQ) { + start = _rdtsc(); + pong(&mid, &cnt); + end = _rdtsc(); + +#ifdef SAMPLE_METADATA + assert(cnt == i); +#endif + + /* exclude the warm-up round */ + if(i != 0) { + diff1 += mid - start; + diff2 += end - mid; + } + + i++; + } + + diff1_d = diff1; + diff2_d = diff2; + + diff1_d /= i - 1; + diff2_d /= i - 1; + + puts( "Sample protection domain ping-pong switching latency measurements:"); + printf(" %u iterations\n", i - 1); + printf(" Avg. # cycles ping -> pong: %.2f\n", diff1_d); + printf(" + Avg. # cycles pong -> ping: %.2f\n", diff2_d); + puts( " ----------------------------------------"); + printf(" Avg. # cycles round-trip: %.2f\n", diff1_d + diff2_d); +} +/*---------------------------------------------------------------------------*/ +KERN_STARTUP_FUNC(sample_domain_init) +{ + PROT_DOMAINS_INIT_ID(ping_dcd); + prot_domains_reg(&ping_dcd, 0, 0, 0, 0, false); + SYSCALLS_INIT(ping); + SYSCALLS_AUTHZ(ping, ping_dcd); + + PROT_DOMAINS_INIT_ID(pong_dcd); + prot_domains_reg(&pong_dcd, 0, 0, +#ifdef SAMPLE_METADATA + (uintptr_t)&meta, sizeof(meta), false); +#else + 0, 0, false); +#endif + SYSCALLS_INIT(pong); + SYSCALLS_AUTHZ(pong, pong_dcd); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(prot_domain_latency_process, ev, data) +{ + PROCESS_BEGIN(); + + /* Run the latency test from the ping domain so that interrupts + * are disabled during the test. + */ + ping(); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/galileo/contiki-main.c b/platform/galileo/contiki-main.c index 7b31a9961..ccc1f519f 100644 --- a/platform/galileo/contiki-main.c +++ b/platform/galileo/contiki-main.c @@ -54,6 +54,8 @@ PROCINIT( &etimer_process #endif ); +extern int _sdata_kern_startup_func, _edata_kern_startup_func; + /*---------------------------------------------------------------------------*/ void app_main(void) @@ -78,6 +80,8 @@ app_main(void) int main(void) { + uintptr_t *func_ptr; + #ifdef X86_CONF_RESTRICT_DMA quarkX1000_imr_conf(); #endif @@ -104,6 +108,13 @@ main(void) */ pci_root_complex_lock(); + func_ptr = (uintptr_t *)&_sdata_kern_startup_func; + while(func_ptr != (uintptr_t *)&_edata_kern_startup_func) { + ((void (*)(void))*func_ptr)(); + + func_ptr++; + } + prot_domains_leave_main(); return 0; From f8c4d1155f675db1eb5e9544ed5444f670bcf216 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Sat, 23 Apr 2016 01:15:21 +0200 Subject: [PATCH 189/374] Disable RPL DAO ACK by default --- core/net/rpl/rpl-conf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/net/rpl/rpl-conf.h b/core/net/rpl/rpl-conf.h index 6822ff550..b86a36a85 100644 --- a/core/net/rpl/rpl-conf.h +++ b/core/net/rpl/rpl-conf.h @@ -242,7 +242,7 @@ #ifdef RPL_CONF_WITH_DAO_ACK #define RPL_WITH_DAO_ACK RPL_CONF_WITH_DAO_ACK #else -#define RPL_WITH_DAO_ACK 1 +#define RPL_WITH_DAO_ACK 0 #endif /* RPL_CONF_WITH_DAO_ACK */ /* From 753a557903eca3bf09bdefc80bae4a7d5c08df99 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Sat, 23 Apr 2016 07:58:06 +0200 Subject: [PATCH 190/374] Travis: use a single random seed rather than two. As a result, a single failed simulation results in overall failure --- regression-tests/Makefile.simulation-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression-tests/Makefile.simulation-test b/regression-tests/Makefile.simulation-test index 58818c328..9995eeea8 100644 --- a/regression-tests/Makefile.simulation-test +++ b/regression-tests/Makefile.simulation-test @@ -31,7 +31,7 @@ TESTLOGS=$(patsubst %.csc,%.testlog,$(TESTS)) LOGS=$(patsubst %.csc,%.log,$(TESTS)) FAILLOGS=$(patsubst %.csc,%.*.faillog,$(TESTS)) #Set random seeds to create reproduceable results. -RANDOMSEED=1 5 +RANDOMSEED=1 CONTIKI=../.. From 03ae4c91fac1805d84fc35e19fec1087b3c64040 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Sat, 23 Apr 2016 01:10:00 +0200 Subject: [PATCH 191/374] Fix output of RPL tests --- regression-tests/12-rpl/01-rpl-up-route.csc | 10 ++++------ regression-tests/12-rpl/02-rpl-root-reboot.csc | 10 ++++------ regression-tests/12-rpl/03-rpl-28-hours.csc | 10 ++++------ regression-tests/12-rpl/04-rpl-large-network.csc | 10 ++++------ regression-tests/12-rpl/05-rpl-up-and-down-routes.csc | 10 ++++------ regression-tests/12-rpl/06-rpl-temporary-root-loss.csc | 10 ++++------ regression-tests/12-rpl/08-rpl-dao-route-loss-0.csc | 10 ++++------ regression-tests/12-rpl/08-rpl-dao-route-loss-1.csc | 10 ++++------ regression-tests/12-rpl/08-rpl-dao-route-loss-2.csc | 10 ++++------ regression-tests/12-rpl/08-rpl-dao-route-loss-3.csc | 10 ++++------ regression-tests/12-rpl/08-rpl-dao-route-loss-4.csc | 10 ++++------ regression-tests/12-rpl/08-rpl-dao-route-loss-5.csc | 10 ++++------ regression-tests/12-rpl/09-rpl-probing.csc | 10 ++++------ regression-tests/12-rpl/10-rpl-multi-dodag.csc | 10 ++++------ 14 files changed, 56 insertions(+), 84 deletions(-) diff --git a/regression-tests/12-rpl/01-rpl-up-route.csc b/regression-tests/12-rpl/01-rpl-up-route.csc index 5af9d8857..fc79cfc27 100644 --- a/regression-tests/12-rpl/01-rpl-up-route.csc +++ b/regression-tests/12-rpl/01-rpl-up-route.csc @@ -315,22 +315,20 @@ while(true) { } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { -// log.log("" + msg + "\n"); data = msg.split(" "); num = parseInt(data[14]); - packets = packets.substr(0, num) + "*"; - log.log("" + hops + " " + packets + "\n"); -// log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { numMissed = num - lastMsg - 1; - lostMsgs += numMissed; + lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i) + "_"; + packets = packets.substr(0, lastMsg + i + 1) + "_"; } } } + packets = packets.substr(0, num) + "*"; + log.log("" + hops + " " + packets + "\n"); lastMsg = num; } } diff --git a/regression-tests/12-rpl/02-rpl-root-reboot.csc b/regression-tests/12-rpl/02-rpl-root-reboot.csc index ce9f3cee0..14f87c7a9 100644 --- a/regression-tests/12-rpl/02-rpl-root-reboot.csc +++ b/regression-tests/12-rpl/02-rpl-root-reboot.csc @@ -315,22 +315,20 @@ while(true) { } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { -// log.log("" + msg + "\n"); data = msg.split(" "); num = parseInt(data[14]); - packets = packets.substr(0, num) + "*"; - log.log("" + hops + " " + packets + "\n"); -// log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { numMissed = num - lastMsg - 1; - lostMsgs += numMissed; + lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i) + "_"; + packets = packets.substr(0, lastMsg + i + 1) + "_"; } } } + packets = packets.substr(0, num) + "*"; + log.log("" + hops + " " + packets + "\n"); lastMsg = num; } } diff --git a/regression-tests/12-rpl/03-rpl-28-hours.csc b/regression-tests/12-rpl/03-rpl-28-hours.csc index a8cefd469..1cf2c5e43 100644 --- a/regression-tests/12-rpl/03-rpl-28-hours.csc +++ b/regression-tests/12-rpl/03-rpl-28-hours.csc @@ -264,22 +264,20 @@ while(true) { } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { -// log.log("" + msg + "\n"); data = msg.split(" "); num = parseInt(data[14]); - packets = packets.substr(0, num) + "*"; - log.log("" + hops + " " + packets + "\n"); -// log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { numMissed = num - lastMsg - 1; - lostMsgs += numMissed; + lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i) + "_"; + packets = packets.substr(0, lastMsg + i + 1) + "_"; } } } + packets = packets.substr(0, num) + "*"; + log.log("" + hops + " " + packets + "\n"); lastMsg = num; } } diff --git a/regression-tests/12-rpl/04-rpl-large-network.csc b/regression-tests/12-rpl/04-rpl-large-network.csc index 145cad14c..e40b7a339 100644 --- a/regression-tests/12-rpl/04-rpl-large-network.csc +++ b/regression-tests/12-rpl/04-rpl-large-network.csc @@ -7030,22 +7030,20 @@ while(true) { } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { -// log.log("" + msg + "\n"); data = msg.split(" "); num = parseInt(data[14]); - packets = packets.substr(0, num) + "*"; - log.log("" + hops + " " + packets + "\n"); -// log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { numMissed = num - lastMsg - 1; - lostMsgs += numMissed; + lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i) + "_"; + packets = packets.substr(0, lastMsg + i + 1) + "_"; } } } + packets = packets.substr(0, num) + "*"; + log.log("" + hops + " " + packets + "\n"); lastMsg = num; } } diff --git a/regression-tests/12-rpl/05-rpl-up-and-down-routes.csc b/regression-tests/12-rpl/05-rpl-up-and-down-routes.csc index 3ed5a71f7..c2b3cb506 100644 --- a/regression-tests/12-rpl/05-rpl-up-and-down-routes.csc +++ b/regression-tests/12-rpl/05-rpl-up-and-down-routes.csc @@ -313,22 +313,20 @@ while(true) { } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { -// log.log("" + msg + "\n"); data = msg.split(" "); num = parseInt(data[14]); - packets = packets.substr(0, num) + "*"; - log.log("" + hops + " " + packets + "\n"); -// log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { numMissed = num - lastMsg - 1; - lostMsgs += numMissed; + lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i) + "_"; + packets = packets.substr(0, lastMsg + i + 1) + "_"; } } } + packets = packets.substr(0, num) + "*"; + log.log("" + hops + " " + packets + "\n"); lastMsg = num; } } diff --git a/regression-tests/12-rpl/06-rpl-temporary-root-loss.csc b/regression-tests/12-rpl/06-rpl-temporary-root-loss.csc index bd771d7e7..08126f22b 100644 --- a/regression-tests/12-rpl/06-rpl-temporary-root-loss.csc +++ b/regression-tests/12-rpl/06-rpl-temporary-root-loss.csc @@ -318,23 +318,21 @@ while(true) { } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { -// log.log("" + msg + "\n"); data = msg.split(" "); num = parseInt(data[14]); - packets = packets.substr(0, num) + "*"; - log.log("" + hops + " " + packets + "\n"); -// log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { lastMissed = num; numMissed = num - lastMsg - 1; - lostMsgs += numMissed; + lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i) + "_"; + packets = packets.substr(0, lastMsg + i + 1) + "_"; } } } + packets = packets.substr(0, num) + "*"; + log.log("" + hops + " " + packets + "\n"); lastMsg = num; } } diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-0.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-0.csc index afdbed672..b5aeac9b2 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-0.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-0.csc @@ -330,23 +330,21 @@ while(true) { } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { -// log.log("" + msg + "\n"); data = msg.split(" "); num = parseInt(data[14]); - packets = packets.substr(0, num) + "*"; - log.log("" + hops + " " + packets + "\n"); seenMsgs++; -// log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { numMissed = num - lastMsg - 1; - lostMsgs += numMissed; + lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i) + "_"; + packets = packets.substr(0, lastMsg + i + 1) + "_"; } } } + packets = packets.substr(0, num) + "*"; + log.log("" + hops + " " + packets + "\n"); lastMsg = num; } } diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-1.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-1.csc index 3657d4b8a..d17bc193c 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-1.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-1.csc @@ -330,23 +330,21 @@ while(true) { } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { -// log.log("" + msg + "\n"); data = msg.split(" "); num = parseInt(data[14]); - packets = packets.substr(0, num) + "*"; - log.log("" + hops + " " + packets + "\n"); seenMsgs++; -// log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { numMissed = num - lastMsg - 1; - lostMsgs += numMissed; + lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i) + "_"; + packets = packets.substr(0, lastMsg + i + 1) + "_"; } } } + packets = packets.substr(0, num) + "*"; + log.log("" + hops + " " + packets + "\n"); lastMsg = num; } } diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-2.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-2.csc index 8c78725a3..fe3db3dc3 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-2.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-2.csc @@ -330,23 +330,21 @@ while(true) { } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { -// log.log("" + msg + "\n"); data = msg.split(" "); num = parseInt(data[14]); - packets = packets.substr(0, num) + "*"; - log.log("" + hops + " " + packets + "\n"); seenMsgs++; -// log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { numMissed = num - lastMsg - 1; - lostMsgs += numMissed; + lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i) + "_"; + packets = packets.substr(0, lastMsg + i + 1) + "_"; } } } + packets = packets.substr(0, num) + "*"; + log.log("" + hops + " " + packets + "\n"); lastMsg = num; } } diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-3.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-3.csc index fd1983379..7ee838b2c 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-3.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-3.csc @@ -330,23 +330,21 @@ while(true) { } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { -// log.log("" + msg + "\n"); data = msg.split(" "); num = parseInt(data[14]); - packets = packets.substr(0, num) + "*"; - log.log("" + hops + " " + packets + "\n"); seenMsgs++; -// log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { numMissed = num - lastMsg - 1; - lostMsgs += numMissed; + lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i) + "_"; + packets = packets.substr(0, lastMsg + i + 1) + "_"; } } } + packets = packets.substr(0, num) + "*"; + log.log("" + hops + " " + packets + "\n"); lastMsg = num; } } diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-4.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-4.csc index 8db19c568..35c5bd753 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-4.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-4.csc @@ -330,23 +330,21 @@ while(true) { } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { -// log.log("" + msg + "\n"); data = msg.split(" "); num = parseInt(data[14]); - packets = packets.substr(0, num) + "*"; - log.log("" + hops + " " + packets + "\n"); seenMsgs++; -// log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { numMissed = num - lastMsg - 1; - lostMsgs += numMissed; + lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i) + "_"; + packets = packets.substr(0, lastMsg + i + 1) + "_"; } } } + packets = packets.substr(0, num) + "*"; + log.log("" + hops + " " + packets + "\n"); lastMsg = num; } } diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-5.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-5.csc index 0f4d7db7d..4dc5038bc 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-5.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-5.csc @@ -330,23 +330,21 @@ while(true) { } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { -// log.log("" + msg + "\n"); data = msg.split(" "); num = parseInt(data[14]); - packets = packets.substr(0, num) + "*"; - log.log("" + hops + " " + packets + "\n"); seenMsgs++; -// log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { numMissed = num - lastMsg - 1; - lostMsgs += numMissed; + lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i) + "_"; + packets = packets.substr(0, lastMsg + i + 1) + "_"; } } } + packets = packets.substr(0, num) + "*"; + log.log("" + hops + " " + packets + "\n"); lastMsg = num; } } diff --git a/regression-tests/12-rpl/09-rpl-probing.csc b/regression-tests/12-rpl/09-rpl-probing.csc index bc29029af..5206f1cfd 100644 --- a/regression-tests/12-rpl/09-rpl-probing.csc +++ b/regression-tests/12-rpl/09-rpl-probing.csc @@ -226,23 +226,21 @@ while(true) { } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { -// log.log("" + msg + "\n"); data = msg.split(" "); num = parseInt(data[14]); - packets = packets.substr(0, num) + "*"; - log.log("" + hops + " " + packets + "\n"); -// log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { numMissed = num - lastMsg - 1; - lostMsgs += numMissed; + lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i) + "_"; + packets = packets.substr(0, lastMsg + i + 1) + "_"; } } } lastMsgHops = hops; + packets = packets.substr(0, num) + "*"; + log.log("" + hops + " " + packets + "\n"); lastMsg = num; } } diff --git a/regression-tests/12-rpl/10-rpl-multi-dodag.csc b/regression-tests/12-rpl/10-rpl-multi-dodag.csc index aa0ab3d43..fa015e8d9 100644 --- a/regression-tests/12-rpl/10-rpl-multi-dodag.csc +++ b/regression-tests/12-rpl/10-rpl-multi-dodag.csc @@ -356,12 +356,8 @@ while(true) { } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { -// log.log("" + msg + "\n"); data = msg.split(" "); num = parseInt(data[14]); - packets = packets.substr(0, num) + "*"; - log.log("" + hops + " " + packets + "\n"); -// log.log("Num " + num + "\n"); if(newSink) { newDagOk++; newSink = 0; @@ -369,13 +365,15 @@ while(true) { if(lastMsg != -1) { if(num != lastMsg + 1) { numMissed = num - lastMsg - 1; - lostMsgs += numMissed; + lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i) + "_"; + packets = packets.substr(0, lastMsg + i + 1) + "_"; } } } + packets = packets.substr(0, num) + "*"; + log.log("" + hops + " " + packets + "\n"); lastMsg = num; } } From 70d94133ea2fc6b3050932886aacd53a6d9514e4 Mon Sep 17 00:00:00 2001 From: Pere Tuset Date: Mon, 25 Apr 2016 01:50:23 +0200 Subject: [PATCH 192/374] Updated OpenMote example and platform. --- examples/openmote-cc2538/openmote-demo.c | 20 +++-- platform/openmote-cc2538/dev/adxl346.c | 100 ++++++++++++++++++++--- platform/openmote-cc2538/dev/adxl346.h | 10 ++- 3 files changed, 109 insertions(+), 21 deletions(-) diff --git a/examples/openmote-cc2538/openmote-demo.c b/examples/openmote-cc2538/openmote-demo.c index 46a301511..393203a0c 100644 --- a/examples/openmote-cc2538/openmote-demo.c +++ b/examples/openmote-cc2538/openmote-demo.c @@ -85,25 +85,29 @@ PROCESS_THREAD(openmote_demo_process, ev, data) static struct etimer et; static int16_t counter; static uint16_t adxl346_present, sht21_present, max44009_present; - static uint16_t accel, light, temperature, humidity; + static int16_t accel, light, temperature, humidity; PROCESS_EXITHANDLER(broadcast_close(&bc)) PROCESS_BEGIN(); - /* Initialize and activate the ADXL346 sensor */ + /* Initialize and calibrate the ADXL346 sensor */ adxl346_present = SENSORS_ACTIVATE(adxl346); if(adxl346_present == ADXL346_ERROR) { printf("ADXL346 sensor is NOT present!\n"); leds_on(LEDS_YELLOW); + } else { + adxl346.configure(ADXL346_CALIB_OFFSET, 0); } + /* Initialize the MAX44009 sensor */ max44009_present = SENSORS_ACTIVATE(max44009); if(max44009_present == MAX44009_ERROR) { printf("MAX44009 sensor is NOT present!\n"); leds_on(LEDS_ORANGE); } + /* Initialize the SHT21 sensor */ sht21_present = SENSORS_ACTIVATE(sht21); if(sht21_present == SHT21_ERROR) { printf("SHT21 sensor is NOT present!\n"); @@ -123,12 +127,12 @@ PROCESS_THREAD(openmote_demo_process, ev, data) if(ev == PROCESS_EVENT_TIMER) { if(adxl346_present != ADXL346_ERROR) { leds_on(LEDS_YELLOW); - accel = adxl346.value(ADXL346_READ_X); - printf("X Acceleration: %u\n", accel); - accel = adxl346.value(ADXL346_READ_Y); - printf("Y Acceleration: %u\n", accel); - accel = adxl346.value(ADXL346_READ_Z); - printf("Z Acceleration: %u\n", accel); + accel = adxl346.value(ADXL346_READ_X_mG); + printf("X Acceleration: %d.%u G\n", accel / 1000, accel % 1000); + accel = adxl346.value(ADXL346_READ_Y_mG); + printf("Y Acceleration: %d.%u G\n", accel / 1000, accel % 1000); + accel = adxl346.value(ADXL346_READ_Z_mG); + printf("Z Acceleration: %d.%u G\n", accel / 1000, accel % 1000); leds_off(LEDS_YELLOW); } diff --git a/platform/openmote-cc2538/dev/adxl346.c b/platform/openmote-cc2538/dev/adxl346.c index 7fb406051..09d725474 100644 --- a/platform/openmote-cc2538/dev/adxl346.c +++ b/platform/openmote-cc2538/dev/adxl346.c @@ -153,6 +153,9 @@ #define ADXL346_DATA_FORMAT_RANGE_PM_4g (1) #define ADXL346_DATA_FORMAT_RANGE_PM_8g (2) #define ADXL346_DATA_FORMAT_RANGE_PM_16g (3) + +#define ADXL346_USER_CONFIGURATION (ADXL346_DATA_FORMAT_RANGE_PM_2g) + /** @} */ /*---------------------------------------------------------------------------*/ static uint8_t enabled; @@ -163,13 +166,11 @@ adxl346_init(void) uint8_t config[2]; config[0] = ADXL346_BW_RATE_ADDR; - config[1] = (ADXL346_BW_RATE_RATE(11)); + config[1] = (ADXL346_BW_RATE_RATE(6)); i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); config[0] = ADXL346_DATA_FORMAT_ADDR; - config[1] = (ADXL346_DATA_FORMAT_SELF_TEST | - ADXL346_DATA_FORMAT_FULL_RES | - ADXL346_DATA_FORMAT_RANGE_PM_16g); + config[1] = (ADXL346_USER_CONFIGURATION); i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); config[0] = ADXL346_POWER_CTL_ADDR; @@ -185,23 +186,86 @@ adxl346_is_present(void) i2c_single_send(ADXL346_ADDRESS, ADXL346_DEVID_ADDR); i2c_single_receive(ADXL346_ADDRESS, &is_present); - return is_present == ADXL346_DEVID_VALUE; + return (is_present == ADXL346_DEVID_VALUE); } /*---------------------------------------------------------------------------*/ -static uint16_t +static int16_t adxl346_read_accel(uint8_t addr1, uint8_t addr2) { uint8_t acceleration[2]; - uint16_t z; + int16_t result; i2c_single_send(ADXL346_ADDRESS, addr1); i2c_single_receive(ADXL346_ADDRESS, &acceleration[0]); i2c_single_send(ADXL346_ADDRESS, addr2); i2c_single_receive(ADXL346_ADDRESS, &acceleration[1]); - z = (acceleration[0] << 8) | acceleration[1]; + result = (acceleration[1] << 8) | acceleration[0]; + + return result; +} +/*---------------------------------------------------------------------------*/ +static int16_t +adxl346_convert_accel(int16_t accel) +{ + int32_t result; + + result = (1000 * accel) / 256; + + return (int16_t) result; +} +/*---------------------------------------------------------------------------*/ +static void +adxl346_calibrate_offset(void) +{ + int32_t accum_x = 0; + int32_t accum_y = 0; + int32_t accum_z = 0; + uint8_t config[2]; + int8_t offset; + + config[0] = ADXL346_OFSX_ADDR; + config[1] = 0; + i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); + config[0] = ADXL346_OFSY_ADDR; + config[1] = 0; + i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); + config[0] = ADXL346_OFSZ_ADDR; + config[1] = 0; + i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); + + uint16_t i; + for (i = 0; i < 100; i++) { + uint16_t x, y, z; + + x = adxl346_read_accel(ADXL346_DATAX0_ADDR, ADXL346_DATAX1_ADDR); + accum_x += x; + + y = adxl346_read_accel(ADXL346_DATAY0_ADDR, ADXL346_DATAY1_ADDR); + accum_y += y; + + z = adxl346_read_accel(ADXL346_DATAZ0_ADDR, ADXL346_DATAZ1_ADDR); + accum_z += z; + } + + offset = (64 * accum_x) / 25600; + config[0] = ADXL346_OFSX_ADDR; + config[1] = -offset; + i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); + PRINTF("ADXL346: X calibration offset is %d\n", offset); + + offset = (64 * accum_y) / 25600; + config[0] = ADXL346_OFSY_ADDR; + config[1] = -offset; + i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); + PRINTF("ADXL346: Y calibration offset is %d\n", offset); + + offset = (64 * accum_z) / 25600; + config[0] = ADXL346_OFSZ_ADDR; + config[1] = -offset; + i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); + PRINTF("ADXL346: Z calibration offset is %d\n", offset); - return z; } /*---------------------------------------------------------------------------*/ static int @@ -218,6 +282,7 @@ status(int type) static int value(int type) { + int16_t accel; if(!enabled) { PRINTF("ADXL346: sensor not started\n"); return ADXL346_ERROR; @@ -225,10 +290,19 @@ value(int type) if(type == ADXL346_READ_X) { return adxl346_read_accel(ADXL346_DATAX0_ADDR, ADXL346_DATAX1_ADDR); - } else if(type == ADXL346_READ_Y) { + } else if(type == ADXL346_READ_Y) { return adxl346_read_accel(ADXL346_DATAY0_ADDR, ADXL346_DATAY1_ADDR); } else if(type == ADXL346_READ_Z) { return adxl346_read_accel(ADXL346_DATAZ0_ADDR, ADXL346_DATAZ1_ADDR); + } else if(type == ADXL346_READ_X_mG) { + accel = adxl346_read_accel(ADXL346_DATAX0_ADDR, ADXL346_DATAX1_ADDR); + return adxl346_convert_accel(accel); + } else if(type == ADXL346_READ_Y_mG) { + accel = adxl346_read_accel(ADXL346_DATAY0_ADDR, ADXL346_DATAY1_ADDR); + return adxl346_convert_accel(accel); + } else if(type == ADXL346_READ_Z_mG) { + accel = adxl346_read_accel(ADXL346_DATAZ0_ADDR, ADXL346_DATAZ1_ADDR); + return adxl346_convert_accel(accel); } else { PRINTF("ADXL346: invalid value requested\n"); return ADXL346_ERROR; @@ -243,6 +317,7 @@ configure(int type, int value) if(type == ADXL346_ACTIVATE) { if(!adxl346_is_present()) { PRINTF("ADXL346: is not present\n"); + enabled = 0; return ADXL346_ERROR; } else { adxl346_init(); @@ -251,6 +326,11 @@ configure(int type, int value) } } + if(type == ADXL346_CALIB_OFFSET && enabled) { + adxl346_calibrate_offset(); + return ADXL346_SUCCESS; + } + return ADXL346_ERROR; } /*---------------------------------------------------------------------------*/ diff --git a/platform/openmote-cc2538/dev/adxl346.h b/platform/openmote-cc2538/dev/adxl346.h index acd0d21f5..401e601d1 100644 --- a/platform/openmote-cc2538/dev/adxl346.h +++ b/platform/openmote-cc2538/dev/adxl346.h @@ -51,9 +51,13 @@ #define ADXL346_SUCCESS (0) #define ADXL346_ACTIVATE (SENSORS_ACTIVE) #define ADXL346_READ_X (2) -#define ADXL346_READ_Y (3) -#define ADXL346_READ_Z (4) -#define ADXL346_NONE (5) +#define ADXL346_READ_X_mG (3) +#define ADXL346_READ_Y (4) +#define ADXL346_READ_Y_mG (5) +#define ADXL346_READ_Z (6) +#define ADXL346_READ_Z_mG (7) +#define ADXL346_CALIB_OFFSET (8) +#define ADXL346_NONE (9) /*---------------------------------------------------------------------------*/ #define ADXL346_SENSOR "ADXL346 Sensor" /*---------------------------------------------------------------------------*/ From 0296e6aba06647ec01fff0122dbca0fb16eb6c61 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 22 Apr 2016 21:41:03 +0200 Subject: [PATCH 193/374] Indent tcpip.c --- core/net/ip/tcpip.c | 322 ++++++++++++++++++++++---------------------- 1 file changed, 161 insertions(+), 161 deletions(-) diff --git a/core/net/ip/tcpip.c b/core/net/ip/tcpip.c index 23b9605eb..ff514a186 100644 --- a/core/net/ip/tcpip.c +++ b/core/net/ip/tcpip.c @@ -219,7 +219,7 @@ struct uip_conn * tcp_connect(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate) { struct uip_conn *c; - + c = uip_connect(ripaddr, port); if(c == NULL) { return NULL; @@ -227,9 +227,9 @@ tcp_connect(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate) c->appstate.p = PROCESS_CURRENT(); c->appstate.state = appstate; - + tcpip_poll_tcp(c); - + return c; } #endif /* UIP_ACTIVE_OPEN */ @@ -300,7 +300,7 @@ udp_new(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate) { struct uip_udp_conn *c; uip_udp_appstate_t *s; - + c = uip_udp_new(ripaddr, port); if(c == NULL) { return NULL; @@ -365,151 +365,151 @@ eventhandler(process_event_t ev, process_data_t data) struct process *p; switch(ev) { - case PROCESS_EVENT_EXITED: - /* This is the event we get if a process has exited. We go through + case PROCESS_EVENT_EXITED: + /* This is the event we get if a process has exited. We go through the TCP/IP tables to see if this process had any open connections or listening TCP ports. If so, we'll close those connections. */ - p = (struct process *)data; + p = (struct process *)data; #if UIP_TCP - l = s.listenports; - for(i = 0; i < UIP_LISTENPORTS; ++i) { - if(l->p == p) { - uip_unlisten(l->port); - l->port = 0; - l->p = PROCESS_NONE; - } - ++l; + l = s.listenports; + for(i = 0; i < UIP_LISTENPORTS; ++i) { + if(l->p == p) { + uip_unlisten(l->port); + l->port = 0; + l->p = PROCESS_NONE; } - - { - struct uip_conn *cptr; - - for(cptr = &uip_conns[0]; cptr < &uip_conns[UIP_CONNS]; ++cptr) { - if(cptr->appstate.p == p) { - cptr->appstate.p = PROCESS_NONE; - cptr->tcpstateflags = UIP_CLOSED; - } + ++l; + } + + { + struct uip_conn *cptr; + + for(cptr = &uip_conns[0]; cptr < &uip_conns[UIP_CONNS]; ++cptr) { + if(cptr->appstate.p == p) { + cptr->appstate.p = PROCESS_NONE; + cptr->tcpstateflags = UIP_CLOSED; } } + } #endif /* UIP_TCP */ #if UIP_UDP - { - struct uip_udp_conn *cptr; + { + struct uip_udp_conn *cptr; - for(cptr = &uip_udp_conns[0]; - cptr < &uip_udp_conns[UIP_UDP_CONNS]; ++cptr) { - if(cptr->appstate.p == p) { - cptr->lport = 0; - } + for(cptr = &uip_udp_conns[0]; + cptr < &uip_udp_conns[UIP_UDP_CONNS]; ++cptr) { + if(cptr->appstate.p == p) { + cptr->lport = 0; } } + } #endif /* UIP_UDP */ - break; + break; - case PROCESS_EVENT_TIMER: - /* We get this event if one of our timers have expired. */ - { - /* Check the clock so see if we should call the periodic uIP + case PROCESS_EVENT_TIMER: + /* We get this event if one of our timers have expired. */ + { + /* Check the clock so see if we should call the periodic uIP processing. */ - if(data == &periodic && - etimer_expired(&periodic)) { + if(data == &periodic && + etimer_expired(&periodic)) { #if UIP_TCP - for(i = 0; i < UIP_CONNS; ++i) { - if(uip_conn_active(i)) { - /* Only restart the timer if there are active + for(i = 0; i < UIP_CONNS; ++i) { + if(uip_conn_active(i)) { + /* Only restart the timer if there are active connections. */ - etimer_restart(&periodic); - uip_periodic(i); + etimer_restart(&periodic); + uip_periodic(i); #if NETSTACK_CONF_WITH_IPV6 - tcpip_ipv6_output(); + tcpip_ipv6_output(); #else - if(uip_len > 0) { - PRINTF("tcpip_output from periodic len %d\n", uip_len); - tcpip_output(); - PRINTF("tcpip_output after periodic len %d\n", uip_len); - } -#endif /* NETSTACK_CONF_WITH_IPV6 */ - } + if(uip_len > 0) { + PRINTF("tcpip_output from periodic len %d\n", uip_len); + tcpip_output(); + PRINTF("tcpip_output after periodic len %d\n", uip_len); } +#endif /* NETSTACK_CONF_WITH_IPV6 */ + } + } #endif /* UIP_TCP */ #if UIP_CONF_IP_FORWARD - uip_fw_periodic(); + uip_fw_periodic(); #endif /* UIP_CONF_IP_FORWARD */ - } - + } + #if NETSTACK_CONF_WITH_IPV6 #if UIP_CONF_IPV6_REASSEMBLY - /* - * check the timer for reassembly - */ - if(data == &uip_reass_timer && - etimer_expired(&uip_reass_timer)) { - uip_reass_over(); - tcpip_ipv6_output(); - } + /* + * check the timer for reassembly + */ + if(data == &uip_reass_timer && + etimer_expired(&uip_reass_timer)) { + uip_reass_over(); + tcpip_ipv6_output(); + } #endif /* UIP_CONF_IPV6_REASSEMBLY */ - /* - * check the different timers for neighbor discovery and - * stateless autoconfiguration - */ - /*if(data == &uip_ds6_timer_periodic && + /* + * check the different timers for neighbor discovery and + * stateless autoconfiguration + */ + /*if(data == &uip_ds6_timer_periodic && etimer_expired(&uip_ds6_timer_periodic)) { uip_ds6_periodic(); tcpip_ipv6_output(); }*/ #if !UIP_CONF_ROUTER - if(data == &uip_ds6_timer_rs && - etimer_expired(&uip_ds6_timer_rs)) { - uip_ds6_send_rs(); - tcpip_ipv6_output(); - } + if(data == &uip_ds6_timer_rs && + etimer_expired(&uip_ds6_timer_rs)) { + uip_ds6_send_rs(); + tcpip_ipv6_output(); + } #endif /* !UIP_CONF_ROUTER */ - if(data == &uip_ds6_timer_periodic && - etimer_expired(&uip_ds6_timer_periodic)) { - uip_ds6_periodic(); - tcpip_ipv6_output(); - } + if(data == &uip_ds6_timer_periodic && + etimer_expired(&uip_ds6_timer_periodic)) { + uip_ds6_periodic(); + tcpip_ipv6_output(); + } #endif /* NETSTACK_CONF_WITH_IPV6 */ - } - break; - + } + break; + #if UIP_TCP - case TCP_POLL: - if(data != NULL) { - uip_poll_conn(data); + case TCP_POLL: + if(data != NULL) { + uip_poll_conn(data); #if NETSTACK_CONF_WITH_IPV6 - tcpip_ipv6_output(); + tcpip_ipv6_output(); #else /* NETSTACK_CONF_WITH_IPV6 */ - if(uip_len > 0) { - PRINTF("tcpip_output from tcp poll len %d\n", uip_len); - tcpip_output(); - } -#endif /* NETSTACK_CONF_WITH_IPV6 */ - /* Start the periodic polling, if it isn't already active. */ - start_periodic_tcp_timer(); + if(uip_len > 0) { + PRINTF("tcpip_output from tcp poll len %d\n", uip_len); + tcpip_output(); } - break; +#endif /* NETSTACK_CONF_WITH_IPV6 */ + /* Start the periodic polling, if it isn't already active. */ + start_periodic_tcp_timer(); + } + break; #endif /* UIP_TCP */ #if UIP_UDP - case UDP_POLL: - if(data != NULL) { - uip_udp_periodic_conn(data); + case UDP_POLL: + if(data != NULL) { + uip_udp_periodic_conn(data); #if NETSTACK_CONF_WITH_IPV6 - tcpip_ipv6_output(); + tcpip_ipv6_output(); #else - if(uip_len > 0) { - tcpip_output(); - } -#endif /* UIP_UDP */ + if(uip_len > 0) { + tcpip_output(); } - break; +#endif /* UIP_UDP */ + } + break; #endif /* UIP_UDP */ - case PACKET_INPUT: - packet_input(); - break; + case PACKET_INPUT: + packet_input(); + break; }; } /*---------------------------------------------------------------------------*/ @@ -563,25 +563,25 @@ tcpip_ipv6_output(void) nexthop = uip_ds6_defrt_choose(); if(nexthop == NULL) { #ifdef UIP_FALLBACK_INTERFACE - PRINTF("FALLBACK: removing ext hdrs & setting proto %d %d\n", - uip_ext_len, *((uint8_t *)UIP_IP_BUF + 40)); - if(uip_ext_len > 0) { - extern void remove_ext_hdr(void); - uint8_t proto = *((uint8_t *)UIP_IP_BUF + 40); - remove_ext_hdr(); - /* This should be copied from the ext header... */ - UIP_IP_BUF->proto = proto; - } - /* Inform the other end that the destination is not reachable. If it's - * not informed routes might get lost unexpectedly until there's a need - * to send a new packet to the peer */ - if(UIP_FALLBACK_INTERFACE.output() < 0) { - PRINTF("FALLBACK: output error. Reporting DST UNREACH\n"); - uip_icmp6_error_output(ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR, 0); - uip_flags = 0; - tcpip_ipv6_output(); - return; - } + PRINTF("FALLBACK: removing ext hdrs & setting proto %d %d\n", + uip_ext_len, *((uint8_t *)UIP_IP_BUF + 40)); + if(uip_ext_len > 0) { + extern void remove_ext_hdr(void); + uint8_t proto = *((uint8_t *)UIP_IP_BUF + 40); + remove_ext_hdr(); + /* This should be copied from the ext header... */ + UIP_IP_BUF->proto = proto; + } + /* Inform the other end that the destination is not reachable. If it's + * not informed routes might get lost unexpectedly until there's a need + * to send a new packet to the peer */ + if(UIP_FALLBACK_INTERFACE.output() < 0) { + PRINTF("FALLBACK: output error. Reporting DST UNREACH\n"); + uip_icmp6_error_output(ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR, 0); + uip_flags = 0; + tcpip_ipv6_output(); + return; + } #else PRINTF("tcpip_ipv6_output: Destination off-link but no route\n"); #endif /* !UIP_FALLBACK_INTERFACE */ @@ -655,13 +655,13 @@ tcpip_ipv6_output(void) uip_packetqueue_set_buflen(&nbr->packethandle, uip_len); } #endif - /* RFC4861, 7.2.2: - * "If the source address of the packet prompting the solicitation is the - * same as one of the addresses assigned to the outgoing interface, that - * address SHOULD be placed in the IP Source Address of the outgoing - * solicitation. Otherwise, any one of the addresses assigned to the - * interface should be used."*/ - if(uip_ds6_is_my_addr(&UIP_IP_BUF->srcipaddr)){ + /* RFC4861, 7.2.2: + * "If the source address of the packet prompting the solicitation is the + * same as one of the addresses assigned to the outgoing interface, that + * address SHOULD be placed in the IP Source Address of the outgoing + * solicitation. Otherwise, any one of the addresses assigned to the + * interface should be used."*/ + if(uip_ds6_is_my_addr(&UIP_IP_BUF->srcipaddr)){ uip_nd6_ns_output(&UIP_IP_BUF->srcipaddr, NULL, &nbr->ipaddr); } else { uip_nd6_ns_output(NULL, NULL, &nbr->ipaddr); @@ -747,7 +747,7 @@ void tcpip_uipcall(void) { uip_udp_appstate_t *ts; - + #if UIP_UDP if(uip_conn != NULL) { ts = &uip_conn->appstate; @@ -759,30 +759,30 @@ tcpip_uipcall(void) #endif /* UIP_UDP */ #if UIP_TCP - { - unsigned char i; - struct listenport *l; + { + unsigned char i; + struct listenport *l; - /* If this is a connection request for a listening port, we must + /* If this is a connection request for a listening port, we must mark the connection with the right process ID. */ - if(uip_connected()) { - l = &s.listenports[0]; - for(i = 0; i < UIP_LISTENPORTS; ++i) { - if(l->port == uip_conn->lport && - l->p != PROCESS_NONE) { - ts->p = l->p; - ts->state = NULL; - break; - } - ++l; - } - - /* Start the periodic polling, if it isn't already active. */ - start_periodic_tcp_timer(); - } - } + if(uip_connected()) { + l = &s.listenports[0]; + for(i = 0; i < UIP_LISTENPORTS; ++i) { + if(l->port == uip_conn->lport && + l->p != PROCESS_NONE) { + ts->p = l->p; + ts->state = NULL; + break; + } + ++l; + } + + /* Start the periodic polling, if it isn't already active. */ + start_periodic_tcp_timer(); + } + } #endif /* UIP_TCP */ - + if(ts->p != NULL) { process_post_synch(ts->p, tcpip_event, ts->state); } @@ -793,14 +793,14 @@ PROCESS_THREAD(tcpip_process, ev, data) PROCESS_BEGIN(); #if UIP_TCP - { - unsigned char i; + { + unsigned char i; - for(i = 0; i < UIP_LISTENPORTS; ++i) { - s.listenports[i].port = 0; - } - s.p = PROCESS_CURRENT(); - } + for(i = 0; i < UIP_LISTENPORTS; ++i) { + s.listenports[i].port = 0; + } + s.p = PROCESS_CURRENT(); + } #endif tcpip_event = process_alloc_event(); @@ -813,7 +813,7 @@ PROCESS_THREAD(tcpip_process, ev, data) #ifdef UIP_FALLBACK_INTERFACE UIP_FALLBACK_INTERFACE.init(); #endif -/* initialize RPL if configured for using RPL */ + /* initialize RPL if configured for using RPL */ #if NETSTACK_CONF_WITH_IPV6 && UIP_CONF_IPV6_RPL rpl_init(); #endif /* UIP_CONF_IPV6_RPL */ @@ -822,7 +822,7 @@ PROCESS_THREAD(tcpip_process, ev, data) PROCESS_YIELD(); eventhandler(ev, data); } - + PROCESS_END(); } /*---------------------------------------------------------------------------*/ From f0f13fa58b3423164848a6d681db9bddcd4a330a Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 22 Apr 2016 21:44:24 +0200 Subject: [PATCH 194/374] Indent uip6.c --- core/net/ipv6/uip6.c | 888 +++++++++++++++++++++---------------------- 1 file changed, 444 insertions(+), 444 deletions(-) diff --git a/core/net/ipv6/uip6.c b/core/net/ipv6/uip6.c index 7e9ab0016..a8caee054 100644 --- a/core/net/ipv6/uip6.c +++ b/core/net/ipv6/uip6.c @@ -468,7 +468,7 @@ uip_connect(const uip_ipaddr_t *ripaddr, uint16_t rport) register struct uip_conn *conn, *cconn; /* Find an unused local port. */ - again: + again: ++lastport; if(lastport >= 32000) { @@ -563,7 +563,7 @@ uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport) register struct uip_udp_conn *conn; /* Find an unused local port. */ - again: + again: ++lastport; if(lastport >= 32000) { @@ -787,7 +787,7 @@ uip_reass(void) return 0; } - /* If we have come this far, we have a full packet in the + /* If we have come this far, we have a full packet in the buffer, so we copy it to uip_buf. We also reset the timer. */ uip_reass_on = 0; etimer_stop(&uip_reass_timer); @@ -811,7 +811,7 @@ uip_reass(void) void uip_reass_over(void) { - /* to late, we abandon the reassembly of the packet */ + /* to late, we abandon the reassembly of the packet */ uip_reass_on = 0; etimer_stop(&uip_reass_timer); @@ -859,77 +859,77 @@ uip_add_rcv_nxt(uint16_t n) static uint8_t ext_hdr_options_process(void) { - /* - * Length field in the extension header: length of the header in units of - * 8 bytes, excluding the first 8 bytes - * length field in an option : the length of data in the option - */ + /* + * Length field in the extension header: length of the header in units of + * 8 bytes, excluding the first 8 bytes + * length field in an option : the length of data in the option + */ uip_ext_opt_offset = 2; while(uip_ext_opt_offset < ((UIP_EXT_BUF->len << 3) + 8)) { switch(UIP_EXT_HDR_OPT_BUF->type) { - /* - * for now we do not support any options except padding ones - * PAD1 does not make sense as the header must be 8bytes aligned, - * hence we can only have + /* + * for now we do not support any options except padding ones + * PAD1 does not make sense as the header must be 8bytes aligned, + * hence we can only have + */ + case UIP_EXT_HDR_OPT_PAD1: + PRINTF("Processing PAD1 option\n"); + uip_ext_opt_offset += 1; + break; + case UIP_EXT_HDR_OPT_PADN: + PRINTF("Processing PADN option\n"); + uip_ext_opt_offset += UIP_EXT_HDR_OPT_PADN_BUF->opt_len + 2; + break; + case UIP_EXT_HDR_OPT_RPL: + /* Fixes situation when a node that is not using RPL + * joins a network which does. The received packages will include the + * RPL header and processed by the "default" case of the switch + * (0x63 & 0xC0 = 0x40). Hence, the packet is discarded as the header + * is considered invalid. + * Using this fix, the header is ignored, and the next header (if + * present) is processed. */ - case UIP_EXT_HDR_OPT_PAD1: - PRINTF("Processing PAD1 option\n"); - uip_ext_opt_offset += 1; - break; - case UIP_EXT_HDR_OPT_PADN: - PRINTF("Processing PADN option\n"); - uip_ext_opt_offset += UIP_EXT_HDR_OPT_PADN_BUF->opt_len + 2; - break; - case UIP_EXT_HDR_OPT_RPL: - /* Fixes situation when a node that is not using RPL - * joins a network which does. The received packages will include the - * RPL header and processed by the "default" case of the switch - * (0x63 & 0xC0 = 0x40). Hence, the packet is discarded as the header - * is considered invalid. - * Using this fix, the header is ignored, and the next header (if - * present) is processed. - */ #if UIP_CONF_IPV6_RPL - PRINTF("Processing RPL option\n"); - if(rpl_verify_header(uip_ext_opt_offset)) { - PRINTF("RPL Option Error: Dropping Packet\n"); + PRINTF("Processing RPL option\n"); + if(rpl_verify_header(uip_ext_opt_offset)) { + PRINTF("RPL Option Error: Dropping Packet\n"); + return 1; + } +#endif /* UIP_CONF_IPV6_RPL */ + uip_ext_opt_offset += (UIP_EXT_HDR_OPT_BUF->len) + 2; + return 0; + default: + /* + * check the two highest order bits of the option + * - 00 skip over this option and continue processing the header. + * - 01 discard the packet. + * - 10 discard the packet and, regardless of whether or not the + * packet's Destination Address was a multicast address, send an + * ICMP Parameter Problem, Code 2, message to the packet's + * Source Address, pointing to the unrecognized Option Type. + * - 11 discard the packet and, only if the packet's Destination + * Address was not a multicast address, send an ICMP Parameter + * Problem, Code 2, message to the packet's Source Address, + * pointing to the unrecognized Option Type. + */ + PRINTF("MSB %x\n", UIP_EXT_HDR_OPT_BUF->type); + switch(UIP_EXT_HDR_OPT_BUF->type & 0xC0) { + case 0: + break; + case 0x40: + return 1; + case 0xC0: + if(uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) { return 1; } -#endif /* UIP_CONF_IPV6_RPL */ - uip_ext_opt_offset += (UIP_EXT_HDR_OPT_BUF->len) + 2; - return 0; - default: - /* - * check the two highest order bits of the option - * - 00 skip over this option and continue processing the header. - * - 01 discard the packet. - * - 10 discard the packet and, regardless of whether or not the - * packet's Destination Address was a multicast address, send an - * ICMP Parameter Problem, Code 2, message to the packet's - * Source Address, pointing to the unrecognized Option Type. - * - 11 discard the packet and, only if the packet's Destination - * Address was not a multicast address, send an ICMP Parameter - * Problem, Code 2, message to the packet's Source Address, - * pointing to the unrecognized Option Type. - */ - PRINTF("MSB %x\n", UIP_EXT_HDR_OPT_BUF->type); - switch(UIP_EXT_HDR_OPT_BUF->type & 0xC0) { - case 0: - break; - case 0x40: - return 1; - case 0xC0: - if(uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) { - return 1; - } - case 0x80: - uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, - (uint32_t)UIP_IPH_LEN + uip_ext_len + uip_ext_opt_offset); - return 2; - } - /* in the cases were we did not discard, update ext_opt* */ - uip_ext_opt_offset += UIP_EXT_HDR_OPT_BUF->len + 2; - break; + case 0x80: + uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, + (uint32_t)UIP_IPH_LEN + uip_ext_len + uip_ext_opt_offset); + return 2; + } + /* in the cases were we did not discard, update ext_opt* */ + uip_ext_opt_offset += UIP_EXT_HDR_OPT_BUF->len + 2; + break; } } return 0; @@ -1039,33 +1039,33 @@ uip_process(uint8_t flag) */ UIP_STAT(++uip_stat.tcp.rexmit); switch(uip_connr->tcpstateflags & UIP_TS_MASK) { - case UIP_SYN_RCVD: - /* In the SYN_RCVD state, we should retransmit our SYNACK. */ - goto tcp_send_synack; + case UIP_SYN_RCVD: + /* In the SYN_RCVD state, we should retransmit our SYNACK. */ + goto tcp_send_synack; #if UIP_ACTIVE_OPEN - case UIP_SYN_SENT: - /* In the SYN_SENT state, we retransmit out SYN. */ - UIP_TCP_BUF->flags = 0; - goto tcp_send_syn; + case UIP_SYN_SENT: + /* In the SYN_SENT state, we retransmit out SYN. */ + UIP_TCP_BUF->flags = 0; + goto tcp_send_syn; #endif /* UIP_ACTIVE_OPEN */ - case UIP_ESTABLISHED: - /* - * In the ESTABLISHED state, we call upon the application - * to do the actual retransmit after which we jump into - * the code for sending out the packet (the apprexmit - * label). - */ - uip_flags = UIP_REXMIT; - UIP_APPCALL(); - goto apprexmit; + case UIP_ESTABLISHED: + /* + * In the ESTABLISHED state, we call upon the application + * to do the actual retransmit after which we jump into + * the code for sending out the packet (the apprexmit + * label). + */ + uip_flags = UIP_REXMIT; + UIP_APPCALL(); + goto apprexmit; - case UIP_FIN_WAIT_1: - case UIP_CLOSING: - case UIP_LAST_ACK: - /* In all these states we should retransmit a FINACK. */ - goto tcp_send_finack; + case UIP_FIN_WAIT_1: + case UIP_CLOSING: + case UIP_LAST_ACK: + /* In all these states we should retransmit a FINACK. */ + goto tcp_send_finack; } } } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) { @@ -1162,20 +1162,20 @@ uip_process(uint8_t flag) uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_HBHO; #endif /* UIP_CONF_IPV6_CHECKS */ switch(ext_hdr_options_process()) { - case 0: - /* continue */ - uip_next_hdr = &UIP_EXT_BUF->next; - uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; - break; - case 1: - PRINTF("Dropping packet after extension header processing\n"); - /* silently discard */ - goto drop; - case 2: - PRINTF("Sending error message after extension header processing\n"); - /* send icmp error message (created in ext_hdr_options_process) - * and discard*/ - goto send; + case 0: + /* continue */ + uip_next_hdr = &UIP_EXT_BUF->next; + uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; + break; + case 1: + PRINTF("Dropping packet after extension header processing\n"); + /* silently discard */ + goto drop; + case 2: + PRINTF("Sending error message after extension header processing\n"); + /* send icmp error message (created in ext_hdr_options_process) + * and discard*/ + goto send; } } @@ -1281,44 +1281,44 @@ uip_process(uint8_t flag) while(1) { switch(*uip_next_hdr){ #if UIP_TCP - case UIP_PROTO_TCP: - /* TCP, for both IPv4 and IPv6 */ - goto tcp_input; + case UIP_PROTO_TCP: + /* TCP, for both IPv4 and IPv6 */ + goto tcp_input; #endif /* UIP_TCP */ #if UIP_UDP - case UIP_PROTO_UDP: - /* UDP, for both IPv4 and IPv6 */ - goto udp_input; + case UIP_PROTO_UDP: + /* UDP, for both IPv4 and IPv6 */ + goto udp_input; #endif /* UIP_UDP */ - case UIP_PROTO_ICMP6: - /* ICMPv6 */ - goto icmp6_input; - case UIP_PROTO_HBHO: - PRINTF("Processing hbh header\n"); - /* Hop by hop option header */ + case UIP_PROTO_ICMP6: + /* ICMPv6 */ + goto icmp6_input; + case UIP_PROTO_HBHO: + PRINTF("Processing hbh header\n"); + /* Hop by hop option header */ #if UIP_CONF_IPV6_CHECKS - /* Hop by hop option header. If we saw one HBH already, drop */ - if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_HBHO) { - goto bad_hdr; - } else { - uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_HBHO; - } + /* Hop by hop option header. If we saw one HBH already, drop */ + if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_HBHO) { + goto bad_hdr; + } else { + uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_HBHO; + } #endif /*UIP_CONF_IPV6_CHECKS*/ - switch(ext_hdr_options_process()) { - case 0: - /*continue*/ - uip_next_hdr = &UIP_EXT_BUF->next; - uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; - break; - case 1: - /*silently discard*/ - goto drop; - case 2: - /* send icmp error message (created in ext_hdr_options_process) - * and discard*/ - goto send; - } + switch(ext_hdr_options_process()) { + case 0: + /*continue*/ + uip_next_hdr = &UIP_EXT_BUF->next; + uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; break; + case 1: + /*silently discard*/ + goto drop; + case 2: + /* send icmp error message (created in ext_hdr_options_process) + * and discard*/ + goto send; + } + break; case UIP_PROTO_DESTO: #if UIP_CONF_IPV6_CHECKS /* Destination option header. if we saw two already, drop */ @@ -1334,76 +1334,76 @@ uip_process(uint8_t flag) } #endif /*UIP_CONF_IPV6_CHECKS*/ switch(ext_hdr_options_process()) { - case 0: - /*continue*/ - uip_next_hdr = &UIP_EXT_BUF->next; - uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; - break; - case 1: - /*silently discard*/ - goto drop; - case 2: - /* send icmp error message (created in ext_hdr_options_process) - * and discard*/ - goto send; - } - break; - case UIP_PROTO_ROUTING: -#if UIP_CONF_IPV6_CHECKS - /* Routing header. If we saw one already, drop */ - if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_ROUTING) { - goto bad_hdr; - } else { - uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_ROUTING; - } -#endif /*UIP_CONF_IPV6_CHECKS*/ - /* - * Routing Header length field is in units of 8 bytes, excluding - * As per RFC2460 section 4.4, if routing type is unrecognized: - * if segments left = 0, ignore the header - * if segments left > 0, discard packet and send icmp error pointing - * to the routing type - */ - - PRINTF("Processing Routing header\n"); - if(UIP_ROUTING_BUF->seg_left > 0) { - uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, UIP_IPH_LEN + uip_ext_len + 2); - UIP_STAT(++uip_stat.ip.drop); - UIP_LOG("ip6: unrecognized routing type"); - goto send; - } - uip_next_hdr = &UIP_EXT_BUF->next; - uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; - break; - case UIP_PROTO_FRAG: - /* Fragmentation header:call the reassembly function, then leave */ -#if UIP_CONF_IPV6_REASSEMBLY - PRINTF("Processing frag header\n"); - uip_len = uip_reass(); - if(uip_len == 0) { + case 0: + /*continue*/ + uip_next_hdr = &UIP_EXT_BUF->next; + uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; + break; + case 1: + /*silently discard*/ goto drop; - } - if(uip_reassflags & UIP_REASS_FLAG_ERROR_MSG){ - /* we are not done with reassembly, this is an error message */ + case 2: + /* send icmp error message (created in ext_hdr_options_process) + * and discard*/ goto send; } - /*packet is reassembled, reset the next hdr to the beginning - of the IP header and restart the parsing of the reassembled pkt*/ - PRINTF("Processing reassembled packet\n"); - uip_ext_len = 0; - uip_ext_bitmap = 0; - uip_next_hdr = &UIP_IP_BUF->proto; break; + case UIP_PROTO_ROUTING: +#if UIP_CONF_IPV6_CHECKS + /* Routing header. If we saw one already, drop */ + if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_ROUTING) { + goto bad_hdr; + } else { + uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_ROUTING; + } +#endif /*UIP_CONF_IPV6_CHECKS*/ + /* + * Routing Header length field is in units of 8 bytes, excluding + * As per RFC2460 section 4.4, if routing type is unrecognized: + * if segments left = 0, ignore the header + * if segments left > 0, discard packet and send icmp error pointing + * to the routing type + */ + + PRINTF("Processing Routing header\n"); + if(UIP_ROUTING_BUF->seg_left > 0) { + uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, UIP_IPH_LEN + uip_ext_len + 2); + UIP_STAT(++uip_stat.ip.drop); + UIP_LOG("ip6: unrecognized routing type"); + goto send; + } + uip_next_hdr = &UIP_EXT_BUF->next; + uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; + break; + case UIP_PROTO_FRAG: + /* Fragmentation header:call the reassembly function, then leave */ +#if UIP_CONF_IPV6_REASSEMBLY + PRINTF("Processing frag header\n"); + uip_len = uip_reass(); + if(uip_len == 0) { + goto drop; + } + if(uip_reassflags & UIP_REASS_FLAG_ERROR_MSG){ + /* we are not done with reassembly, this is an error message */ + goto send; + } + /*packet is reassembled, reset the next hdr to the beginning + of the IP header and restart the parsing of the reassembled pkt*/ + PRINTF("Processing reassembled packet\n"); + uip_ext_len = 0; + uip_ext_bitmap = 0; + uip_next_hdr = &UIP_IP_BUF->proto; + break; #else /* UIP_CONF_IPV6_REASSEMBLY */ - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.fragerr); - UIP_LOG("ip: fragment dropped."); - goto drop; + UIP_STAT(++uip_stat.ip.drop); + UIP_STAT(++uip_stat.ip.fragerr); + UIP_LOG("ip: fragment dropped."); + goto drop; #endif /* UIP_CONF_IPV6_REASSEMBLY */ - case UIP_PROTO_NONE: - goto drop; - default: - goto bad_hdr; + case UIP_PROTO_NONE: + goto drop; + default: + goto bad_hdr; } } bad_hdr: @@ -1470,7 +1470,7 @@ uip_process(uint8_t flag) #if UIP_UDP /* UDP input processing. */ - udp_input: + udp_input: remove_ext_hdr(); UIP_IP_BUF->proto = UIP_PROTO_UDP; @@ -1528,7 +1528,7 @@ uip_process(uint8_t flag) uip_icmp6_error_output(ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0); goto send; - udp_found: + udp_found: PRINTF("In udp_found\n"); UIP_STAT(++uip_stat.udp.recv); @@ -1540,7 +1540,7 @@ uip_process(uint8_t flag) uip_slen = 0; UIP_UDP_APPCALL(); - udp_send: + udp_send: PRINTF("In udp_send\n"); if(uip_slen == 0) { @@ -1585,7 +1585,7 @@ uip_process(uint8_t flag) #if UIP_TCP /* TCP input processing. */ - tcp_input: + tcp_input: remove_ext_hdr(); UIP_IP_BUF->proto = UIP_PROTO_TCP; @@ -1640,7 +1640,7 @@ uip_process(uint8_t flag) /* No matching connection found, so we send a RST packet. */ UIP_STAT(++uip_stat.tcp.synrst); - reset: + reset: PRINTF("In reset\n"); /* We do not send resets in response to resets. */ if(UIP_TCP_BUF->flags & TCP_RST) { @@ -1695,7 +1695,7 @@ uip_process(uint8_t flag) /* This label will be jumped to if we matched the incoming packet with a connection in LISTEN. In that case, we should create a new connection and send a SYNACK in return. */ - found_listen: + found_listen: PRINTF("In found listen\n"); /* First we check if there are any connections avaliable. Unused connections are kept in the same table as used connections, but @@ -1785,13 +1785,13 @@ uip_process(uint8_t flag) /* Our response will be a SYNACK. */ #if UIP_ACTIVE_OPEN - tcp_send_synack: + tcp_send_synack: UIP_TCP_BUF->flags = TCP_ACK; - tcp_send_syn: + tcp_send_syn: UIP_TCP_BUF->flags |= TCP_SYN; #else /* UIP_ACTIVE_OPEN */ - tcp_send_synack: + tcp_send_synack: UIP_TCP_BUF->flags = TCP_SYN | TCP_ACK; #endif /* UIP_ACTIVE_OPEN */ @@ -1806,7 +1806,7 @@ uip_process(uint8_t flag) goto tcp_send; /* This label will be jumped to if we found an active connection. */ - found: + found: PRINTF("In found\n"); uip_conn = uip_connr; uip_flags = 0; @@ -1900,96 +1900,96 @@ uip_process(uint8_t flag) /* Do different things depending on in what state the connection is. */ switch(uip_connr->tcpstateflags & UIP_TS_MASK) { - /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not + /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not implemented, since we force the application to close when the peer sends a FIN (hence the application goes directly from ESTABLISHED to LAST_ACK). */ - case UIP_SYN_RCVD: - /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and + case UIP_SYN_RCVD: + /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and we are waiting for an ACK that acknowledges the data we sent out the last time. Therefore, we want to have the UIP_ACKDATA flag set. If so, we enter the ESTABLISHED state. */ - if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_ESTABLISHED; - uip_flags = UIP_CONNECTED; - uip_connr->len = 0; - if(uip_len > 0) { - uip_flags |= UIP_NEWDATA; - uip_add_rcv_nxt(uip_len); - } - uip_slen = 0; - UIP_APPCALL(); - goto appsend; + if(uip_flags & UIP_ACKDATA) { + uip_connr->tcpstateflags = UIP_ESTABLISHED; + uip_flags = UIP_CONNECTED; + uip_connr->len = 0; + if(uip_len > 0) { + uip_flags |= UIP_NEWDATA; + uip_add_rcv_nxt(uip_len); } - /* We need to retransmit the SYNACK */ - if((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN) { - goto tcp_send_synack; - } - goto drop; + uip_slen = 0; + UIP_APPCALL(); + goto appsend; + } + /* We need to retransmit the SYNACK */ + if((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN) { + goto tcp_send_synack; + } + goto drop; #if UIP_ACTIVE_OPEN - case UIP_SYN_SENT: - /* In SYN_SENT, we wait for a SYNACK that is sent in response to + case UIP_SYN_SENT: + /* In SYN_SENT, we wait for a SYNACK that is sent in response to our SYN. The rcv_nxt is set to sequence number in the SYNACK plus one, and we send an ACK. We move into the ESTABLISHED state. */ - if((uip_flags & UIP_ACKDATA) && - (UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) { + if((uip_flags & UIP_ACKDATA) && + (UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) { - /* Parse the TCP MSS option, if present. */ - if((UIP_TCP_BUF->tcpoffset & 0xf0) > 0x50) { - for(c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) { - opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c]; - if(opt == TCP_OPT_END) { - /* End of options. */ - break; - } else if(opt == TCP_OPT_NOOP) { - ++c; - /* NOP option. */ - } else if(opt == TCP_OPT_MSS && - uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) { - /* An MSS option with the right option length. */ - tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | + /* Parse the TCP MSS option, if present. */ + if((UIP_TCP_BUF->tcpoffset & 0xf0) > 0x50) { + for(c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) { + opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c]; + if(opt == TCP_OPT_END) { + /* End of options. */ + break; + } else if(opt == TCP_OPT_NOOP) { + ++c; + /* NOP option. */ + } else if(opt == TCP_OPT_MSS && + uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) { + /* An MSS option with the right option length. */ + tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c]; - uip_connr->initialmss = + uip_connr->initialmss = uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16; - /* And we are done processing options. */ - break; - } else { - /* All other options have a length field, so that we easily + /* And we are done processing options. */ + break; + } else { + /* All other options have a length field, so that we easily can skip past them. */ - if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) { - /* If the length field is zero, the options are malformed + if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) { + /* If the length field is zero, the options are malformed and we don't process them further. */ - break; - } - c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c]; + break; } + c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c]; } } - uip_connr->tcpstateflags = UIP_ESTABLISHED; - uip_connr->rcv_nxt[0] = UIP_TCP_BUF->seqno[0]; - uip_connr->rcv_nxt[1] = UIP_TCP_BUF->seqno[1]; - uip_connr->rcv_nxt[2] = UIP_TCP_BUF->seqno[2]; - uip_connr->rcv_nxt[3] = UIP_TCP_BUF->seqno[3]; - uip_add_rcv_nxt(1); - uip_flags = UIP_CONNECTED | UIP_NEWDATA; - uip_connr->len = 0; - uip_clear_buf(); - uip_slen = 0; - UIP_APPCALL(); - goto appsend; } - /* Inform the application that the connection failed */ - uip_flags = UIP_ABORT; + uip_connr->tcpstateflags = UIP_ESTABLISHED; + uip_connr->rcv_nxt[0] = UIP_TCP_BUF->seqno[0]; + uip_connr->rcv_nxt[1] = UIP_TCP_BUF->seqno[1]; + uip_connr->rcv_nxt[2] = UIP_TCP_BUF->seqno[2]; + uip_connr->rcv_nxt[3] = UIP_TCP_BUF->seqno[3]; + uip_add_rcv_nxt(1); + uip_flags = UIP_CONNECTED | UIP_NEWDATA; + uip_connr->len = 0; + uip_clear_buf(); + uip_slen = 0; UIP_APPCALL(); - /* The connection is closed after we send the RST */ - uip_conn->tcpstateflags = UIP_CLOSED; - goto reset; + goto appsend; + } + /* Inform the application that the connection failed */ + uip_flags = UIP_ABORT; + UIP_APPCALL(); + /* The connection is closed after we send the RST */ + uip_conn->tcpstateflags = UIP_CLOSED; + goto reset; #endif /* UIP_ACTIVE_OPEN */ - case UIP_ESTABLISHED: - /* In the ESTABLISHED state, we call upon the application to feed + case UIP_ESTABLISHED: + /* In the ESTABLISHED state, we call upon the application to feed data into the uip_buf. If the UIP_ACKDATA flag is set, the application should put new data into the buffer, otherwise we are retransmitting an old segment, and the application should put that @@ -2000,56 +2000,56 @@ uip_process(uint8_t flag) state. We require that there is no outstanding data; otherwise the sequence numbers will be screwed up. */ - if(UIP_TCP_BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) { - if(uip_outstanding(uip_connr)) { - goto drop; - } - uip_add_rcv_nxt(1 + uip_len); - uip_flags |= UIP_CLOSE; - if(uip_len > 0) { - uip_flags |= UIP_NEWDATA; - } - UIP_APPCALL(); - uip_connr->len = 1; - uip_connr->tcpstateflags = UIP_LAST_ACK; - uip_connr->nrtx = 0; + if(UIP_TCP_BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) { + if(uip_outstanding(uip_connr)) { + goto drop; + } + uip_add_rcv_nxt(1 + uip_len); + uip_flags |= UIP_CLOSE; + if(uip_len > 0) { + uip_flags |= UIP_NEWDATA; + } + UIP_APPCALL(); + uip_connr->len = 1; + uip_connr->tcpstateflags = UIP_LAST_ACK; + uip_connr->nrtx = 0; tcp_send_finack: - UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK; - goto tcp_send_nodata; - } + UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK; + goto tcp_send_nodata; + } - /* Check the URG flag. If this is set, the segment carries urgent + /* Check the URG flag. If this is set, the segment carries urgent data that we must pass to the application. */ - if((UIP_TCP_BUF->flags & TCP_URG) != 0) { + if((UIP_TCP_BUF->flags & TCP_URG) != 0) { #if UIP_URGDATA > 0 - uip_urglen = (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1]; - if(uip_urglen > uip_len) { - /* There is more urgent data in the next segment to come. */ - uip_urglen = uip_len; - } - uip_add_rcv_nxt(uip_urglen); - uip_len -= uip_urglen; - uip_urgdata = uip_appdata; - uip_appdata += uip_urglen; - } else { - uip_urglen = 0; -#else /* UIP_URGDATA > 0 */ - uip_appdata = ((char *)uip_appdata) + ((UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1]); - uip_len -= (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1]; -#endif /* UIP_URGDATA > 0 */ + uip_urglen = (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1]; + if(uip_urglen > uip_len) { + /* There is more urgent data in the next segment to come. */ + uip_urglen = uip_len; } + uip_add_rcv_nxt(uip_urglen); + uip_len -= uip_urglen; + uip_urgdata = uip_appdata; + uip_appdata += uip_urglen; + } else { + uip_urglen = 0; +#else /* UIP_URGDATA > 0 */ + uip_appdata = ((char *)uip_appdata) + ((UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1]); + uip_len -= (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1]; +#endif /* UIP_URGDATA > 0 */ + } - /* If uip_len > 0 we have TCP data in the packet, and we flag this + /* If uip_len > 0 we have TCP data in the packet, and we flag this by setting the UIP_NEWDATA flag and update the sequence number we acknowledge. If the application has stopped the dataflow using uip_stop(), we must not accept any data packets from the remote host. */ - if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) { - uip_flags |= UIP_NEWDATA; - uip_add_rcv_nxt(uip_len); - } + if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) { + uip_flags |= UIP_NEWDATA; + uip_add_rcv_nxt(uip_len); + } - /* Check if the available buffer space advertised by the other end + /* Check if the available buffer space advertised by the other end is smaller than the initial MSS for this connection. If so, we set the current MSS to the window size to ensure that the application does not send more data than the other end can @@ -2060,15 +2060,15 @@ uip_process(uint8_t flag) of data. This data will not be acknowledged by the receiver, and the application will retransmit it. This is called the "persistent timer" and uses the retransmission mechanim. - */ - tmp16 = ((uint16_t)UIP_TCP_BUF->wnd[0] << 8) + (uint16_t)UIP_TCP_BUF->wnd[1]; - if(tmp16 > uip_connr->initialmss || - tmp16 == 0) { - tmp16 = uip_connr->initialmss; - } - uip_connr->mss = tmp16; + */ + tmp16 = ((uint16_t)UIP_TCP_BUF->wnd[0] << 8) + (uint16_t)UIP_TCP_BUF->wnd[1]; + if(tmp16 > uip_connr->initialmss || + tmp16 == 0) { + tmp16 = uip_connr->initialmss; + } + uip_connr->mss = tmp16; - /* If this packet constitutes an ACK for outstanding data (flagged + /* If this packet constitutes an ACK for outstanding data (flagged by the UIP_ACKDATA flag, we should call the application since it might want to send more data. If the incoming packet had data from the peer (as flagged by the UIP_NEWDATA flag), the @@ -2084,166 +2084,166 @@ uip_process(uint8_t flag) put into the uip_appdata and the length of the data should be put into uip_len. If the application don't have any data to send, uip_len must be set to 0. */ - if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) { - uip_slen = 0; - UIP_APPCALL(); + if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) { + uip_slen = 0; + UIP_APPCALL(); appsend: - if(uip_flags & UIP_ABORT) { - uip_slen = 0; - uip_connr->tcpstateflags = UIP_CLOSED; - UIP_TCP_BUF->flags = TCP_RST | TCP_ACK; - goto tcp_send_nodata; - } + if(uip_flags & UIP_ABORT) { + uip_slen = 0; + uip_connr->tcpstateflags = UIP_CLOSED; + UIP_TCP_BUF->flags = TCP_RST | TCP_ACK; + goto tcp_send_nodata; + } - if(uip_flags & UIP_CLOSE) { - uip_slen = 0; - uip_connr->len = 1; - uip_connr->tcpstateflags = UIP_FIN_WAIT_1; - uip_connr->nrtx = 0; - UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK; - goto tcp_send_nodata; - } + if(uip_flags & UIP_CLOSE) { + uip_slen = 0; + uip_connr->len = 1; + uip_connr->tcpstateflags = UIP_FIN_WAIT_1; + uip_connr->nrtx = 0; + UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK; + goto tcp_send_nodata; + } - /* If uip_slen > 0, the application has data to be sent. */ - if(uip_slen > 0) { + /* If uip_slen > 0, the application has data to be sent. */ + if(uip_slen > 0) { - /* If the connection has acknowledged data, the contents of + /* If the connection has acknowledged data, the contents of the ->len variable should be discarded. */ - if((uip_flags & UIP_ACKDATA) != 0) { - uip_connr->len = 0; - } + if((uip_flags & UIP_ACKDATA) != 0) { + uip_connr->len = 0; + } - /* If the ->len variable is non-zero the connection has + /* If the ->len variable is non-zero the connection has already data in transit and cannot send anymore right now. */ - if(uip_connr->len == 0) { + if(uip_connr->len == 0) { - /* The application cannot send more than what is allowed by + /* The application cannot send more than what is allowed by the mss (the minumum of the MSS and the available window). */ - if(uip_slen > uip_connr->mss) { - uip_slen = uip_connr->mss; - } + if(uip_slen > uip_connr->mss) { + uip_slen = uip_connr->mss; + } - /* Remember how much data we send out now so that we know + /* Remember how much data we send out now so that we know when everything has been acknowledged. */ - uip_connr->len = uip_slen; - } else { + uip_connr->len = uip_slen; + } else { - /* If the application already had unacknowledged data, we + /* If the application already had unacknowledged data, we make sure that the application does not send (i.e., retransmit) out more than it previously sent out. */ - uip_slen = uip_connr->len; - } + uip_slen = uip_connr->len; } - uip_connr->nrtx = 0; + } + uip_connr->nrtx = 0; apprexmit: - uip_appdata = uip_sappdata; + uip_appdata = uip_sappdata; - /* If the application has data to be sent, or if the incoming + /* If the application has data to be sent, or if the incoming packet had new data in it, we must send out a packet. */ - if(uip_slen > 0 && uip_connr->len > 0) { - /* Add the length of the IP and TCP headers. */ - uip_len = uip_connr->len + UIP_TCPIP_HLEN; - /* We always set the ACK flag in response packets. */ - UIP_TCP_BUF->flags = TCP_ACK | TCP_PSH; - /* Send the packet. */ - goto tcp_send_noopts; - } - /* If there is no data to send, just send out a pure ACK if + if(uip_slen > 0 && uip_connr->len > 0) { + /* Add the length of the IP and TCP headers. */ + uip_len = uip_connr->len + UIP_TCPIP_HLEN; + /* We always set the ACK flag in response packets. */ + UIP_TCP_BUF->flags = TCP_ACK | TCP_PSH; + /* Send the packet. */ + goto tcp_send_noopts; + } + /* If there is no data to send, just send out a pure ACK if there is newdata. */ - if(uip_flags & UIP_NEWDATA) { - uip_len = UIP_TCPIP_HLEN; - UIP_TCP_BUF->flags = TCP_ACK; - goto tcp_send_noopts; - } + if(uip_flags & UIP_NEWDATA) { + uip_len = UIP_TCPIP_HLEN; + UIP_TCP_BUF->flags = TCP_ACK; + goto tcp_send_noopts; } - goto drop; - case UIP_LAST_ACK: - /* We can close this connection if the peer has acknowledged our + } + goto drop; + case UIP_LAST_ACK: + /* We can close this connection if the peer has acknowledged our FIN. This is indicated by the UIP_ACKDATA flag. */ - if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_CLOSED; - uip_flags = UIP_CLOSE; - UIP_APPCALL(); - } - break; + if(uip_flags & UIP_ACKDATA) { + uip_connr->tcpstateflags = UIP_CLOSED; + uip_flags = UIP_CLOSE; + UIP_APPCALL(); + } + break; - case UIP_FIN_WAIT_1: - /* The application has closed the connection, but the remote host + case UIP_FIN_WAIT_1: + /* The application has closed the connection, but the remote host hasn't closed its end yet. Thus we do nothing but wait for a FIN from the other side. */ - if(uip_len > 0) { - uip_add_rcv_nxt(uip_len); - } - if(UIP_TCP_BUF->flags & TCP_FIN) { - if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_TIME_WAIT; - uip_connr->timer = 0; - uip_connr->len = 0; - } else { - uip_connr->tcpstateflags = UIP_CLOSING; - } - uip_add_rcv_nxt(1); - uip_flags = UIP_CLOSE; - UIP_APPCALL(); - goto tcp_send_ack; - } else if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_FIN_WAIT_2; - uip_connr->len = 0; - goto drop; - } - if(uip_len > 0) { - goto tcp_send_ack; - } - goto drop; - - case UIP_FIN_WAIT_2: - if(uip_len > 0) { - uip_add_rcv_nxt(uip_len); - } - if(UIP_TCP_BUF->flags & TCP_FIN) { - uip_connr->tcpstateflags = UIP_TIME_WAIT; - uip_connr->timer = 0; - uip_add_rcv_nxt(1); - uip_flags = UIP_CLOSE; - UIP_APPCALL(); - goto tcp_send_ack; - } - if(uip_len > 0) { - goto tcp_send_ack; - } - goto drop; - - case UIP_TIME_WAIT: - goto tcp_send_ack; - - case UIP_CLOSING: + if(uip_len > 0) { + uip_add_rcv_nxt(uip_len); + } + if(UIP_TCP_BUF->flags & TCP_FIN) { if(uip_flags & UIP_ACKDATA) { uip_connr->tcpstateflags = UIP_TIME_WAIT; uip_connr->timer = 0; + uip_connr->len = 0; + } else { + uip_connr->tcpstateflags = UIP_CLOSING; } + uip_add_rcv_nxt(1); + uip_flags = UIP_CLOSE; + UIP_APPCALL(); + goto tcp_send_ack; + } else if(uip_flags & UIP_ACKDATA) { + uip_connr->tcpstateflags = UIP_FIN_WAIT_2; + uip_connr->len = 0; + goto drop; + } + if(uip_len > 0) { + goto tcp_send_ack; + } + goto drop; + + case UIP_FIN_WAIT_2: + if(uip_len > 0) { + uip_add_rcv_nxt(uip_len); + } + if(UIP_TCP_BUF->flags & TCP_FIN) { + uip_connr->tcpstateflags = UIP_TIME_WAIT; + uip_connr->timer = 0; + uip_add_rcv_nxt(1); + uip_flags = UIP_CLOSE; + UIP_APPCALL(); + goto tcp_send_ack; + } + if(uip_len > 0) { + goto tcp_send_ack; + } + goto drop; + + case UIP_TIME_WAIT: + goto tcp_send_ack; + + case UIP_CLOSING: + if(uip_flags & UIP_ACKDATA) { + uip_connr->tcpstateflags = UIP_TIME_WAIT; + uip_connr->timer = 0; + } } goto drop; /* We jump here when we are ready to send the packet, and just want to set the appropriate TCP sequence numbers in the TCP header. */ - tcp_send_ack: + tcp_send_ack: UIP_TCP_BUF->flags = TCP_ACK; - tcp_send_nodata: + tcp_send_nodata: uip_len = UIP_IPTCPH_LEN; - tcp_send_noopts: + tcp_send_noopts: UIP_TCP_BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4; /* We're done with the input processing. We are now ready to send a reply. Our job is to fill in all the fields of the TCP and IP headers before calculating the checksum and finally send the packet. */ - tcp_send: + tcp_send: PRINTF("In tcp_send\n"); UIP_TCP_BUF->ackno[0] = uip_connr->rcv_nxt[0]; @@ -2276,7 +2276,7 @@ uip_process(uint8_t flag) UIP_TCP_BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff); } - tcp_send_noconn: + tcp_send_noconn: UIP_IP_BUF->proto = UIP_PROTO_TCP; UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit; @@ -2292,21 +2292,21 @@ uip_process(uint8_t flag) #endif /* UIP_TCP */ #if UIP_UDP - ip_send_nolen: + ip_send_nolen: #endif UIP_IP_BUF->vtc = 0x60; UIP_IP_BUF->tcflow = 0x00; UIP_IP_BUF->flow = 0x00; - send: + send: PRINTF("Sending packet with length %d (%d)\n", uip_len, - (UIP_IP_BUF->len[0] << 8) | UIP_IP_BUF->len[1]); + (UIP_IP_BUF->len[0] << 8) | UIP_IP_BUF->len[1]); UIP_STAT(++uip_stat.ip.sent); /* Return and let the caller do the actual transmission. */ uip_flags = 0; return; - drop: + drop: uip_clear_buf(); uip_ext_bitmap = 0; uip_flags = 0; @@ -2332,8 +2332,8 @@ uip_send(const void *data, int len) if(uip_sappdata != NULL) { copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN - - (int)((char *)uip_sappdata - - (char *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN])); + (int)((char *)uip_sappdata - + (char *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN])); } else { copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN); } @@ -2342,7 +2342,7 @@ uip_send(const void *data, int len) if(data != uip_sappdata) { if(uip_sappdata == NULL) { memcpy((char *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN], - (data), uip_slen); + (data), uip_slen); } else { memcpy(uip_sappdata, (data), uip_slen); } From e1ea4955c71d61293cd80aeed768ba5e307e8f59 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Sat, 23 Apr 2016 00:28:07 +0200 Subject: [PATCH 195/374] TSCH: remove 'not for us' log --- core/net/mac/tsch/tsch-slot-operation.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/core/net/mac/tsch/tsch-slot-operation.c b/core/net/mac/tsch/tsch-slot-operation.c index 03905617e..7c3257c84 100644 --- a/core/net/mac/tsch/tsch-slot-operation.c +++ b/core/net/mac/tsch/tsch-slot-operation.c @@ -810,12 +810,6 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t)) log->rx.sec_level = frame.aux_hdr.security_control.security_level; log->rx.estimated_drift = estimated_drift; ); - } else { - TSCH_LOG_ADD(tsch_log_message, - snprintf(log->message, sizeof(log->message), - "!not for us %x:%x", - destination_address.u8[LINKADDR_SIZE - 2], destination_address.u8[LINKADDR_SIZE - 1]); - ); } /* Poll process for processing of pending input and logs */ From 39921f1231b807c34eb036a12148b3b0d24780c6 Mon Sep 17 00:00:00 2001 From: kkrentz Date: Sun, 24 Apr 2016 00:59:07 -0700 Subject: [PATCH 196/374] rdc.h: Read LLSEC802154_ENABLED instead of LLSEC802154_CONF_ENABLED --- core/net/mac/rdc.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/net/mac/rdc.h b/core/net/mac/rdc.h index 72717455b..8ac34e444 100644 --- a/core/net/mac/rdc.h +++ b/core/net/mac/rdc.h @@ -43,6 +43,7 @@ #include "contiki-conf.h" #include "net/mac/mac.h" +#include "net/llsec/llsec802154.h" #ifdef RDC_CONF_WITH_DUPLICATE_DETECTION #define RDC_WITH_DUPLICATE_DETECTION RDC_CONF_WITH_DUPLICATE_DETECTION @@ -51,7 +52,7 @@ frame because it has seen its sequence number already. Replay protection should be implemented at the LLSEC layer where the authenticity of frames is verified. */ -#define RDC_WITH_DUPLICATE_DETECTION !LLSEC802154_CONF_ENABLED +#define RDC_WITH_DUPLICATE_DETECTION !LLSEC802154_ENABLED #endif /* RDC_CONF_WITH_DUPLICATE_DETECTION */ /* List of packets to be sent by RDC layer */ From ca0f32f45b23dfe8c0193c873d9433427bffda23 Mon Sep 17 00:00:00 2001 From: Billy Kozak Date: Fri, 1 Apr 2016 10:41:02 -0600 Subject: [PATCH 197/374] Use collisions for csma backoff and retry The collision count is now used in the calculation fot the CSMA backoff and transmission will fail after a certain number of collisisons. --- core/net/mac/csma.c | 218 +++++++++++++++++++++++++------------------- 1 file changed, 126 insertions(+), 92 deletions(-) diff --git a/core/net/mac/csma.c b/core/net/mac/csma.c index 4de46be19..e6f79b066 100644 --- a/core/net/mac/csma.c +++ b/core/net/mac/csma.c @@ -123,7 +123,6 @@ LIST(neighbor_list); static void packet_sent(void *ptr, int status, int num_transmissions); static void transmit_packet_list(void *ptr); - /*---------------------------------------------------------------------------*/ static struct neighbor_queue * neighbor_queue_from_addr(const linkaddr_t *addr) @@ -150,7 +149,7 @@ default_timebase(void) does not turn the radio off), we make the retransmission time proportional to the configured MAC channel check rate. */ if(time == 0) { - time = CLOCK_SECOND / NETSTACK_RDC_CHANNEL_CHECK_RATE; + time = (CLOCK_SECOND / 3125) ? (CLOCK_SECOND / 3125) : 1; } return time; } @@ -202,34 +201,116 @@ free_packet(struct neighbor_queue *n, struct rdc_buf_list *p, int status) } /*---------------------------------------------------------------------------*/ static void +tx_done(int status, struct rdc_buf_list *q, struct neighbor_queue *n) +{ + mac_callback_t sent; + struct qbuf_metadata *metadata; + void *cptr; + + metadata = (struct qbuf_metadata *)q->ptr; + sent = metadata->sent; + cptr = metadata->cptr; + + switch(status) { + case MAC_TX_OK: + PRINTF("csma: rexmit ok %d\n", n->transmissions); + break; + case MAC_TX_COLLISION: + case MAC_TX_NOACK: + PRINTF("csma: drop with status %d after %d transmissions, %d collisions\n", + status, n->transmissions, n->collisions); + break; + default: + PRINTF("csma: rexmit failed %d: %d\n", n->transmissions, status); + break; + } + + free_packet(n, q, status); + mac_call_sent_callback(sent, cptr, status, n->transmissions); +} +/*---------------------------------------------------------------------------*/ +static void +rexmit(struct rdc_buf_list *q, struct neighbor_queue *n) +{ + clock_time_t time; + int backoff_exponent; + int backoff_transmissions; + + time = default_timebase(); + backoff_exponent = n->collisions; + + /* Proceed to exponentiation. */ + backoff_transmissions = 1 << backoff_exponent; + + /* Pick a time for next transmission, within the interval: + * [time, time + 2^backoff_exponent * time[ */ + time = time + (random_rand() % (backoff_transmissions * time)); + + PRINTF("csma: retransmitting with time %lu %p\n", time, q); + ctimer_set(&n->transmit_timer, time, transmit_packet_list, n); + /* This is needed to correctly attribute energy that we spent + transmitting this packet. */ + queuebuf_update_attr_from_packetbuf(q->buf); +} +/*---------------------------------------------------------------------------*/ +static void +collision(struct rdc_buf_list *q, struct neighbor_queue *n, + int num_transmissions) +{ + struct qbuf_metadata *metadata; + + metadata = (struct qbuf_metadata *)q->ptr; + + n->collisions += num_transmissions; + + if(n->collisions > CSMA_MAX_BACKOFF_EXPONENT) { + n->collisions = 0; + n->transmissions += num_transmissions; + } + + if(n->transmissions >= metadata->max_transmissions) { + tx_done(MAC_TX_COLLISION, q, n); + } else { + PRINTF("csma: rexmit collision %d\n", n->transmissions); + rexmit(q, n); + } +} +/*---------------------------------------------------------------------------*/ +static void +noack(struct rdc_buf_list *q, struct neighbor_queue *n, int num_transmissions) +{ + struct qbuf_metadata *metadata; + + metadata = (struct qbuf_metadata *)q->ptr; + + n->transmissions += num_transmissions; + n->collisions = 0; + + if(n->transmissions >= metadata->max_transmissions) { + tx_done(MAC_TX_NOACK, q, n); + } else { + PRINTF("csma: rexmit noack %d\n", n->transmissions); + rexmit(q, n); + } +} +/*---------------------------------------------------------------------------*/ +static void +tx_ok(struct rdc_buf_list *q, struct neighbor_queue *n, int num_transmissions) +{ + n->transmissions += num_transmissions; + tx_done(MAC_TX_OK, q, n); +} +/*---------------------------------------------------------------------------*/ +static void packet_sent(void *ptr, int status, int num_transmissions) { struct neighbor_queue *n; struct rdc_buf_list *q; - struct qbuf_metadata *metadata; - clock_time_t time = 0; - mac_callback_t sent; - void *cptr; - int num_tx; - int backoff_exponent; - int backoff_transmissions; n = ptr; if(n == NULL) { return; } - switch(status) { - case MAC_TX_OK: - case MAC_TX_NOACK: - n->transmissions += num_transmissions; - break; - case MAC_TX_COLLISION: - n->collisions += num_transmissions; - break; - case MAC_TX_DEFERRED: - n->deferrals += num_transmissions; - break; - } /* Find out what packet this callback refers to */ for(q = list_head(n->queued_packet_list); @@ -240,78 +321,31 @@ packet_sent(void *ptr, int status, int num_transmissions) } } - if(q != NULL) { - metadata = (struct qbuf_metadata *)q->ptr; + if(q == NULL) { + PRINTF("csma: seqno %d not found\n", + packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO)); + return; + } else if(q->ptr == NULL) { + PRINTF("csma: no metadata\n"); + return; + } - if(metadata != NULL) { - sent = metadata->sent; - cptr = metadata->cptr; - num_tx = n->transmissions; - if(status == MAC_TX_COLLISION || - status == MAC_TX_NOACK) { - - /* If the transmission was not performed because of a - collision or noack, we must retransmit the packet. */ - - switch(status) { - case MAC_TX_COLLISION: - PRINTF("csma: rexmit collision %d\n", n->transmissions); - break; - case MAC_TX_NOACK: - PRINTF("csma: rexmit noack %d\n", n->transmissions); - break; - default: - PRINTF("csma: rexmit err %d, %d\n", status, n->transmissions); - } - - /* The retransmission time must be proportional to the channel - check interval of the underlying radio duty cycling layer. */ - time = default_timebase(); - - /* The retransmission time uses a truncated exponential backoff - * so that the interval between the transmissions increase with - * each retransmit. */ - backoff_exponent = num_tx; - - /* Truncate the exponent if needed. */ - if(backoff_exponent > CSMA_MAX_BACKOFF_EXPONENT) { - backoff_exponent = CSMA_MAX_BACKOFF_EXPONENT; - } - - /* Proceed to exponentiation. */ - backoff_transmissions = 1 << backoff_exponent; - - /* Pick a time for next transmission, within the interval: - * [time, time + 2^backoff_exponent * time[ */ - time = time + (random_rand() % (backoff_transmissions * time)); - - if(n->transmissions < metadata->max_transmissions) { - PRINTF("csma: retransmitting with time %lu %p\n", time, q); - ctimer_set(&n->transmit_timer, time, - transmit_packet_list, n); - /* This is needed to correctly attribute energy that we spent - transmitting this packet. */ - queuebuf_update_attr_from_packetbuf(q->buf); - } else { - PRINTF("csma: drop with status %d after %d transmissions, %d collisions\n", - status, n->transmissions, n->collisions); - free_packet(n, q, status); - mac_call_sent_callback(sent, cptr, status, num_tx); - } - } else { - if(status == MAC_TX_OK) { - PRINTF("csma: rexmit ok %d\n", n->transmissions); - } else { - PRINTF("csma: rexmit failed %d: %d\n", n->transmissions, status); - } - free_packet(n, q, status); - mac_call_sent_callback(sent, cptr, status, num_tx); - } - } else { - PRINTF("csma: no metadata\n"); - } - } else { - PRINTF("csma: seqno %d not found\n", packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO)); + switch(status) { + case MAC_TX_OK: + tx_ok(q, n, num_transmissions); + break; + case MAC_TX_NOACK: + noack(q, n, num_transmissions); + break; + case MAC_TX_COLLISION: + collision(q, n, num_transmissions); + break; + case MAC_TX_DEFERRED: + n->deferrals += num_transmissions; + break; + default: + tx_done(status, q, n); + break; } } /*---------------------------------------------------------------------------*/ From 90b886aa71499a8486549f97ad7107fc487e7c0a Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 22 Apr 2016 23:27:43 +0200 Subject: [PATCH 198/374] Csma: comply with IEEE 802.15.4 --- core/contiki-default-conf.h | 8 -- core/net/ipv6/sicslowpan.c | 9 -- core/net/mac/csma.c | 120 +++++++++++--------- platform/cooja/contiki-conf.h | 3 - platform/exp5438/contiki-conf.h | 3 - platform/jn516x/contiki-conf.h | 3 - platform/native/contiki-conf.h | 3 - platform/sky/contiki-conf.h | 3 - platform/stm32nucleo-spirit1/contiki-conf.h | 4 - platform/wismote/contiki-conf.h | 3 - 10 files changed, 65 insertions(+), 94 deletions(-) diff --git a/core/contiki-default-conf.h b/core/contiki-default-conf.h index ed82c73ac..36bf6afe1 100644 --- a/core/contiki-default-conf.h +++ b/core/contiki-default-conf.h @@ -220,14 +220,6 @@ * on the target platform, and are therefore platform-specific. */ -/* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS specifies how many times the - MAC layer should resend packets if no link-layer ACK was - received. This only makes sense with the csma_driver - NETSTACK_CONF_MAC. */ -#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 4 -#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ - /* SICSLOWPAN_CONF_FRAG specifies if 6lowpan fragmentation should be used or not. Fragmentation is on by default. */ #ifndef SICSLOWPAN_CONF_FRAG diff --git a/core/net/ipv6/sicslowpan.c b/core/net/ipv6/sicslowpan.c index de9d78181..942acd13b 100644 --- a/core/net/ipv6/sicslowpan.c +++ b/core/net/ipv6/sicslowpan.c @@ -92,12 +92,6 @@ void uip_log(char *msg); #define UIP_LOG(m) #endif /* UIP_LOGGING == 1 */ -#ifdef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_MAX_MAC_TRANSMISSIONS SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#else -#define SICSLOWPAN_MAX_MAC_TRANSMISSIONS 4 -#endif - #ifndef SICSLOWPAN_COMPRESSION #ifdef SICSLOWPAN_CONF_COMPRESSION #define SICSLOWPAN_COMPRESSION SICSLOWPAN_CONF_COMPRESSION @@ -1290,9 +1284,6 @@ output(const uip_lladdr_t *localdest) packetbuf_clear(); packetbuf_ptr = packetbuf_dataptr(); - packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, - SICSLOWPAN_MAX_MAC_TRANSMISSIONS); - if(callback) { /* call the attribution when the callback comes, but set attributes here ! */ diff --git a/core/net/mac/csma.c b/core/net/mac/csma.c index e6f79b066..eea86b4e8 100644 --- a/core/net/mac/csma.c +++ b/core/net/mac/csma.c @@ -63,26 +63,35 @@ #define PRINTF(...) #endif /* DEBUG */ -#ifndef CSMA_MAX_BACKOFF_EXPONENT -#ifdef CSMA_CONF_MAX_BACKOFF_EXPONENT -#define CSMA_MAX_BACKOFF_EXPONENT CSMA_CONF_MAX_BACKOFF_EXPONENT -#else -#define CSMA_MAX_BACKOFF_EXPONENT 3 -#endif /* CSMA_CONF_MAX_BACKOFF_EXPONENT */ -#endif /* CSMA_MAX_BACKOFF_EXPONENT */ +/* Constants of the IEEE 802.15.4 standard */ -#ifndef CSMA_MAX_MAC_TRANSMISSIONS -#ifdef CSMA_CONF_MAX_MAC_TRANSMISSIONS -#define CSMA_MAX_MAC_TRANSMISSIONS CSMA_CONF_MAX_MAC_TRANSMISSIONS +/* macMinBE: Initial backoff exponent. Range 0--CSMA_MAX_BE */ +#ifdef CSMA_CONF_MIN_BE +#define CSMA_MIN_BE CSMA_CONF_MIN_BE #else -#define CSMA_MAX_MAC_TRANSMISSIONS 3 -#endif /* CSMA_CONF_MAX_MAC_TRANSMISSIONS */ -#endif /* CSMA_MAX_MAC_TRANSMISSIONS */ +#define CSMA_MIN_BE 0 +#endif -#if CSMA_MAX_MAC_TRANSMISSIONS < 1 -#error CSMA_CONF_MAX_MAC_TRANSMISSIONS must be at least 1. -#error Change CSMA_CONF_MAX_MAC_TRANSMISSIONS in contiki-conf.h or in your Makefile. -#endif /* CSMA_CONF_MAX_MAC_TRANSMISSIONS < 1 */ +/* macMaxBE: Maximum backoff exponent. Range 3--8 */ +#ifdef CSMA_CONF_MAX_BE +#define CSMA_MAX_BE CSMA_CONF_MAX_BE +#else +#define CSMA_MAX_BE 4 +#endif + +/* macMaxCSMABackoffs: Maximum number of backoffs in case of channel busy/collision. Range 0--5 */ +#ifdef CSMA_CONF_MAX_BACKOFF +#define CSMA_MAX_BACKOFF CSMA_CONF_MAX_BACKOFF +#else +#define CSMA_MAX_BACKOFF 5 +#endif + +/* macMaxFrameRetries: Maximum number of re-transmissions attampts. Range 0--7 */ +#ifdef CSMA_CONF_MAX_FRAME_RETRIES +#define CSMA_MAX_MAX_FRAME_RETRIES CSMA_CONF_MAX_FRAME_RETRIES +#else +#define CSMA_MAX_MAX_FRAME_RETRIES 7 +#endif /* Packet metadata */ struct qbuf_metadata { @@ -97,7 +106,7 @@ struct neighbor_queue { linkaddr_t addr; struct ctimer transmit_timer; uint8_t transmissions; - uint8_t collisions, deferrals; + uint8_t collisions; LIST_STRUCT(queued_packet_list); }; @@ -138,18 +147,18 @@ neighbor_queue_from_addr(const linkaddr_t *addr) } /*---------------------------------------------------------------------------*/ static clock_time_t -default_timebase(void) +backoff_period(void) { clock_time_t time; /* The retransmission time must be proportional to the channel check interval of the underlying radio duty cycling layer. */ time = NETSTACK_RDC.channel_check_interval(); - /* If the radio duty cycle has no channel check interval (i.e., it - does not turn the radio off), we make the retransmission time - proportional to the configured MAC channel check rate. */ + /* If the radio duty cycle has no channel check interval, we use + * the default in IEEE 802.15.4: aUnitBackoffPeriod which is + * 20 symbols i.e. 320 usec. That is, 1/3125 second. */ if(time == 0) { - time = (CLOCK_SECOND / 3125) ? (CLOCK_SECOND / 3125) : 1; + time = MAX(CLOCK_SECOND / 3125, 1); } return time; } @@ -170,10 +179,28 @@ transmit_packet_list(void *ptr) } /*---------------------------------------------------------------------------*/ static void +schedule_transmission(struct neighbor_queue *n) +{ + clock_time_t delay; + int backoff_exponent; /* BE in IEEE 802.15.4 */ + + backoff_exponent = MIN(n->collisions, CSMA_MAX_BE); + + /* Compute max delay as per IEEE 802.15.4: 2^BE-1 backoff periods */ + delay = ((1 << backoff_exponent) - 1) * backoff_period(); + if(delay > 0) { + /* Pick a time for next transmission */ + delay = random_rand() % delay; + } + + PRINTF("csma: scheduling transmission in %u ticks, NB=%u, BE=%u\n", + (unsigned)delay, n->collisions, backoff_exponent); + ctimer_set(&n->transmit_timer, delay, transmit_packet_list, n); +} +/*---------------------------------------------------------------------------*/ +static void free_packet(struct neighbor_queue *n, struct rdc_buf_list *p, int status) { - clock_time_t tx_delay; - if(p != NULL) { /* Remove packet from list and deallocate */ list_remove(n->queued_packet_list, p); @@ -186,11 +213,9 @@ free_packet(struct neighbor_queue *n, struct rdc_buf_list *p, int status) if(list_head(n->queued_packet_list) != NULL) { /* There is a next packet. We reset current tx information */ n->transmissions = 0; - n->collisions = 0; - n->deferrals = 0; - /* Set a timer for next transmissions */ - tx_delay = (status == MAC_TX_OK) ? 0 : default_timebase(); - ctimer_set(&n->transmit_timer, tx_delay, transmit_packet_list, n); + n->collisions = CSMA_MIN_BE; + /* Schedule next transmissions */ + schedule_transmission(n); } else { /* This was the last packet in the queue, we free the neighbor */ ctimer_stop(&n->transmit_timer); @@ -232,22 +257,7 @@ tx_done(int status, struct rdc_buf_list *q, struct neighbor_queue *n) static void rexmit(struct rdc_buf_list *q, struct neighbor_queue *n) { - clock_time_t time; - int backoff_exponent; - int backoff_transmissions; - - time = default_timebase(); - backoff_exponent = n->collisions; - - /* Proceed to exponentiation. */ - backoff_transmissions = 1 << backoff_exponent; - - /* Pick a time for next transmission, within the interval: - * [time, time + 2^backoff_exponent * time[ */ - time = time + (random_rand() % (backoff_transmissions * time)); - - PRINTF("csma: retransmitting with time %lu %p\n", time, q); - ctimer_set(&n->transmit_timer, time, transmit_packet_list, n); + schedule_transmission(n); /* This is needed to correctly attribute energy that we spent transmitting this packet. */ queuebuf_update_attr_from_packetbuf(q->buf); @@ -263,9 +273,10 @@ collision(struct rdc_buf_list *q, struct neighbor_queue *n, n->collisions += num_transmissions; - if(n->collisions > CSMA_MAX_BACKOFF_EXPONENT) { - n->collisions = 0; - n->transmissions += num_transmissions; + if(n->collisions > CSMA_MAX_BACKOFF) { + n->collisions = CSMA_MIN_BE; + /* Increment to indicate a next retry */ + n->transmissions++; } if(n->transmissions >= metadata->max_transmissions) { @@ -283,8 +294,8 @@ noack(struct rdc_buf_list *q, struct neighbor_queue *n, int num_transmissions) metadata = (struct qbuf_metadata *)q->ptr; + n->collisions = CSMA_MIN_BE; n->transmissions += num_transmissions; - n->collisions = 0; if(n->transmissions >= metadata->max_transmissions) { tx_done(MAC_TX_NOACK, q, n); @@ -297,6 +308,7 @@ noack(struct rdc_buf_list *q, struct neighbor_queue *n, int num_transmissions) static void tx_ok(struct rdc_buf_list *q, struct neighbor_queue *n, int num_transmissions) { + n->collisions = CSMA_MIN_BE; n->transmissions += num_transmissions; tx_done(MAC_TX_OK, q, n); } @@ -341,7 +353,6 @@ packet_sent(void *ptr, int status, int num_transmissions) collision(q, n, num_transmissions); break; case MAC_TX_DEFERRED: - n->deferrals += num_transmissions; break; default: tx_done(status, q, n); @@ -380,8 +391,7 @@ send_packet(mac_callback_t sent, void *ptr) /* Init neighbor entry */ linkaddr_copy(&n->addr, addr); n->transmissions = 0; - n->collisions = 0; - n->deferrals = 0; + n->collisions = CSMA_MIN_BE; /* Init packet list for this neighbor */ LIST_STRUCT_INIT(n, queued_packet_list); /* Add neighbor to the list */ @@ -402,7 +412,7 @@ send_packet(mac_callback_t sent, void *ptr) /* Neighbor and packet successfully allocated */ if(packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS) == 0) { /* Use default configuration for max transmissions */ - metadata->max_transmissions = CSMA_MAX_MAC_TRANSMISSIONS; + metadata->max_transmissions = CSMA_MAX_MAX_FRAME_RETRIES + 1; } else { metadata->max_transmissions = packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS); @@ -423,7 +433,7 @@ send_packet(mac_callback_t sent, void *ptr) list_length(n->queued_packet_list), memb_numfree(&packet_memb)); /* If q is the first packet in the neighbor's queue, send asap */ if(list_head(n->queued_packet_list) == q) { - ctimer_set(&n->transmit_timer, 0, transmit_packet_list, n); + schedule_transmission(n); } return; } diff --git a/platform/cooja/contiki-conf.h b/platform/cooja/contiki-conf.h index 04f1c4d43..dba7e9553 100644 --- a/platform/cooja/contiki-conf.h +++ b/platform/cooja/contiki-conf.h @@ -168,9 +168,6 @@ #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 8 -#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ #endif /* NETSTACK_CONF_WITH_IPV6 */ diff --git a/platform/exp5438/contiki-conf.h b/platform/exp5438/contiki-conf.h index bb7a5fcdd..9220ba890 100644 --- a/platform/exp5438/contiki-conf.h +++ b/platform/exp5438/contiki-conf.h @@ -174,9 +174,6 @@ #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 5 -#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ #else /* NETSTACK_CONF_WITH_IPV6 */ #define UIP_CONF_IP_FORWARD 1 #define UIP_CONF_BUFFER_SIZE 108 diff --git a/platform/jn516x/contiki-conf.h b/platform/jn516x/contiki-conf.h index 8b702a56e..1a326f62b 100644 --- a/platform/jn516x/contiki-conf.h +++ b/platform/jn516x/contiki-conf.h @@ -154,9 +154,6 @@ #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 5 -#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ #define UIP_CONF_ICMP_DEST_UNREACH 1 #define UIP_CONF_DHCP_LIGHT diff --git a/platform/native/contiki-conf.h b/platform/native/contiki-conf.h index e011bff96..03eacbbde 100644 --- a/platform/native/contiki-conf.h +++ b/platform/native/contiki-conf.h @@ -110,9 +110,6 @@ typedef unsigned short uip_stats_t; #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 5 -#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ #define UIP_CONF_IPV6_CHECKS 1 #define UIP_CONF_IPV6_QUEUE_PKT 1 diff --git a/platform/sky/contiki-conf.h b/platform/sky/contiki-conf.h index ff4ad8578..39d8bc882 100644 --- a/platform/sky/contiki-conf.h +++ b/platform/sky/contiki-conf.h @@ -179,9 +179,6 @@ #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 5 -#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ #else /* NETSTACK_CONF_WITH_IPV6 */ #define UIP_CONF_IP_FORWARD 1 #define UIP_CONF_BUFFER_SIZE 108 diff --git a/platform/stm32nucleo-spirit1/contiki-conf.h b/platform/stm32nucleo-spirit1/contiki-conf.h index 14baa8d97..9a97ab355 100644 --- a/platform/stm32nucleo-spirit1/contiki-conf.h +++ b/platform/stm32nucleo-spirit1/contiki-conf.h @@ -106,10 +106,6 @@ #define SICSLOWPAN_CONF_MAXAGE 4 #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 5 -#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ - #define UIP_CONF_ICMP_DEST_UNREACH 1 #define UIP_CONF_DHCP_LIGHT diff --git a/platform/wismote/contiki-conf.h b/platform/wismote/contiki-conf.h index bcc6c10ca..f7150c5ff 100644 --- a/platform/wismote/contiki-conf.h +++ b/platform/wismote/contiki-conf.h @@ -157,9 +157,6 @@ #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 5 -#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ #else /* NETSTACK_CONF_WITH_IPV6 */ #define UIP_CONF_IP_FORWARD 1 #define UIP_CONF_BUFFER_SIZE 108 From abf08a71676f2f2935dfb3515db2246a9483b07e Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 20 Apr 2016 11:45:54 +0200 Subject: [PATCH 199/374] Added net-debug.[ch] to provide debug functions even in the non-IP case --- core/net/ip/uip-debug.c | 18 +----- core/net/ip/uip-debug.h | 38 ++--------- core/net/mac/frame802154e-ie.c | 2 +- core/net/mac/tsch/tsch-log.c | 2 +- core/net/mac/tsch/tsch-packet.c | 2 +- core/net/mac/tsch/tsch-queue.c | 2 +- core/net/mac/tsch/tsch-rpl.c | 2 +- core/net/mac/tsch/tsch-schedule.c | 2 +- core/net/mac/tsch/tsch-security.c | 2 +- core/net/mac/tsch/tsch-slot-operation.c | 2 +- core/net/mac/tsch/tsch.c | 2 +- core/net/net-debug.c | 65 +++++++++++++++++++ core/net/net-debug.h | 86 +++++++++++++++++++++++++ platform/cc2530dk/uip-debug.c | 12 ---- platform/mbxxx/contiki-main.c | 2 +- 15 files changed, 166 insertions(+), 73 deletions(-) create mode 100644 core/net/net-debug.c create mode 100644 core/net/net-debug.h diff --git a/core/net/ip/uip-debug.c b/core/net/ip/uip-debug.c index ab3ba0765..7804ba4db 100644 --- a/core/net/ip/uip-debug.c +++ b/core/net/ip/uip-debug.c @@ -30,7 +30,7 @@ /** * \file - * A set of debugging tools + * A set of debugging tools for the IP stack * \author * Nicolas Tsiftes * Niclas Finne @@ -92,19 +92,3 @@ uip_debug_ipaddr_print(const uip_ipaddr_t *addr) #endif /* NETSTACK_CONF_WITH_IPV6 */ } /*---------------------------------------------------------------------------*/ -void -uip_debug_lladdr_print(const uip_lladdr_t *addr) -{ - unsigned int i; - if(addr == NULL) { - PRINTA("(NULL LL addr)"); - return; - } - for(i = 0; i < sizeof(uip_lladdr_t); i++) { - if(i > 0) { - PRINTA(":"); - } - PRINTA("%02x", addr->addr[i]); - } -} -/*---------------------------------------------------------------------------*/ diff --git a/core/net/ip/uip-debug.h b/core/net/ip/uip-debug.h index 6ffc1e638..d8e238fe4 100644 --- a/core/net/ip/uip-debug.h +++ b/core/net/ip/uip-debug.h @@ -31,57 +31,27 @@ */ /** * \file - * A set of debugging macros. + * A set of debugging macros for the IP stack * * \author Nicolas Tsiftes * Niclas Finne * Joakim Eriksson + * Simon Duquennoy */ #ifndef UIP_DEBUG_H #define UIP_DEBUG_H +#include "net/net-debug.h" #include "net/ip/uip.h" #include void uip_debug_ipaddr_print(const uip_ipaddr_t *addr); -void uip_debug_lladdr_print(const uip_lladdr_t *addr); - -#define DEBUG_NONE 0 -#define DEBUG_PRINT 1 -#define DEBUG_ANNOTATE 2 -#define DEBUG_FULL DEBUG_ANNOTATE | DEBUG_PRINT - -/* PRINTA will always print if the debug routines are called directly */ -#ifdef __AVR__ -#include -#define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args) -#else -#define PRINTA(...) printf(__VA_ARGS__) -#endif - -#if (DEBUG) & DEBUG_ANNOTATE -#ifdef __AVR__ -#define ANNOTATE(FORMAT,args...) printf_P(PSTR(FORMAT),##args) -#else -#define ANNOTATE(...) printf(__VA_ARGS__) -#endif -#else -#define ANNOTATE(...) -#endif /* (DEBUG) & DEBUG_ANNOTATE */ #if (DEBUG) & DEBUG_PRINT -#ifdef __AVR__ -#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args) -#else -#define PRINTF(...) printf(__VA_ARGS__) -#endif #define PRINT6ADDR(addr) uip_debug_ipaddr_print(addr) -#define PRINTLLADDR(lladdr) uip_debug_lladdr_print(lladdr) #else -#define PRINTF(...) #define PRINT6ADDR(addr) -#define PRINTLLADDR(lladdr) #endif /* (DEBUG) & DEBUG_PRINT */ -#endif +#endif /* UIP_DEBUG_H */ diff --git a/core/net/mac/frame802154e-ie.c b/core/net/mac/frame802154e-ie.c index 55c397631..db0118889 100644 --- a/core/net/mac/frame802154e-ie.c +++ b/core/net/mac/frame802154e-ie.c @@ -41,7 +41,7 @@ #include "net/mac/frame802154e-ie.h" #define DEBUG DEBUG_NONE -#include "net/ip/uip-debug.h" +#include "net/net-debug.h" /* c.f. IEEE 802.15.4e Table 4b */ enum ieee802154e_header_ie_id { diff --git a/core/net/mac/tsch/tsch-log.c b/core/net/mac/tsch/tsch-log.c index bfb033e9d..8473648a6 100644 --- a/core/net/mac/tsch/tsch-log.c +++ b/core/net/mac/tsch/tsch-log.c @@ -56,7 +56,7 @@ #else /* TSCH_LOG_LEVEL */ #define DEBUG DEBUG_NONE #endif /* TSCH_LOG_LEVEL */ -#include "net/ip/uip-debug.h" +#include "net/net-debug.h" #if TSCH_LOG_LEVEL >= 2 /* Skip this file for log levels 0 or 1 */ diff --git a/core/net/mac/tsch/tsch-packet.c b/core/net/mac/tsch/tsch-packet.c index 9f9a8e107..17601d054 100644 --- a/core/net/mac/tsch/tsch-packet.c +++ b/core/net/mac/tsch/tsch-packet.c @@ -60,7 +60,7 @@ #else /* TSCH_LOG_LEVEL */ #define DEBUG DEBUG_NONE #endif /* TSCH_LOG_LEVEL */ -#include "net/ip/uip-debug.h" +#include "net/net-debug.h" /*---------------------------------------------------------------------------*/ /* Construct enhanced ACK packet and return ACK length */ diff --git a/core/net/mac/tsch/tsch-queue.c b/core/net/mac/tsch/tsch-queue.c index 1fdf04232..e3f60f45c 100644 --- a/core/net/mac/tsch/tsch-queue.c +++ b/core/net/mac/tsch/tsch-queue.c @@ -61,7 +61,7 @@ #else /* TSCH_LOG_LEVEL */ #define DEBUG DEBUG_NONE #endif /* TSCH_LOG_LEVEL */ -#include "net/ip/uip-debug.h" +#include "net/net-debug.h" /* Check if TSCH_QUEUE_NUM_PER_NEIGHBOR is power of two */ #if (TSCH_QUEUE_NUM_PER_NEIGHBOR & (TSCH_QUEUE_NUM_PER_NEIGHBOR - 1)) != 0 diff --git a/core/net/mac/tsch/tsch-rpl.c b/core/net/mac/tsch/tsch-rpl.c index 772c886b3..960f757f6 100644 --- a/core/net/mac/tsch/tsch-rpl.c +++ b/core/net/mac/tsch/tsch-rpl.c @@ -51,7 +51,7 @@ #else /* TSCH_LOG_LEVEL */ #define DEBUG DEBUG_NONE #endif /* TSCH_LOG_LEVEL */ -#include "net/ip/uip-debug.h" +#include "net/net-debug.h" /*---------------------------------------------------------------------------*/ /* To use, set #define TSCH_CALLBACK_JOINING_NETWORK tsch_rpl_callback_joining_network */ diff --git a/core/net/mac/tsch/tsch-schedule.c b/core/net/mac/tsch/tsch-schedule.c index e0028c492..0a61b5f12 100644 --- a/core/net/mac/tsch/tsch-schedule.c +++ b/core/net/mac/tsch/tsch-schedule.c @@ -60,7 +60,7 @@ #else /* TSCH_LOG_LEVEL */ #define DEBUG DEBUG_NONE #endif /* TSCH_LOG_LEVEL */ -#include "net/ip/uip-debug.h" +#include "net/net-debug.h" /* Pre-allocated space for links */ MEMB(link_memb, struct tsch_link, TSCH_SCHEDULE_MAX_LINKS); diff --git a/core/net/mac/tsch/tsch-security.c b/core/net/mac/tsch/tsch-security.c index e7439c519..6d862e19e 100644 --- a/core/net/mac/tsch/tsch-security.c +++ b/core/net/mac/tsch/tsch-security.c @@ -58,7 +58,7 @@ #else /* TSCH_LOG_LEVEL */ #define DEBUG DEBUG_NONE #endif /* TSCH_LOG_LEVEL */ -#include "net/ip/uip-debug.h" +#include "net/net-debug.h" /* The two keys K1 and K2 from 6TiSCH minimal configuration * K1: well-known, used for EBs diff --git a/core/net/mac/tsch/tsch-slot-operation.c b/core/net/mac/tsch/tsch-slot-operation.c index 03905617e..e7100c0ed 100644 --- a/core/net/mac/tsch/tsch-slot-operation.c +++ b/core/net/mac/tsch/tsch-slot-operation.c @@ -59,7 +59,7 @@ #else /* TSCH_LOG_LEVEL */ #define DEBUG DEBUG_NONE #endif /* TSCH_LOG_LEVEL */ -#include "net/ip/uip-debug.h" +#include "net/net-debug.h" /* TSCH debug macros, i.e. to set LEDs or GPIOs on various TSCH * timeslot events */ diff --git a/core/net/mac/tsch/tsch.c b/core/net/mac/tsch/tsch.c index 442323abc..2085f39ff 100644 --- a/core/net/mac/tsch/tsch.c +++ b/core/net/mac/tsch/tsch.c @@ -64,7 +64,7 @@ #else /* TSCH_LOG_LEVEL */ #define DEBUG DEBUG_NONE #endif /* TSCH_LOG_LEVEL */ -#include "net/ip/uip-debug.h" +#include "net/net-debug.h" /* Use to collect link statistics even on Keep-Alive, even though they were * not sent from an upper layer and don't have a valid packet_sent callback */ diff --git a/core/net/net-debug.c b/core/net/net-debug.c new file mode 100644 index 000000000..8dd630666 --- /dev/null +++ b/core/net/net-debug.c @@ -0,0 +1,65 @@ +/* + * 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. + * + */ + +/** + * \file + * A set of debugging tools for the IP stack + * \author + * Nicolas Tsiftes + * Niclas Finne + * Joakim Eriksson + * Simon Duquennoy + */ + +#include "net/net-debug.h" + +/*---------------------------------------------------------------------------*/ +void +net_debug_lladdr_print(const uip_lladdr_t *addr) +{ + if(addr == NULL) { + PRINTA("(NULL LL addr)"); + return; + } else { +#if NETSTACK_CONF_WITH_RIME + /* Rime uses traditionally a %u.%u format */ + PRINTA("%u.%u", addr->addr[0], addr->addr[1]); +#else /* NETSTACK_CONF_WITH_RIME */ + unsigned int i; + for(i = 0; i < LINKADDR_SIZE; i++) { + if(i > 0) { + PRINTA(":"); + } + PRINTA("%02x", addr->addr[i]); + } +#endif /* NETSTACK_CONF_WITH_RIME */ + } +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/net-debug.h b/core/net/net-debug.h new file mode 100644 index 000000000..a4c6a3313 --- /dev/null +++ b/core/net/net-debug.h @@ -0,0 +1,86 @@ +/* + * 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. + * + * This file is part of the Contiki operating system. + * + */ +/** + * \file + * A set of debugging macros for the netstack + * + * \author Nicolas Tsiftes + * Niclas Finne + * Joakim Eriksson + * Simon Duquennoy + */ + +#ifndef NET_DEBUG_H +#define NET_DEBUG_H + +#include "net/ip/uip.h" +#include "net/linkaddr.h" +#include + +void net_debug_lladdr_print(const uip_lladdr_t *addr); + +#define DEBUG_NONE 0 +#define DEBUG_PRINT 1 +#define DEBUG_ANNOTATE 2 +#define DEBUG_FULL DEBUG_ANNOTATE | DEBUG_PRINT + +/* PRINTA will always print if the debug routines are called directly */ +#ifdef __AVR__ +#include +#define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args) +#else +#define PRINTA(...) printf(__VA_ARGS__) +#endif + +#if (DEBUG) & DEBUG_ANNOTATE +#ifdef __AVR__ +#define ANNOTATE(FORMAT,args...) printf_P(PSTR(FORMAT),##args) +#else +#define ANNOTATE(...) printf(__VA_ARGS__) +#endif +#else +#define ANNOTATE(...) +#endif /* (DEBUG) & DEBUG_ANNOTATE */ + +#if (DEBUG) & DEBUG_PRINT +#ifdef __AVR__ +#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args) +#else +#define PRINTF(...) printf(__VA_ARGS__) +#endif +#define PRINTLLADDR(lladdr) net_debug_lladdr_print(lladdr) +#else +#define PRINTF(...) +#define PRINTLLADDR(lladdr) +#endif /* (DEBUG) & DEBUG_PRINT */ + +#endif /* NET_DEBUG_H */ diff --git a/platform/cc2530dk/uip-debug.c b/platform/cc2530dk/uip-debug.c index 5f5b23ca8..1a1660e65 100644 --- a/platform/cc2530dk/uip-debug.c +++ b/platform/cc2530dk/uip-debug.c @@ -68,15 +68,3 @@ uip_debug_ipaddr_print(const uip_ipaddr_t *addr) #endif /* NETSTACK_CONF_WITH_IPV6 */ } /*---------------------------------------------------------------------------*/ -void -uip_debug_lladdr_print(const uip_lladdr_t *addr) -{ - unsigned int i; - for(i = 0; i < sizeof(uip_lladdr_t); i++) { - if(i > 0) { - putstring(":"); - } - puthex(addr->addr[i]); - } -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/mbxxx/contiki-main.c b/platform/mbxxx/contiki-main.c index 700fbb5cc..f1ad1d8d4 100644 --- a/platform/mbxxx/contiki-main.c +++ b/platform/mbxxx/contiki-main.c @@ -179,7 +179,7 @@ main(void) NETSTACK_RDC.channel_check_interval())); printf("802.15.4 PAN ID 0x%x, EUI-%d:", IEEE802154_CONF_PANID, UIP_CONF_LL_802154?64:16); - uip_debug_lladdr_print((const uip_lladdr_t *)&linkaddr_node_addr); + net_debug_lladdr_print((const uip_lladdr_t *)&linkaddr_node_addr); printf(", radio channel %u\n", RF_CHANNEL); procinit_init(); From 7ba5b0d15017189df9ec3743a5295611f0dc30fd Mon Sep 17 00:00:00 2001 From: Frank Freihube Date: Wed, 27 Apr 2016 10:39:05 +0200 Subject: [PATCH 200/374] Trailing zeros in file leading to unexpected file length get set in destination buffer --- core/cfs/cfs-coffee.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/cfs/cfs-coffee.c b/core/cfs/cfs-coffee.c index 6391e173c..07df6121b 100644 --- a/core/cfs/cfs-coffee.c +++ b/core/cfs/cfs-coffee.c @@ -1098,8 +1098,8 @@ cfs_read(int fd, void *buf, unsigned size) fdp = &coffee_fd_set[fd]; file = fdp->file; - if(fdp->offset + size > file->end) { - size = file->end - fdp->offset; + while(fdp->offset + size > file->end) { + ((char*)buf)[--size] = 0; } /* If the file is not modified, read directly from the file extent. */ From f47c0f579d3d9b597e9a2cb743c1b92852920039 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 27 Apr 2016 14:00:55 +0200 Subject: [PATCH 201/374] RPL DAO ACK: improve logging --- core/net/rpl/rpl-icmp6.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 0f20ddb67..32338e456 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -936,7 +936,7 @@ handle_dao_retransmission(void *ptr) return; } - PRINTF("Should retransmit DAO - seq:%d trans:%d\n", instance->my_dao_seqno, + PRINTF("RPL: will retransmit DAO - seq:%d trans:%d\n", instance->my_dao_seqno, instance->my_dao_transmissions); if(get_global_addr(&prefix) == 0) { @@ -1172,7 +1172,7 @@ dao_ack_input(void) uip_ds6_route_rm(re); } } else { - PRINTF("RPL: No route entry to fwd DAO ACK to\n"); + PRINTF("RPL: No route entry found to forward DAO ACK (seqno %u)\n", sequence); } } #endif /* RPL_WITH_DAO_ACK */ From 0379398d7cc92093ed89f57c4873424aa9b13146 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 27 Apr 2016 14:01:44 +0200 Subject: [PATCH 202/374] RPL DAO ACK: increment DAO seqno before storing it to my_dao_seqno --- core/net/rpl/rpl-icmp6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 32338e456..406b1b6c4 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -969,6 +969,7 @@ dao_output(rpl_parent_t *parent, uint8_t lifetime) return; } + RPL_LOLLIPOP_INCREMENT(dao_sequence); #if RPL_WITH_DAO_ACK /* set up the state since this will be the first transmission of DAO */ /* retransmissions will call directly to dao_output_target_seq */ @@ -995,7 +996,6 @@ dao_output(rpl_parent_t *parent, uint8_t lifetime) void dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime) { - RPL_LOLLIPOP_INCREMENT(dao_sequence); dao_output_target_seq(parent, prefix, lifetime, dao_sequence); } /*---------------------------------------------------------------------------*/ From bb5e5d5c6bdb23c7baf28e981bcdf140f57d0447 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Sat, 23 Apr 2016 00:19:21 +0200 Subject: [PATCH 203/374] TSCH: use RTIMER_CLOCK_DIFF to compute estimated drift, fixing a bug that would occur on 16-bit rtimer platforms --- core/net/mac/tsch/tsch-slot-operation.c | 2 +- core/sys/rtimer.h | 8 +++++--- cpu/arm/aducrf101/aducrf101-contiki.h | 2 +- cpu/mc1322x/contiki-mc1322x-conf.h | 4 ++-- platform/cc2538dk/contiki-conf.h | 4 ++-- platform/cooja/contiki-conf.h | 2 +- platform/galileo/contiki-conf.h | 2 +- platform/jn516x/platform-conf.h | 4 ++-- platform/mbxxx/platform-conf.h | 2 +- platform/openmote-cc2538/contiki-conf.h | 4 ++-- platform/seedeye/contiki-conf.h | 2 +- platform/srf06-cc26xx/contiki-conf.h | 4 ++-- platform/stm32nucleo-spirit1/platform-conf.h | 2 +- platform/zoul/contiki-conf.h | 4 ++-- 14 files changed, 24 insertions(+), 22 deletions(-) diff --git a/core/net/mac/tsch/tsch-slot-operation.c b/core/net/mac/tsch/tsch-slot-operation.c index 03905617e..55fc06a24 100644 --- a/core/net/mac/tsch/tsch-slot-operation.c +++ b/core/net/mac/tsch/tsch-slot-operation.c @@ -737,7 +737,7 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t)) if(linkaddr_cmp(&destination_address, &linkaddr_node_addr) || linkaddr_cmp(&destination_address, &linkaddr_null)) { int do_nack = 0; - estimated_drift = ((int32_t)expected_rx_time - (int32_t)rx_start_time); + estimated_drift = RTIMER_CLOCK_DIFF(expected_rx_time, rx_start_time); #if TSCH_TIMESYNC_REMOVE_JITTER /* remove jitter due to measurement errors */ diff --git a/core/sys/rtimer.h b/core/sys/rtimer.h index 91c23b932..a89ed8299 100644 --- a/core/sys/rtimer.h +++ b/core/sys/rtimer.h @@ -55,10 +55,12 @@ #include "contiki-conf.h" -#ifndef RTIMER_CLOCK_LT +#ifndef RTIMER_CLOCK_DIFF typedef unsigned short rtimer_clock_t; -#define RTIMER_CLOCK_LT(a,b) ((signed short)((a)-(b)) < 0) -#endif /* RTIMER_CLOCK_LT */ +#define RTIMER_CLOCK_DIFF(a,b) ((signed short)((a)-(b))) +#endif /* RTIMER_CLOCK_DIFF */ + +#define RTIMER_CLOCK_LT(a, b) (RTIMER_CLOCK_DIFF((a),(b)) < 0) #include "rtimer-arch.h" diff --git a/cpu/arm/aducrf101/aducrf101-contiki.h b/cpu/arm/aducrf101/aducrf101-contiki.h index 00fd8765d..4610c49d6 100644 --- a/cpu/arm/aducrf101/aducrf101-contiki.h +++ b/cpu/arm/aducrf101/aducrf101-contiki.h @@ -46,7 +46,7 @@ typedef uint32_t clock_time_t; typedef uint16_t uip_stats_t; typedef uint32_t rtimer_clock_t; -#define RTIMER_CLOCK_LT(a, b) ((int32_t)((a) - (b)) < 0) +#define RTIMER_CLOCK_DIFF(a, b) ((int32_t)((a) - (b))) rtimer_clock_t rtimer_arch_now(void); #endif diff --git a/cpu/mc1322x/contiki-mc1322x-conf.h b/cpu/mc1322x/contiki-mc1322x-conf.h index e6c65df56..2dfb7e0f1 100644 --- a/cpu/mc1322x/contiki-mc1322x-conf.h +++ b/cpu/mc1322x/contiki-mc1322x-conf.h @@ -55,8 +55,8 @@ typedef unsigned short uip_stats_t; typedef uint32_t clock_time_t; -/* Core rtimer.h defaults to 16 bit timer unless RTIMER_CLOCK_LT is defined */ +/* Core rtimer.h defaults to 16 bit timer unless RTIMER_CLOCK_DIFF is defined */ typedef unsigned long rtimer_clock_t; -#define RTIMER_CLOCK_LT(a,b) ((signed long)((a)-(b)) < 0) +#define RTIMER_CLOCK_DIFF(a,b) ((signed long)((a)-(b))) #endif diff --git a/platform/cc2538dk/contiki-conf.h b/platform/cc2538dk/contiki-conf.h index ad9aafeeb..9d18ec344 100644 --- a/platform/cc2538dk/contiki-conf.h +++ b/platform/cc2538dk/contiki-conf.h @@ -34,10 +34,10 @@ typedef uint32_t uip_stats_t; /* * rtimer.h typedefs rtimer_clock_t as unsigned short. We need to define - * RTIMER_CLOCK_LT to override this + * RTIMER_CLOCK_DIFF to override this */ typedef uint32_t rtimer_clock_t; -#define RTIMER_CLOCK_LT(a,b) ((int32_t)((a)-(b)) < 0) +#define RTIMER_CLOCK_DIFF(a,b) ((int32_t)((a)-(b))) /** @} */ /*---------------------------------------------------------------------------*/ /** diff --git a/platform/cooja/contiki-conf.h b/platform/cooja/contiki-conf.h index 04f1c4d43..d021ff547 100644 --- a/platform/cooja/contiki-conf.h +++ b/platform/cooja/contiki-conf.h @@ -201,7 +201,7 @@ typedef unsigned short uip_stats_t; #define CLOCK_CONF_SECOND 1000L typedef unsigned long clock_time_t; typedef unsigned long rtimer_clock_t; -#define RTIMER_CLOCK_LT(a,b) ((signed long)((a)-(b)) < 0) +#define RTIMER_CLOCK_DIFF(a,b) ((signed long)((a)-(b))) #define AODV_COMPLIANCE #define AODV_NUM_RT_ENTRIES 32 diff --git a/platform/galileo/contiki-conf.h b/platform/galileo/contiki-conf.h index dca42b8de..2d64c440f 100644 --- a/platform/galileo/contiki-conf.h +++ b/platform/galileo/contiki-conf.h @@ -46,7 +46,7 @@ typedef unsigned long clock_time_t; typedef uint64_t rtimer_clock_t; #define RTIMER_ARCH_SECOND 1024 -#define RTIMER_CLOCK_LT(a, b) ((int64_t)((a) - (b)) < 0) +#define RTIMER_CLOCK_DIFF(a, b) ((int64_t)((a) - (b))) /* We define the following macros and types otherwise Contiki does not * compile. diff --git a/platform/jn516x/platform-conf.h b/platform/jn516x/platform-conf.h index c1c372b64..408b4957e 100644 --- a/platform/jn516x/platform-conf.h +++ b/platform/jn516x/platform-conf.h @@ -80,9 +80,9 @@ #define JN516X_EXTERNAL_CRYSTAL_OSCILLATOR (RTIMER_USE_32KHZ || JN516X_SLEEP_ENABLED) #endif /* JN516X_EXTERNAL_CRYSTAL_OSCILLATOR */ -/* Core rtimer.h defaults to 16 bit timer unless RTIMER_CLOCK_LT is defined */ +/* Core rtimer.h defaults to 16 bit timer unless RTIMER_CLOCK_DIFF is defined */ typedef uint32_t rtimer_clock_t; -#define RTIMER_CLOCK_LT(a, b) ((int32_t)((a) - (b)) < 0) +#define RTIMER_CLOCK_DIFF(a, b) ((int32_t)((a) - (b))) /* 8ms timer tick */ #define CLOCK_CONF_SECOND 125 diff --git a/platform/mbxxx/platform-conf.h b/platform/mbxxx/platform-conf.h index 6b811ec96..98870980d 100644 --- a/platform/mbxxx/platform-conf.h +++ b/platform/mbxxx/platform-conf.h @@ -87,7 +87,7 @@ typedef unsigned long clock_time_t; typedef unsigned long rtimer_clock_t; -#define RTIMER_CLOCK_LT(a,b) ((signed long)((a)-(b)) < 0) +#define RTIMER_CLOCK_DIFF(a,b) ((signed long)((a)-(b))) #define LEDS_CONF_RED_PIN boardDescription->io->leds[1].gpioPin #define LEDS_CONF_GREEN_PIN boardDescription->io->leds[0].gpioPin diff --git a/platform/openmote-cc2538/contiki-conf.h b/platform/openmote-cc2538/contiki-conf.h index 6c0349025..87b58f299 100644 --- a/platform/openmote-cc2538/contiki-conf.h +++ b/platform/openmote-cc2538/contiki-conf.h @@ -73,10 +73,10 @@ typedef uint32_t uip_stats_t; /* * rtimer.h typedefs rtimer_clock_t as unsigned short. We need to define - * RTIMER_CLOCK_LT to override this + * RTIMER_CLOCK_DIFF to override this */ typedef uint32_t rtimer_clock_t; -#define RTIMER_CLOCK_LT(a, b) ((int32_t)((a) - (b)) < 0) +#define RTIMER_CLOCK_DIFF(a, b) ((int32_t)((a) - (b))) /** @} */ /*---------------------------------------------------------------------------*/ /** diff --git a/platform/seedeye/contiki-conf.h b/platform/seedeye/contiki-conf.h index 69c788381..d58ff686d 100644 --- a/platform/seedeye/contiki-conf.h +++ b/platform/seedeye/contiki-conf.h @@ -60,7 +60,7 @@ typedef uint16_t uip_stats_t; typedef uint32_t clock_time_t; typedef uint32_t rtimer_clock_t; -#define RTIMER_CLOCK_LT(a,b) ((int32_t)((a)-(b)) < 0) +#define RTIMER_CLOCK_DIFF(a,b) ((int32_t)((a)-(b))) #define RF_CHANNEL 13 diff --git a/platform/srf06-cc26xx/contiki-conf.h b/platform/srf06-cc26xx/contiki-conf.h index 79c1d479a..6e52b5c0c 100644 --- a/platform/srf06-cc26xx/contiki-conf.h +++ b/platform/srf06-cc26xx/contiki-conf.h @@ -325,10 +325,10 @@ typedef uint32_t uip_stats_t; /* * rtimer.h typedefs rtimer_clock_t as unsigned short. We need to define - * RTIMER_CLOCK_LT to override this + * RTIMER_CLOCK_DIFF to override this */ typedef uint32_t rtimer_clock_t; -#define RTIMER_CLOCK_LT(a, b) ((int32_t)((a) - (b)) < 0) +#define RTIMER_CLOCK_DIFF(a, b) ((int32_t)((a) - (b))) /** @} */ /*---------------------------------------------------------------------------*/ /* board.h assumes that basic configuration is done */ diff --git a/platform/stm32nucleo-spirit1/platform-conf.h b/platform/stm32nucleo-spirit1/platform-conf.h index dede0bdeb..0f2a0077b 100644 --- a/platform/stm32nucleo-spirit1/platform-conf.h +++ b/platform/stm32nucleo-spirit1/platform-conf.h @@ -78,7 +78,7 @@ #define CLOCK_CONF_SECOND 128 /* One tick: 62.5 ms */ -#define RTIMER_CLOCK_LT(a, b) ((signed short)((a) - (b)) < 0) +#define RTIMER_CLOCK_DIFF(a, b) ((signed short)((a) - (b))) /*---------------------------------------------------------------------------*/ typedef unsigned long clock_time_t; typedef unsigned long long rtimer_clock_t; diff --git a/platform/zoul/contiki-conf.h b/platform/zoul/contiki-conf.h index 52cd22dfd..50d781832 100644 --- a/platform/zoul/contiki-conf.h +++ b/platform/zoul/contiki-conf.h @@ -71,10 +71,10 @@ typedef uint32_t uip_stats_t; /* * rtimer.h typedefs rtimer_clock_t as unsigned short. We need to define - * RTIMER_CLOCK_LT to override this + * RTIMER_CLOCK_DIFF to override this */ typedef uint32_t rtimer_clock_t; -#define RTIMER_CLOCK_LT(a, b) ((int32_t)((a) - (b)) < 0) +#define RTIMER_CLOCK_DIFF(a, b) ((int32_t)((a) - (b))) /** @} */ /*---------------------------------------------------------------------------*/ /** From 439250701949f9fd85b326125efa9ba2dd673cdb Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 27 Apr 2016 14:19:26 +0200 Subject: [PATCH 204/374] RPL: do not add K flag to no-path DAO as we discard the ACK anyway --- core/net/rpl/rpl-icmp6.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 0f20ddb67..c6f9e160d 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -1050,7 +1050,9 @@ dao_output_target_seq(rpl_parent_t *parent, uip_ipaddr_t *prefix, buffer[pos] |= RPL_DAO_D_FLAG; #endif /* RPL_DAO_SPECIFY_DAG */ #if RPL_WITH_DAO_ACK - buffer[pos] |= RPL_DAO_K_FLAG; + if(lifetime != RPL_ZERO_LIFETIME) { + buffer[pos] |= RPL_DAO_K_FLAG; + } #endif /* RPL_WITH_DAO_ACK */ ++pos; buffer[pos++] = 0; /* reserved */ From ace607a32daadc14f7d0a549f138870119cf45ed Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 27 Apr 2016 17:04:29 +0200 Subject: [PATCH 205/374] Fix RPL default lifetime --- core/net/rpl/rpl-conf.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/net/rpl/rpl-conf.h b/core/net/rpl/rpl-conf.h index b86a36a85..073186071 100644 --- a/core/net/rpl/rpl-conf.h +++ b/core/net/rpl/rpl-conf.h @@ -200,7 +200,7 @@ * used in RPL lifetime values, in seconds. */ #ifndef RPL_CONF_DEFAULT_LIFETIME_UNIT -#define RPL_DEFAULT_LIFETIME_UNIT 0x60 +#define RPL_DEFAULT_LIFETIME_UNIT 60 #else #define RPL_DEFAULT_LIFETIME_UNIT RPL_CONF_DEFAULT_LIFETIME_UNIT #endif @@ -209,7 +209,7 @@ * Default route lifetime as a multiple of the lifetime unit. */ #ifndef RPL_CONF_DEFAULT_LIFETIME -#define RPL_DEFAULT_LIFETIME 0x30 +#define RPL_DEFAULT_LIFETIME 30 #else #define RPL_DEFAULT_LIFETIME RPL_CONF_DEFAULT_LIFETIME #endif From 19120788c0bed2226f2da3b278b904250faa89d5 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Tue, 26 Apr 2016 20:00:21 +0200 Subject: [PATCH 206/374] made a text-based version of the MessageList for headless execution --- .../cooja/avrmote/MicaZMoteType.java | 6 +- .../cooja/mspmote/AbstractMspMoteType.java | 3 +- .../cooja/mspmote/CC430MoteType.java | 6 +- .../contikios/cooja/mspmote/ESBMoteType.java | 6 +- .../cooja/mspmote/Eth1120MoteType.java | 6 +- .../cooja/mspmote/Exp1101MoteType.java | 6 +- .../cooja/mspmote/Exp1120MoteType.java | 6 +- .../cooja/mspmote/Exp2420MoteType.java | 6 +- .../cooja/mspmote/Exp5438MoteType.java | 6 +- .../contikios/cooja/mspmote/SkyMoteType.java | 6 +- .../cooja/mspmote/Trxeb1120MoteType.java | 6 +- .../cooja/mspmote/Trxeb2520MoteType.java | 6 +- .../cooja/mspmote/TyndallMoteType.java | 6 +- .../cooja/mspmote/plugins/MspCodeWatcher.java | 3 +- .../cooja/java/org/contikios/cooja/Cooja.java | 19 +- .../java/org/contikios/cooja/CoreComm.java | 5 +- .../java/org/contikios/cooja/MoteType.java | 1 + .../cooja/contikimote/ContikiMoteType.java | 8 +- .../cooja/dialogs/AbstractCompileDialog.java | 4 +- .../cooja/dialogs/CompileContiki.java | 18 +- .../cooja/dialogs/ConfigurationWizard.java | 22 +- .../cooja/dialogs/MessageContainer.java | 17 + .../contikios/cooja/dialogs/MessageList.java | 362 +----------------- .../cooja/dialogs/MessageListText.java | 27 ++ .../cooja/dialogs/MessageListUI.java | 334 ++++++++++++++++ .../contikios/cooja/plugins/ScriptRunner.java | 13 +- .../plugins/skins/AddressVisualizerSkin.java | 1 - .../org/contikios/cooja/util/ExecuteJAR.java | 6 +- 28 files changed, 488 insertions(+), 427 deletions(-) create mode 100644 tools/cooja/java/org/contikios/cooja/dialogs/MessageContainer.java create mode 100644 tools/cooja/java/org/contikios/cooja/dialogs/MessageListText.java create mode 100644 tools/cooja/java/org/contikios/cooja/dialogs/MessageListUI.java diff --git a/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/MicaZMoteType.java b/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/MicaZMoteType.java index c1a33b625..9499aafe9 100644 --- a/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/MicaZMoteType.java +++ b/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/MicaZMoteType.java @@ -63,7 +63,9 @@ import org.contikios.cooja.avrmote.interfaces.MicaZLED; import org.contikios.cooja.avrmote.interfaces.MicaZRadio; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; import org.contikios.cooja.interfaces.Position; @@ -364,7 +366,7 @@ public class MicaZMoteType implements MoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/AbstractMspMoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/AbstractMspMoteType.java index ec7feffd3..d03c0dfa1 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/AbstractMspMoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/AbstractMspMoteType.java @@ -45,7 +45,6 @@ import org.apache.log4j.Logger; import org.contikios.cooja.*; import org.contikios.cooja.dialogs.*; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; /** * @@ -119,7 +118,7 @@ public abstract class AbstractMspMoteType extends MspMoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/CC430MoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/CC430MoteType.java index 8be39971f..3a5144197 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/CC430MoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/CC430MoteType.java @@ -50,8 +50,10 @@ import org.contikios.cooja.MoteInterface; import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; @@ -113,7 +115,7 @@ public class CC430MoteType extends MspMoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/ESBMoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/ESBMoteType.java index 41bf80384..13ad2025a 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/ESBMoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/ESBMoteType.java @@ -51,7 +51,9 @@ import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; @@ -149,7 +151,7 @@ public class ESBMoteType extends MspMoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Eth1120MoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Eth1120MoteType.java index 84483d047..c51c29384 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Eth1120MoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Eth1120MoteType.java @@ -11,7 +11,9 @@ import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; @@ -71,7 +73,7 @@ public class Eth1120MoteType extends Exp5438MoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp1101MoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp1101MoteType.java index b46f1c1f0..b36fb30e9 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp1101MoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp1101MoteType.java @@ -11,7 +11,9 @@ import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; @@ -71,7 +73,7 @@ public class Exp1101MoteType extends Exp5438MoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp1120MoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp1120MoteType.java index d745097df..46ad50713 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp1120MoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp1120MoteType.java @@ -11,7 +11,9 @@ import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; @@ -72,7 +74,7 @@ public class Exp1120MoteType extends Exp5438MoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp2420MoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp2420MoteType.java index 8e24ef145..8a63bf527 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp2420MoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp2420MoteType.java @@ -11,7 +11,9 @@ import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; @@ -72,7 +74,7 @@ public class Exp2420MoteType extends Exp5438MoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp5438MoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp5438MoteType.java index f9fc4d813..c5b9b8436 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp5438MoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp5438MoteType.java @@ -48,7 +48,9 @@ import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; @@ -113,7 +115,7 @@ public class Exp5438MoteType extends MspMoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/SkyMoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/SkyMoteType.java index 793418969..3ab5854b3 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/SkyMoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/SkyMoteType.java @@ -51,7 +51,9 @@ import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; @@ -135,7 +137,7 @@ public class SkyMoteType extends MspMoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Trxeb1120MoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Trxeb1120MoteType.java index e69daf55f..eac27e122 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Trxeb1120MoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Trxeb1120MoteType.java @@ -11,7 +11,9 @@ import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; @@ -71,7 +73,7 @@ public class Trxeb1120MoteType extends Exp5438MoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Trxeb2520MoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Trxeb2520MoteType.java index bd3190770..939e60fcd 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Trxeb2520MoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Trxeb2520MoteType.java @@ -11,7 +11,9 @@ import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; @@ -71,7 +73,7 @@ public class Trxeb2520MoteType extends Exp5438MoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/TyndallMoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/TyndallMoteType.java index 4298a67aa..4e6472b11 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/TyndallMoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/TyndallMoteType.java @@ -49,7 +49,9 @@ import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; @@ -112,7 +114,7 @@ public class TyndallMoteType extends MspMoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/plugins/MspCodeWatcher.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/plugins/MspCodeWatcher.java index 76f57c326..422c08381 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/plugins/MspCodeWatcher.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/plugins/MspCodeWatcher.java @@ -77,6 +77,7 @@ import org.contikios.cooja.Watchpoint; import org.contikios.cooja.WatchpointMote; import org.contikios.cooja.WatchpointMote.WatchpointListener; import org.contikios.cooja.dialogs.MessageList; +import org.contikios.cooja.dialogs.MessageListUI; import org.contikios.cooja.mspmote.MspMote; import org.contikios.cooja.mspmote.MspMoteType; import se.sics.mspsim.core.EmulationException; @@ -468,7 +469,7 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { } } - private MessageList rulesDebuggingOutput = new MessageList(); + private MessageListUI rulesDebuggingOutput = new MessageListUI(); private boolean rulesWithDebuggingOutput = false; private int[] rulesMatched = null; private int[] rulesOK = null; diff --git a/tools/cooja/java/org/contikios/cooja/Cooja.java b/tools/cooja/java/org/contikios/cooja/Cooja.java index a4c1be53d..4f0814249 100644 --- a/tools/cooja/java/org/contikios/cooja/Cooja.java +++ b/tools/cooja/java/org/contikios/cooja/Cooja.java @@ -133,6 +133,7 @@ import org.contikios.cooja.dialogs.ConfigurationWizard; import org.contikios.cooja.dialogs.CreateSimDialog; import org.contikios.cooja.dialogs.ExternalToolsDialog; import org.contikios.cooja.dialogs.MessageList; +import org.contikios.cooja.dialogs.MessageListUI; import org.contikios.cooja.dialogs.ProjectDirectoriesDialog; import org.contikios.cooja.plugins.MoteTypeInformation; import org.contikios.cooja.plugins.ScriptRunner; @@ -3834,7 +3835,7 @@ public class Cooja extends Observable { /* Contiki error */ if (exception instanceof ContikiError) { String contikiError = ((ContikiError) exception).getContikiError(); - MessageList list = new MessageList(); + MessageListUI list = new MessageListUI(); for (String l: contikiError.split("\n")) { list.addMessage(l); } @@ -3843,14 +3844,14 @@ public class Cooja extends Observable { } /* Compilation output */ - MessageList compilationOutput = null; + MessageListUI compilationOutput = null; if (exception instanceof MoteTypeCreationException && ((MoteTypeCreationException) exception).hasCompilationOutput()) { - compilationOutput = ((MoteTypeCreationException) exception).getCompilationOutput(); + compilationOutput = (MessageListUI) ((MoteTypeCreationException) exception).getCompilationOutput(); } else if (exception.getCause() != null && exception.getCause() instanceof MoteTypeCreationException && ((MoteTypeCreationException) exception.getCause()).hasCompilationOutput()) { - compilationOutput = ((MoteTypeCreationException) exception.getCause()).getCompilationOutput(); + compilationOutput = (MessageListUI) ((MoteTypeCreationException) exception.getCause()).getCompilationOutput(); } if (compilationOutput != null) { compilationOutput.addPopupMenuItem(null, true); @@ -3858,8 +3859,8 @@ public class Cooja extends Observable { } /* Stack trace */ - MessageList stackTrace = new MessageList(); - PrintStream printStream = stackTrace.getInputStream(MessageList.NORMAL); + MessageListUI stackTrace = new MessageListUI(); + PrintStream printStream = stackTrace.getInputStream(MessageListUI.NORMAL); exception.printStackTrace(printStream); stackTrace.addPopupMenuItem(null, true); tabbedPane.addTab("Java stack trace", new JScrollPane(stackTrace)); @@ -3931,7 +3932,7 @@ public class Cooja extends Observable { Box buttonBox = Box.createHorizontalBox(); /* Warnings message list */ - MessageList compilationOutput = new MessageList(); + MessageListUI compilationOutput = new MessageListUI(); for (String w: warnings) { compilationOutput.addMessage(w, MessageList.ERROR); } @@ -4354,14 +4355,14 @@ public class Cooja extends Observable { private static JProgressBar PROGRESS_BAR = null; private static ArrayList PROGRESS_WARNINGS = new ArrayList(); public static void setProgressMessage(String msg) { - setProgressMessage(msg, MessageList.NORMAL); + setProgressMessage(msg, MessageListUI.NORMAL); } public static void setProgressMessage(String msg, int type) { if (PROGRESS_BAR != null && PROGRESS_BAR.isShowing()) { PROGRESS_BAR.setString(msg); PROGRESS_BAR.setStringPainted(true); } - if (type != MessageList.NORMAL) { + if (type != MessageListUI.NORMAL) { PROGRESS_WARNINGS.add(msg); } } diff --git a/tools/cooja/java/org/contikios/cooja/CoreComm.java b/tools/cooja/java/org/contikios/cooja/CoreComm.java index ca124ad5b..a714eac23 100644 --- a/tools/cooja/java/org/contikios/cooja/CoreComm.java +++ b/tools/cooja/java/org/contikios/cooja/CoreComm.java @@ -36,6 +36,7 @@ import java.util.Vector; import org.contikios.cooja.MoteType.MoteTypeCreationException; import org.contikios.cooja.contikimote.ContikiMoteType; import org.contikios.cooja.dialogs.MessageList; +import org.contikios.cooja.dialogs.MessageListUI; /** * The purpose of corecomm's is communicating with a compiled Contiki system @@ -203,9 +204,9 @@ public abstract class CoreComm { */ public static void compileSourceFile(String className) throws MoteTypeCreationException { - MessageList compilationOutput = new MessageList(); + MessageListUI compilationOutput = new MessageListUI(); OutputStream compilationStandardStream = compilationOutput - .getInputStream(MessageList.NORMAL); + .getInputStream(MessageListUI.NORMAL); OutputStream compilationErrorStream = compilationOutput .getInputStream(MessageList.ERROR); diff --git a/tools/cooja/java/org/contikios/cooja/MoteType.java b/tools/cooja/java/org/contikios/cooja/MoteType.java index c5acb6880..60d9016be 100644 --- a/tools/cooja/java/org/contikios/cooja/MoteType.java +++ b/tools/cooja/java/org/contikios/cooja/MoteType.java @@ -37,6 +37,7 @@ import org.jdom.Element; import org.contikios.cooja.contikimote.ContikiMoteType; import org.contikios.cooja.dialogs.MessageList; +import org.contikios.cooja.dialogs.MessageListUI; /** * The mote type defines properties common for several motes. These properties diff --git a/tools/cooja/java/org/contikios/cooja/contikimote/ContikiMoteType.java b/tools/cooja/java/org/contikios/cooja/contikimote/ContikiMoteType.java index eef80bbc8..42205b94f 100644 --- a/tools/cooja/java/org/contikios/cooja/contikimote/ContikiMoteType.java +++ b/tools/cooja/java/org/contikios/cooja/contikimote/ContikiMoteType.java @@ -45,13 +45,11 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Random; -import java.util.Vector; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.JComponent; import javax.swing.JLabel; -import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.jdom.Element; @@ -68,8 +66,8 @@ import org.contikios.cooja.mote.memory.SectionMoteMemory; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.ContikiMoteCompileDialog; -import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.mote.memory.ArrayMemory; import org.contikios.cooja.mote.memory.MemoryInterface; import org.contikios.cooja.mote.memory.MemoryInterface.Symbol; @@ -319,7 +317,7 @@ public class ContikiMoteType implements MoteType { if (getCompileCommands() == null) { throw new MoteTypeCreationException("No compile commands specified"); } - final MessageList compilationOutput = new MessageList(); + final MessageListUI compilationOutput = new MessageListUI(); String[] arr = getCompileCommands().split("\n"); for (String cmd : arr) { if (cmd.trim().isEmpty()) { diff --git a/tools/cooja/java/org/contikios/cooja/dialogs/AbstractCompileDialog.java b/tools/cooja/java/org/contikios/cooja/dialogs/AbstractCompileDialog.java index ee4cf486e..7210cb174 100644 --- a/tools/cooja/java/org/contikios/cooja/dialogs/AbstractCompileDialog.java +++ b/tools/cooja/java/org/contikios/cooja/dialogs/AbstractCompileDialog.java @@ -468,7 +468,7 @@ public abstract class AbstractCompileDialog extends JDialog { protected String[] compilationEnvironment = null; /* Default environment: inherit from current process */ public void compileContiki() throws Exception { - final MessageList taskOutput = new MessageList(); + final MessageListUI taskOutput = new MessageListUI(); if (contikiFirmware.exists()) { contikiFirmware.delete(); @@ -861,7 +861,7 @@ public abstract class AbstractCompileDialog extends JDialog { currentCompilationProcess = null; } - private boolean createNewCompilationTab(MessageList output) { + private boolean createNewCompilationTab(MessageListUI output) { abortAnyCompilation(); tabbedPane.remove(currentCompilationOutput); diff --git a/tools/cooja/java/org/contikios/cooja/dialogs/CompileContiki.java b/tools/cooja/java/org/contikios/cooja/dialogs/CompileContiki.java index 8a0deaee8..702024d13 100644 --- a/tools/cooja/java/org/contikios/cooja/dialogs/CompileContiki.java +++ b/tools/cooja/java/org/contikios/cooja/dialogs/CompileContiki.java @@ -127,7 +127,7 @@ public class CompileContiki { /* TODO Fix me */ final MessageList messageDialog; if (compilationOutput == null) { - messageDialog = new MessageList(); + messageDialog = new MessageListUI(); } else { messageDialog = compilationOutput; } @@ -138,8 +138,8 @@ public class CompileContiki { cmd += c + " "; } logger.info("> " + cmd); - messageDialog.addMessage("", MessageList.NORMAL); - messageDialog.addMessage("> " + cmd, MessageList.NORMAL); + messageDialog.addMessage("", MessageListUI.NORMAL); + messageDialog.addMessage("> " + cmd, MessageListUI.NORMAL); } final Process compileProcess; @@ -170,7 +170,7 @@ public class CompileContiki { String readLine; while ((readLine = processNormal.readLine()) != null) { if (messageDialog != null) { - messageDialog.addMessage(readLine, MessageList.NORMAL); + messageDialog.addMessage(readLine, MessageListUI.NORMAL); } } } catch (IOException e) { @@ -203,7 +203,7 @@ public class CompileContiki { compileProcess.waitFor(); } catch (Exception e) { messageDialog.addMessage(e.getMessage(), MessageList.ERROR); - syncException.setCompilationOutput(new MessageList()); + syncException.setCompilationOutput(new MessageListUI()); syncException.fillInStackTrace(); return; } @@ -214,7 +214,7 @@ public class CompileContiki { if (onFailure != null) { onFailure.actionPerformed(null); } - syncException.setCompilationOutput(new MessageList()); + syncException.setCompilationOutput(new MessageListUI()); syncException.fillInStackTrace(); return; } @@ -232,13 +232,13 @@ public class CompileContiki { if (onFailure != null) { onFailure.actionPerformed(null); } - syncException.setCompilationOutput(new MessageList()); + syncException.setCompilationOutput(new MessageListUI()); syncException.fillInStackTrace(); return; } - messageDialog.addMessage("", MessageList.NORMAL); - messageDialog.addMessage("Compilation succeded", MessageList.NORMAL); + messageDialog.addMessage("", MessageListUI.NORMAL); + messageDialog.addMessage("Compilation succeded", MessageListUI.NORMAL); if (onSuccess != null) { onSuccess.actionPerformed(null); } diff --git a/tools/cooja/java/org/contikios/cooja/dialogs/ConfigurationWizard.java b/tools/cooja/java/org/contikios/cooja/dialogs/ConfigurationWizard.java index a677c07a9..cfea6820a 100644 --- a/tools/cooja/java/org/contikios/cooja/dialogs/ConfigurationWizard.java +++ b/tools/cooja/java/org/contikios/cooja/dialogs/ConfigurationWizard.java @@ -150,7 +150,7 @@ public class ConfigurationWizard extends JDialog { private static int relBssSectionAddr; private static int bssSectionSize; - private static MessageList output; + private static MessageListUI output; private static JDialog progressDialog; private static JButton button; private static JProgressBar progressBar; @@ -430,7 +430,7 @@ public class ConfigurationWizard extends JDialog { } private static void prepareShowTestProgress(JFrame parent, String desc) { - output = new MessageList(); + output = new MessageListUI(); output.addPopupMenuItem(null, true); progressDialog = new JDialog(parent, desc); button = new JButton("Close"); @@ -542,7 +542,7 @@ public class ConfigurationWizard extends JDialog { return (String) optionPane.getValue(); } - public static boolean performCompileCTest(MessageList testOutput, PrintStream normalStream, PrintStream errorStream) { + public static boolean performCompileCTest(MessageListUI testOutput, PrintStream normalStream, PrintStream errorStream) { javaLibraryName = "LibTest" + testCounter; cLibraryName = "libtest" + testCounter; cLibrarySourceFile = new File(ContikiMoteType.tempOutputDirectory, cLibraryName + ".c"); @@ -642,8 +642,8 @@ public class ConfigurationWizard extends JDialog { return true; } - public static boolean performLoadTest(MessageList testOutput, PrintStream normalStream, PrintStream errorStream) { - MessageList dummy = new MessageList(); + public static boolean performLoadTest(MessageListUI testOutput, PrintStream normalStream, PrintStream errorStream) { + MessageListUI dummy = new MessageListUI(); PrintStream dummyStream = dummy.getInputStream(MessageList.NORMAL); if (!performCompileCTest(dummy, dummyStream, errorStream)) { return false; @@ -696,8 +696,8 @@ public class ConfigurationWizard extends JDialog { return true; } - public static boolean performAddressTest(MessageList testOutput, PrintStream normalStream, PrintStream errorStream) { - MessageList dummy = new MessageList(); + public static boolean performAddressTest(MessageListUI testOutput, PrintStream normalStream, PrintStream errorStream) { + MessageListUI dummy = new MessageListUI(); PrintStream dummyStream = dummy.getInputStream(MessageList.NORMAL); if (!performCompileCTest(dummy, dummyStream, errorStream)) { return false; @@ -743,7 +743,7 @@ public class ConfigurationWizard extends JDialog { return false; } - private static boolean performMapAddressTest(MessageList testOutput, PrintStream normalStream, PrintStream errorStream) { + private static boolean performMapAddressTest(MessageListUI testOutput, PrintStream normalStream, PrintStream errorStream) { testOutput.addMessage("### Testing map file based address parsing"); File mapFile = new File(ContikiMoteType.tempOutputDirectory, cLibraryName + ContikiMoteType.mapSuffix); @@ -839,7 +839,7 @@ public class ConfigurationWizard extends JDialog { return true; } - private static boolean performCommandAddressTest(MessageList testOutput, PrintStream normalStream, PrintStream errorStream) { + private static boolean performCommandAddressTest(MessageListUI testOutput, PrintStream normalStream, PrintStream errorStream) { testOutput.addMessage("### Testing command based address parsing"); testOutput.addMessage("### Executing command"); @@ -933,8 +933,8 @@ public class ConfigurationWizard extends JDialog { } - public static boolean performMemoryReplacementTest(MessageList testOutput, PrintStream normalStream, PrintStream errorStream) { - MessageList dummy = new MessageList(); + public static boolean performMemoryReplacementTest(MessageListUI testOutput, PrintStream normalStream, PrintStream errorStream) { + MessageListUI dummy = new MessageListUI(); PrintStream dummyStream = dummy.getInputStream(MessageList.NORMAL); if (!performCompileCTest(dummy, dummyStream, errorStream)) { return false; diff --git a/tools/cooja/java/org/contikios/cooja/dialogs/MessageContainer.java b/tools/cooja/java/org/contikios/cooja/dialogs/MessageContainer.java new file mode 100644 index 000000000..89fea5593 --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/dialogs/MessageContainer.java @@ -0,0 +1,17 @@ +package org.contikios.cooja.dialogs; + +public class MessageContainer { + + public final int type; + public final String message; + + public MessageContainer(String message, int type) { + this.message = message; + this.type = type; + } + + @Override + public String toString() { + return message; + } +} diff --git a/tools/cooja/java/org/contikios/cooja/dialogs/MessageList.java b/tools/cooja/java/org/contikios/cooja/dialogs/MessageList.java index 1921a68ce..f0af5f405 100644 --- a/tools/cooja/java/org/contikios/cooja/dialogs/MessageList.java +++ b/tools/cooja/java/org/contikios/cooja/dialogs/MessageList.java @@ -1,359 +1,17 @@ -/* - * 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. - * - */ - package org.contikios.cooja.dialogs; -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Toolkit; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.StringSelection; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; -import java.io.PrintStream; -import java.util.ArrayList; +public interface MessageList { -import javax.swing.DefaultListCellRenderer; -import javax.swing.DefaultListModel; -import javax.swing.JCheckBoxMenuItem; -import javax.swing.JList; -import javax.swing.JMenuItem; -import javax.swing.JPopupMenu; -import javax.swing.JSeparator; -import javax.swing.ListModel; -import javax.swing.ListSelectionModel; -import org.apache.log4j.Logger; + public static final int NORMAL = 0; + public static final int WARNING = 1; + public static final int ERROR = 2; + + public void addMessage(String string, int normal); -import org.contikios.cooja.Cooja; + public MessageContainer[] getMessages(); -/** - * - * @author Adam Dunkels - * @author Joakim Eriksson - * @author Niclas Finne - * @author Fredrik Osterlind - */ -public class MessageList extends JList { + public void clearMessages(); - private static final Logger logger = Logger.getLogger(MessageList.class); + public void addMessage(String string); - public static final int NORMAL = 0; - public static final int WARNING = 1; - public static final int ERROR = 2; - - private Color[] foregrounds = new Color[] { null, Color.red }; - private Color[] backgrounds = new Color[] { null, null }; - - private JPopupMenu popup = null; - private boolean hideNormal = false; - - private int max = -1; - - public MessageList() { - super.setModel(new MessageModel()); - setCellRenderer(new MessageRenderer()); - setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - } - - /** - * @param max Maximum number of messages - */ - public MessageList(int max) { - this(); - this.max = max; - } - - public Color getForeground(int type) { - Color c = type > 0 && type <= foregrounds.length - ? foregrounds[type - 1] : null; - return c == null ? getForeground() : c; - } - - public void setForeground(int type, Color color) { - if (type > 0 && type <= foregrounds.length) { - foregrounds[type - 1] = color; - } else if (type == NORMAL) { - setForeground(color); - } - } - - public Color getBackground(int type) { - Color c = type > 0 && type <= backgrounds.length - ? backgrounds[type - 1] : null; - return c == null ? getBackground() : c; - } - - public void setBackground(int type, Color color) { - if (type > 0 && type <= backgrounds.length) { - backgrounds[type - 1] = color; - } else if (type == NORMAL) { - setBackground(color); - } - } - - public PrintStream getInputStream(final int type) { - try { - PipedInputStream input = new PipedInputStream(); - PipedOutputStream output = new PipedOutputStream(input); - final BufferedReader stringInput = new BufferedReader(new InputStreamReader(input)); - - Thread readThread = new Thread(new Runnable() { - @Override - public void run() { - String readLine; - try { - while ((readLine = stringInput.readLine()) != null) { - addMessage(readLine, type); - } - } catch (IOException e) { - // Occurs when write end closes pipe - die quietly - } - } - - }); - readThread.start(); - - return new PrintStream(output); - } catch (IOException e) { - logger.error(messages); - return null; - } - } - - public void addMessage(String message) { - addMessage(message, NORMAL); - } - - private ArrayList messages = new ArrayList(); - - public MessageContainer[] getMessages() { - return messages.toArray(new MessageContainer[0]); - } - - private void updateModel() { - boolean scroll = getLastVisibleIndex() >= getModel().getSize() - 2; - - while (messages.size() > getModel().getSize()) { - ((DefaultListModel) getModel()).addElement(messages.get(getModel().getSize())); - } - while (max > 0 && getModel().getSize() > max) { - ((DefaultListModel) getModel()).removeElementAt(0); - messages.remove(0); - } - - if (scroll) { - ensureIndexIsVisible(getModel().getSize() - 1); - } - } - - public void addMessage(final String message, final int type) { - Cooja.setProgressMessage(message, type); - - MessageContainer msg = new MessageContainer(message, type); - messages.add(msg); - - java.awt.EventQueue.invokeLater(new Runnable() { - @Override - public void run() { - updateModel(); - } - }); - } - - public void clearMessages() { - messages.clear(); - ((DefaultListModel) getModel()).clear(); - } - - @Override - public void setModel(ListModel model) { - throw new IllegalArgumentException("changing model not permitted"); - } - - public void addPopupMenuItem(JMenuItem item, boolean withDefaults) { - if (popup == null) { - popup = new JPopupMenu(); - addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - if (e.isPopupTrigger()) { - popup.show(MessageList.this, e.getX(), e.getY()); - } - } - @Override - public void mousePressed(MouseEvent e) { - if (e.isPopupTrigger()) { - popup.show(MessageList.this, e.getX(), e.getY()); - } - } - @Override - public void mouseReleased(MouseEvent e) { - if (e.isPopupTrigger()) { - popup.show(MessageList.this, e.getX(), e.getY()); - } - } - }); - - JMenuItem headerMenuItem = new JMenuItem("Output:"); - headerMenuItem.setEnabled(false); - popup.add(headerMenuItem); - popup.add(new JSeparator()); - - if (withDefaults) { - /* Create default menu items */ - final JMenuItem hideNormalMenuItem = new JCheckBoxMenuItem("Hide normal output"); - hideNormalMenuItem.setEnabled(true); - hideNormalMenuItem.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - MessageList.this.hideNormal = hideNormalMenuItem.isSelected(); - ((MessageModel)getModel()).updateList(); - } - }); - popup.add(hideNormalMenuItem); - - JMenuItem consoleOutputMenuItem = new JMenuItem("Output to console"); - consoleOutputMenuItem.setEnabled(true); - consoleOutputMenuItem.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - MessageContainer[] messages = getMessages(); - logger.info("\nCOMPILATION OUTPUT:\n"); - for (MessageContainer msg: messages) { - if (hideNormal && msg.type == NORMAL) { - continue; - } - logger.info(msg); - } - logger.info("\n"); - } - }); - popup.add(consoleOutputMenuItem); - - JMenuItem clipboardMenuItem = new JMenuItem("Copy to clipboard"); - clipboardMenuItem.setEnabled(true); - clipboardMenuItem.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); - - StringBuilder sb = new StringBuilder(); - MessageContainer[] messages = getMessages(); - for (MessageContainer msg: messages) { - if (hideNormal && msg.type == NORMAL) { - continue; - } - sb.append(msg + "\n"); - } - - StringSelection stringSelection = new StringSelection(sb.toString()); - clipboard.setContents(stringSelection, null); - } - }); - popup.add(clipboardMenuItem); - - popup.add(new JSeparator()); - } - } - - if (item == null) { - return; - } - - popup.add(item); - } - - // ------------------------------------------------------------------- - // MessageContainer - // ------------------------------------------------------------------- - - public static class MessageContainer { - public final int type; - public final String message; - - public MessageContainer(String message, int type) { - this.message = message; - this.type = type; - } - - @Override - public String toString() { - return message; - } - - } // end of inner class MessageContainer - - - // ------------------------------------------------------------------- - // Renderer for messages - // ------------------------------------------------------------------- - - private class MessageModel extends DefaultListModel { - public void updateList() { - fireContentsChanged(this, 0, getSize()); - } - } - - private class MessageRenderer extends DefaultListCellRenderer { - private Dimension nullDimension = new Dimension(0,0); - @Override - public Component getListCellRendererComponent( - JList list, - Object value, - int index, - boolean isSelected, - boolean cellHasFocus) - { - super.getListCellRendererComponent(list, value, index, isSelected, - cellHasFocus); - MessageContainer msg = (MessageContainer) value; - - if (hideNormal && msg.type == NORMAL && index != MessageList.this.getModel().getSize()-1) { - setPreferredSize(nullDimension); - return this; - } - - setPreferredSize(null); - setForeground(((MessageList) list).getForeground(msg.type)); - setBackground(((MessageList) list).getBackground(msg.type)); - return this; - } - - } // end of inner class MessageRenderer - -} // end of MessagList +} diff --git a/tools/cooja/java/org/contikios/cooja/dialogs/MessageListText.java b/tools/cooja/java/org/contikios/cooja/dialogs/MessageListText.java new file mode 100644 index 000000000..bd24c3485 --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/dialogs/MessageListText.java @@ -0,0 +1,27 @@ +package org.contikios.cooja.dialogs; + +public class MessageListText implements MessageList { + + @Override + public void addMessage(String string, int type) { + System.out.println("Message:" + string); + } + + @Override + public MessageContainer[] getMessages() { + // TODO Auto-generated method stub + return new MessageContainer[0]; + } + + @Override + public void clearMessages() { + // TODO Auto-generated method stub + } + + @Override + public void addMessage(String string) { + // TODO Auto-generated method stub + addMessage(string, MessageList.NORMAL); + } + +} diff --git a/tools/cooja/java/org/contikios/cooja/dialogs/MessageListUI.java b/tools/cooja/java/org/contikios/cooja/dialogs/MessageListUI.java new file mode 100644 index 000000000..11449b7ef --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/dialogs/MessageListUI.java @@ -0,0 +1,334 @@ +/* + * 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. + * + */ + +package org.contikios.cooja.dialogs; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.io.PrintStream; +import java.util.ArrayList; + +import javax.swing.DefaultListCellRenderer; +import javax.swing.DefaultListModel; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JList; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.JSeparator; +import javax.swing.ListModel; +import javax.swing.ListSelectionModel; +import org.apache.log4j.Logger; + +import org.contikios.cooja.Cooja; + +/** + * + * @author Adam Dunkels + * @author Joakim Eriksson + * @author Niclas Finne + * @author Fredrik Osterlind + */ +public class MessageListUI extends JList implements MessageList { + + private static final Logger logger = Logger.getLogger(MessageListUI.class); + + private Color[] foregrounds = new Color[] { null, Color.red }; + private Color[] backgrounds = new Color[] { null, null }; + + private JPopupMenu popup = null; + private boolean hideNormal = false; + + private int max = -1; + + public MessageListUI() { + super.setModel(new MessageModel()); + setCellRenderer(new MessageRenderer()); + setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + } + + /** + * @param max Maximum number of messages + */ + public MessageListUI(int max) { + this(); + this.max = max; + } + + public Color getForeground(int type) { + Color c = type > 0 && type <= foregrounds.length + ? foregrounds[type - 1] : null; + return c == null ? getForeground() : c; + } + + public void setForeground(int type, Color color) { + if (type > 0 && type <= foregrounds.length) { + foregrounds[type - 1] = color; + } else if (type == NORMAL) { + setForeground(color); + } + } + + public Color getBackground(int type) { + Color c = type > 0 && type <= backgrounds.length + ? backgrounds[type - 1] : null; + return c == null ? getBackground() : c; + } + + public void setBackground(int type, Color color) { + if (type > 0 && type <= backgrounds.length) { + backgrounds[type - 1] = color; + } else if (type == NORMAL) { + setBackground(color); + } + } + + public PrintStream getInputStream(final int type) { + try { + PipedInputStream input = new PipedInputStream(); + PipedOutputStream output = new PipedOutputStream(input); + final BufferedReader stringInput = new BufferedReader(new InputStreamReader(input)); + + Thread readThread = new Thread(new Runnable() { + @Override + public void run() { + String readLine; + try { + while ((readLine = stringInput.readLine()) != null) { + addMessage(readLine, type); + } + } catch (IOException e) { + // Occurs when write end closes pipe - die quietly + } + } + + }); + readThread.start(); + + return new PrintStream(output); + } catch (IOException e) { + logger.error(messages); + return null; + } + } + + public void addMessage(String message) { + addMessage(message, NORMAL); + } + + private ArrayList messages = new ArrayList(); + + public MessageContainer[] getMessages() { + return messages.toArray(new MessageContainer[0]); + } + + private void updateModel() { + boolean scroll = getLastVisibleIndex() >= getModel().getSize() - 2; + + while (messages.size() > getModel().getSize()) { + ((DefaultListModel) getModel()).addElement(messages.get(getModel().getSize())); + } + while (max > 0 && getModel().getSize() > max) { + ((DefaultListModel) getModel()).removeElementAt(0); + messages.remove(0); + } + + if (scroll) { + ensureIndexIsVisible(getModel().getSize() - 1); + } + } + + public void addMessage(final String message, final int type) { + Cooja.setProgressMessage(message, type); + + MessageContainer msg = new MessageContainer(message, type); + messages.add(msg); + + java.awt.EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + updateModel(); + } + }); + } + + public void clearMessages() { + messages.clear(); + ((DefaultListModel) getModel()).clear(); + } + + @Override + public void setModel(ListModel model) { + throw new IllegalArgumentException("changing model not permitted"); + } + + public void addPopupMenuItem(JMenuItem item, boolean withDefaults) { + if (popup == null) { + popup = new JPopupMenu(); + addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (e.isPopupTrigger()) { + popup.show(MessageListUI.this, e.getX(), e.getY()); + } + } + @Override + public void mousePressed(MouseEvent e) { + if (e.isPopupTrigger()) { + popup.show(MessageListUI.this, e.getX(), e.getY()); + } + } + @Override + public void mouseReleased(MouseEvent e) { + if (e.isPopupTrigger()) { + popup.show(MessageListUI.this, e.getX(), e.getY()); + } + } + }); + + JMenuItem headerMenuItem = new JMenuItem("Output:"); + headerMenuItem.setEnabled(false); + popup.add(headerMenuItem); + popup.add(new JSeparator()); + + if (withDefaults) { + /* Create default menu items */ + final JMenuItem hideNormalMenuItem = new JCheckBoxMenuItem("Hide normal output"); + hideNormalMenuItem.setEnabled(true); + hideNormalMenuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + MessageListUI.this.hideNormal = hideNormalMenuItem.isSelected(); + ((MessageModel)getModel()).updateList(); + } + }); + popup.add(hideNormalMenuItem); + + JMenuItem consoleOutputMenuItem = new JMenuItem("Output to console"); + consoleOutputMenuItem.setEnabled(true); + consoleOutputMenuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + MessageContainer[] messages = getMessages(); + logger.info("\nCOMPILATION OUTPUT:\n"); + for (MessageContainer msg: messages) { + if (hideNormal && msg.type == NORMAL) { + continue; + } + logger.info(msg); + } + logger.info("\n"); + } + }); + popup.add(consoleOutputMenuItem); + + JMenuItem clipboardMenuItem = new JMenuItem("Copy to clipboard"); + clipboardMenuItem.setEnabled(true); + clipboardMenuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + + StringBuilder sb = new StringBuilder(); + MessageContainer[] messages = getMessages(); + for (MessageContainer msg: messages) { + if (hideNormal && msg.type == NORMAL) { + continue; + } + sb.append(msg + "\n"); + } + + StringSelection stringSelection = new StringSelection(sb.toString()); + clipboard.setContents(stringSelection, null); + } + }); + popup.add(clipboardMenuItem); + + popup.add(new JSeparator()); + } + } + + if (item == null) { + return; + } + + popup.add(item); + } + + // ------------------------------------------------------------------- + // Renderer for messages + // ------------------------------------------------------------------- + + private class MessageModel extends DefaultListModel { + public void updateList() { + fireContentsChanged(this, 0, getSize()); + } + } + + private class MessageRenderer extends DefaultListCellRenderer { + private Dimension nullDimension = new Dimension(0,0); + @Override + public Component getListCellRendererComponent( + JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) + { + super.getListCellRendererComponent(list, value, index, isSelected, + cellHasFocus); + MessageContainer msg = (MessageContainer) value; + + if (hideNormal && msg.type == NORMAL && index != MessageListUI.this.getModel().getSize()-1) { + setPreferredSize(nullDimension); + return this; + } + + setPreferredSize(null); + setForeground(((MessageListUI) list).getForeground(msg.type)); + setBackground(((MessageListUI) list).getBackground(msg.type)); + return this; + } + + } // end of inner class MessageRenderer + +} // end of MessagList diff --git a/tools/cooja/java/org/contikios/cooja/plugins/ScriptRunner.java b/tools/cooja/java/org/contikios/cooja/plugins/ScriptRunner.java index bce5764e6..2df863a25 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/ScriptRunner.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/ScriptRunner.java @@ -85,6 +85,7 @@ import org.contikios.cooja.PluginType; import org.contikios.cooja.Simulation; import org.contikios.cooja.VisPlugin; import org.contikios.cooja.dialogs.MessageList; +import org.contikios.cooja.dialogs.MessageListUI; import org.contikios.cooja.util.StringUtils; @ClassDescription("Simulation script editor") @@ -503,7 +504,7 @@ public class ScriptRunner extends VisPlugin { final BufferedReader err = new BufferedReader(new InputStreamReader(process.getErrorStream())); /* GUI components */ - final MessageList testOutput = new MessageList(); + final MessageListUI testOutput = new MessageListUI(); final AbstractAction abort = new AbstractAction() { public void actionPerformed(ActionEvent e) { process.destroy(); @@ -538,14 +539,14 @@ public class ScriptRunner extends VisPlugin { String line; try { while ((line = input.readLine()) != null) { - testOutput.addMessage(line, MessageList.NORMAL); + testOutput.addMessage(line, MessageListUI.NORMAL); } } catch (IOException e) { } - testOutput.addMessage("", MessageList.NORMAL); - testOutput.addMessage("", MessageList.NORMAL); - testOutput.addMessage("", MessageList.NORMAL); + testOutput.addMessage("", MessageListUI.NORMAL); + testOutput.addMessage("", MessageListUI.NORMAL); + testOutput.addMessage("", MessageListUI.NORMAL); /* Parse log file, check if test succeeded */ try { @@ -559,7 +560,7 @@ public class ScriptRunner extends VisPlugin { if (l == null) { line = ""; } - testOutput.addMessage(l, MessageList.NORMAL); + testOutput.addMessage(l, MessageListUI.NORMAL); if (l.contains("TEST OK")) { testSucceeded = true; break; diff --git a/tools/cooja/java/org/contikios/cooja/plugins/skins/AddressVisualizerSkin.java b/tools/cooja/java/org/contikios/cooja/plugins/skins/AddressVisualizerSkin.java index 44a77fc6a..609b2e771 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/skins/AddressVisualizerSkin.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/skins/AddressVisualizerSkin.java @@ -46,7 +46,6 @@ import org.contikios.cooja.ClassDescription; import org.contikios.cooja.Mote; import org.contikios.cooja.Simulation; import org.contikios.cooja.SimEventCentral.MoteCountListener; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Position; import org.contikios.cooja.interfaces.RimeAddress; diff --git a/tools/cooja/java/org/contikios/cooja/util/ExecuteJAR.java b/tools/cooja/java/org/contikios/cooja/util/ExecuteJAR.java index 66bbbd193..57d1fb4f6 100644 --- a/tools/cooja/java/org/contikios/cooja/util/ExecuteJAR.java +++ b/tools/cooja/java/org/contikios/cooja/util/ExecuteJAR.java @@ -54,8 +54,8 @@ import org.contikios.cooja.Plugin; import org.contikios.cooja.ProjectConfig; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; -import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageContainer; +import org.contikios.cooja.dialogs.MessageListUI; import org.contikios.cooja.plugins.ScriptRunner; import org.contikios.cooja.PluginType; @@ -415,7 +415,7 @@ public class ExecuteJAR { } logger.info("Building executable JAR: " + outputFile); - MessageList errors = new MessageList(); + MessageListUI errors = new MessageListUI(); try { CompileContiki.compile( "jar cfm " + outputFile.getAbsolutePath() + " manifest.tmp .", From 763c63f428a62b98a71736cd5d08ca9cf77264ce Mon Sep 17 00:00:00 2001 From: Yasuyuki Tanaka Date: Wed, 27 Apr 2016 20:35:05 +0200 Subject: [PATCH 207/374] Handle the case when log->link is NULL in tsch_log_process_pending --- core/net/mac/tsch/tsch-log.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/core/net/mac/tsch/tsch-log.c b/core/net/mac/tsch/tsch-log.c index bfb033e9d..23794a5dd 100644 --- a/core/net/mac/tsch/tsch-log.c +++ b/core/net/mac/tsch/tsch-log.c @@ -84,11 +84,15 @@ tsch_log_process_pending(void) } while((log_index = ringbufindex_peek_get(&log_ringbuf)) != -1) { struct tsch_log_t *log = &log_array[log_index]; - struct tsch_slotframe *sf = tsch_schedule_get_slotframe_by_handle(log->link->slotframe_handle); - printf("TSCH: {asn-%x.%lx link-%u-%u-%u-%u ch-%u} ", - log->asn.ms1b, log->asn.ls4b, - log->link->slotframe_handle, sf ? sf->size.val : 0, log->link->timeslot, log->link->channel_offset, - tsch_calculate_channel(&log->asn, log->link->channel_offset)); + if(log->link == NULL) { + printf("TSCH: {asn-%x.%lx link-NULL} ", log->asn.ms1b, log->asn.ls4b); + } else { + struct tsch_slotframe *sf = tsch_schedule_get_slotframe_by_handle(log->link->slotframe_handle); + printf("TSCH: {asn-%x.%lx link-%u-%u-%u-%u ch-%u} ", + log->asn.ms1b, log->asn.ls4b, + log->link->slotframe_handle, sf ? sf->size.val : 0, log->link->timeslot, log->link->channel_offset, + tsch_calculate_channel(&log->asn, log->link->channel_offset)); + } switch(log->type) { case tsch_log_tx: printf("%s-%u-%u %u tx %d, st %d-%d", From 5bd7fc86c307756b0969cfeafa70c8aef41ad63b Mon Sep 17 00:00:00 2001 From: Frank Freihube Date: Fri, 29 Apr 2016 07:56:35 +0200 Subject: [PATCH 208/374] make changes configurable through io_semantics() --- core/cfs/cfs-coffee.c | 15 +++++++++++++-- core/cfs/cfs-coffee.h | 9 +++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/core/cfs/cfs-coffee.c b/core/cfs/cfs-coffee.c index 07df6121b..d4d988ae8 100644 --- a/core/cfs/cfs-coffee.c +++ b/core/cfs/cfs-coffee.c @@ -1098,9 +1098,20 @@ cfs_read(int fd, void *buf, unsigned size) fdp = &coffee_fd_set[fd]; file = fdp->file; - while(fdp->offset + size > file->end) { - ((char*)buf)[--size] = 0; + +#if COFFEE_IO_SEMANTICS + if(fdp->io_flags & CFS_COFFEE_IO_FIRM_SIZE) { + while(fdp->offset + size > file->end) { + ((char*)buf)[--size] = 0; + } + } else { +#endif + if(fdp->offset + size > file->end) { + size = file->end - fdp->offset; + } +#if COFFEE_IO_SEMANTICS } +#endif /* If the file is not modified, read directly from the file extent. */ if(!FILE_MODIFIED(file)) { diff --git a/core/cfs/cfs-coffee.h b/core/cfs/cfs-coffee.h index 2c62f2512..96d382980 100644 --- a/core/cfs/cfs-coffee.h +++ b/core/cfs/cfs-coffee.h @@ -63,6 +63,15 @@ */ #define CFS_COFFEE_IO_FIRM_SIZE 0x2 +/** + * Instruct Coffee to set unused bytes in the destination buffer to zero. + * Trailing zeros may cause a wrong file size, this option ensures that + * the corresponding bytes get set, so Coffee does not read unexpected data. + * + * \sa cfs_coffee_set_io_semantics() + */ +#define CFS_COFFEE_IO_ENSURE_READ_LENGTH 0x4 + /** * \file * Header for the Coffee file system. From 59727ede70ea4f997a525d55664316e3b058e435 Mon Sep 17 00:00:00 2001 From: Frank Freihube Date: Fri, 29 Apr 2016 08:12:55 +0200 Subject: [PATCH 209/374] fixup! make changes configurable through io_semantics() --- core/cfs/cfs-coffee.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/cfs/cfs-coffee.c b/core/cfs/cfs-coffee.c index d4d988ae8..79eb18d94 100644 --- a/core/cfs/cfs-coffee.c +++ b/core/cfs/cfs-coffee.c @@ -1100,7 +1100,7 @@ cfs_read(int fd, void *buf, unsigned size) file = fdp->file; #if COFFEE_IO_SEMANTICS - if(fdp->io_flags & CFS_COFFEE_IO_FIRM_SIZE) { + if(fdp->io_flags & CFS_COFFEE_IO_ENSURE_READ_LENGTH) { while(fdp->offset + size > file->end) { ((char*)buf)[--size] = 0; } From 37b2d9f6008384d6712c44baa6d82f9d6accfdfc Mon Sep 17 00:00:00 2001 From: Yasuyuki Tanaka Date: Mon, 2 May 2016 18:18:12 +0200 Subject: [PATCH 210/374] Replace the '+' operator with String.prototype.concat() --- regression-tests/12-rpl/01-rpl-up-route.csc | 4 ++-- regression-tests/12-rpl/02-rpl-root-reboot.csc | 4 ++-- regression-tests/12-rpl/03-rpl-28-hours.csc | 4 ++-- regression-tests/12-rpl/04-rpl-large-network.csc | 4 ++-- regression-tests/12-rpl/05-rpl-up-and-down-routes.csc | 4 ++-- regression-tests/12-rpl/06-rpl-temporary-root-loss.csc | 4 ++-- regression-tests/12-rpl/08-rpl-dao-route-loss-0.csc | 4 ++-- regression-tests/12-rpl/08-rpl-dao-route-loss-1.csc | 4 ++-- regression-tests/12-rpl/08-rpl-dao-route-loss-2.csc | 4 ++-- regression-tests/12-rpl/08-rpl-dao-route-loss-3.csc | 4 ++-- regression-tests/12-rpl/08-rpl-dao-route-loss-4.csc | 4 ++-- regression-tests/12-rpl/08-rpl-dao-route-loss-5.csc | 4 ++-- regression-tests/12-rpl/09-rpl-probing.csc | 4 ++-- regression-tests/12-rpl/10-rpl-multi-dodag.csc | 4 ++-- 14 files changed, 28 insertions(+), 28 deletions(-) diff --git a/regression-tests/12-rpl/01-rpl-up-route.csc b/regression-tests/12-rpl/01-rpl-up-route.csc index fc79cfc27..da4743d44 100644 --- a/regression-tests/12-rpl/01-rpl-up-route.csc +++ b/regression-tests/12-rpl/01-rpl-up-route.csc @@ -323,11 +323,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/12-rpl/02-rpl-root-reboot.csc b/regression-tests/12-rpl/02-rpl-root-reboot.csc index 14f87c7a9..6c4ce9d28 100644 --- a/regression-tests/12-rpl/02-rpl-root-reboot.csc +++ b/regression-tests/12-rpl/02-rpl-root-reboot.csc @@ -323,11 +323,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/12-rpl/03-rpl-28-hours.csc b/regression-tests/12-rpl/03-rpl-28-hours.csc index 1cf2c5e43..3ebc7adda 100644 --- a/regression-tests/12-rpl/03-rpl-28-hours.csc +++ b/regression-tests/12-rpl/03-rpl-28-hours.csc @@ -272,11 +272,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/12-rpl/04-rpl-large-network.csc b/regression-tests/12-rpl/04-rpl-large-network.csc index e40b7a339..f4ea0fda8 100644 --- a/regression-tests/12-rpl/04-rpl-large-network.csc +++ b/regression-tests/12-rpl/04-rpl-large-network.csc @@ -7038,11 +7038,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/12-rpl/05-rpl-up-and-down-routes.csc b/regression-tests/12-rpl/05-rpl-up-and-down-routes.csc index c2b3cb506..0dd110738 100644 --- a/regression-tests/12-rpl/05-rpl-up-and-down-routes.csc +++ b/regression-tests/12-rpl/05-rpl-up-and-down-routes.csc @@ -321,11 +321,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/12-rpl/06-rpl-temporary-root-loss.csc b/regression-tests/12-rpl/06-rpl-temporary-root-loss.csc index 08126f22b..096713102 100644 --- a/regression-tests/12-rpl/06-rpl-temporary-root-loss.csc +++ b/regression-tests/12-rpl/06-rpl-temporary-root-loss.csc @@ -327,11 +327,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-0.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-0.csc index b5aeac9b2..0fc6e032d 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-0.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-0.csc @@ -339,11 +339,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-1.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-1.csc index d17bc193c..2c0ce41ff 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-1.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-1.csc @@ -339,11 +339,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-2.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-2.csc index fe3db3dc3..cdb2bd748 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-2.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-2.csc @@ -339,11 +339,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-3.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-3.csc index 7ee838b2c..34b930c0d 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-3.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-3.csc @@ -339,11 +339,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-4.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-4.csc index 35c5bd753..ff9a400c1 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-4.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-4.csc @@ -339,11 +339,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-5.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-5.csc index 4dc5038bc..e491b666f 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-5.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-5.csc @@ -339,11 +339,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/12-rpl/09-rpl-probing.csc b/regression-tests/12-rpl/09-rpl-probing.csc index 5206f1cfd..66a156e9c 100644 --- a/regression-tests/12-rpl/09-rpl-probing.csc +++ b/regression-tests/12-rpl/09-rpl-probing.csc @@ -234,12 +234,12 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } lastMsgHops = hops; - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/12-rpl/10-rpl-multi-dodag.csc b/regression-tests/12-rpl/10-rpl-multi-dodag.csc index fa015e8d9..0f446cc65 100644 --- a/regression-tests/12-rpl/10-rpl-multi-dodag.csc +++ b/regression-tests/12-rpl/10-rpl-multi-dodag.csc @@ -368,11 +368,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } From cd7885ae766de1ba4998c11f15f7c8d55b8e7775 Mon Sep 17 00:00:00 2001 From: Jens Dede Date: Mon, 2 May 2016 18:48:16 +0200 Subject: [PATCH 211/374] do not use setBaudrate --- tools/sky/msp430-bsl-linux | 3 ++- tools/zolertia/z1-bsl | 3 ++- tools/zolertia/z1-bsl-nopic | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/sky/msp430-bsl-linux b/tools/sky/msp430-bsl-linux index 133f1bd35..c78e18640 100755 --- a/tools/sky/msp430-bsl-linux +++ b/tools/sky/msp430-bsl-linux @@ -1162,8 +1162,9 @@ class BootStrapLoader(LowLevel): sys.stderr.flush() self.bslTxRx(self.BSL_CHANGEBAUD, #Command: change baudrate a, l) #args are coded in adr and len + self.serialport.flush() time.sleep(0.010) #recomended delay - self.serialport.setBaudrate(baudrate) + self.serialport.baudrate = baudrate def actionReadBSLVersion(self): """informational output of BSL version number. diff --git a/tools/zolertia/z1-bsl b/tools/zolertia/z1-bsl index 7c0584337..31d58d1df 100755 --- a/tools/zolertia/z1-bsl +++ b/tools/zolertia/z1-bsl @@ -1350,8 +1350,9 @@ class BootStrapLoader(LowLevel): sys.stderr.flush() self.bslTxRx(self.BSL_CHANGEBAUD, #Command: change baudrate a, l) #args are coded in adr and len + self.serialport.flush() time.sleep(0.010) #recomended delay - self.serialport.setBaudrate(baudrate) + self.serialport.baudrate = baudrate def actionReadBSLVersion(self): """informational output of BSL version number. diff --git a/tools/zolertia/z1-bsl-nopic b/tools/zolertia/z1-bsl-nopic index 802c84642..8b5edd8f5 100755 --- a/tools/zolertia/z1-bsl-nopic +++ b/tools/zolertia/z1-bsl-nopic @@ -1364,8 +1364,9 @@ class BootStrapLoader(LowLevel): sys.stderr.flush() self.bslTxRx(self.BSL_CHANGEBAUD, #Command: change baudrate a, l) #args are coded in adr and len + self.serialport.flush() time.sleep(0.010) #recomended delay - self.serialport.setBaudrate(baudrate) + self.serialport.baudrate = baudrate def actionReadBSLVersion(self): """informational output of BSL version number. From 43fb479c9d67d14820f0f493f4825d84c0a31945 Mon Sep 17 00:00:00 2001 From: Jens Dede Date: Mon, 2 May 2016 18:57:48 +0200 Subject: [PATCH 212/374] Fix broken include --- platform/z1/contiki-z1-main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/z1/contiki-z1-main.c b/platform/z1/contiki-z1-main.c index 477bab975..92a7b5bd7 100644 --- a/platform/z1/contiki-z1-main.c +++ b/platform/z1/contiki-z1-main.c @@ -77,7 +77,7 @@ static struct timer mgt_timer; #if NETSTACK_CONF_WITH_IPV4 #include "net/ip/uip.h" #include "net/ipv4/uip-fw.h" -#include "net/uip-fw-drv.h" +#include "net/ipv4/uip-fw-drv.h" #include "net/ipv4/uip-over-mesh.h" static struct uip_fw_netif slipif = { UIP_FW_NETIF(192, 168, 1, 2, 255, 255, 255, 255, slip_send) }; From 119291d083deb73e9bc053e38ff6d6482b5f38ab Mon Sep 17 00:00:00 2001 From: Jens Dede Date: Mon, 2 May 2016 19:13:26 +0200 Subject: [PATCH 213/374] Fix putchar include when using IPv4 --- cpu/msp430/dev/uart0-putchar.c | 5 ++++- cpu/msp430/dev/uart1-putchar.c | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/cpu/msp430/dev/uart0-putchar.c b/cpu/msp430/dev/uart0-putchar.c index 819f627d2..c9fa974a6 100644 --- a/cpu/msp430/dev/uart0-putchar.c +++ b/cpu/msp430/dev/uart0-putchar.c @@ -1,9 +1,12 @@ -#include "dev/uart0.h" #include +#include "dev/uart0.h" +#ifndef NETSTACK_CONF_WITH_IPV4 +/* In case of IPv4: putchar() is defined by the SLIP driver */ int putchar(int c) { uart0_writeb((char)c); return c; } +#endif /* NETSTACK_CONF_WITH_IPV4 */ diff --git a/cpu/msp430/dev/uart1-putchar.c b/cpu/msp430/dev/uart1-putchar.c index 3d7f65c7b..c966b920d 100644 --- a/cpu/msp430/dev/uart1-putchar.c +++ b/cpu/msp430/dev/uart1-putchar.c @@ -1,9 +1,12 @@ #include #include "dev/uart1.h" +#ifndef NETSTACK_CONF_WITH_IPV4 +/* In case of IPv4: putchar() is defined by the SLIP driver */ int putchar(int c) { uart1_writeb((char)c); return c; } +#endif /* NETSTACK_CONF_WITH_IPV4 */ From 59afae85e201701f5450a83bd0ceb4b191665203 Mon Sep 17 00:00:00 2001 From: Jens Dede Date: Mon, 2 May 2016 22:34:58 +0200 Subject: [PATCH 214/374] Use if instead of ifdef. Is more contiki standard-compliant --- cpu/msp430/dev/uart0-putchar.c | 4 ++-- cpu/msp430/dev/uart1-putchar.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cpu/msp430/dev/uart0-putchar.c b/cpu/msp430/dev/uart0-putchar.c index c9fa974a6..e797e8b28 100644 --- a/cpu/msp430/dev/uart0-putchar.c +++ b/cpu/msp430/dev/uart0-putchar.c @@ -1,7 +1,7 @@ #include #include "dev/uart0.h" -#ifndef NETSTACK_CONF_WITH_IPV4 +#if !NETSTACK_CONF_WITH_IPV4 /* In case of IPv4: putchar() is defined by the SLIP driver */ int putchar(int c) @@ -9,4 +9,4 @@ putchar(int c) uart0_writeb((char)c); return c; } -#endif /* NETSTACK_CONF_WITH_IPV4 */ +#endif /* ! NETSTACK_CONF_WITH_IPV4 */ diff --git a/cpu/msp430/dev/uart1-putchar.c b/cpu/msp430/dev/uart1-putchar.c index c966b920d..e005ff255 100644 --- a/cpu/msp430/dev/uart1-putchar.c +++ b/cpu/msp430/dev/uart1-putchar.c @@ -1,7 +1,7 @@ #include #include "dev/uart1.h" -#ifndef NETSTACK_CONF_WITH_IPV4 +#if !NETSTACK_CONF_WITH_IPV4 /* In case of IPv4: putchar() is defined by the SLIP driver */ int putchar(int c) @@ -9,4 +9,4 @@ putchar(int c) uart1_writeb((char)c); return c; } -#endif /* NETSTACK_CONF_WITH_IPV4 */ +#endif /* ! NETSTACK_CONF_WITH_IPV4 */ From 19550f9f7f63d6fe2dab191f2044f4e4f5d59df6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Sat, 23 Apr 2016 10:03:09 +0200 Subject: [PATCH 215/374] core/cfs: Disallow seeking past the end of a file if it is not writable --- core/cfs/cfs-coffee.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/cfs/cfs-coffee.c b/core/cfs/cfs-coffee.c index 79eb18d94..37b1a707e 100644 --- a/core/cfs/cfs-coffee.c +++ b/core/cfs/cfs-coffee.c @@ -1055,7 +1055,12 @@ cfs_seek(int fd, cfs_offset_t offset, int whence) } if(fdp->file->end < new_offset) { - fdp->file->end = new_offset; + if(FD_WRITABLE(fd)) { + fdp->file->end = new_offset; + } else { + /* Disallow seeking past the end of the file for read only FDs */ + return (cfs_offset_t)-1; + } } return fdp->offset = new_offset; From 7f80b1ad5718ce3615efbe5458e67d8b9d355608 Mon Sep 17 00:00:00 2001 From: Jens Dede Date: Wed, 4 May 2016 11:12:37 +0200 Subject: [PATCH 216/374] Remove include of stdio.h --- cpu/msp430/dev/uart0-putchar.c | 1 - cpu/msp430/dev/uart1-putchar.c | 1 - 2 files changed, 2 deletions(-) diff --git a/cpu/msp430/dev/uart0-putchar.c b/cpu/msp430/dev/uart0-putchar.c index e797e8b28..96f24abf0 100644 --- a/cpu/msp430/dev/uart0-putchar.c +++ b/cpu/msp430/dev/uart0-putchar.c @@ -1,4 +1,3 @@ -#include #include "dev/uart0.h" #if !NETSTACK_CONF_WITH_IPV4 diff --git a/cpu/msp430/dev/uart1-putchar.c b/cpu/msp430/dev/uart1-putchar.c index e005ff255..5cb631190 100644 --- a/cpu/msp430/dev/uart1-putchar.c +++ b/cpu/msp430/dev/uart1-putchar.c @@ -1,4 +1,3 @@ -#include #include "dev/uart1.h" #if !NETSTACK_CONF_WITH_IPV4 From cb729b0785ca41cda501c4a1e8dfa67f32ca6aeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Wed, 4 May 2016 19:12:58 +0200 Subject: [PATCH 217/374] oma-lwm2m: Use sv for string value, bv for boolean Like the OMA docs specify --- apps/oma-lwm2m/lwm2m-engine.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/oma-lwm2m/lwm2m-engine.c b/apps/oma-lwm2m/lwm2m-engine.c index 62f549db4..e2f6bba7c 100644 --- a/apps/oma-lwm2m/lwm2m-engine.c +++ b/apps/oma-lwm2m/lwm2m-engine.c @@ -639,10 +639,10 @@ write_rd_json_data(const lwm2m_context_t *context, value = lwm2m_object_get_resource_string(resource, context); slen = lwm2m_object_get_resource_strlen(resource, context); if(value != NULL) { - PRINTF("%s{\"n\":\"%u\",\"vs\":\"%.*s\"}", s, + PRINTF("%s{\"n\":\"%u\",\"sv\":\"%.*s\"}", s, resource->id, slen, value); len = snprintf(&buffer[rdlen], size - rdlen, - "%s{\"n\":\"%u\",\"vs\":\"%.*s\"}", s, + "%s{\"n\":\"%u\",\"sv\":\"%.*s\"}", s, resource->id, slen, value); } } else if(lwm2m_object_is_resource_int(resource)) { @@ -682,10 +682,10 @@ write_rd_json_data(const lwm2m_context_t *context, } else if(lwm2m_object_is_resource_boolean(resource)) { int value; if(lwm2m_object_get_resource_boolean(resource, context, &value)) { - PRINTF("%s{\"n\":\"%u\",\"v\":%s}", s, resource->id, + PRINTF("%s{\"n\":\"%u\",\"bv\":%s}", s, resource->id, value ? "true" : "false"); len = snprintf(&buffer[rdlen], size - rdlen, - "%s{\"n\":\"%u\",\"v\":%s}", s, resource->id, + "%s{\"n\":\"%u\",\"bv\":%s}", s, resource->id, value ? "true" : "false"); } } From 22e9ccadf78ef0c74f9671f67bcc50f42648c631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Wed, 4 May 2016 19:10:12 +0200 Subject: [PATCH 218/374] ipso-temperature: Use "Cel" for degrees celsius Like the IPSO documentation says --- apps/ipso-objects/ipso-temperature.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/ipso-objects/ipso-temperature.c b/apps/ipso-objects/ipso-temperature.c index 61c87554a..457dfe0f8 100644 --- a/apps/ipso-objects/ipso-temperature.c +++ b/apps/ipso-objects/ipso-temperature.c @@ -79,7 +79,7 @@ LWM2M_RESOURCES(temperature_resources, /* Temperature (Current) */ LWM2M_RESOURCE_CALLBACK(5700, { temp, NULL, NULL }), /* Units */ - LWM2M_RESOURCE_STRING(5701, "Celcius"), + LWM2M_RESOURCE_STRING(5701, "Cel"), /* Min Range Value */ LWM2M_RESOURCE_FLOATFIX(5603, IPSO_TEMPERATURE_MIN), /* Max Range Value */ From d9fd19eb2fb86c6695384e7e76b6e6c43d80536d Mon Sep 17 00:00:00 2001 From: Marco Grella Date: Thu, 5 May 2016 16:44:07 +0200 Subject: [PATCH 219/374] Update to stm32nucleo-spirit1 platform README file. --- platform/stm32nucleo-spirit1/README.md | 51 +++++++++++--------------- 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/platform/stm32nucleo-spirit1/README.md b/platform/stm32nucleo-spirit1/README.md index 80d178dfa..dcb29caf4 100644 --- a/platform/stm32nucleo-spirit1/README.md +++ b/platform/stm32nucleo-spirit1/README.md @@ -7,13 +7,13 @@ Maintainers and Contacts ======================== Long-term maintainers: -* Marco Grella, marco.grella@st.com, github user: [STclab](https://github.com/STclab) -* Alok Mittal, alok.mittal@st.com, github user: [STclab](https://github.com/STclab) -* Indar Prakash Singhal, indar.singhal@st.com, github user: [STclab](https://github.com/STclab) +* Marco Grella, marco.grella@st.com, github user: [mgrella](https://github.com/mgrella) +* Alok Mittal, alok.mittal@st.com, github user: [alokclab](https://github.com/alokclab) +* Indar Prakash Singhal, indar.singhal@st.com, github user: [indars](https://github.com/indars) Contributors: * David Siorpaes, david.siorpaes@st.com, github user: [siorpaes](https://github.com/siorpaes) -* Luca Celetto, luca.celetto@st.com +* Luca Celetto, luca.celetto@st.com, github user: [luckyluke72](https://github.com/luckyluke72) Port Feature ============ @@ -25,11 +25,18 @@ The port supports the following boards from ST: - X-NUCLEO-IKS01A1 featuring motion MEMS and environmental sensors (optional) The following drivers are included: -- LEDs and buttons (user, reset) +- LEDs and user button - USB - SPIRIT1 sub-1GHz transceiver - HTS221, LIS3MDL, LPS25HB, LSM6DS0 sensors +Documentation +============= + +- User Manual: UM2000 "Getting started with the Contiki OS/6LoWPAN on STM32 Nucleo with SPIRIT1 and sensors expansion boards" +- Quick Start Guide (presentation): "Contiki 6LoWPAN Quick Guide" + +To access this documentation and other collaterals, please go to http://www.st.com and search for "STSW-CONTIKI6LP" part number. Hardware Requirements ===================== @@ -38,8 +45,7 @@ Hardware Requirements >The NUCLEO-L152RE board belongs to the STM32 Nucleo family. It features an STM32L152RET6 ultra-low power microcontroller based on ARM Cortex M3 MCU. -Detailed information on the NUCLEO-L152RE development board can be found at: -http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260002 +For detailed information on the NUCLEO-L152RE development board, please go to http://www.st.com and search for the "NUCLEO-L152RE" part number. * X-NUCLEO-IDS01Ax sub-1GHz expansion board @@ -49,22 +55,15 @@ the module SPSGRF-868 or SPSGRF-915 based on SPIRIT1 low data rate, low power su >The user can select the X-NUCLEO-IDS01A4 board to operate the SPIRIT1 transceiver at 868MHz or the X-NUCLEO-IDS01A5 board to operate the SPIRIT1 transceiver at 915MHz. - >Detailed information on the X-NUCLEO-IDS01A4 expansion board can be found at: -http://www.st.com/web/catalog/tools/FM146/CL2167/SC2006/PF261982 - - >Detailed information on the X-NUCLEO-IDS01A5 expansion board can be found at: -http://www.st.com/web/catalog/tools/FM146/CL2167/SC2006/PF261983 - - >Detailed information on the SPIRIT1 sub-1GHz transceiver can be found at: -http://www.st.com/web/catalog/sense_power/FM2185/SC1845/PF253167 +>For detailed information on the X-NUCLEO-IDS01A4 or X-NUCLEO-IDS01A5 expansion board, or the SPIRIT1 transceiver please go to http://www.st.com and search for the specific part number. + * X-NUCLEO-IKS01A1, motion MEMS and environmental sensors expansion board (OPTIONAL) >The X-NUCLEO-IKS01A1 is a motion MEMS and environmental sensor evaluation board. The use of this board is optional in the stm32nucleo-spirit1 Contiki platform. - >Detailed information on the X-NUCLEO-IKS01A1 expansion board can be found at: -http://www.st.com/web/catalog/tools/FM146/CL2167/SC2006/PF261191 + >For detailed information on the X-NUCLEO-IKS01A1 expansion board, please go to http://www.st.com and search for the "X-NUCLEO-IKS01A1" part number. * USB type A to Mini-B USB cable, to connect the STM32 Nucleo board to the PC @@ -76,17 +75,16 @@ The following software are needed: * ST port of Contiki for STM32 Nucleo and expansion boards. - >The port is automatically installed when both the Contiki and the submodule repository are cloned: the former hosts the Contiki distribution and the ST platform interface, the latter hosts the actual library. The following commands are needed to download the full porting: + >The port is automatically installed when both the Contiki and the submodule repository are cloned: the former hosts the Contiki distribution and the ST platform interface, the latter hosts the actual library. The following command downloads the full porting: + + git clone --recursive https://github.com/contiki-os/contiki + +Alternatively, if you cloned the contiki repository without the "--recursive" option, you can simply download the submodule repository with the following commands: - git clone https://github.com/STclab/contiki.git cd contiki/ - git checkout stm32nucleo-spirit1 git submodule init git submodule update - -Note: the first and third steps are required only if using the STclab GitHub repository, they won't be needed any more once the Pull Request is accepted. - The platform name is: stm32nucleo-spirit1 * A toolchain to build the firmware: The port has been developed and tested with GNU Tools @@ -158,10 +156,3 @@ automatically created when plugging the STM32 Nucleo board to the PC. 6. Reset the MCU by using the reset button on the STM32 Nucleo board - - - - - - - From 4870f9e8f33251bead63230a6917c8ddce37eae2 Mon Sep 17 00:00:00 2001 From: Thomas Date: Mon, 9 May 2016 18:18:28 +0200 Subject: [PATCH 220/374] Fix for IPv6 compilation and linkage errors Two errors have been spotted, when IPv6 is enabled in the ravenusb Project-Makefile: #CONTIKI_NO_NET=1 CONTIKI_WITH_IPV6=1 The compile error results from a variable name mismatch in cdc_task.c The variable 'r' is undeclared and should be renamed to 'route' The linker also fails with 'undefined references' This has been mediated by adding 'core/net' to Modules in the Project-Makefile. --- examples/ravenusbstick/Makefile.ravenusbstick | 2 +- platform/avr-ravenusb/cdc_task.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/ravenusbstick/Makefile.ravenusbstick b/examples/ravenusbstick/Makefile.ravenusbstick index d00ba6cba..27b244b11 100644 --- a/examples/ravenusbstick/Makefile.ravenusbstick +++ b/examples/ravenusbstick/Makefile.ravenusbstick @@ -8,7 +8,7 @@ CONTIKI_WITH_IPV6=0 CONTIKI = ../.. -MODULES+=core/net/mac/sicslowmac core/net/mac core/net/llsec +MODULES+=core/net/mac/sicslowmac core/net core/net/mac core/net/llsec PROJECT_SOURCEFILES += fakeuip.c diff --git a/platform/avr-ravenusb/cdc_task.c b/platform/avr-ravenusb/cdc_task.c index 8caabc772..de30d8d65 100644 --- a/platform/avr-ravenusb/cdc_task.c +++ b/platform/avr-ravenusb/cdc_task.c @@ -611,7 +611,7 @@ extern uip_ds6_netif_t uip_ds6_if; uip_ds6_route_t *route; for(route = uip_ds6_route_head(); route != NULL; - route = uip_ds6_route_next(r)) { + route = uip_ds6_route_next(route)) { ipaddr_add(&route->ipaddr); PRINTF_P(PSTR("/%u (via "), route->length); ipaddr_add(uip_ds6_route_nexthop(route)); From 633bf09f6db22fb307ec310625344724fa35bfc7 Mon Sep 17 00:00:00 2001 From: Yasuyuki Tanaka Date: Thu, 12 May 2016 21:13:41 +0200 Subject: [PATCH 221/374] Fix the path for wpcapslip in testscript for Instant Contiki --- regression-tests/20-ip64/01-cooja-ip64-http-socket.csc | 2 +- regression-tests/21-large-rpl/testscript.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/regression-tests/20-ip64/01-cooja-ip64-http-socket.csc b/regression-tests/20-ip64/01-cooja-ip64-http-socket.csc index bc075971b..cec228b5e 100644 --- a/regression-tests/20-ip64/01-cooja-ip64-http-socket.csc +++ b/regression-tests/20-ip64/01-cooja-ip64-http-socket.csc @@ -151,7 +151,7 @@ if (travis == null) { /* Instant Contiki */ CMD_TUNNEL = "echo '-vj' > ~/.slirprc && make Connect.class && java Connect 'nc localhost 60001' 'script -t -f -c slirp'"; CMD_PING = "ping -c 5 8.8.8.8"; - CMD_DIR = "../../wpcapslip"; + CMD_DIR = "../../tools/wpcapslip"; } else { /* Travis */ CMD_TUNNEL = "cd $TRAVIS_BUILD_DIR/tools/wpcapslip && sudo apt-get install slirp && echo '-vj' > ~/.slirprc && make Connect.class && java Connect 'nc localhost 60001' 'script -t -f -c slirp'"; diff --git a/regression-tests/21-large-rpl/testscript.js b/regression-tests/21-large-rpl/testscript.js index 0c23bceef..4c4c8a56b 100644 --- a/regression-tests/21-large-rpl/testscript.js +++ b/regression-tests/21-large-rpl/testscript.js @@ -9,7 +9,7 @@ if (travis == null) { /* Instant Contiki */ CMD_TUNNEL = "echo '-vj' > ~/.slirprc && make Connect.class && java Connect 'nc localhost 60001' 'script -t -f -c slirp'"; CMD_PING = "ping -c 5 8.8.8.8"; - CMD_DIR = "../../wpcapslip"; + CMD_DIR = "../../tools/wpcapslip"; } else { /* Travis */ CMD_TUNNEL = "cd $TRAVIS_BUILD_DIR/tools/wpcapslip && sudo apt-get install slirp && echo '-vj' > ~/.slirprc && make Connect.class && java Connect 'nc localhost 60001' 'script -t -f -c slirp'"; From 5bc158fa75e691b552efaf477c9dced27018fdc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Corbal=C3=A1n?= Date: Fri, 13 May 2016 17:56:49 +0100 Subject: [PATCH 222/374] Add upload script to Makefile.launchpad --- .../srf06-cc26xx/launchpad/Makefile.launchpad | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/platform/srf06-cc26xx/launchpad/Makefile.launchpad b/platform/srf06-cc26xx/launchpad/Makefile.launchpad index deefeed81..853450142 100644 --- a/platform/srf06-cc26xx/launchpad/Makefile.launchpad +++ b/platform/srf06-cc26xx/launchpad/Makefile.launchpad @@ -4,3 +4,19 @@ CONTIKI_TARGET_DIRS += launchpad common BOARD_SOURCEFILES += board.c launchpad-sensors.c leds-arch.c button-sensor.c BOARD_SOURCEFILES += ext-flash.c board-spi.c + +PYTHON = python +BSL_FLAGS += -e -w -v + +ifdef PORT + BSL_FLAGS += -p $(PORT) +endif + +BSL = $(CONTIKI)/tools/cc2538-bsl/cc2538-bsl.py + +%.upload: %.bin +ifeq ($(wildcard $(BSL)), ) + @echo "ERROR: Could not find the cc2538-bsl script. Did you run 'git submodule update --init' ?" +else + $(PYTHON) $(BSL) $(BSL_FLAGS) $< +endif From 3c19e870f1f264f725a3686ba70350d1f338e353 Mon Sep 17 00:00:00 2001 From: Robert Olsson Date: Sat, 14 May 2016 12:05:19 +0200 Subject: [PATCH 223/374] Moving the avr-rss2 platform examples to the global examples location as suggested by the maintainers. --- .../avr-rss2}/avr_radio_power/AtMega256RFR2-summary-power.dat | 0 .../examples => examples/avr-rss2}/avr_radio_power/Makefile | 0 .../examples => examples/avr-rss2}/avr_radio_power/README.md | 0 .../avr-rss2}/avr_radio_power/avr_radio_power.c | 0 .../examples => examples/avr-rss2}/avr_radio_power/project-conf.h | 0 .../examples => examples/avr-rss2}/hello-sensors/Makefile | 0 .../examples => examples/avr-rss2}/hello-sensors/README.md | 0 .../examples => examples/avr-rss2}/hello-sensors/hello-sensors.c | 0 .../examples => examples/avr-rss2}/hello-sensors/project-conf.h | 0 .../examples => examples/avr-rss2}/ipv6/dc-rpl-coap/Makefile | 0 .../examples => examples/avr-rss2}/ipv6/dc-rpl-coap/README.md | 0 .../examples => examples/avr-rss2}/ipv6/dc-rpl-coap/coap-client.c | 0 .../examples => examples/avr-rss2}/ipv6/dc-rpl-coap/coap-server.c | 0 .../avr-rss2}/ipv6/dc-rpl-coap/dc-rpl-coap.csc | 0 .../avr-rss2}/ipv6/dc-rpl-coap/dev/dc-hw-sensor.c | 0 .../avr-rss2}/ipv6/dc-rpl-coap/dev/dc-hw-sensor.h | 0 .../avr-rss2}/ipv6/dc-rpl-coap/dev/dc-status-sensor.c | 0 .../avr-rss2}/ipv6/dc-rpl-coap/dev/dc-status-sensor.h | 0 .../avr-rss2}/ipv6/dc-rpl-coap/dev/dc-vdc-sensor.c | 0 .../avr-rss2}/ipv6/dc-rpl-coap/dev/dc-vdc-sensor.h | 0 .../examples => examples/avr-rss2}/ipv6/dc-rpl-coap/er-dc-test.h | 0 .../avr-rss2}/ipv6/dc-rpl-coap/project-conf.h | 0 .../avr-rss2}/ipv6/dc-rpl-coap/resources/res-dc-co2.c | 0 .../avr-rss2}/ipv6/dc-rpl-coap/resources/res-dc-hwcfg.c | 0 .../avr-rss2}/ipv6/dc-rpl-coap/resources/res-dc-status-obs.c | 0 .../avr-rss2}/ipv6/dc-rpl-coap/resources/res-dc-vdc.c | 0 .../avr-rss2}/ipv6/rpl-border-router/Makefile | 0 .../avr-rss2}/ipv6/rpl-border-router/README.ETHERNET.md | 0 .../avr-rss2}/ipv6/rpl-border-router/README.md | 0 .../avr-rss2}/ipv6/rpl-border-router/border-router.c | 0 .../avr-rss2}/ipv6/rpl-border-router/enc28j60-ip64-driver.c | 0 .../avr-rss2}/ipv6/rpl-border-router/enc28j60-ip64-driver.h | 0 .../avr-rss2}/ipv6/rpl-border-router/eth-bridge.c | 0 .../avr-rss2}/ipv6/rpl-border-router/httpd-simple.c | 0 .../avr-rss2}/ipv6/rpl-border-router/httpd-simple.h | 0 .../avr-rss2}/ipv6/rpl-border-router/project-conf.h | 0 .../examples => examples/avr-rss2}/ipv6/rpl-udp-report/Makefile | 0 .../examples => examples/avr-rss2}/ipv6/rpl-udp-report/README.md | 0 .../avr-rss2}/ipv6/rpl-udp-report/project-conf.h | 0 .../examples => examples/avr-rss2}/ipv6/rpl-udp-report/report.c | 0 .../avr-rss2}/ipv6/rpl-udp-report/rss2-rpl-udp.csc | 0 .../examples => examples/avr-rss2}/ipv6/rpl-udp-report/sink.c | 0 .../examples => examples/avr-rss2}/ipv6/sensd_client/Makefile | 0 .../examples => examples/avr-rss2}/ipv6/sensd_client/README.md | 0 .../avr-rss2}/ipv6/sensd_client/project-conf.h | 0 .../avr-rss2}/ipv6/sensd_client/sensd_client.c | 0 .../examples => examples/avr-rss2}/ipv6/sensd_client/server.c | 0 47 files changed, 0 insertions(+), 0 deletions(-) rename {platform/avr-rss2/examples => examples/avr-rss2}/avr_radio_power/AtMega256RFR2-summary-power.dat (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/avr_radio_power/Makefile (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/avr_radio_power/README.md (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/avr_radio_power/avr_radio_power.c (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/avr_radio_power/project-conf.h (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/hello-sensors/Makefile (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/hello-sensors/README.md (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/hello-sensors/hello-sensors.c (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/hello-sensors/project-conf.h (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/dc-rpl-coap/Makefile (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/dc-rpl-coap/README.md (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/dc-rpl-coap/coap-client.c (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/dc-rpl-coap/coap-server.c (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/dc-rpl-coap/dc-rpl-coap.csc (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/dc-rpl-coap/dev/dc-hw-sensor.c (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/dc-rpl-coap/dev/dc-hw-sensor.h (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/dc-rpl-coap/dev/dc-status-sensor.c (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/dc-rpl-coap/dev/dc-status-sensor.h (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/dc-rpl-coap/dev/dc-vdc-sensor.c (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/dc-rpl-coap/dev/dc-vdc-sensor.h (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/dc-rpl-coap/er-dc-test.h (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/dc-rpl-coap/project-conf.h (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/dc-rpl-coap/resources/res-dc-co2.c (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/dc-rpl-coap/resources/res-dc-hwcfg.c (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/dc-rpl-coap/resources/res-dc-status-obs.c (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/dc-rpl-coap/resources/res-dc-vdc.c (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/rpl-border-router/Makefile (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/rpl-border-router/README.ETHERNET.md (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/rpl-border-router/README.md (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/rpl-border-router/border-router.c (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/rpl-border-router/enc28j60-ip64-driver.c (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/rpl-border-router/enc28j60-ip64-driver.h (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/rpl-border-router/eth-bridge.c (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/rpl-border-router/httpd-simple.c (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/rpl-border-router/httpd-simple.h (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/rpl-border-router/project-conf.h (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/rpl-udp-report/Makefile (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/rpl-udp-report/README.md (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/rpl-udp-report/project-conf.h (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/rpl-udp-report/report.c (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/rpl-udp-report/rss2-rpl-udp.csc (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/rpl-udp-report/sink.c (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/sensd_client/Makefile (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/sensd_client/README.md (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/sensd_client/project-conf.h (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/sensd_client/sensd_client.c (100%) rename {platform/avr-rss2/examples => examples/avr-rss2}/ipv6/sensd_client/server.c (100%) diff --git a/platform/avr-rss2/examples/avr_radio_power/AtMega256RFR2-summary-power.dat b/examples/avr-rss2/avr_radio_power/AtMega256RFR2-summary-power.dat similarity index 100% rename from platform/avr-rss2/examples/avr_radio_power/AtMega256RFR2-summary-power.dat rename to examples/avr-rss2/avr_radio_power/AtMega256RFR2-summary-power.dat diff --git a/platform/avr-rss2/examples/avr_radio_power/Makefile b/examples/avr-rss2/avr_radio_power/Makefile similarity index 100% rename from platform/avr-rss2/examples/avr_radio_power/Makefile rename to examples/avr-rss2/avr_radio_power/Makefile diff --git a/platform/avr-rss2/examples/avr_radio_power/README.md b/examples/avr-rss2/avr_radio_power/README.md similarity index 100% rename from platform/avr-rss2/examples/avr_radio_power/README.md rename to examples/avr-rss2/avr_radio_power/README.md diff --git a/platform/avr-rss2/examples/avr_radio_power/avr_radio_power.c b/examples/avr-rss2/avr_radio_power/avr_radio_power.c similarity index 100% rename from platform/avr-rss2/examples/avr_radio_power/avr_radio_power.c rename to examples/avr-rss2/avr_radio_power/avr_radio_power.c diff --git a/platform/avr-rss2/examples/avr_radio_power/project-conf.h b/examples/avr-rss2/avr_radio_power/project-conf.h similarity index 100% rename from platform/avr-rss2/examples/avr_radio_power/project-conf.h rename to examples/avr-rss2/avr_radio_power/project-conf.h diff --git a/platform/avr-rss2/examples/hello-sensors/Makefile b/examples/avr-rss2/hello-sensors/Makefile similarity index 100% rename from platform/avr-rss2/examples/hello-sensors/Makefile rename to examples/avr-rss2/hello-sensors/Makefile diff --git a/platform/avr-rss2/examples/hello-sensors/README.md b/examples/avr-rss2/hello-sensors/README.md similarity index 100% rename from platform/avr-rss2/examples/hello-sensors/README.md rename to examples/avr-rss2/hello-sensors/README.md diff --git a/platform/avr-rss2/examples/hello-sensors/hello-sensors.c b/examples/avr-rss2/hello-sensors/hello-sensors.c similarity index 100% rename from platform/avr-rss2/examples/hello-sensors/hello-sensors.c rename to examples/avr-rss2/hello-sensors/hello-sensors.c diff --git a/platform/avr-rss2/examples/hello-sensors/project-conf.h b/examples/avr-rss2/hello-sensors/project-conf.h similarity index 100% rename from platform/avr-rss2/examples/hello-sensors/project-conf.h rename to examples/avr-rss2/hello-sensors/project-conf.h diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/Makefile b/examples/avr-rss2/ipv6/dc-rpl-coap/Makefile similarity index 100% rename from platform/avr-rss2/examples/ipv6/dc-rpl-coap/Makefile rename to examples/avr-rss2/ipv6/dc-rpl-coap/Makefile diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/README.md b/examples/avr-rss2/ipv6/dc-rpl-coap/README.md similarity index 100% rename from platform/avr-rss2/examples/ipv6/dc-rpl-coap/README.md rename to examples/avr-rss2/ipv6/dc-rpl-coap/README.md diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-client.c b/examples/avr-rss2/ipv6/dc-rpl-coap/coap-client.c similarity index 100% rename from platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-client.c rename to examples/avr-rss2/ipv6/dc-rpl-coap/coap-client.c diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-server.c b/examples/avr-rss2/ipv6/dc-rpl-coap/coap-server.c similarity index 100% rename from platform/avr-rss2/examples/ipv6/dc-rpl-coap/coap-server.c rename to examples/avr-rss2/ipv6/dc-rpl-coap/coap-server.c diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dc-rpl-coap.csc b/examples/avr-rss2/ipv6/dc-rpl-coap/dc-rpl-coap.csc similarity index 100% rename from platform/avr-rss2/examples/ipv6/dc-rpl-coap/dc-rpl-coap.csc rename to examples/avr-rss2/ipv6/dc-rpl-coap/dc-rpl-coap.csc diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-hw-sensor.c b/examples/avr-rss2/ipv6/dc-rpl-coap/dev/dc-hw-sensor.c similarity index 100% rename from platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-hw-sensor.c rename to examples/avr-rss2/ipv6/dc-rpl-coap/dev/dc-hw-sensor.c diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-hw-sensor.h b/examples/avr-rss2/ipv6/dc-rpl-coap/dev/dc-hw-sensor.h similarity index 100% rename from platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-hw-sensor.h rename to examples/avr-rss2/ipv6/dc-rpl-coap/dev/dc-hw-sensor.h diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-status-sensor.c b/examples/avr-rss2/ipv6/dc-rpl-coap/dev/dc-status-sensor.c similarity index 100% rename from platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-status-sensor.c rename to examples/avr-rss2/ipv6/dc-rpl-coap/dev/dc-status-sensor.c diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-status-sensor.h b/examples/avr-rss2/ipv6/dc-rpl-coap/dev/dc-status-sensor.h similarity index 100% rename from platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-status-sensor.h rename to examples/avr-rss2/ipv6/dc-rpl-coap/dev/dc-status-sensor.h diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-vdc-sensor.c b/examples/avr-rss2/ipv6/dc-rpl-coap/dev/dc-vdc-sensor.c similarity index 100% rename from platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-vdc-sensor.c rename to examples/avr-rss2/ipv6/dc-rpl-coap/dev/dc-vdc-sensor.c diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-vdc-sensor.h b/examples/avr-rss2/ipv6/dc-rpl-coap/dev/dc-vdc-sensor.h similarity index 100% rename from platform/avr-rss2/examples/ipv6/dc-rpl-coap/dev/dc-vdc-sensor.h rename to examples/avr-rss2/ipv6/dc-rpl-coap/dev/dc-vdc-sensor.h diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/er-dc-test.h b/examples/avr-rss2/ipv6/dc-rpl-coap/er-dc-test.h similarity index 100% rename from platform/avr-rss2/examples/ipv6/dc-rpl-coap/er-dc-test.h rename to examples/avr-rss2/ipv6/dc-rpl-coap/er-dc-test.h diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/project-conf.h b/examples/avr-rss2/ipv6/dc-rpl-coap/project-conf.h similarity index 100% rename from platform/avr-rss2/examples/ipv6/dc-rpl-coap/project-conf.h rename to examples/avr-rss2/ipv6/dc-rpl-coap/project-conf.h diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-co2.c b/examples/avr-rss2/ipv6/dc-rpl-coap/resources/res-dc-co2.c similarity index 100% rename from platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-co2.c rename to examples/avr-rss2/ipv6/dc-rpl-coap/resources/res-dc-co2.c diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-hwcfg.c b/examples/avr-rss2/ipv6/dc-rpl-coap/resources/res-dc-hwcfg.c similarity index 100% rename from platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-hwcfg.c rename to examples/avr-rss2/ipv6/dc-rpl-coap/resources/res-dc-hwcfg.c diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-status-obs.c b/examples/avr-rss2/ipv6/dc-rpl-coap/resources/res-dc-status-obs.c similarity index 100% rename from platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-status-obs.c rename to examples/avr-rss2/ipv6/dc-rpl-coap/resources/res-dc-status-obs.c diff --git a/platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-vdc.c b/examples/avr-rss2/ipv6/dc-rpl-coap/resources/res-dc-vdc.c similarity index 100% rename from platform/avr-rss2/examples/ipv6/dc-rpl-coap/resources/res-dc-vdc.c rename to examples/avr-rss2/ipv6/dc-rpl-coap/resources/res-dc-vdc.c diff --git a/platform/avr-rss2/examples/ipv6/rpl-border-router/Makefile b/examples/avr-rss2/ipv6/rpl-border-router/Makefile similarity index 100% rename from platform/avr-rss2/examples/ipv6/rpl-border-router/Makefile rename to examples/avr-rss2/ipv6/rpl-border-router/Makefile diff --git a/platform/avr-rss2/examples/ipv6/rpl-border-router/README.ETHERNET.md b/examples/avr-rss2/ipv6/rpl-border-router/README.ETHERNET.md similarity index 100% rename from platform/avr-rss2/examples/ipv6/rpl-border-router/README.ETHERNET.md rename to examples/avr-rss2/ipv6/rpl-border-router/README.ETHERNET.md diff --git a/platform/avr-rss2/examples/ipv6/rpl-border-router/README.md b/examples/avr-rss2/ipv6/rpl-border-router/README.md similarity index 100% rename from platform/avr-rss2/examples/ipv6/rpl-border-router/README.md rename to examples/avr-rss2/ipv6/rpl-border-router/README.md diff --git a/platform/avr-rss2/examples/ipv6/rpl-border-router/border-router.c b/examples/avr-rss2/ipv6/rpl-border-router/border-router.c similarity index 100% rename from platform/avr-rss2/examples/ipv6/rpl-border-router/border-router.c rename to examples/avr-rss2/ipv6/rpl-border-router/border-router.c diff --git a/platform/avr-rss2/examples/ipv6/rpl-border-router/enc28j60-ip64-driver.c b/examples/avr-rss2/ipv6/rpl-border-router/enc28j60-ip64-driver.c similarity index 100% rename from platform/avr-rss2/examples/ipv6/rpl-border-router/enc28j60-ip64-driver.c rename to examples/avr-rss2/ipv6/rpl-border-router/enc28j60-ip64-driver.c diff --git a/platform/avr-rss2/examples/ipv6/rpl-border-router/enc28j60-ip64-driver.h b/examples/avr-rss2/ipv6/rpl-border-router/enc28j60-ip64-driver.h similarity index 100% rename from platform/avr-rss2/examples/ipv6/rpl-border-router/enc28j60-ip64-driver.h rename to examples/avr-rss2/ipv6/rpl-border-router/enc28j60-ip64-driver.h diff --git a/platform/avr-rss2/examples/ipv6/rpl-border-router/eth-bridge.c b/examples/avr-rss2/ipv6/rpl-border-router/eth-bridge.c similarity index 100% rename from platform/avr-rss2/examples/ipv6/rpl-border-router/eth-bridge.c rename to examples/avr-rss2/ipv6/rpl-border-router/eth-bridge.c diff --git a/platform/avr-rss2/examples/ipv6/rpl-border-router/httpd-simple.c b/examples/avr-rss2/ipv6/rpl-border-router/httpd-simple.c similarity index 100% rename from platform/avr-rss2/examples/ipv6/rpl-border-router/httpd-simple.c rename to examples/avr-rss2/ipv6/rpl-border-router/httpd-simple.c diff --git a/platform/avr-rss2/examples/ipv6/rpl-border-router/httpd-simple.h b/examples/avr-rss2/ipv6/rpl-border-router/httpd-simple.h similarity index 100% rename from platform/avr-rss2/examples/ipv6/rpl-border-router/httpd-simple.h rename to examples/avr-rss2/ipv6/rpl-border-router/httpd-simple.h diff --git a/platform/avr-rss2/examples/ipv6/rpl-border-router/project-conf.h b/examples/avr-rss2/ipv6/rpl-border-router/project-conf.h similarity index 100% rename from platform/avr-rss2/examples/ipv6/rpl-border-router/project-conf.h rename to examples/avr-rss2/ipv6/rpl-border-router/project-conf.h diff --git a/platform/avr-rss2/examples/ipv6/rpl-udp-report/Makefile b/examples/avr-rss2/ipv6/rpl-udp-report/Makefile similarity index 100% rename from platform/avr-rss2/examples/ipv6/rpl-udp-report/Makefile rename to examples/avr-rss2/ipv6/rpl-udp-report/Makefile diff --git a/platform/avr-rss2/examples/ipv6/rpl-udp-report/README.md b/examples/avr-rss2/ipv6/rpl-udp-report/README.md similarity index 100% rename from platform/avr-rss2/examples/ipv6/rpl-udp-report/README.md rename to examples/avr-rss2/ipv6/rpl-udp-report/README.md diff --git a/platform/avr-rss2/examples/ipv6/rpl-udp-report/project-conf.h b/examples/avr-rss2/ipv6/rpl-udp-report/project-conf.h similarity index 100% rename from platform/avr-rss2/examples/ipv6/rpl-udp-report/project-conf.h rename to examples/avr-rss2/ipv6/rpl-udp-report/project-conf.h diff --git a/platform/avr-rss2/examples/ipv6/rpl-udp-report/report.c b/examples/avr-rss2/ipv6/rpl-udp-report/report.c similarity index 100% rename from platform/avr-rss2/examples/ipv6/rpl-udp-report/report.c rename to examples/avr-rss2/ipv6/rpl-udp-report/report.c diff --git a/platform/avr-rss2/examples/ipv6/rpl-udp-report/rss2-rpl-udp.csc b/examples/avr-rss2/ipv6/rpl-udp-report/rss2-rpl-udp.csc similarity index 100% rename from platform/avr-rss2/examples/ipv6/rpl-udp-report/rss2-rpl-udp.csc rename to examples/avr-rss2/ipv6/rpl-udp-report/rss2-rpl-udp.csc diff --git a/platform/avr-rss2/examples/ipv6/rpl-udp-report/sink.c b/examples/avr-rss2/ipv6/rpl-udp-report/sink.c similarity index 100% rename from platform/avr-rss2/examples/ipv6/rpl-udp-report/sink.c rename to examples/avr-rss2/ipv6/rpl-udp-report/sink.c diff --git a/platform/avr-rss2/examples/ipv6/sensd_client/Makefile b/examples/avr-rss2/ipv6/sensd_client/Makefile similarity index 100% rename from platform/avr-rss2/examples/ipv6/sensd_client/Makefile rename to examples/avr-rss2/ipv6/sensd_client/Makefile diff --git a/platform/avr-rss2/examples/ipv6/sensd_client/README.md b/examples/avr-rss2/ipv6/sensd_client/README.md similarity index 100% rename from platform/avr-rss2/examples/ipv6/sensd_client/README.md rename to examples/avr-rss2/ipv6/sensd_client/README.md diff --git a/platform/avr-rss2/examples/ipv6/sensd_client/project-conf.h b/examples/avr-rss2/ipv6/sensd_client/project-conf.h similarity index 100% rename from platform/avr-rss2/examples/ipv6/sensd_client/project-conf.h rename to examples/avr-rss2/ipv6/sensd_client/project-conf.h diff --git a/platform/avr-rss2/examples/ipv6/sensd_client/sensd_client.c b/examples/avr-rss2/ipv6/sensd_client/sensd_client.c similarity index 100% rename from platform/avr-rss2/examples/ipv6/sensd_client/sensd_client.c rename to examples/avr-rss2/ipv6/sensd_client/sensd_client.c diff --git a/platform/avr-rss2/examples/ipv6/sensd_client/server.c b/examples/avr-rss2/ipv6/sensd_client/server.c similarity index 100% rename from platform/avr-rss2/examples/ipv6/sensd_client/server.c rename to examples/avr-rss2/ipv6/sensd_client/server.c From cd5a0ef29156e959f0124edbfe225721f85ec468 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 14 May 2016 19:16:43 +0100 Subject: [PATCH 224/374] Consolidate .upload for all CC26xx/CC13xx boards The block that controls the `.upload` target is unnecessarily replicated in multiple sub-board Makefiles. This was originally done because the SmartRF and the Launchpad can be programmed with the c2538-bsl script, whereas the sensortag cannot. This commit moves the `cc2538-bsl` / `.upload` target logic to the top level cpu Makefile (`cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx`). Board makefiles simply set the make variable `BOARD_SUPPORTS_BSL` to 1 to signal that they can be programmed by the BSL script. If `BOARD_SUPPORTS_BSL` is not equal to 1, trying to use the `.upload` target will return an error message. For example: ``` $ make BOARD=sensortag/cc2650 cc26xx-demo.upload using saved target 'srf06-cc26xx' This board cannot be programmed with the ROM bootloader and therefore does not support the .upload target. ``` --- cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx | 20 +++++++++++++++++++ .../srf06-cc26xx/launchpad/Makefile.launchpad | 17 ++-------------- platform/srf06-cc26xx/srf06/Makefile.srf06 | 17 ++-------------- 3 files changed, 24 insertions(+), 30 deletions(-) diff --git a/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx b/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx index f6ac275da..d0cf1cf31 100644 --- a/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx +++ b/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx @@ -81,6 +81,15 @@ CONTIKI_SOURCEFILES += $(CONTIKI_CPU_SOURCEFILES) $(DEBUG_IO_SOURCEFILES) TARGET_START_SOURCEFILES += fault-handlers.c $(TI_XXWARE_STARTUP_SRCS) TARGET_STARTFILES = $(addprefix $(OBJECTDIR)/,$(call oname, $(TARGET_START_SOURCEFILES))) +PYTHON = python +BSL_FLAGS += -e -w -v + +ifdef PORT + BSL_FLAGS += -p $(PORT) +endif + +BSL = $(CONTIKI)/tools/cc2538-bsl/cc2538-bsl.py + ### Don't treat the .elf as intermediate .PRECIOUS: %.elf %.hex %.bin @@ -125,3 +134,14 @@ STACK_SIZE = 0 @$(SIZE) -A $< | egrep "data|bss" | awk '{s+=$$2} END {s=s+$(STACK_SIZE); f=$(RAM_SIZE)-s; printf "[RAM] used %6d, free %6d\n",s,f;}' @$(SIZE) -A $< | egrep "text|isr_vector" | awk '{s+=$$2} END {f=$(FLASH_SIZE)-s; printf "[Flash] used %6d, free %6d\n",s,f;}' +ifeq ($(BOARD_SUPPORTS_BSL),1) +%.upload: %.bin +ifeq ($(wildcard $(BSL)), ) + @echo "ERROR: Could not find the cc2538-bsl script. Did you run 'git submodule update --init' ?" +else + $(PYTHON) $(BSL) $(BSL_FLAGS) $< +endif +else +%.upload: + @echo "This board cannot be programmed through the ROM bootloader and therefore does not support the .upload target." +endif diff --git a/platform/srf06-cc26xx/launchpad/Makefile.launchpad b/platform/srf06-cc26xx/launchpad/Makefile.launchpad index 853450142..54bd81ced 100644 --- a/platform/srf06-cc26xx/launchpad/Makefile.launchpad +++ b/platform/srf06-cc26xx/launchpad/Makefile.launchpad @@ -5,18 +5,5 @@ CONTIKI_TARGET_DIRS += launchpad common BOARD_SOURCEFILES += board.c launchpad-sensors.c leds-arch.c button-sensor.c BOARD_SOURCEFILES += ext-flash.c board-spi.c -PYTHON = python -BSL_FLAGS += -e -w -v - -ifdef PORT - BSL_FLAGS += -p $(PORT) -endif - -BSL = $(CONTIKI)/tools/cc2538-bsl/cc2538-bsl.py - -%.upload: %.bin -ifeq ($(wildcard $(BSL)), ) - @echo "ERROR: Could not find the cc2538-bsl script. Did you run 'git submodule update --init' ?" -else - $(PYTHON) $(BSL) $(BSL_FLAGS) $< -endif +### Signal that we can be programmed with cc2538-bsl +BOARD_SUPPORTS_BSL=1 diff --git a/platform/srf06-cc26xx/srf06/Makefile.srf06 b/platform/srf06-cc26xx/srf06/Makefile.srf06 index 3459cbadc..afdeeddec 100644 --- a/platform/srf06-cc26xx/srf06/Makefile.srf06 +++ b/platform/srf06-cc26xx/srf06/Makefile.srf06 @@ -4,18 +4,5 @@ CONTIKI_TARGET_DIRS += srf06 BOARD_SOURCEFILES += leds-arch.c srf06-sensors.c button-sensor.c board.c -PYTHON = python -BSL_FLAGS += -e -w -v - -ifdef PORT - BSL_FLAGS += -p $(PORT) -endif - -BSL = $(CONTIKI)/tools/cc2538-bsl/cc2538-bsl.py - -%.upload: %.bin -ifeq ($(wildcard $(BSL)), ) - @echo "ERROR: Could not find the cc2538-bsl script. Did you run 'git submodule update --init' ?" -else - $(PYTHON) $(BSL) $(BSL_FLAGS) $< -endif +### Signal that we can be programmed with cc2538-bsl +BOARD_SUPPORTS_BSL=1 From 099a933c90c27f3b533692db8c3c860a6f393a48 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 13 Mar 2016 13:02:41 +0000 Subject: [PATCH 225/374] Add support for the CC1310 LaunchPad --- .../launchpad/cc1310/Makefile.cc1310 | 8 + .../srf06-cc26xx/launchpad/cc1310/board.h | 189 ++++++++++++++++++ 2 files changed, 197 insertions(+) create mode 100644 platform/srf06-cc26xx/launchpad/cc1310/Makefile.cc1310 create mode 100644 platform/srf06-cc26xx/launchpad/cc1310/board.h diff --git a/platform/srf06-cc26xx/launchpad/cc1310/Makefile.cc1310 b/platform/srf06-cc26xx/launchpad/cc1310/Makefile.cc1310 new file mode 100644 index 000000000..8d3d2abd4 --- /dev/null +++ b/platform/srf06-cc26xx/launchpad/cc1310/Makefile.cc1310 @@ -0,0 +1,8 @@ +### Will allow the inclusion of the correct CPU makefile +CPU_FAMILY = cc13xx + +### Add to the source dirs +CONTIKI_TARGET_DIRS += launchpad/cc1310 + +### Include the common launchpad makefile +include $(PLATFORM_ROOT_DIR)/launchpad/Makefile.launchpad diff --git a/platform/srf06-cc26xx/launchpad/cc1310/board.h b/platform/srf06-cc26xx/launchpad/cc1310/board.h new file mode 100644 index 000000000..d6cfeeedb --- /dev/null +++ b/platform/srf06-cc26xx/launchpad/cc1310/board.h @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2016, Texas Instruments Incorporated - http://www.ti.com/ + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +/** \addtogroup launchpad-peripherals + * @{ + * + * \defgroup launchpad-cc1310-specific CC1310 LaunchPad Peripherals + * + * Defines related to the CC1310 LaunchPad + * + * This file provides connectivity information on LEDs, Buttons, UART and + * other peripherals + * + * This file is not meant to be modified by the user. + * @{ + * + * \file + * Header file with definitions related to the I/O connections on the TI + * CC1310 LaunchPad + * + * \note Do not include this file directly. It gets included by contiki-conf + * after all relevant directives have been set. + */ +/*---------------------------------------------------------------------------*/ +#ifndef BOARD_H_ +#define BOARD_H_ +/*---------------------------------------------------------------------------*/ +#include "ioc.h" +/*---------------------------------------------------------------------------*/ +/** + * \name LED configurations + * + * Those values are not meant to be modified by the user + * @{ + */ +/* Some files include leds.h before us, so we need to get rid of defaults in + * leds.h before we provide correct definitions */ +#undef LEDS_GREEN +#undef LEDS_YELLOW +#undef LEDS_RED +#undef LEDS_CONF_ALL + +#define LEDS_RED 1 +#define LEDS_GREEN 2 +#define LEDS_YELLOW LEDS_GREEN +#define LEDS_ORANGE LEDS_RED + +#define LEDS_CONF_ALL 3 + +/* Notify various examples that we have LEDs */ +#define PLATFORM_HAS_LEDS 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name LED IOID mappings + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_LED_1 IOID_6 +#define BOARD_IOID_LED_2 IOID_7 +#define BOARD_LED_1 (1 << BOARD_IOID_LED_1) +#define BOARD_LED_2 (1 << BOARD_IOID_LED_2) +#define BOARD_LED_ALL (BOARD_LED_1 | BOARD_LED_2) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name UART IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_UART_RX IOID_2 +#define BOARD_IOID_UART_TX IOID_3 +#define BOARD_IOID_UART_RTS IOID_18 +#define BOARD_IOID_UART_CTS IOID_19 +#define BOARD_UART_RX (1 << BOARD_IOID_UART_RX) +#define BOARD_UART_TX (1 << BOARD_IOID_UART_TX) +#define BOARD_UART_RTS (1 << BOARD_IOID_UART_RTS) +#define BOARD_UART_CTS (1 << BOARD_IOID_UART_CTS) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Button IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_KEY_LEFT IOID_13 +#define BOARD_IOID_KEY_RIGHT IOID_14 +#define BOARD_KEY_LEFT (1 << BOARD_IOID_KEY_LEFT) +#define BOARD_KEY_RIGHT (1 << BOARD_IOID_KEY_RIGHT) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \brief SPI IOID mappings + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_SPI_MOSI IOID_9 +#define BOARD_IOID_SPI_MISO IOID_8 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name External flash IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_FLASH_CS IOID_20 +#define BOARD_FLASH_CS (1 << BOARD_IOID_FLASH_CS) +#define BOARD_IOID_SPI_CLK_FLASH IOID_10 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \brief I2C IOID mappings + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_SCL IOID_4 +#define BOARD_IOID_SDA IOID_5 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \brief Remaining pins + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_CS IOID_11 +#define BOARD_IOID_TDO IOID_16 +#define BOARD_IOID_TDI IOID_17 +#define BOARD_IOID_DIO12 IOID_12 +#define BOARD_IOID_DIO15 IOID_15 +#define BOARD_IOID_DIO21 IOID_21 +#define BOARD_IOID_DIO22 IOID_22 +#define BOARD_IOID_DIO23 IOID_23 +#define BOARD_IOID_DIO24 IOID_24 +#define BOARD_IOID_DIO25 IOID_25 +#define BOARD_IOID_DIO26 IOID_26 +#define BOARD_IOID_DIO27 IOID_27 +#define BOARD_IOID_DIO28 IOID_28 +#define BOARD_IOID_DIO29 IOID_29 +#define BOARD_IOID_DIO30 IOID_30 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Device string used on startup + * @{ + */ +#define BOARD_STRING "TI CC1310 LaunchPad" + +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* BOARD_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ From 06f446399634219bc90199ad219025efa73bbcba Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 13 Mar 2016 13:03:02 +0000 Subject: [PATCH 226/374] Extend documentation to include the CC1310 LaunchPad --- platform/srf06-cc26xx/README.md | 4 +++- platform/srf06-cc26xx/contiki-main.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/platform/srf06-cc26xx/README.md b/platform/srf06-cc26xx/README.md index 4e709ca7d..04d66a0d4 100644 --- a/platform/srf06-cc26xx/README.md +++ b/platform/srf06-cc26xx/README.md @@ -8,6 +8,7 @@ platform supports two different boards: (relevant files and drivers are under `srf06/`) * CC2650 SensorTag 2.0 (relevant drivers under `sensortag/cc2650`) * CC2650 LaunchPad (relevant drivers under `launchpad/cc2650`) +* CC1310 LaunchPad (relevant drivers under `launchpad/cc1310`) The CPU code, common for both platforms, can be found under `$(CONTIKI)/cpu/cc26xx-cc13xx`. The port was developed and tested with CC2650s, but the intention is for it to @@ -45,7 +46,7 @@ In terms of hardware support, the following drivers have been implemented: * OPT3001 sensor * Buzzer * External SPI flash -* Launchpad +* LaunchPads * LEDs * Buttons * External SPI flash @@ -99,6 +100,7 @@ Other options for the `BOARD` make variable are: * Srf06+CC13xxEM: Set `BOARD=srf06/cc13xx` * CC2650 tag: Set `BOARD=sensortag/cc2650` * CC2650 Launchpad: Set `BOARD=launchpad/cc2650` +* CC1310 Launchpad: Set `BOARD=launchpad/cc1310` If the `BOARD` variable is unspecified, an image for the Srf06 CC26XXEM will be built. diff --git a/platform/srf06-cc26xx/contiki-main.c b/platform/srf06-cc26xx/contiki-main.c index b103918e7..9e91cec5d 100644 --- a/platform/srf06-cc26xx/contiki-main.c +++ b/platform/srf06-cc26xx/contiki-main.c @@ -32,13 +32,14 @@ * \addtogroup cc26xx-platforms * @{ * - * \defgroup cc26xx-srf-tag SmartRF+CC13xx/CC26xx EM, CC2650 SensorTag and LaunchPad + * \defgroup cc26xx-srf-tag SmartRF+CC13xx/CC26xx EM, CC2650 SensorTag and LaunchPads * * This platform supports a number of different boards: * - A standard TI SmartRF06EB with a CC26xx EM mounted on it * - A standard TI SmartRF06EB with a CC1310 EM mounted on it * - The new TI SensorTag2.0 * - The TI CC2650 LaunchPad + * - The TI CC1310 LaunchPad * @{ */ #include "ti-lib.h" From 18f67dade263b9d4c7e9c89258199d3e32888275 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 13 Mar 2016 13:03:17 +0000 Subject: [PATCH 227/374] Compile-test CC1310 LaunchPad sources --- regression-tests/18-compile-arm-ports/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/regression-tests/18-compile-arm-ports/Makefile b/regression-tests/18-compile-arm-ports/Makefile index 4222eb7f6..55924037d 100644 --- a/regression-tests/18-compile-arm-ports/Makefile +++ b/regression-tests/18-compile-arm-ports/Makefile @@ -12,6 +12,7 @@ cc26xx/very-sleepy-demo/srf06-cc26xx:BOARD=sensortag/cc2650 \ cc26xx/cc26xx-web-demo/srf06-cc26xx:BOARD=sensortag/cc2650 \ cc26xx/cc26xx-web-demo/srf06-cc26xx:BOARD=srf06/cc13xx \ cc26xx/cc26xx-web-demo/srf06-cc26xx:BOARD=launchpad/cc2650 \ +cc26xx/cc26xx-web-demo/srf06-cc26xx:BOARD=launchpad/cc1310 \ cc26xx/very-sleepy-demo/srf06-cc26xx \ hello-world/cc2538dk \ ipv6/rpl-border-router/cc2538dk \ From 80efd730ae889b0911df1b8097634ae7eb9bf12c Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 14 May 2016 20:22:11 +0100 Subject: [PATCH 228/374] Extend the flash driver to support the MX25R1635F According to the CC1310LP design files, the flash on it is the same as the flash on the CC2650 LP (MX25R8035F 8Mbit). However, the flash on some CC1310 LPs reportedly identifies itself as the 16Mbit one (MX25R1635F). Instruction sets are identical, we simply need to tell the driver to recognise this part's Device ID. --- platform/srf06-cc26xx/common/ext-flash.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/platform/srf06-cc26xx/common/ext-flash.c b/platform/srf06-cc26xx/common/ext-flash.c index 721a36424..62fea2288 100644 --- a/platform/srf06-cc26xx/common/ext-flash.c +++ b/platform/srf06-cc26xx/common/ext-flash.c @@ -40,6 +40,9 @@ #include "ext-flash.h" #include "ti-lib.h" #include "board-spi.h" + +#include +#include /*---------------------------------------------------------------------------*/ /* Instruction codes */ @@ -73,6 +76,7 @@ #define BLS_DEVICE_ID_W25X20CL 0x11 #define BLS_DEVICE_ID_W25X40CL 0x12 #define BLS_DEVICE_ID_MX25R8035F 0x14 +#define BLS_DEVICE_ID_MX25R1635F 0x15 #define BLS_WINBOND_MID 0xEF #define BLS_MACRONIX_MID 0xC2 @@ -179,7 +183,8 @@ verify_part(void) if((rbuf[0] != BLS_WINBOND_MID && rbuf[0] != BLS_MACRONIX_MID) || (rbuf[1] != BLS_DEVICE_ID_W25X20CL && rbuf[1] != BLS_DEVICE_ID_W25X40CL - && rbuf[1] != BLS_DEVICE_ID_MX25R8035F)) { + && rbuf[1] != BLS_DEVICE_ID_MX25R8035F + && rbuf[1] != BLS_DEVICE_ID_MX25R1635F)) { return VERIFY_PART_POWERED_DOWN; } return VERIFY_PART_OK; From d331d39e93ed7696c5c31a1dbe2287c2e80936d5 Mon Sep 17 00:00:00 2001 From: Robert Olsson Date: Sat, 14 May 2016 22:48:09 +0200 Subject: [PATCH 229/374] Correct paths when moving examples for regession tests --- examples/avr-rss2/avr_radio_power/Makefile | 2 +- examples/avr-rss2/hello-sensors/Makefile | 2 +- examples/avr-rss2/ipv6/dc-rpl-coap/Makefile | 2 +- examples/avr-rss2/ipv6/rpl-border-router/Makefile | 2 +- examples/avr-rss2/ipv6/rpl-udp-report/Makefile | 2 +- examples/avr-rss2/ipv6/sensd_client/Makefile | 2 +- regression-tests/23-compile-avr/Makefile | 6 +++--- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/avr-rss2/avr_radio_power/Makefile b/examples/avr-rss2/avr_radio_power/Makefile index fb9b062a1..abaab89f1 100644 --- a/examples/avr-rss2/avr_radio_power/Makefile +++ b/examples/avr-rss2/avr_radio_power/Makefile @@ -4,6 +4,6 @@ CONTIKI_PROJECT = avr_radio_power APPS+=powertrace all: $(CONTIKI_PROJECT) -CONTIKI = ../../../.. +CONTIKI = ../../.. CONTIKI_WITH_RIME = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/avr-rss2/hello-sensors/Makefile b/examples/avr-rss2/hello-sensors/Makefile index c6e0da805..0d1d41b9f 100644 --- a/examples/avr-rss2/hello-sensors/Makefile +++ b/examples/avr-rss2/hello-sensors/Makefile @@ -15,5 +15,5 @@ CUSTOM_RULE_LINK = 1 -CONTIKI = ../../../.. +CONTIKI = ../../.. include $(CONTIKI)/Makefile.include diff --git a/examples/avr-rss2/ipv6/dc-rpl-coap/Makefile b/examples/avr-rss2/ipv6/dc-rpl-coap/Makefile index 9d8bccece..46a7e9c3f 100644 --- a/examples/avr-rss2/ipv6/dc-rpl-coap/Makefile +++ b/examples/avr-rss2/ipv6/dc-rpl-coap/Makefile @@ -2,7 +2,7 @@ CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" all: coap-client coap-server APPS=servreg-hack -CONTIKI=../../../../.. +CONTIKI=../../../.. ifdef WITH_COMPOWER APPS+=powertrace diff --git a/examples/avr-rss2/ipv6/rpl-border-router/Makefile b/examples/avr-rss2/ipv6/rpl-border-router/Makefile index ba3f16af6..630d9dd53 100644 --- a/examples/avr-rss2/ipv6/rpl-border-router/Makefile +++ b/examples/avr-rss2/ipv6/rpl-border-router/Makefile @@ -1,7 +1,7 @@ CONTIKI_PROJECT=border-router all: $(CONTIKI_PROJECT) -CONTIKI=../../../../.. +CONTIKI=../../../.. #linker optimizations SMALL=1 diff --git a/examples/avr-rss2/ipv6/rpl-udp-report/Makefile b/examples/avr-rss2/ipv6/rpl-udp-report/Makefile index 770ad3749..f4c90317e 100644 --- a/examples/avr-rss2/ipv6/rpl-udp-report/Makefile +++ b/examples/avr-rss2/ipv6/rpl-udp-report/Makefile @@ -3,7 +3,7 @@ CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" all: report sink APPS=servreg-hack -CONTIKI=../../../../.. +CONTIKI=../../../.. ifdef WITH_COMPOWER APPS+=powertrace diff --git a/examples/avr-rss2/ipv6/sensd_client/Makefile b/examples/avr-rss2/ipv6/sensd_client/Makefile index c0eabf9b0..f1b0d7d48 100644 --- a/examples/avr-rss2/ipv6/sensd_client/Makefile +++ b/examples/avr-rss2/ipv6/sensd_client/Makefile @@ -2,7 +2,7 @@ CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" all: sensd_client server -CONTIKI=../../../../.. +CONTIKI=../../../.. ifdef PERIOD CFLAGS+=-DPERIOD=$(PERIOD) diff --git a/regression-tests/23-compile-avr/Makefile b/regression-tests/23-compile-avr/Makefile index 0904e2f37..56cef07d3 100644 --- a/regression-tests/23-compile-avr/Makefile +++ b/regression-tests/23-compile-avr/Makefile @@ -4,9 +4,9 @@ TOOLSDIR=../../tools # build avr-rss2 examples, covering IPv6, RPL, Rime, Nullrdc, Contikimac EXAMPLES = \ -platform/avr-rss2/examples/hello-sensors/avr-rss2 \ -platform/avr-rss2/examples/ipv6/rpl-udp-report/avr-rss2 \ -platform/avr-rss2/examples/ipv6/rpl-border-router/avr-rss2 \ +examples/avr-rss2/hello-sensors/avr-rss2 \ +examples/avr-rss2/ipv6/rpl-udp-report/avr-rss2 \ +examples/avr-rss2/ipv6/rpl-border-router/avr-rss2 \ examples/ipv6/rpl-udp/avr-rss2 \ examples/powertrace/avr-rss2 \ examples/rime/avr-rss2 From 2b30370b42fc641510b541c4370a3473b92099cc Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Sun, 15 May 2016 11:20:23 +0200 Subject: [PATCH 230/374] AT driver (master) and example --- apps/at-master/Makefile.at-master | 1 + apps/at-master/at-master.c | 148 ++++++ apps/at-master/at-master.h | 123 +++++ examples/zolertia/zoul/at-test/Makefile | 7 + .../zolertia/zoul/at-test/at-master-test.c | 487 ++++++++++++++++++ examples/zolertia/zoul/at-test/project-conf.h | 67 +++ 6 files changed, 833 insertions(+) create mode 100644 apps/at-master/Makefile.at-master create mode 100644 apps/at-master/at-master.c create mode 100644 apps/at-master/at-master.h create mode 100644 examples/zolertia/zoul/at-test/Makefile create mode 100644 examples/zolertia/zoul/at-test/at-master-test.c create mode 100644 examples/zolertia/zoul/at-test/project-conf.h diff --git a/apps/at-master/Makefile.at-master b/apps/at-master/Makefile.at-master new file mode 100644 index 000000000..9ab561a16 --- /dev/null +++ b/apps/at-master/Makefile.at-master @@ -0,0 +1 @@ +at-master_src = at-master.c diff --git a/apps/at-master/at-master.c b/apps/at-master/at-master.c new file mode 100644 index 000000000..c9e0597b6 --- /dev/null +++ b/apps/at-master/at-master.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * 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. + * + */ +#include "contiki.h" +#include "contiki-lib.h" +#include "at-master.h" +#include "cpu.h" +#include "dev/uart.h" +#include "dev/serial-line.h" +#include "dev/sys-ctrl.h" +#include "lib/list.h" +#include "sys/cc.h" + +#include +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +LIST(at_cmd_list); +process_event_t at_cmd_received_event; +/*---------------------------------------------------------------------------*/ +static uint8_t at_uart = 0; +/*---------------------------------------------------------------------------*/ +PROCESS(at_process, "AT process"); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(at_process, ev, data) +{ + uint8_t plen; + char *pch, *buf; + struct at_cmd *a; + PROCESS_BEGIN(); + + while(1) { + PROCESS_WAIT_EVENT_UNTIL(ev == serial_line_event_message && data != NULL); + buf = (char *)data; + plen = strlen(buf); + for(a = list_head(at_cmd_list); a != NULL; a = list_item_next(a)) { + pch = strstr(buf, a->cmd_header); + if((plen <= a->cmd_max_len) && (pch != NULL)) { + if(strncmp(a->cmd_header, pch, a->cmd_hdr_len) == 0) { + if((a->cmd_hdr_len == plen) || (a->cmd_max_len > a->cmd_hdr_len)) { + a->event_callback(a, plen, (char *)pch); + process_post(a->app_process, at_cmd_received_event, NULL); + break; + } + } + } + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +struct at_cmd * +at_list(void) +{ + return list_head(at_cmd_list); +} +/*---------------------------------------------------------------------------*/ +uint8_t +at_send(char *s, uint8_t len) +{ + uint8_t i = 0; + while(s && *s != 0) { + if(i >= len) { + break; + } + uart_write_byte(at_uart, *s++); + i++; + } + return i; +} +/*---------------------------------------------------------------------------*/ +void +at_init(uint8_t uart_sel) +{ + static uint8_t inited = 0; + if(!inited) { + list_init(at_cmd_list); + at_cmd_received_event = process_alloc_event(); + inited = 1; + + at_uart = uart_sel; + uart_init(at_uart); + uart_set_input(at_uart, serial_line_input_byte); + serial_line_init(); + + process_start(&at_process, NULL); + PRINTF("AT: Started (%u)\n", at_uart); + } +} +/*---------------------------------------------------------------------------*/ +at_status_t +at_register(struct at_cmd *cmd, struct process *app_process, + const char *cmd_hdr, const uint8_t hdr_len, + const uint8_t cmd_max_len, at_event_callback_t event_callback) +{ + if((hdr_len < 1) || (cmd_max_len < 1) || (!strncmp(cmd_hdr, "AT", 2) == 0) || + (event_callback == NULL)) { + PRINTF("AT: Invalid argument\n"); + return AT_STATUS_INVALID_ARGS_ERROR; + } + + memset(cmd, 0, sizeof(struct at_cmd)); + cmd->event_callback = event_callback; + cmd->cmd_header = cmd_hdr; + cmd->cmd_hdr_len = hdr_len; + cmd->cmd_max_len = cmd_max_len; + cmd->app_process = app_process; + list_add(at_cmd_list, cmd); + PRINTF("AT: registered HDR %s LEN %u MAX %u\n", cmd->cmd_header, + cmd->cmd_hdr_len, + cmd->cmd_max_len); + return AT_STATUS_OK; +} +/*---------------------------------------------------------------------------*/ diff --git a/apps/at-master/at-master.h b/apps/at-master/at-master.h new file mode 100644 index 000000000..ad625c0dc --- /dev/null +++ b/apps/at-master/at-master.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * 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. + * + */ +#ifndef AT_MASTER_H_ +#define AT_MASTER_H_ +#include "contiki.h" +/*---------------------------------------------------------------------------*/ +#define AT_DEFAULT_RESPONSE_OK "\r\nOK\r\n" +#define AT_DEFAULT_RESPONSE_ERROR "\r\nERROR\r\n" +/*---------------------------------------------------------------------------*/ +#define AT_RESPONSE(x) at_send((x), (strlen(x))) +/*---------------------------------------------------------------------------*/ +extern process_event_t at_cmd_received_event; +struct at_cmd; +/*---------------------------------------------------------------------------*/ +typedef enum { + AT_STATUS_OK, + AT_STATUS_ERROR, + AT_STATUS_INVALID_ARGS_ERROR, +} at_status_t; +/*---------------------------------------------------------------------------*/ +/** + * \brief AT initialization + * \param uart selects which UART to use + * + * The AT driver invokes this function upon registering a command, this will + * wait for the serial_line_event_message event + */ +void at_init(uint8_t uart); +/*---------------------------------------------------------------------------*/ +/** + * \brief AT initialization + * \param uart selects which UART to use + * + * The AT driver invokes this function upon registering a command, this will + * wait for the serial_line_event_message event + */ +uint8_t at_send(char *s, uint8_t len); +/*---------------------------------------------------------------------------*/ +/** + * \brief AT event callback + * \param cmd A pointer to the AT command placeholder + * \param len Lenght of the received data (including the AT command header) + * \param data A user-defined pointer + * + * The AT event callback function gets called whenever there is an + * event on an incoming AT command + */ +typedef void (*at_event_callback_t)(struct at_cmd *cmd, + uint8_t len, + char *data); +/*---------------------------------------------------------------------------*/ +struct at_cmd { + struct at_cmd *next; + const char *cmd_header; + uint8_t cmd_hdr_len; + uint8_t cmd_max_len; + at_event_callback_t event_callback; + struct process *app_process; +}; +/*---------------------------------------------------------------------------*/ +/** + * \brief Registers the callback to return an AT command + * \param cmd A pointer to the CMD placeholder + * \param cmd_hdr String to compare when an AT command is received + * \param cmd_len Lenght of cmd_hdr + * \param event_callback Callback function to handle the AT command + * \return AT_STATUS_OK or AT_STATUS_INVALID_ARGS_ERROR + * + * Register the commands to search for when a valid AT frame has been received + */ +at_status_t at_register(struct at_cmd *cmd, + struct process *app_process, + const char *cmd_hdr, + const uint8_t cmd_hdr_len, + const uint8_t cmd_max_len, + at_event_callback_t event_callback); +/*---------------------------------------------------------------------------*/ +struct at_cmd *at_list(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Registers the callback to return an AT command + * \param cmd A pointer to the CMD placeholder + * \param cmd_hdr String to compare when an AT command is received + * \param cmd_len Lenght of cmd_hdr + * \param event_callback Callback function to handle the AT command + * \return AT_STATUS_OK or AT_STATUS_INVALID_ARGS_ERROR + * + * Register the commands to search for when a valid AT frame has been received + */ +at_status_t at_register(struct at_cmd *cmd, + struct process *app_process, + const char *cmd_hdr, + const uint8_t cmd_hdr_len, + const uint8_t cmd_max_len, + at_event_callback_t event_callback); +#endif /* AT_MASTER_H_ */ diff --git a/examples/zolertia/zoul/at-test/Makefile b/examples/zolertia/zoul/at-test/Makefile new file mode 100644 index 000000000..14ab8b54b --- /dev/null +++ b/examples/zolertia/zoul/at-test/Makefile @@ -0,0 +1,7 @@ +DEFINES+=PROJECT_CONF_H=\"project-conf.h\" +CONTIKI_PROJECT = at-master-test +APPS = at-master +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/zolertia/zoul/at-test/at-master-test.c b/examples/zolertia/zoul/at-test/at-master-test.c new file mode 100644 index 000000000..520c28bdb --- /dev/null +++ b/examples/zolertia/zoul/at-test/at-master-test.c @@ -0,0 +1,487 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-AT-master-test + * @{ + * + * Test the Zoul hardware using AT commands + * @{ + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "cpu.h" +#include "at-master.h" +#include "sys/ctimer.h" +#include "sys/process.h" +#include "dev/adc.h" +#include "dev/leds.h" +#include "dev/watchdog.h" +#include "dev/sys-ctrl.h" +#include "dev/gpio.h" +#include "dev/ioc.h" +#include "net/rime/rime.h" +#include "lib/list.h" +#include "dev/sha256.h" +#include +#include +#include +/*---------------------------------------------------------------------------*/ +PROCESS(at_test_process, "AT test process"); +AUTOSTART_PROCESSES(&at_test_process); +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +static struct at_cmd at_cmd_test; +static struct at_cmd at_cmd_board; +static struct at_cmd at_cmd_led; +static struct at_cmd at_cmd_addr; +static struct at_cmd at_cmd_gpio; +static struct at_cmd at_cmd_read; +static struct at_cmd at_cmd_flop; +static struct at_cmd at_cmd_reset; +static struct at_cmd at_cmd_sha256; +static struct at_cmd at_cmd_adc; +/*---------------------------------------------------------------------------*/ +#define HWTEST_GPIO_INPUT 0 +#define HWTEST_GPIO_OUTPUT 1 +#define HWTEST_GPIO_OUTPUT_ODD 3 +#define HWTEST_GPIO_OUTPUT_LIST 4 +#define HWTEST_GPIO_OUTPUT_MASK 0x55 +#define HWTEST_GPIO_OUTPUT_ODD_MASK 0xAA +/*---------------------------------------------------------------------------*/ +typedef struct { + char *name; + uint8_t port; + uint8_t pin; +} gpio_list_t; +/*---------------------------------------------------------------------------*/ +static struct ctimer ct; +/*---------------------------------------------------------------------------*/ +static void +floppin(uint8_t port, uint8_t pin) +{ + uint8_t i; + GPIO_CLR_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + clock_delay_usec(500); + for(i = 0; i < 50; i++) { + GPIO_SET_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + clock_delay_usec(500); + GPIO_CLR_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + clock_delay_usec(500); + } +} +/*---------------------------------------------------------------------------*/ +#if DEBUG +static char * +pname(uint8_t num) +{ + if(num == GPIO_A_NUM) { + return "PA"; + } + if(num == GPIO_B_NUM) { + return "PB"; + } + if(num == GPIO_C_NUM) { + return "PC"; + } + if(num == GPIO_D_NUM) { + return "PD"; + } + return "INVALID"; +} +#endif +/*---------------------------------------------------------------------------*/ +static void +config_gpio(uint8_t port, uint8_t pin, uint8_t type) +{ + GPIO_SOFTWARE_CONTROL(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + if(type == HWTEST_GPIO_OUTPUT) { + GPIO_SET_OUTPUT(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + } else if(type == HWTEST_GPIO_INPUT) { + GPIO_SET_INPUT(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + } +} +/*---------------------------------------------------------------------------*/ +static void +at_cmd_test_callback(struct at_cmd *cmd, uint8_t len, char *data) +{ + AT_RESPONSE("Hello!"); + AT_RESPONSE(AT_DEFAULT_RESPONSE_OK); +} +/*---------------------------------------------------------------------------*/ +static void +at_cmd_board_callback(struct at_cmd *cmd, uint8_t len, char *data) +{ + AT_RESPONSE(BOARD_STRING); + AT_RESPONSE(AT_DEFAULT_RESPONSE_OK); +} +/*---------------------------------------------------------------------------*/ +static void +at_cmd_flop_callback(struct at_cmd *cmd, uint8_t len, char *data) +{ + /* Format: AT&FLOP=PN where P(ort)N(number) */ + uint8_t port; + uint8_t pin = atoi(&data[9]); + + if((pin < 0) || (pin > 9)) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + if(strncmp(&data[8], "A", 1) == 0) { + port = GPIO_A_NUM; + } else if(strncmp(&data[8], "B", 1) == 0) { + port = GPIO_B_NUM; + } else if(strncmp(&data[8], "C", 1) == 0) { + port = GPIO_C_NUM; + } else if(strncmp(&data[8], "D", 1) == 0) { + port = GPIO_D_NUM; + } else { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + config_gpio(port, pin, HWTEST_GPIO_OUTPUT); + floppin(port, pin); + + AT_RESPONSE(AT_DEFAULT_RESPONSE_OK); +} +/*---------------------------------------------------------------------------*/ +static void +at_cmd_address_callback(struct at_cmd *cmd, uint8_t len, char *data) +{ + static char _lladdr[17]; + snprintf(_lladdr, 17, "%02x%02x%02x%02x%02x%02x%02x%02x", + linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1], + linkaddr_node_addr.u8[2], linkaddr_node_addr.u8[3], + linkaddr_node_addr.u8[4], linkaddr_node_addr.u8[5], + linkaddr_node_addr.u8[6], linkaddr_node_addr.u8[7]); + + AT_RESPONSE(_lladdr); + AT_RESPONSE(AT_DEFAULT_RESPONSE_OK); +} +/*---------------------------------------------------------------------------*/ +static void +at_cmd_reset_callback(struct at_cmd *cmd, uint8_t len, char *data) +{ + uint8_t reset_val = atoi(&data[9]); + /* AT&RESET=n, where n: + * 0 : CC2538 soft reset + */ + if((reset_val != 0) && (reset_val != 1)) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + /* Send the response and wait a second until executing the command */ + AT_RESPONSE(AT_DEFAULT_RESPONSE_OK); + + if(reset_val == 0) { + ctimer_set(&ct, CLOCK_SECOND, sys_ctrl_reset, NULL); + } +} +/*---------------------------------------------------------------------------*/ +static void +at_cmd_leds_callback(struct at_cmd *cmd, uint8_t len, char *data) +{ + /* Format: AT&LED=L,s where L(ed)=R/G/B, s(tate)=1/0*/ + uint8_t led; + uint8_t state = strncmp(&data[9], "1", 1) ? 0 : 1; + + if(strncmp(&data[8], ",", 1) != 0) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + if(strncmp(&data[7], "R", 1) == 0) { + led = LEDS_RED; + } else if(strncmp(&data[7], "G", 1) == 0) { + led = LEDS_GREEN; + } else if(strncmp(&data[7], "B", 1) == 0) { + led = LEDS_BLUE; + } else { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + if(state) { + leds_on(led); + } else { + leds_off(led); + } + AT_RESPONSE(AT_DEFAULT_RESPONSE_OK); +} +/*---------------------------------------------------------------------------*/ +static void +at_cmd_gpio_callback(struct at_cmd *cmd, uint8_t len, char *data) +{ + /* Format: AT&GPIO=PN,s where P(ort)N(number), s(tate)=1/0 */ + uint8_t port; + uint8_t state = strncmp(&data[11], "1", 1) ? 0 : 1; + uint8_t pin = atoi(&data[9]); + + if(strncmp(&data[10], ",", 1) != 0) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + if((pin < 0) || (pin > 7)) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + if((state < 0) || (state > 1)) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + if(strncmp(&data[8], "A", 1) == 0) { + port = GPIO_A_NUM; + } else if(strncmp(&data[8], "B", 1) == 0) { + port = GPIO_B_NUM; + } else if(strncmp(&data[8], "C", 1) == 0) { + port = GPIO_C_NUM; + } else if(strncmp(&data[8], "D", 1) == 0) { + port = GPIO_D_NUM; + } else { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + config_gpio(port, pin, HWTEST_GPIO_OUTPUT); + + if(state) { + GPIO_SET_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + } else { + GPIO_CLR_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + } + + AT_RESPONSE(AT_DEFAULT_RESPONSE_OK); +} +/*---------------------------------------------------------------------------*/ +static void +at_cmd_adc_callback(struct at_cmd *cmd, uint8_t len, char *data) +{ + /* Format: AT&ADC=N where N is 4-7, it can be "*" to read all */ + uint8_t i, pin; + uint16_t res[4]; + char read_result[24]; + + if(strncmp(&data[7], "*", 1) == 0) { + pin = 8; + } else { + pin = atoi(&data[7]); + } + + if((pin < 4) || (pin > 8)) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + if(pin < 8) { + config_gpio(GPIO_A_NUM, pin, HWTEST_GPIO_INPUT); + ioc_set_over(GPIO_A_NUM, pin, IOC_OVERRIDE_ANA); + res[pin - 4] = adc_get((SOC_ADC_ADCCON_CH_AIN0 + pin), + SOC_ADC_ADCCON_REF_AVDD5, + SOC_ADC_ADCCON_DIV_512); + res[pin - 4] = res[pin - 4] / 10; + PRINTF("ADC%u: %04d\n", pin, res[pin - 4]); + snprintf(read_result, 5, "%04d", res[pin - 4]); + } else { + for(i = 4; i < 8; i++) { + config_gpio(GPIO_A_NUM, i, HWTEST_GPIO_INPUT); + ioc_set_over(GPIO_A_NUM, i, IOC_OVERRIDE_ANA); + res[i - 4] = adc_get((SOC_ADC_ADCCON_CH_AIN0 + i), + SOC_ADC_ADCCON_REF_AVDD5, + SOC_ADC_ADCCON_DIV_512); + res[i - 4] = res[i - 4] / 10; + } + snprintf(read_result, 24, "%04d %04d %04d %04d", res[0], res[1], + res[2], res[3]); + } + + AT_RESPONSE(read_result); + AT_RESPONSE(AT_DEFAULT_RESPONSE_OK); +} +/*---------------------------------------------------------------------------*/ +static void +at_cmd_read_callback(struct at_cmd *cmd, uint8_t len, char *data) +{ + /* Format: AT&READ=PN where P(ort)N(number), N can be "*" to read all */ + uint8_t port, pin; + char read_result[5]; + + if(strncmp(&data[9], "*", 1) == 0) { + pin = 0xFF; + } else { + pin = atoi(&data[9]); + } + + if((pin < 0) || (pin > 7)) { + if(pin != 0xFF) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + } + + if(pin < 8) { + pin = GPIO_PIN_MASK(pin); + } + + /* Exclude PA0-PA3 */ + if(strncmp(&data[8], "A", 1) == 0) { + port = GPIO_A_NUM; + if(pin < 0x1F) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } else { + if(pin == 0xFF) { + pin = 0xF0; + } + } + } else if(strncmp(&data[8], "B", 1) == 0) { + port = GPIO_B_NUM; + } else if(strncmp(&data[8], "C", 1) == 0) { + port = GPIO_C_NUM; + } else if(strncmp(&data[8], "D", 1) == 0) { + port = GPIO_D_NUM; + } else { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + config_gpio(port, pin, HWTEST_GPIO_INPUT); + snprintf(read_result, 5, "0x%02X", + (uint16_t)GPIO_READ_PIN(GPIO_PORT_TO_BASE(port), pin)); + AT_RESPONSE(read_result); + AT_RESPONSE(AT_DEFAULT_RESPONSE_OK); +} +/*---------------------------------------------------------------------------*/ +static void +at_cmd_sha256_callback(struct at_cmd *cmd, uint8_t len, char *data) +{ + /* Format: AT&SHA256=s, where s is a string up to 64 bytes */ + uint8_t i; + char tmp[4], sha256[32], sha256_res[64]; + static sha256_state_t state; + + crypto_init(); + if(sha256_init(&state) != CRYPTO_SUCCESS) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + if(sha256_process(&state, &data[10], + len - (cmd->cmd_hdr_len)) != CRYPTO_SUCCESS) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + if(sha256_done(&state, sha256) != CRYPTO_SUCCESS) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + crypto_disable(); + + PRINTF("Input: %s:\n", &data[10]); + snprintf(tmp, 3, "%02X", sha256[0]); + strncpy(sha256_res, tmp, 3); + for(i = 1; i < 32; i++) { + PRINTF("0x%02X ", sha256[i]); + snprintf(tmp, 3, "%02X", sha256[i]); + strcat(sha256_res, tmp); + } + PRINTF("\nSHA256: %s\n", sha256_res); + AT_RESPONSE(sha256_res); + AT_RESPONSE(AT_DEFAULT_RESPONSE_OK); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(at_test_process, ev, data) +{ + PROCESS_BEGIN(); + struct at_cmd *a; + + /* Initialize the driver, default is UART0 */ + at_init(0); + + /* Register a list of commands, is mandatory to start with "AT" */ + at_register(&at_cmd_test, &at_test_process, "AT", 2, 2, + at_cmd_test_callback); + at_register(&at_cmd_board, &at_test_process, "AT&V", 4, 4, + at_cmd_board_callback); + at_register(&at_cmd_led, &at_test_process, "AT&LED", 6, 10, + at_cmd_leds_callback); + at_register(&at_cmd_addr, &at_test_process, "AT&A", 4, 4, + at_cmd_address_callback); + at_register(&at_cmd_gpio, &at_test_process, "AT&GPIO=", 8, 12, + at_cmd_gpio_callback); + at_register(&at_cmd_read, &at_test_process, "AT&READ=", 8, 10, + at_cmd_read_callback); + at_register(&at_cmd_adc, &at_test_process, "AT&ADC=", 7, 8, + at_cmd_adc_callback); + at_register(&at_cmd_flop, &at_test_process, "AT&FLOP=", 8, 10, + at_cmd_flop_callback); + at_register(&at_cmd_reset, &at_test_process, "AT&RESET=", 9, 10, + at_cmd_reset_callback); + at_register(&at_cmd_sha256, &at_test_process, "AT&SHA256=", 10, 64, + at_cmd_sha256_callback); + + /* Print the command list */ + PRINTF("AT command list:\n"); + for(a = at_list(); a != NULL; a = list_item_next(a)) { + PRINTF("* HDR %s LEN %u MAX %u\n", a->cmd_header, a->cmd_hdr_len, + a->cmd_max_len); + } + + /* + * When an AT command is received over the serial line, the registered + * callbacks will be invoked, let the process spin until then + */ + while(1) { + PROCESS_YIELD(); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + * @} + */ diff --git a/examples/zolertia/zoul/at-test/project-conf.h b/examples/zolertia/zoul/at-test/project-conf.h new file mode 100644 index 000000000..4a29f1d59 --- /dev/null +++ b/examples/zolertia/zoul/at-test/project-conf.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup remote-examples + * @{ + * + * \defgroup zoul-AT-master-test + * + * Test the Zoul hardware over AT API + * @{ + * + * \file + * Test the Zoul hardware over AT API + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +/* Drop maximum to PM1 to have the UART on all the time */ +#define LPM_CONF_MAX_PM 1 + +/* the radio is not used */ +#define CONTIKI_NO_NET 1 + +/* Override serial-line defaults */ +#define SERIAL_LINE_CONF_BUFSIZE 128 +#undef IGNORE_CHAR +#undef END +#define IGNORE_CHAR(c) (c == 0x0d) +#define END 0x0a + +#define NETSTACK_CONF_RDC nullrdc_driver + +#endif /* PROJECT_CONF_H_ */ + +/** @} */ From 18876a1fae22b302c1d951b6268627134d789157 Mon Sep 17 00:00:00 2001 From: Robert Olsson Date: Fri, 18 Mar 2016 10:55:54 +0100 Subject: [PATCH 231/374] Adding CRC valid check in rf230bb radios registermaps --- cpu/avr/radio/rf230bb/atmega128rfa1_registermap.h | 1 + cpu/avr/radio/rf230bb/atmega256rfr2_registermap.h | 1 + 2 files changed, 2 insertions(+) diff --git a/cpu/avr/radio/rf230bb/atmega128rfa1_registermap.h b/cpu/avr/radio/rf230bb/atmega128rfa1_registermap.h index 7eeb068ab..b28ed0ec0 100644 --- a/cpu/avr/radio/rf230bb/atmega128rfa1_registermap.h +++ b/cpu/avr/radio/rf230bb/atmega128rfa1_registermap.h @@ -71,6 +71,7 @@ #define RG_PHY_ED_LEVEL PHY_ED_LEVEL #define RG_RX_SYN RX_SYN #define SR_RSSI 0x146, 0x1f, 0 +#define SR_RX_CRC_VALID 0x146, 0x80, 7 #define SR_PLL_CF_START 0x15a, 0x80, 7 #define SR_PLL_DCU_START 0x15b, 0x80, 7 #define SR_MAX_CSMA_RETRIES 0x16c, 0x0e, 1 diff --git a/cpu/avr/radio/rf230bb/atmega256rfr2_registermap.h b/cpu/avr/radio/rf230bb/atmega256rfr2_registermap.h index bc737de9a..1baf1a3ac 100644 --- a/cpu/avr/radio/rf230bb/atmega256rfr2_registermap.h +++ b/cpu/avr/radio/rf230bb/atmega256rfr2_registermap.h @@ -71,6 +71,7 @@ #define RG_PHY_ED_LEVEL PHY_ED_LEVEL #define RG_RX_SYN RX_SYN #define SR_RSSI 0x146, 0x1f, 0 +#define SR_RX_CRC_VALID 0x146, 0x80, 7 #define SR_RX_SYN 0x155, 0xff, 0 #define SR_TRX_RPC 0x156, 0xff, 0 #define SR_XAH_CTRL_1 0x157, 0xf5, 2 From 868f100366f8fad5224e8bf362a4b3012f69581e Mon Sep 17 00:00:00 2001 From: Robert Olsson Date: Sun, 15 May 2016 16:23:29 +0200 Subject: [PATCH 232/374] Fix compilation warning in co2_sa_kxx-sensor.c --- platform/avr-rss2/dev/co2_sa_kxx-sensor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/avr-rss2/dev/co2_sa_kxx-sensor.c b/platform/avr-rss2/dev/co2_sa_kxx-sensor.c index 1866c0f2f..564f8c011 100644 --- a/platform/avr-rss2/dev/co2_sa_kxx-sensor.c +++ b/platform/avr-rss2/dev/co2_sa_kxx-sensor.c @@ -112,7 +112,7 @@ value(int var) status = i2c_readAck(); - if(status & 0x01 == 0) + if((status & 0x01) == 0) goto err; buf[0] = i2c_readAck(); From a11cfa10b44e5938977ae7f0af49d453c3214dd9 Mon Sep 17 00:00:00 2001 From: Robert Olsson Date: Sun, 15 May 2016 16:36:19 +0200 Subject: [PATCH 233/374] Removed unneeded file for avr-rss2 sniffer --- .../avr-rss2/apps/sniffer/rf230-promisc.pat | 39 ------------------- 1 file changed, 39 deletions(-) delete mode 100644 platform/avr-rss2/apps/sniffer/rf230-promisc.pat diff --git a/platform/avr-rss2/apps/sniffer/rf230-promisc.pat b/platform/avr-rss2/apps/sniffer/rf230-promisc.pat deleted file mode 100644 index 3e2c98e6f..000000000 --- a/platform/avr-rss2/apps/sniffer/rf230-promisc.pat +++ /dev/null @@ -1,39 +0,0 @@ -diff --git a/cpu/avr/radio/rf230bb/rf230bb.c b/cpu/avr/radio/rf230bb/rf230bb.c -index 53959d1..b9f2262 100644 ---- a/cpu/avr/radio/rf230bb/rf230bb.c -+++ b/cpu/avr/radio/rf230bb/rf230bb.c -@@ -544,7 +544,7 @@ rf230_set_promiscuous_mode(bool isPromiscuous) { - #if RF230_CONF_AUTOACK - is_promiscuous = isPromiscuous; - /* TODO: Figure out when to pass promisc state to 802.15.4 */ --// radio_set_trx_state(is_promiscuous?RX_ON:RX_AACK_ON); -+ radio_set_trx_state(is_promiscuous?RX_ON:RX_AACK_ON); - #endif - } - -@@ -1392,6 +1392,25 @@ PROCESS_THREAD(rf230_process, ev, data) - /* Restore interrupts. */ - HAL_LEAVE_CRITICAL_REGION(); - PRINTF("rf230_read: %u bytes lqi %u\n",len,rf230_last_correlation); -+ -+ if(is_promiscuous) { -+ uint8_t i; -+ unsigned const char * rxdata = packetbuf_dataptr(); -+ /* Print magic */ -+ putchar(0xC1); -+ putchar(0x1F); -+ putchar(0xFE); -+ putchar(0x72); -+ /* Print version */ -+ putchar(0x01); -+ /* Print CMD == frame */ -+ putchar(0x00); -+ putchar(len+3); -+ -+ for (i=0;i1 - { - uint8_t i; From 17eb0afbe2250380cd632f8cde234addfef9d541 Mon Sep 17 00:00:00 2001 From: Robert Olsson Date: Sun, 15 May 2016 16:38:52 +0200 Subject: [PATCH 234/374] Removed failing regression test for avr-rss2 platform --- regression-tests/23-compile-avr/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/regression-tests/23-compile-avr/Makefile b/regression-tests/23-compile-avr/Makefile index 56cef07d3..e7d2dff77 100644 --- a/regression-tests/23-compile-avr/Makefile +++ b/regression-tests/23-compile-avr/Makefile @@ -7,7 +7,6 @@ EXAMPLES = \ examples/avr-rss2/hello-sensors/avr-rss2 \ examples/avr-rss2/ipv6/rpl-udp-report/avr-rss2 \ examples/avr-rss2/ipv6/rpl-border-router/avr-rss2 \ -examples/ipv6/rpl-udp/avr-rss2 \ examples/powertrace/avr-rss2 \ examples/rime/avr-rss2 TOOLS= From 958dcf06f7d3b7086e580da9e47b57a7e29cb017 Mon Sep 17 00:00:00 2001 From: Robert Olsson Date: Sun, 15 May 2016 17:43:09 +0200 Subject: [PATCH 235/374] Remove wsnbridge. Let's focus sniffing efforts on sensniff. --- platform/avr-rss2/apps/sniffer/README.md | 6 +- platform/avr-rss2/apps/sniffer/host/Makefile | 17 - platform/avr-rss2/apps/sniffer/host/README.md | 38 -- .../avr-rss2/apps/sniffer/host/wsbridge.c | 459 ------------------ 4 files changed, 5 insertions(+), 515 deletions(-) delete mode 100644 platform/avr-rss2/apps/sniffer/host/Makefile delete mode 100644 platform/avr-rss2/apps/sniffer/host/README.md delete mode 100644 platform/avr-rss2/apps/sniffer/host/wsbridge.c diff --git a/platform/avr-rss2/apps/sniffer/README.md b/platform/avr-rss2/apps/sniffer/README.md index fa139878b..b9332893b 100644 --- a/platform/avr-rss2/apps/sniffer/README.md +++ b/platform/avr-rss2/apps/sniffer/README.md @@ -22,4 +22,8 @@ Look in the host directory Contiki support --------------- The code promisc for support is needed. This also adds the sensniff -format. See rf230-promisc.pat for the rf230bb radions. +format. + +References +---------- +https://github.com/g-oikonomou/sensniff diff --git a/platform/avr-rss2/apps/sniffer/host/Makefile b/platform/avr-rss2/apps/sniffer/host/Makefile deleted file mode 100644 index 7308f66a5..000000000 --- a/platform/avr-rss2/apps/sniffer/host/Makefile +++ /dev/null @@ -1,17 +0,0 @@ - -CC = gcc -CFLAGS = -c -SOURCES = wsbridge.c -OBJECTS = $(SOURCES:.c=.o) -EXE = wsbridge - -all: $(SOURCES) $(EXE) - -$(EXE): $(OBJECTS) - $(CC) $(OBJECTS) -o $@ - -%.o:%.c - $(CC) $(CFLAGS) $< -o $@ - -clean: - rm *.o diff --git a/platform/avr-rss2/apps/sniffer/host/README.md b/platform/avr-rss2/apps/sniffer/host/README.md deleted file mode 100644 index cb7960d50..000000000 --- a/platform/avr-rss2/apps/sniffer/host/README.md +++ /dev/null @@ -1,38 +0,0 @@ -Sniffer application host side -============================= -This a Unix application to link between the serial port having the -sensor node connected and Wireshark or tcpdump. Enclosed is a modified -wsbridge (See copyright i file) code to use the format used by sensniff. - -You can also use sensniff which is a Python script. Author of senssniff -is George Oikonomou (oikonomou@users.sf.net) - -See: -https://github.com/g-oikonomou/sensniff - - -Function --------- -The mote captures WSN data and formats according sensniff format sends -over the serial line. The data is binary. The wsbridge reads reads serial -line (typically /dev/ttyUSB) on Linux systems decodes the sensnaiff and -create timestamp and adds the the PCAP farming and writes the result to -a FIFO or named pipe. /tmp/wireshark or /tmp/sensniff. - -Bulld ------ -Just use the Makefile. Put binary for convince in your path. - -Usage ------ -* wsbridge /dev/ttYUSB -* wireshart -k -i /tmp/wireshark - -Default serial port speed -------------------------- -38400 bps - -References ----------- -http://www.freaklabs.org/index.php/wsbridge.html -https://github.com/g-oikonomou/sensniff diff --git a/platform/avr-rss2/apps/sniffer/host/wsbridge.c b/platform/avr-rss2/apps/sniffer/host/wsbridge.c deleted file mode 100644 index 6809f36a8..000000000 --- a/platform/avr-rss2/apps/sniffer/host/wsbridge.c +++ /dev/null @@ -1,459 +0,0 @@ -/******************************************************************* - Copyright (C) 2009 FreakLabs - 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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. - - Originally written by Christopher Wang aka Akiba. - Please post support questions to the FreakLabs forum. - - *******************************************************************/ -/*! - FreakLabs Freakduino/Wireshark Bridge - - This program allows data from the Freakduino to be piped into wireshark. - When the sniffer firmware is loaded into the Freakduino, then the Freakduino - will be in promiscuous mode and will just dump any frames it sees. This - program takes the frame dump and sends it into Wireshark for analysis. The - global header is already set up to inform wireshark that the link layer for - all frames will be in IEEE 802.15.4 format. After that, it is up to the user - to choose any higher layer protocols to decode above 802.15.4 via the - wireshark "enable protocols" menu. - */ - -/* - - Modified for sensniff format. Magic[4] + Vers[1] + CMD[1] + len[1] - Robert Olsson 2015-11-10 - - */ - -/**************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PORTBUFSIZE 32 -#define BUFSIZE 1024 -#define PACKET_FCS 2 -#define DEBUG 1 -#define PIPENAME "/tmp/wireshark" -#define BAUDRATE B38400 - -enum FSM { - START_CAPTURE, - PACKET_CAPTURE -}; - -static int FD_pipe = -1; -static int FD_com = -1; -static uint8_t port_buf[PORTBUFSIZE]; -static uint8_t circ_buf[BUFSIZE]; -static uint16_t rd_idx = 0; -static uint16_t wr_idx = 0; -static uint8_t len; -static uint8_t state = START_CAPTURE; -static uint8_t file_write = 0; -static fd_set fds; -static const uint8_t magic[] = { 0xC1, 0x1F, 0xFE, 0x72 }; - -/**************************************************************************/ -/*! - Open the serial port that we'll be communicating with the Freakduino (sniffer) - through. - */ -/**************************************************************************/ - -int -serial_open(char *portname) -{ - int baud = B38400; - int fd; /* file descriptor for the serial port */ - struct termios tc, tp; - - fd = open(portname, O_RDONLY | O_NOCTTY | O_NDELAY); - - if(fd == -1) { /* if open is unsucessful */ - printf("serial_open: Unable to open %s.\n", portname); - exit(-1); - } - - fcntl(fd, F_GETFL); - fcntl(fd, F_SETFL, O_RDWR); - - tp.c_cflag = baud | CS8 | CLOCAL | CREAD; - tp.c_oflag = 0; /* Raw Input */ - tp.c_lflag = 0; /* No conoical */ - tp.c_oflag &= ~(OLCUC | OCRNL | ONOCR | ONLRET | OFILL | OFDEL | NLDLY | CRDLY); - - /* ignore CR, ignore parity */ - tp.c_iflag = ~(IGNBRK | PARMRK | INPCK | INLCR | IUCLC | IXOFF) | - BRKINT | IGNPAR | ICRNL | IXON | ISIG | ICANON; - - tp.c_lflag &= ~(ECHO | ECHONL); - tp.c_oflag = 0; /* Raw Input */ - tp.c_iflag &= ~ISTRIP; - - tcflush(fd, TCIFLUSH); - - cfsetospeed(&tp, baud); - cfsetispeed(&tp, baud); - - if(tcsetattr(fd, TCSANOW, &tp) < 0) { - perror("Couldn't set term attributes"); - return -1; - } - return fd; -} -/**************************************************************************/ -/*! - Create the named pipe that we will be communicating with wireshark through. - */ -/**************************************************************************/ -static void -named_pipe_create(char *name) -{ - int rv = 0; - rv = mkfifo(name, 0666); - if((rv == -1) && (errno != EEXIST)) { - perror("Error creating named pipe"); - exit(1); - } - - FD_pipe = open(name, O_WRONLY); - - if(FD_pipe == -1) { - perror("Error connecting to named pipe"); - exit(1); - } -} -/**************************************************************************/ -/*! - Write data to the pipe - */ -/**************************************************************************/ -size_t -data_write(const void *ptr, size_t size) -{ - ssize_t bytes = 0; - if(FD_pipe != -1) { - bytes = write(FD_pipe, ptr, size); - } -} -/**************************************************************************/ -/*! - Write the global header to wireshark. This is only done once at the - beginning of the capture. - */ -/**************************************************************************/ -static void -write_global_hdr() -{ - uint32_t magic_number = 0xa1b2c3d4; /* magic number */ - uint16_t version_major = 2; /* major version number */ - uint16_t version_minor = 4; /* minor version number */ - int32_t thiszone = 0; /* GMT to local correction */ - uint32_t sigfigs = 0; /* accuracy of timestamps */ - uint32_t snaplen = 65535; /* max length of captured packets, in octets */ - uint32_t network = 195; /* data link type (DLT) - IEEE 802.15.4 */ - - data_write(&magic_number, sizeof(magic_number)); - data_write(&version_major, sizeof(version_major)); - data_write(&version_minor, sizeof(version_minor)); - data_write(&thiszone, sizeof(thiszone)); - data_write(&sigfigs, sizeof(sigfigs)); - data_write(&snaplen, sizeof(snaplen)); - data_write(&network, sizeof(network)); -} -/**************************************************************************/ -/*! - Write the frame header into wireshark. This is required for the libpcap - format and informs wireshark that a new frame is coming. - */ -/**************************************************************************/ -static void -write_frame_hdr(uint8_t len) -{ - uint32_t ts_sec; /* timestamp seconds */ - uint32_t ts_usec; /* timestamp microseconds */ - uint32_t incl_len; /* number of octets of packet saved in file */ - uint32_t orig_len; /* actual length of packet */ - struct timeval tv; - - gettimeofday(&tv, NULL); - ts_sec = tv.tv_sec; - ts_usec = tv.tv_usec; - incl_len = len; - orig_len = len + PACKET_FCS; - - data_write(&ts_sec, sizeof(ts_sec)); - data_write(&ts_usec, sizeof(ts_usec)); - data_write(&incl_len, sizeof(incl_len)); - data_write(&orig_len, sizeof(orig_len)); -} -/**************************************************************************/ -/*! - Write one frame into wireshark (via the pipe). - */ -/**************************************************************************/ -static void -write_frame(uint8_t frame_len) -{ - uint8_t i; - - /* actual frame length for wireshark should not include FCS */ - frame_len -= PACKET_FCS; - - /* write header to inform WS that new frame has arrived */ - write_frame_hdr(frame_len); - - /* bump rd_idx. we don't want to write the length byte */ - rd_idx = (rd_idx + 1) % BUFSIZE; - - /* write frame into wireshark */ - for(i = 0; i < frame_len; i++) { - data_write(&circ_buf[rd_idx], 1); - rd_idx = (rd_idx + 1) % BUFSIZE; - } - - /* bump rd_idx. we're not using the trailing FCS value */ - rd_idx = (rd_idx + 1) % BUFSIZE; -} -/**************************************************************************/ -/*! - Calculate total number of bytes in buffer. - */ -/**************************************************************************/ -static uint16_t -calc_bytes_in_buf() -{ - if(rd_idx > wr_idx) { - /* read index is greater than write. we must have wrapped around */ - return BUFSIZE - (rd_idx - wr_idx); - } else { - return wr_idx - rd_idx; - } -} -/**************************************************************************/ -/*! - Deal with any received signals. This includes ctrl-C to stop the program. - */ -/**************************************************************************/ -static void -sig_int(int signo) -{ - (void)signo; - if(FD_pipe != -1) { - printf("\nClosing pipe.\n"); - close(FD_pipe); - } - - if(FD_com != -1) { - printf("\nClosing serial port.\n"); - close(FD_com); - } - - printf("\nSignal captured and devices shut down.\n"); - - exit(0); -} -/**************************************************************************/ -/*! - Init the signals we'll be checking for. - */ -/**************************************************************************/ -static void -signal_init(void) -{ - signal(SIGINT, sig_int); - signal(SIGHUP, sig_int); - signal(SIGTERM, sig_int); -} -int got; -int debug; - -/**************************************************************************/ -/*! - Here's the meat of the code. - */ -/**************************************************************************/ -int -main(int argc, char *argv[]) -{ - int nbytes; - uint8_t i; - - got = 0; - - /* capture any signals that will terminate program */ - signal_init(); - - /* make sure the COM port is specified */ - if(argc == 2) { - /* open the COM port */ - if((FD_com = serial_open(argv[1])) == -1) { - printf("Serial port not opened.\n"); - return 0; - } else { - /* set up the select statement for the COM port. */ - FD_ZERO(&fds); - FD_SET(FD_com, &fds); - - printf("Serial port connected. Waiting for wireshark connection.\n"); - printf("Open wireshark and connect to local interface: %s\n", PIPENAME); - } - } else { - printf("Usage: wsbridge .\n"); - return 0; - } - - /* create and open pipe for wireshark */ - named_pipe_create(PIPENAME); - - /* wait for wireshark to connect to pipe. Once wireshark */ - /* connects, then the global header will be written to it. */ - if(FD_pipe != -1) { - write_global_hdr(); - printf("Client connected to pipe.\n"); - } - - for(;;) { - uint16_t bytes_in_buf; - uint8_t frame_len, byte_ctr; - - /* block until there is data in the serial port */ - select(FD_com + 1, &fds, NULL, NULL, NULL); - if(FD_ISSET(FD_com, &fds)) { - int ii; - /* wait for data to come in on the serial port */ - if((nbytes = read(FD_com, port_buf, PORTBUFSIZE)) > 0) { - - if(debug) { - uint8_t p; - printf("read nbytes=%d\n", nbytes); - for(i = 0; i < nbytes; i++) { - printf(" %02X", port_buf[i]); - } - printf("\n"); - } - /* write data to circular buffer. loop through all received bytes */ - for(i = 0; i < nbytes; i++) { - switch(state) { - case START_CAPTURE: - /* new frame starting */ - if((got == 0) && (port_buf[i] == magic[0])) { - got = 1; - } else if((got == 1) && (port_buf[i] == magic[1])) { - got = 2; - } else if((got == 2) && (port_buf[i] == magic[2])) { - got = 3; - } else if((got == 3) && (port_buf[i] == magic[3])) { - got = 4; - if(debug) { - printf("GOT MAGIC i=%d\n", i); - } - } else if((got == 4) && (port_buf[i] == 1)) { - got = 5; - if(debug) { - printf("GOT VERSION i=%d\n", port_buf[i]); - } - } else if((got == 5) && (port_buf[i] == 0)) { - got = 6; - if(debug) { - printf("GOT COMMAND i=%d\n", port_buf[i]); - } - } else if(got == 6) { - len = port_buf[i]; - byte_ctr = 0; - if(debug) { - printf("Len = %02X.\n", len); - } - circ_buf[wr_idx] = len; - wr_idx = (wr_idx + 1) % BUFSIZE; - state = PACKET_CAPTURE; - } else { - got = 0; - } - break; - - case PACKET_CAPTURE: - /* continue capturing bytes until end of frame */ - /* write data to circular buffer and increment index */ - - circ_buf[wr_idx] = port_buf[i]; - /* ////printf("%02X ", circ_buf[wr_idx]); */ - - wr_idx = (wr_idx + 1) % BUFSIZE; - /* track number of received bytes. when received bytes */ - /* equals frame length, then restart state machine and */ - /* write bytes to wireshark */ - byte_ctr++; - if(byte_ctr == (len - 1)) { - state = START_CAPTURE; - file_write = 1; - /* printf("\n"); */ - got = 0; - } - break; - } - fflush(stdout); - } - /* at least one frame has been written. loop through circular buffer */ - /* and write out all completed frames */ - while(file_write) { - /* capture frame length and check buffer to see if one or more frames */ - /* are available. */ - frame_len = circ_buf[rd_idx]; - bytes_in_buf = calc_bytes_in_buf(); - - if(bytes_in_buf > frame_len) { - /* if more than one frame is available, then write one frame to */ - /* wireshark and then see if any more are available. */ - write_frame(frame_len); - } else if(bytes_in_buf == frame_len) { - /* only one frame is available. write to wireshark and then quit */ - /* the loop */ - write_frame(frame_len); - file_write = 0; - } else { - /* less than one frame is available. quit the loop and collect more */ - /* bytes. we normally should not get here. */ - file_write = 0; - } - } - } - } - } -} From b608b837c239cdc59e3adb4f4f4eb9a6645fc09a Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Wed, 18 May 2016 17:40:20 +0300 Subject: [PATCH 236/374] Add login target to Makefile.cc26xx-cc13xx --- cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx b/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx index d0cf1cf31..15d971004 100644 --- a/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx +++ b/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx @@ -145,3 +145,20 @@ else %.upload: @echo "This board cannot be programmed through the ROM bootloader and therefore does not support the .upload target." endif + +# Check if we are running under Windows +ifeq ($(HOST_OS),Windows) + SERIALDUMP ?= $(CONTIKI)/tools/sky/serialdump-windows +else +ifeq ($(HOST_OS),Darwin) + SERIALDUMP ?= $(CONTIKI)/tools/sky/serialdump-macos +else + # Else assume Linux + SERIALDUMP ?= $(CONTIKI)/tools/sky/serialdump-linux +endif +endif + +UART_BAUDRATE = 115200 + +login: + $(SERIALDUMP) -b$(UART_BAUDRATE) $(PORT) From 287b4767e39b6aff45eb0c8f93a73059e7f5de43 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 20 May 2016 13:40:20 +0200 Subject: [PATCH 237/374] Orchestra: handle case where ORCHESTRA_UNICAST_PERIOD is smaller than the network size --- .../orchestra-rule-unicast-per-neighbor.c | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/apps/orchestra/orchestra-rule-unicast-per-neighbor.c b/apps/orchestra/orchestra-rule-unicast-per-neighbor.c index b70a907d0..acba8e7be 100644 --- a/apps/orchestra/orchestra-rule-unicast-per-neighbor.c +++ b/apps/orchestra/orchestra-rule-unicast-per-neighbor.c @@ -85,10 +85,16 @@ add_uc_link(const linkaddr_t *linkaddr) { if(linkaddr != NULL) { uint16_t timeslot = get_node_timeslot(linkaddr); - tsch_schedule_add_link(sf_unicast, - ORCHESTRA_UNICAST_SENDER_BASED ? LINK_OPTION_RX : LINK_OPTION_TX | UNICAST_SLOT_SHARED_FLAG, - LINK_TYPE_NORMAL, &tsch_broadcast_address, - timeslot, channel_offset); + uint8_t link_options = ORCHESTRA_UNICAST_SENDER_BASED ? LINK_OPTION_RX : LINK_OPTION_TX | UNICAST_SLOT_SHARED_FLAG; + + if(timeslot == get_node_timeslot(&linkaddr_node_addr)) { + /* This is also our timeslot, add necessary flags */ + link_options |= ORCHESTRA_UNICAST_SENDER_BASED ? LINK_OPTION_TX | UNICAST_SLOT_SHARED_FLAG: LINK_OPTION_RX; + } + + /* Add/update link */ + tsch_schedule_add_link(sf_unicast, link_options, LINK_TYPE_NORMAL, &tsch_broadcast_address, + timeslot, channel_offset); } } /*---------------------------------------------------------------------------*/ @@ -123,7 +129,17 @@ remove_uc_link(const linkaddr_t *linkaddr) } item = nbr_table_next(nbr_routes, item); } - tsch_schedule_remove_link(sf_unicast, l); + + /* Do we need this timeslot? */ + if(timeslot == get_node_timeslot(&linkaddr_node_addr)) { + /* This is our link, keep it but update the link options */ + uint8_t link_options = ORCHESTRA_UNICAST_SENDER_BASED ? LINK_OPTION_TX | UNICAST_SLOT_SHARED_FLAG: LINK_OPTION_RX; + tsch_schedule_add_link(sf_unicast, link_options, LINK_TYPE_NORMAL, &tsch_broadcast_address, + timeslot, channel_offset); + } else { + /* Remove link */ + tsch_schedule_remove_link(sf_unicast, l); + } } /*---------------------------------------------------------------------------*/ static void From 7e8d042609a65e45f64ce11c23ada80875ab7474 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 20 May 2016 13:40:50 +0200 Subject: [PATCH 238/374] Orchestra: fix bug in new_time_source --- apps/orchestra/orchestra-rule-unicast-per-neighbor.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/orchestra/orchestra-rule-unicast-per-neighbor.c b/apps/orchestra/orchestra-rule-unicast-per-neighbor.c index acba8e7be..58f5dcc42 100644 --- a/apps/orchestra/orchestra-rule-unicast-per-neighbor.c +++ b/apps/orchestra/orchestra-rule-unicast-per-neighbor.c @@ -176,13 +176,14 @@ static void new_time_source(const struct tsch_neighbor *old, const struct tsch_neighbor *new) { if(new != old) { + const linkaddr_t *old_addr = old != NULL ? &old->addr : NULL; const linkaddr_t *new_addr = new != NULL ? &new->addr : NULL; if(new_addr != NULL) { linkaddr_copy(&orchestra_parent_linkaddr, new_addr); } else { linkaddr_copy(&orchestra_parent_linkaddr, &linkaddr_null); } - remove_uc_link(new_addr); + remove_uc_link(old_addr); add_uc_link(new_addr); } } From c7694e4dbdcfe831b29d8128f3845d9a9806ceac Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 20 May 2016 13:51:24 +0200 Subject: [PATCH 239/374] Orchestra: fix orchestra-rule-eb-per-time-source to handle hash collisions --- .../orchestra-rule-eb-per-time-source.c | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/apps/orchestra/orchestra-rule-eb-per-time-source.c b/apps/orchestra/orchestra-rule-eb-per-time-source.c index 0f774f531..b18617f0a 100644 --- a/apps/orchestra/orchestra-rule-eb-per-time-source.c +++ b/apps/orchestra/orchestra-rule-eb-per-time-source.c @@ -83,14 +83,24 @@ new_time_source(const struct tsch_neighbor *old, const struct tsch_neighbor *new if(old_ts != 0xffff) { /* Stop listening to the old time source's EBs */ - tsch_schedule_remove_link_by_timeslot(sf_eb, old_ts); + if(old_ts == get_node_timeslot(&linkaddr_node_addr)) { + /* This was the same timeslot as slot. Reset original link options */ + tsch_schedule_add_link(sf_eb, LINK_OPTION_TX, LINK_TYPE_ADVERTISING_ONLY, + &tsch_broadcast_address, old_ts, 0); + } else { + /* Remove slot */ + tsch_schedule_remove_link_by_timeslot(sf_eb, old_ts); + } } if(new_ts != 0xffff) { + uint8_t link_options = LINK_OPTION_RX; + if(new_ts == get_node_timeslot(&linkaddr_node_addr)) { + /* This is also our timeslot, add necessary flags */ + link_options |= LINK_OPTION_TX; + } /* Listen to the time source's EBs */ - tsch_schedule_add_link(sf_eb, - LINK_OPTION_RX, - LINK_TYPE_ADVERTISING_ONLY, NULL, - new_ts, 0); + tsch_schedule_add_link(sf_eb, link_options, LINK_TYPE_ADVERTISING_ONLY, + &tsch_broadcast_address, new_ts, 0); } } /*---------------------------------------------------------------------------*/ From 99c77bda8ce2c0dcc305f4389fa3fc6c22d601f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Thu, 19 May 2016 09:46:51 +0200 Subject: [PATCH 240/374] oma-lwm2m: Handle text/plain floatfix numbers without decimal point Fixes bug: If no decimal point is present then the entire number is treated as the decimal part instead of the integer part --- apps/oma-lwm2m/lwm2m-plain-text.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/oma-lwm2m/lwm2m-plain-text.c b/apps/oma-lwm2m/lwm2m-plain-text.c index 34b7f2318..b2bc5dcbe 100644 --- a/apps/oma-lwm2m/lwm2m-plain-text.c +++ b/apps/oma-lwm2m/lwm2m-plain-text.c @@ -100,6 +100,11 @@ lwm2m_plain_text_read_float32fix(const uint8_t *inbuf, size_t len, break; } } + if(dot == 0) { + integerpart = counter; + counter = 0; + frac = 1; + } *value = integerpart << bits; if(frac > 1) { *value += ((counter << bits) / frac); From bc54f8bac36bd8e97d36824146b11d3c72e1f8a1 Mon Sep 17 00:00:00 2001 From: Yasuyuki Tanaka Date: Sat, 21 May 2016 11:55:07 +0200 Subject: [PATCH 241/374] Orchestra: add NULL checks into new_time_source (eb-per-time-source) --- apps/orchestra/orchestra-rule-eb-per-time-source.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/orchestra/orchestra-rule-eb-per-time-source.c b/apps/orchestra/orchestra-rule-eb-per-time-source.c index b18617f0a..ed037291b 100644 --- a/apps/orchestra/orchestra-rule-eb-per-time-source.c +++ b/apps/orchestra/orchestra-rule-eb-per-time-source.c @@ -74,8 +74,8 @@ select_packet(uint16_t *slotframe, uint16_t *timeslot) static void new_time_source(const struct tsch_neighbor *old, const struct tsch_neighbor *new) { - uint16_t old_ts = get_node_timeslot(&old->addr); - uint16_t new_ts = get_node_timeslot(&new->addr); + uint16_t old_ts = old != NULL ? get_node_timeslot(&old->addr) : 0xffff; + uint16_t new_ts = new != NULL ? get_node_timeslot(&new->addr) : 0xffff; if(new_ts == old_ts) { return; From 65ff03537bcf637ecc5b8b3e89bd386f4fa6229d Mon Sep 17 00:00:00 2001 From: Nicholas Humfrey Date: Mon, 23 May 2016 12:54:16 +0100 Subject: [PATCH 242/374] Changed read-only pointers to const in enc28j60 --- dev/enc28j60/enc28j60.c | 6 +++--- dev/enc28j60/enc28j60.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dev/enc28j60/enc28j60.c b/dev/enc28j60/enc28j60.c index 60dded31a..6d7704e7f 100644 --- a/dev/enc28j60/enc28j60.c +++ b/dev/enc28j60/enc28j60.c @@ -207,7 +207,7 @@ setregbank(uint8_t new_bank) } /*---------------------------------------------------------------------------*/ static void -writedata(uint8_t *data, int datalen) +writedata(const uint8_t *data, int datalen) { int i; enc28j60_arch_spi_select(); @@ -477,7 +477,7 @@ reset(void) } /*---------------------------------------------------------------------------*/ void -enc28j60_init(uint8_t *mac_addr) +enc28j60_init(const uint8_t *mac_addr) { if(initialized) { return; @@ -496,7 +496,7 @@ enc28j60_init(uint8_t *mac_addr) } /*---------------------------------------------------------------------------*/ int -enc28j60_send(uint8_t *data, uint16_t datalen) +enc28j60_send(const uint8_t *data, uint16_t datalen) { uint16_t dataend; diff --git a/dev/enc28j60/enc28j60.h b/dev/enc28j60/enc28j60.h index 059528816..473cceca4 100644 --- a/dev/enc28j60/enc28j60.h +++ b/dev/enc28j60/enc28j60.h @@ -32,9 +32,9 @@ #ifndef ENC28J60_H #define ENC28J60_H -void enc28j60_init(uint8_t *mac_addr); +void enc28j60_init(const uint8_t *mac_addr); -int enc28j60_send(uint8_t *data, uint16_t datalen); +int enc28j60_send(const uint8_t *data, uint16_t datalen); int enc28j60_read(uint8_t *buffer, uint16_t bufsize); From de64ed397531b47202d065f5179820a2733ef0ae Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Tue, 24 May 2016 10:50:20 +0200 Subject: [PATCH 243/374] Fixed typo --- platform/zoul/contiki-main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/zoul/contiki-main.c b/platform/zoul/contiki-main.c index b577066fe..fc9ed91e9 100644 --- a/platform/zoul/contiki-main.c +++ b/platform/zoul/contiki-main.c @@ -218,7 +218,7 @@ main(void) #endif /* NETSTACK_CONF_WITH_IPV6 */ process_start(&sensors_process, NULL); -#if PLATFOM_HAS_BUTTON +#if PLATFORM_HAS_BUTTON SENSORS_ACTIVATE(button_sensor); #endif energest_init(); From f5919a2a459a75b711d6295b0d0797a565c66970 Mon Sep 17 00:00:00 2001 From: "Kitty(chun hua) Jiang" Date: Wed, 25 May 2016 10:25:43 +0800 Subject: [PATCH 244/374] fix the bug about chalemeon raw hdrsize --- core/net/rime/chameleon-raw.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) mode change 100644 => 100755 core/net/rime/chameleon-raw.c diff --git a/core/net/rime/chameleon-raw.c b/core/net/rime/chameleon-raw.c old mode 100644 new mode 100755 index 8efcf8a1f..16b17fb5d --- a/core/net/rime/chameleon-raw.c +++ b/core/net/rime/chameleon-raw.c @@ -205,10 +205,7 @@ hdrsize(const struct packetbuf_attrlist *a) continue; } #endif /* CHAMELEON_WITH_MAC_LINK_ADDRESSES */ - len = a->len; - if(len < 8) { - len = 8; - } + len = (a->len & 0xf8) + ((a->len & 7) ? 8: 0); size += len; } return size / 8; From 2299a763d096ff874f866a939095b2ca7ce325a0 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 13 May 2016 14:05:26 +0200 Subject: [PATCH 245/374] Fix tsch-log bug --- core/net/mac/tsch/tsch-log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/net/mac/tsch/tsch-log.c b/core/net/mac/tsch/tsch-log.c index bfb033e9d..982924419 100644 --- a/core/net/mac/tsch/tsch-log.c +++ b/core/net/mac/tsch/tsch-log.c @@ -103,7 +103,7 @@ tsch_log_process_pending(void) break; case tsch_log_rx: printf("%s-%u-%u %u rx %d", - log->rx.is_unicast == 0 ? "bc" : "uc", log->rx.is_data, log->tx.sec_level, + log->rx.is_unicast == 0 ? "bc" : "uc", log->rx.is_data, log->rx.sec_level, log->rx.datalen, log->rx.src); if(log->rx.drift_used) { From 65632cb086308777b3465169389775975a9869e1 Mon Sep 17 00:00:00 2001 From: Mark Solters Date: Thu, 26 May 2016 22:42:53 -0400 Subject: [PATCH 246/374] Fix IPv6 HTTP URL parsing Currently, http-socket uses a `parse_url` method which only works correctly with IPv4 hosts (e.g. `http://192.168.1.1:3000`). When using an IPv6 host (e.g. `http://[abcd::1]:3000`), the port number is not parsed due to a pointer increment error, which leads to the algorithm assuming a default port of 80 even when the user code has specified otherwise. This fix provides full URL parsing for IPv6 hosts, and does not break IPv4 functionality. --- core/net/http-socket/http-socket.c | 1 + 1 file changed, 1 insertion(+) diff --git a/core/net/http-socket/http-socket.c b/core/net/http-socket/http-socket.c index 758c1473e..3495b597b 100644 --- a/core/net/http-socket/http-socket.c +++ b/core/net/http-socket/http-socket.c @@ -324,6 +324,7 @@ parse_url(const char *url, char *host, uint16_t *portptr, char *path) if(host != NULL) { host[i] = 0; } + urlptr++; break; } if(host != NULL) { From 9832b356ba1d1535a5f8463c6c7f0bdcd2e91cfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Wed, 4 May 2016 19:13:51 +0200 Subject: [PATCH 247/374] oma-lwm2m: Use Accept header to determine the writer object for the content --- apps/oma-lwm2m/lwm2m-engine.c | 109 +++++++++++++++++++++++++--------- 1 file changed, 82 insertions(+), 27 deletions(-) diff --git a/apps/oma-lwm2m/lwm2m-engine.c b/apps/oma-lwm2m/lwm2m-engine.c index e2f6bba7c..3728e3505 100644 --- a/apps/oma-lwm2m/lwm2m-engine.c +++ b/apps/oma-lwm2m/lwm2m-engine.c @@ -50,6 +50,7 @@ #include "er-coap-constants.h" #include "er-coap-engine.h" #include "oma-tlv.h" +#include "oma-tlv-reader.h" #include "oma-tlv-writer.h" #include "net/ipv6/uip-ds6.h" #include @@ -707,6 +708,59 @@ write_rd_json_data(const lwm2m_context_t *context, return rdlen; } /*---------------------------------------------------------------------------*/ +/** + * @brief Set the writer pointer to the proper writer based on the Accept: header + * + * @param[in] context LWM2M context to operate on + * @param[in] accept Accept type number from CoAP headers + * + * @return The content type of the response if the selected writer is used + */ +static unsigned int +lwm2m_engine_select_writer(lwm2m_context_t *context, unsigned int accept) +{ + switch(accept) { + case LWM2M_TLV: + context->writer = &oma_tlv_writer; + break; + case LWM2M_TEXT_PLAIN: + case TEXT_PLAIN: + context->writer = &lwm2m_plain_text_writer; + break; + default: + PRINTF("Unknown Accept type %u, using LWM2M plain text\n", accept); + context->writer = &lwm2m_plain_text_writer; + /* Set the response type to plain text */ + accept = LWM2M_TEXT_PLAIN; + break; + } + return accept; +} +/*---------------------------------------------------------------------------*/ +/** + * @brief Set the reader pointer to the proper reader based on the Content-format: header + * + * @param[in] context LWM2M context to operate on + * @param[in] content_format Content-type type number from CoAP headers + */ +static void +lwm2m_engine_select_reader(lwm2m_context_t *context, unsigned int content_format) +{ + switch(content_format) { + case LWM2M_TLV: + context->reader = &oma_tlv_reader; + break; + case LWM2M_TEXT_PLAIN: + case TEXT_PLAIN: + context->reader = &lwm2m_plain_text_reader; + break; + default: + PRINTF("Unknown content type %u, using LWM2M plain text\n", accept); + context->reader = &lwm2m_plain_text_reader; + break; + } +} +/*---------------------------------------------------------------------------*/ void lwm2m_engine_handler(const lwm2m_object_t *object, void *request, void *response, @@ -716,6 +770,8 @@ lwm2m_engine_handler(const lwm2m_object_t *object, int len; const char *url; unsigned int format; + unsigned int accept; + unsigned int content_type; int depth; lwm2m_context_t context; rest_resource_flags_t method; @@ -734,11 +790,19 @@ lwm2m_engine_handler(const lwm2m_object_t *object, /* CoAP content format text plain - assume LWM2M text plain */ format = LWM2M_TEXT_PLAIN; } + if(!REST.get_header_accept(request, &accept)) { + PRINTF("No Accept header, using same as Content-format...\n"); + accept = format; + } depth = lwm2m_engine_parse_context(object, url, len, &context); PRINTF("Context: %u/%u/%u found: %d\n", context.object_id, context.object_instance_id, context.resource_id, depth); + /* Select reader and writer based on provided Content type and Accept headers */ + lwm2m_engine_select_reader(&context, format); + content_type = lwm2m_engine_select_writer(&context, accept); + #if (DEBUG) & DEBUG_PRINT /* for debugging */ if(method == METHOD_GET) { @@ -861,7 +925,7 @@ lwm2m_engine_handler(const lwm2m_object_t *object, if(depth == 3) { const lwm2m_resource_t *resource = get_resource(instance, &context); - size_t tlvlen = 0; + size_t content_len = 0; if(resource == NULL) { PRINTF("Error - do not have resource %d\n", context.resource_id); REST.set_response_status(response, NOT_FOUND_4_04); @@ -879,9 +943,9 @@ lwm2m_engine_handler(const lwm2m_object_t *object, context.reader = &lwm2m_plain_text_reader; PRINTF("PUT Callback with data: '%.*s'\n", plen, data); /* no specific reader for plain text */ - tlvlen = resource->value.callback.write(&context, data, plen, + content_len = resource->value.callback.write(&context, data, plen, buffer, preferred_size); - PRINTF("tlvlen:%u\n", (unsigned int)tlvlen); + PRINTF("content_len:%u\n", (unsigned int)content_len); REST.set_response_status(response, CHANGED_2_04); } else { PRINTF("PUT callback with format %d\n", format); @@ -899,48 +963,39 @@ lwm2m_engine_handler(const lwm2m_object_t *object, } else if(method == METHOD_GET) { if(lwm2m_object_is_resource_string(resource)) { const uint8_t *value; - uint16_t len; value = lwm2m_object_get_resource_string(resource, &context); - len = lwm2m_object_get_resource_strlen(resource, &context); if(value != NULL) { + uint16_t len = lwm2m_object_get_resource_strlen(resource, &context); PRINTF("Get string value: %.*s\n", (int)len, (char *)value); - /* TODO check format */ - REST.set_response_payload(response, value, len); - REST.set_header_content_type(response, LWM2M_TEXT_PLAIN); - /* Done */ - return; + content_len = context.writer->write_string(&context, buffer, + preferred_size, (const char *)value, len); } } else if(lwm2m_object_is_resource_int(resource)) { int32_t value; if(lwm2m_object_get_resource_int(resource, &context, &value)) { - /* export INT as TLV */ - tlvlen = oma_tlv_write_int32(resource->id, value, buffer, preferred_size); - PRINTF("Exporting int as TLV: %" PRId32 ", len: %u\n", - value, (unsigned int)tlvlen); + content_len = context.writer->write_int(&context, buffer, preferred_size, value); } } else if(lwm2m_object_is_resource_floatfix(resource)) { int32_t value; if(lwm2m_object_get_resource_floatfix(resource, &context, &value)) { - /* export FLOATFIX as TLV */ + /* export FLOATFIX */ PRINTF("Exporting %d-bit fix as float: %" PRId32 "\n", LWM2M_FLOAT32_BITS, value); - tlvlen = oma_tlv_write_float32(resource->id, - value, LWM2M_FLOAT32_BITS, - buffer, preferred_size); - PRINTF("Exporting as TLV: len:%u\n", (unsigned int)tlvlen); + content_len = context.writer->write_float32fix(&context, buffer, + preferred_size, value, LWM2M_FLOAT32_BITS); } } else if(lwm2m_object_is_resource_callback(resource)) { if(resource->value.callback.read != NULL) { - tlvlen = resource->value.callback.read(&context, + content_len = resource->value.callback.read(&context, buffer, preferred_size); } else { REST.set_response_status(response, METHOD_NOT_ALLOWED_4_05); return; } } - if(tlvlen > 0) { - REST.set_response_payload(response, buffer, tlvlen); - REST.set_header_content_type(response, LWM2M_TLV); + if(content_len > 0) { + REST.set_response_payload(response, buffer, content_len); + REST.set_header_content_type(response, content_type); } else { /* failed to produce output - it is an internal error */ REST.set_response_status(response, INTERNAL_SERVER_ERROR_5_00); @@ -952,7 +1007,7 @@ lwm2m_engine_handler(const lwm2m_object_t *object, const uint8_t *data; int plen = REST.get_request_payload(request, &data); PRINTF("Execute Callback with data: '%.*s'\n", plen, data); - tlvlen = resource->value.callback.exec(&context, + content_len = resource->value.callback.exec(&context, data, plen, buffer, preferred_size); REST.set_response_status(response, CHANGED_2_04); @@ -973,7 +1028,7 @@ lwm2m_engine_handler(const lwm2m_object_t *object, REST.set_response_status(response, NOT_FOUND_4_04); } else { int rdlen; - if(format == APPLICATION_LINK_FORMAT) { + if(accept == APPLICATION_LINK_FORMAT) { rdlen = write_rd_link_data(object, instance, (char *)buffer, preferred_size); } else { @@ -986,10 +1041,10 @@ lwm2m_engine_handler(const lwm2m_object_t *object, return; } REST.set_response_payload(response, buffer, rdlen); - if(format == APPLICATION_LINK_FORMAT) { + if(accept == APPLICATION_LINK_FORMAT) { REST.set_header_content_type(response, REST.type.APPLICATION_LINK_FORMAT); } else { - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + REST.set_header_content_type(response, LWM2M_JSON); } } } From e8edb6b1a0914e5872053293c801ee2d43148e19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Wed, 4 May 2016 20:39:08 +0200 Subject: [PATCH 248/374] oma-lwm2m: Add JSON writer --- apps/oma-lwm2m/Makefile.oma-lwm2m | 16 ++- apps/oma-lwm2m/lwm2m-engine.c | 5 + apps/oma-lwm2m/lwm2m-json.c | 162 ++++++++++++++++++++++++++++++ apps/oma-lwm2m/lwm2m-json.h | 51 ++++++++++ 4 files changed, 230 insertions(+), 4 deletions(-) create mode 100644 apps/oma-lwm2m/lwm2m-json.c create mode 100644 apps/oma-lwm2m/lwm2m-json.h diff --git a/apps/oma-lwm2m/Makefile.oma-lwm2m b/apps/oma-lwm2m/Makefile.oma-lwm2m index 8445530ed..000147939 100644 --- a/apps/oma-lwm2m/Makefile.oma-lwm2m +++ b/apps/oma-lwm2m/Makefile.oma-lwm2m @@ -1,5 +1,13 @@ -oma-lwm2m_src = lwm2m-object.c lwm2m-engine.c \ - lwm2m-device.c lwm2m-server.c lwm2m-security.c \ - oma-tlv.c oma-tlv-reader.c oma-tlv-writer.c \ - lwm2m-plain-text.c +oma-lwm2m_src = \ + lwm2m-object.c \ + lwm2m-engine.c \ + lwm2m-device.c \ + lwm2m-server.c \ + lwm2m-security.c \ + oma-tlv.c \ + oma-tlv-reader.c \ + oma-tlv-writer.c \ + lwm2m-plain-text.c \ + lwm2m-json.c \ + # CFLAGS += -DHAVE_OMA_LWM2M=1 diff --git a/apps/oma-lwm2m/lwm2m-engine.c b/apps/oma-lwm2m/lwm2m-engine.c index 3728e3505..0fe86bbbb 100644 --- a/apps/oma-lwm2m/lwm2m-engine.c +++ b/apps/oma-lwm2m/lwm2m-engine.c @@ -46,6 +46,7 @@ #include "lwm2m-object.h" #include "lwm2m-device.h" #include "lwm2m-plain-text.h" +#include "lwm2m-json.h" #include "rest-engine.h" #include "er-coap-constants.h" #include "er-coap-engine.h" @@ -727,6 +728,10 @@ lwm2m_engine_select_writer(lwm2m_context_t *context, unsigned int accept) case TEXT_PLAIN: context->writer = &lwm2m_plain_text_writer; break; + case LWM2M_JSON: + case APPLICATION_JSON: + context->writer = &lwm2m_json_writer; + break; default: PRINTF("Unknown Accept type %u, using LWM2M plain text\n", accept); context->writer = &lwm2m_plain_text_writer; diff --git a/apps/oma-lwm2m/lwm2m-json.c b/apps/oma-lwm2m/lwm2m-json.c new file mode 100644 index 000000000..8924ceb8c --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-json.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2016, Eistec AB. + * 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 copyright holder 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 COPYRIGHT HOLDER 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 + * COPYRIGHT HOLDER 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. + */ + +/** + * \addtogroup oma-lwm2m + * @{ + */ + +/** + * \file + * Implementation of the Contiki OMA LWM2M JSON writer + * \author + * Joakim Nohlgård + */ + +#include "lwm2m-object.h" +#include "lwm2m-json.h" +#include "lwm2m-plain-text.h" +#include +#include +#include +#include + +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/*---------------------------------------------------------------------------*/ +static size_t +write_boolean(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + int value) +{ + int len = snprintf((char *)outbuf, outlen, "{\"e\":[{\"n\":\"%u\",\"bv\":%s}]}\n", ctx->resource_id, value ? "true" : "false"); + if((len < 0) || (len >= outlen)) { + return 0; + } + return len; +} +/*---------------------------------------------------------------------------*/ +static size_t +write_int(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + int32_t value) +{ + int len = snprintf((char *)outbuf, outlen, "{\"e\":[{\"n\":\"%u\",\"v\":%" PRId32 "}]}\n", ctx->resource_id, value); + if((len < 0) || (len >= outlen)) { + return 0; + } + return len; +} +/*---------------------------------------------------------------------------*/ +static size_t +write_float32fix(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + int32_t value, int bits) +{ + size_t len = 0; + int res; + res = snprintf((char *)outbuf, outlen, "{\"e\":[{\"n\":\"%u\",\"v\":", ctx->resource_id); + if(res <= 0 || res >= outlen) { + return 0; + } + len += res; + outlen -= res; + res = lwm2m_plain_text_write_float32fix(&outbuf[len], outlen, value, bits); + if((res <= 0) || (res >= outlen)) { + return 0; + } + len += res; + outlen -= res; + res = snprintf((char *)&outbuf[len], outlen, "}]}\n"); + if((res <= 0) || (res >= outlen)) { + return 0; + } + len += res; + return len; +} +/*---------------------------------------------------------------------------*/ +static size_t +write_string(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + const char *value, size_t stringlen) +{ + size_t i; + size_t len = 0; + int res; + PRINTF("{\"e\":[{\"n\":\"%u\",\"sv\":\"", ctx->resource_id); + res = snprintf((char *)outbuf, outlen, "{\"e\":[{\"n\":\"%u\",\"sv\":\"", ctx->resource_id); + if(res < 0 || res >= outlen) { + return 0; + } + len += res; + for (i = 0; i < stringlen && len < outlen; ++i) { + /* Escape special characters */ + /* TODO: Handle UTF-8 strings */ + if(value[i] < '\x20') { + PRINTF("\\x%x", value[i]); + res = snprintf((char *)&outbuf[len], outlen - len, "\\x%x", value[i]); + if((res < 0) || (res >= (outlen - len))) { + return 0; + } + len += res; + continue; + } else if(value[i] == '"' || value[i] == '\\') { + PRINTF("\\"); + outbuf[len] = '\\'; + ++len; + if(len >= outlen) { + return 0; + } + } + PRINTF("%c", value[i]); + outbuf[len] = value[i]; + ++len; + if(len >= outlen) { + return 0; + } + } + PRINTF("\"}]}\n"); + res = snprintf((char *)&outbuf[len], outlen - len, "\"}]}\n"); + if((res < 0) || (res >= (outlen - len))) { + return 0; + } + len += res; + return len; +} +/*---------------------------------------------------------------------------*/ +const lwm2m_writer_t lwm2m_json_writer = { + write_int, + write_string, + write_float32fix, + write_boolean +}; +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/oma-lwm2m/lwm2m-json.h b/apps/oma-lwm2m/lwm2m-json.h new file mode 100644 index 000000000..bc1a1e32a --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-json.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016, Eistec AB. + * 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 copyright holder 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 COPYRIGHT HOLDER 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 + * COPYRIGHT HOLDER 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. + */ + +/** + * \addtogroup oma-lwm2m + * @{ + */ + +/** + * \file + * Header file for the Contiki OMA LWM2M JSON writer + * \author + * Joakim Nohlgård + */ + +#ifndef LWM2M_JSON_H_ +#define LWM2M_JSON_H_ + +#include "lwm2m-object.h" + +extern const lwm2m_writer_t lwm2m_json_writer; + +#endif /* LWM2M_JSON_H_ */ +/** @} */ From 08dc4b0b214f321e55ad10f5d2d89e21a0820996 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Tue, 19 Apr 2016 22:16:56 +0100 Subject: [PATCH 249/374] Add controller for the AUX domain --- cpu/cc26xx-cc13xx/dev/aux-ctrl.c | 116 +++++++++++++++++++++++++ cpu/cc26xx-cc13xx/dev/aux-ctrl.h | 143 +++++++++++++++++++++++++++++++ 2 files changed, 259 insertions(+) create mode 100644 cpu/cc26xx-cc13xx/dev/aux-ctrl.c create mode 100644 cpu/cc26xx-cc13xx/dev/aux-ctrl.h diff --git a/cpu/cc26xx-cc13xx/dev/aux-ctrl.c b/cpu/cc26xx-cc13xx/dev/aux-ctrl.c new file mode 100644 index 000000000..eb316d3df --- /dev/null +++ b/cpu/cc26xx-cc13xx/dev/aux-ctrl.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2016, University of Bristol - http://www.bris.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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/aux-ctrl.h" +#include "lib/list.h" + +#include "ti-lib.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +LIST(consumers_list); +/*---------------------------------------------------------------------------*/ +void +aux_ctrl_register_consumer(aux_consumer_module_t *consumer) +{ + bool interrupts_disabled = ti_lib_int_master_disable(); + + list_add(consumers_list, consumer); + + aux_ctrl_power_up(); + + ti_lib_aux_wuc_clock_enable(consumer->clocks); + while(ti_lib_aux_wuc_clock_status(consumer->clocks) != AUX_WUC_CLOCK_READY); + + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } +} +/*---------------------------------------------------------------------------*/ +void +aux_ctrl_unregister_consumer(aux_consumer_module_t *consumer) +{ + bool interrupts_disabled = ti_lib_int_master_disable(); + + list_remove(consumers_list, consumer); + + aux_ctrl_power_down(false); + + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } +} +/*---------------------------------------------------------------------------*/ +void +aux_ctrl_power_up() +{ + /* Don't if we have no consumers */ + if(list_head(consumers_list) == NULL) { + return; + } + + ti_lib_aon_wuc_aux_wakeup_event(AONWUC_AUX_WAKEUP); + while(!(ti_lib_aon_wuc_power_status_get() & AONWUC_AUX_POWER_ON)); +} +/*---------------------------------------------------------------------------*/ +void +aux_ctrl_power_down(bool force) +{ + aux_consumer_module_t *consumer; + uint32_t clocks_in_use = 0; + + if(!force) { + /* Visit all modules and release clocks */ + for(consumer = list_head(consumers_list); consumer != NULL; + consumer = consumer->next) { + clocks_in_use |= consumer->clocks; + } + + /* If any clocks are still in use, AUX needs to stay powered and clocked */ + if(clocks_in_use) { + ti_lib_aon_wuc_aux_power_down_config(AONWUC_CLOCK_SRC_LF); + return; + } + } + + /* No clock for AUX in power down */ + ti_lib_aon_wuc_aux_power_down_config(AONWUC_NO_CLOCK); + + /* Disable retention */ + ti_lib_aon_wuc_aux_sram_config(false); + + /* Turn off AUX */ + ti_lib_aon_wuc_aux_wakeup_event(AONWUC_AUX_ALLOW_SLEEP); + ti_lib_aux_wuc_power_ctrl(AUX_WUC_POWER_OFF); + while(ti_lib_aon_wuc_power_status_get() & AONWUC_AUX_POWER_ON); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc26xx-cc13xx/dev/aux-ctrl.h b/cpu/cc26xx-cc13xx/dev/aux-ctrl.h new file mode 100644 index 000000000..8e65a7844 --- /dev/null +++ b/cpu/cc26xx-cc13xx/dev/aux-ctrl.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2016, University of Bristol - http://www.bris.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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx + * @{ + * + * \defgroup cc26xx-aux-ctrl CC13xx/CC26xx AUX domain controller + * + * CC13xx/CC26xx AUX domain power management controller + * + * @{ + * + * \file + * Header file for the management of the CC13xx/CC26xx AUX domain + */ +/*---------------------------------------------------------------------------*/ +#ifndef AUX_CTRL_H_ +#define AUX_CTRL_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" + +#include "ti-lib.h" + +#include +/*---------------------------------------------------------------------------*/ +/** + * \brief The data structure to be used for modules that require access to AUX + * + * The clocks field should specify the clocks (within AUX) that your module + * requires in order to perform its functionality. Those clocks are an ORd + * value of AUX_WUC_xxxx_CLOCK. For instance, the oscillators module specifies + * AUX_WUC_OSCCTRL_CLOCK | AUX_WUC_SMPH_CLOCK + */ +typedef struct aux_consumer_module { + struct aux_consumer_module *next; + uint32_t clocks; +} aux_consumer_module_t; +/*---------------------------------------------------------------------------*/ +/** + * \brief Register a module that no longer requires access to the AUX power domain + * \param consumer A pointer to the data structure of your AUX consumer + * + * Call this function if you are developing a module that requires access to + * hardware within the AUX PD. Calling this function will achieve a number of + * things: + * + * - It will power up the AUX PD + * - It will enable the AUX clocks that you require + * + * If you call this function, AUX will stay powered-on and clocked during deep + * sleep, and retention will be enabled (so that you can e.g. use the sensor + * controller to monitor peripherals while the main MCU in deep sleep). If you + * do not need AUX enabled during deep sleep, you must release it by calling + * aux_ctrl_unregister_consumer() + * + * \sa aux_ctrl_unregister_consumer + */ +void aux_ctrl_register_consumer(aux_consumer_module_t *consumer); + +/** + * \brief Deregister a module that no longer requires access to the AUX power domain + * \param consumer A pointer to the data structure of your AUX consumer + * + * When your module is finished using features provided from within the AUX + * domain, you should call this function to signal that AUX is no longer + * required, so that the LPM module can power it down in deep sleep. If there + * are no more registered consumers left, this function will also power down + * AUX. + * + * \sa aux_ctrl_register_consumer + * \sa aux_ctrl_power_down + */ +void aux_ctrl_unregister_consumer(aux_consumer_module_t *consumer); + +/** + * \brief Power-up the AUX power domain + * + * This function will power up the AUX power-domain, but only if there are + * registered consumers for it. If there are not, the PD will stay off. + * + * This function will automatically get called by the LPM module whenever the + * chip comes out of deep sleep. + * + * User applications will normally not need to call this function. if you are + * developing a user application that requires access, to AUX, you should + * normally call aux_ctrl_register_consumer(), which will automatically power + * up AUX for you, if it's not already powered. + */ +void aux_ctrl_power_up(void); + +/** + * \brief Power down the AUX power domain + * \param force Force the power down irrespective of registered consumers + * + * This function will shut down the AUX power-domain. + * + * The shutdown is unconditional if force is true. If force is false and there + * are registered consumers, the power-down will be suppressed. + * + * This function will automatically get called by the LPM module whenever the + * chip tries to enter deep sleep or shuts down. + * + * User applications will normally not need to call this function. if you are + * developing a user application that no longer requires access, to AUX, you + * should normally simply release it by calling aux_ctrl_unregister_consumer(). + * If no other consumers are using AUX, then the lpm module will shut it down. + */ +void aux_ctrl_power_down(bool force); +/*---------------------------------------------------------------------------*/ +#endif /* AUX_CTRL_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ From 698ce3a8657fddfefdc552807ff348fb4e1916e8 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Tue, 19 Apr 2016 22:17:16 +0100 Subject: [PATCH 250/374] Add the AUX controller to the build --- cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx b/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx index f6ac275da..40638e80e 100644 --- a/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx +++ b/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx @@ -68,7 +68,7 @@ CONTIKI_CPU_DIRS += ../arm/common/dbg-io ### CPU-dependent source files CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c soc-rtc.c uart.c -CONTIKI_CPU_SOURCEFILES += contiki-watchdog.c +CONTIKI_CPU_SOURCEFILES += contiki-watchdog.c aux-ctrl.c CONTIKI_CPU_SOURCEFILES += putchar.c ieee-addr.c batmon-sensor.c CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c cc26xx-uart.c lpm.c CONTIKI_CPU_SOURCEFILES += gpio-interrupt.c oscillators.c From 812f1ada31f690dcd6aa77ba973b814eed4bf909 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Tue, 19 Apr 2016 22:18:23 +0100 Subject: [PATCH 251/374] Manipulate OSC modules using the AUX controller --- cpu/cc26xx-cc13xx/dev/oscillators.c | 86 ++++++++++++----------------- 1 file changed, 36 insertions(+), 50 deletions(-) diff --git a/cpu/cc26xx-cc13xx/dev/oscillators.c b/cpu/cc26xx-cc13xx/dev/oscillators.c index 99ba8f841..7890a8e55 100644 --- a/cpu/cc26xx-cc13xx/dev/oscillators.c +++ b/cpu/cc26xx-cc13xx/dev/oscillators.c @@ -37,44 +37,18 @@ */ /*---------------------------------------------------------------------------*/ #include "ti-lib.h" +#include "aux-ctrl.h" #include /*---------------------------------------------------------------------------*/ -static uint32_t -osc_interface_en(void) -{ - uint32_t smph_clk_state; - - /* Enable OSC DIG interface to change clock sources */ - ti_lib_osc_interface_enable(); - - /* Save the state of the SMPH clock within AUX */ - smph_clk_state = ti_lib_aux_wuc_clock_status(AUX_WUC_SMPH_CLOCK); - - /* Make sure the SMPH clock within AUX is enabled */ - ti_lib_aux_wuc_clock_enable(AUX_WUC_SMPH_CLOCK); - while(ti_lib_aux_wuc_clock_status(AUX_WUC_SMPH_CLOCK) != AUX_WUC_CLOCK_READY); - - return smph_clk_state; -} -/*---------------------------------------------------------------------------*/ -static void -osc_interface_dis(uint32_t smph_clk_state) -{ - /* If the SMPH clock was off, turn it back off */ - if(smph_clk_state == AUX_WUC_CLOCK_OFF) { - ti_lib_aux_wuc_clock_disable(AUX_WUC_SMPH_CLOCK); - } - - /* Disable OSC DIG interface */ - ti_lib_osc_interface_disable(); -} -/*---------------------------------------------------------------------------*/ void oscillators_select_lf_xosc(void) { - /* Enable the Osc interface and remember the state of the SMPH clock */ - uint32_t smph_clk_state = osc_interface_en(); + /* Request AUX access, with OSCCTRL and SMPH clocks */ + aux_consumer_module_t osc = { + .clocks = AUX_WUC_OSCCTRL_CLOCK | AUX_WUC_SMPH_CLOCK + }; + aux_ctrl_register_consumer(&osc); /* Switch LF clock source to the LF XOSC if required */ if(ti_lib_osc_clock_source_get(OSC_SRC_CLK_LF) != OSC_XOSC_LF) { @@ -91,15 +65,18 @@ oscillators_select_lf_xosc(void) 0x3); } - /* Restore the SMPH clock and disable the OSC interface */ - osc_interface_dis(smph_clk_state); + /* Release the OSC AUX consumer */ + aux_ctrl_unregister_consumer(&osc); } /*---------------------------------------------------------------------------*/ void oscillators_select_lf_rcosc(void) { - /* Enable the Osc interface and remember the state of the SMPH clock */ - uint32_t smph_clk_state = osc_interface_en(); + /* Request AUX access, with OSCCTRL and SMPH clocks */ + aux_consumer_module_t osc = { + .clocks = AUX_WUC_OSCCTRL_CLOCK | AUX_WUC_SMPH_CLOCK + }; + aux_ctrl_register_consumer(&osc); /* Switch LF clock source to the LF XOSC if required */ if(ti_lib_osc_clock_source_get(OSC_SRC_CLK_LF) != OSC_RCOSC_LF) { @@ -109,15 +86,18 @@ oscillators_select_lf_rcosc(void) while(ti_lib_osc_clock_source_get(OSC_SRC_CLK_LF) != OSC_RCOSC_LF); } - /* Restore the SMPH clock and disable the OSC interface */ - osc_interface_dis(smph_clk_state); + /* Release the OSC AUX consumer */ + aux_ctrl_unregister_consumer(&osc); } /*---------------------------------------------------------------------------*/ void oscillators_request_hf_xosc(void) { - /* Enable the Osc interface and remember the state of the SMPH clock */ - uint32_t smph_clk_state = osc_interface_en(); + /* Request AUX access, with OSCCTRL and SMPH clocks */ + aux_consumer_module_t osc = { + .clocks = AUX_WUC_OSCCTRL_CLOCK | AUX_WUC_SMPH_CLOCK + }; + aux_ctrl_register_consumer(&osc); if(ti_lib_osc_clock_source_get(OSC_SRC_CLK_HF) != OSC_XOSC_HF) { /* @@ -128,30 +108,36 @@ oscillators_request_hf_xosc(void) ti_lib_osc_clock_source_set(OSC_SRC_CLK_MF | OSC_SRC_CLK_HF, OSC_XOSC_HF); } - /* Restore the SMPH clock and disable the OSC interface */ - osc_interface_dis(smph_clk_state); + /* Release the OSC AUX consumer */ + aux_ctrl_unregister_consumer(&osc); } /*---------------------------------------------------------------------------*/ void oscillators_switch_to_hf_xosc(void) { - /* Enable the Osc interface and remember the state of the SMPH clock */ - uint32_t smph_clk_state = osc_interface_en(); + /* Request AUX access, with OSCCTRL and SMPH clocks */ + aux_consumer_module_t osc = { + .clocks = AUX_WUC_OSCCTRL_CLOCK | AUX_WUC_SMPH_CLOCK + }; + aux_ctrl_register_consumer(&osc); if(ti_lib_osc_clock_source_get(OSC_SRC_CLK_HF) != OSC_XOSC_HF) { /* Switch the HF clock source (cc26xxware executes this from ROM) */ ti_lib_osc_hf_source_switch(); } - /* Restore the SMPH clock and disable the OSC interface */ - osc_interface_dis(smph_clk_state); + /* Release the OSC AUX consumer */ + aux_ctrl_unregister_consumer(&osc); } /*---------------------------------------------------------------------------*/ void oscillators_switch_to_hf_rc(void) { - /* Enable the Osc interface and remember the state of the SMPH clock */ - uint32_t smph_clk_state = osc_interface_en(); + /* Request AUX access, with OSCCTRL and SMPH clocks */ + aux_consumer_module_t osc = { + .clocks = AUX_WUC_OSCCTRL_CLOCK | AUX_WUC_SMPH_CLOCK + }; + aux_ctrl_register_consumer(&osc); /* Set all clock sources to the HF RC Osc */ ti_lib_osc_clock_source_set(OSC_SRC_CLK_MF | OSC_SRC_CLK_HF, OSC_RCOSC_HF); @@ -162,8 +148,8 @@ oscillators_switch_to_hf_rc(void) ti_lib_osc_hf_source_switch(); } - /* Restore the SMPH clock and disable the OSC interface */ - osc_interface_dis(smph_clk_state); + /* Release the OSC AUX consumer */ + aux_ctrl_unregister_consumer(&osc); } /*---------------------------------------------------------------------------*/ /** @} */ From 6b40b1b9658aaa8d3cf5bdc27367245403fa1e13 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Wed, 20 Apr 2016 16:19:54 +0100 Subject: [PATCH 252/374] Change LPM to power up/down AUX through the AUX controller --- cpu/cc26xx-cc13xx/lpm.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/cpu/cc26xx-cc13xx/lpm.c b/cpu/cc26xx-cc13xx/lpm.c index eec8ed66d..686065c73 100644 --- a/cpu/cc26xx-cc13xx/lpm.c +++ b/cpu/cc26xx-cc13xx/lpm.c @@ -46,6 +46,7 @@ #include "lpm.h" #include "sys/energest.h" #include "lib/list.h" +#include "dev/aux-ctrl.h" #include "dev/leds.h" #include "dev/watchdog.h" #include "dev/soc-rtc.h" @@ -53,6 +54,7 @@ #include #include +#include /*---------------------------------------------------------------------------*/ #if ENERGEST_CONF_ON static unsigned long irq_energest = 0; @@ -90,8 +92,8 @@ lpm_shutdown(uint32_t wakeup_pin, uint32_t io_pull, uint32_t wake_on) { lpm_registered_module_t *module; int i; - uint32_t io_cfg = (IOC_STD_INPUT & ~IOC_IOPULL_M) | io_pull | - wake_on; + uint32_t io_cfg = (IOC_STD_INPUT & ~IOC_IOPULL_M) | io_pull | wake_on; + aux_consumer_module_t aux = { .clocks = AUX_WUC_OSCCTRL_CLOCK }; /* This procedure may not be interrupted */ ti_lib_int_master_disable(); @@ -135,16 +137,16 @@ lpm_shutdown(uint32_t wakeup_pin, uint32_t io_pull, uint32_t wake_on) ti_lib_prcm_power_domain_off(PRCM_DOMAIN_RFCORE | PRCM_DOMAIN_SERIAL | PRCM_DOMAIN_PERIPH); + /* Register an aux-ctrl consumer to avoid powercycling AUX twice in a row */ + aux_ctrl_register_consumer(&aux); oscillators_switch_to_hf_rc(); oscillators_select_lf_rcosc(); - /* Configure clock sources for MCU and AUX: No clock */ + /* Configure clock sources for MCU: No clock */ ti_lib_aon_wuc_mcu_power_down_config(AONWUC_NO_CLOCK); - ti_lib_aon_wuc_aux_power_down_config(AONWUC_NO_CLOCK); - /* Disable SRAM and AUX retentions */ + /* Disable SRAM retention */ ti_lib_aon_wuc_mcu_sram_config(0); - ti_lib_aon_wuc_aux_sram_config(false); /* * Request CPU, SYSBYS and VIMS PD off. @@ -157,9 +159,8 @@ lpm_shutdown(uint32_t wakeup_pin, uint32_t io_pull, uint32_t wake_on) ti_lib_aon_wuc_jtag_power_off(); /* Turn off AUX */ - ti_lib_aux_wuc_power_ctrl(AUX_WUC_POWER_OFF); + aux_ctrl_power_down(true); ti_lib_aon_wuc_domain_power_down_enable(); - while(ti_lib_aon_wuc_power_status_get() & AONWUC_AUX_POWER_ON); /* * Request MCU VD power off. @@ -222,6 +223,9 @@ wake_up(void) /* Check operating conditions, optimally choose DCDC versus GLDO */ ti_lib_sys_ctrl_dcdc_voltage_conditional_control(); + /* Fire up AUX is the user has requested this */ + aux_ctrl_power_up(); + /* * We may or may not have been woken up by an AON RTC tick. If not, we need * to adjust our software tick counter @@ -306,17 +310,16 @@ deep_sleep(void) */ oscillators_switch_to_hf_rc(); - /* Configure clock sources for MCU and AUX: No clock */ + /* Shut Down the AUX if the user application is not using it */ + aux_ctrl_power_down(false); + + /* Configure clock sources for MCU: No clock */ ti_lib_aon_wuc_mcu_power_down_config(AONWUC_NO_CLOCK); - ti_lib_aon_wuc_aux_power_down_config(AONWUC_NO_CLOCK); /* Full RAM retention. */ ti_lib_aon_wuc_mcu_sram_config(MCU_RAM0_RETENTION | MCU_RAM1_RETENTION | MCU_RAM2_RETENTION | MCU_RAM3_RETENTION); - /* Disable retention of AUX RAM */ - ti_lib_aon_wuc_aux_sram_config(false); - /* * Always turn off RFCORE, CPU, SYSBUS and VIMS. RFCORE should be off * already @@ -327,10 +330,8 @@ deep_sleep(void) /* Request JTAG domain power off */ ti_lib_aon_wuc_jtag_power_off(); - /* Turn off AUX */ - ti_lib_aux_wuc_power_ctrl(AUX_WUC_POWER_OFF); + /* Allow MCU and AUX powerdown */ ti_lib_aon_wuc_domain_power_down_enable(); - while(ti_lib_aon_wuc_power_status_get() & AONWUC_AUX_POWER_ON); /* Configure the recharge controller */ ti_lib_sys_ctrl_set_recharge_before_power_down(XOSC_IN_HIGH_POWER_MODE); From 43b8bf3d3059f42785d7826ca3ec5018ed7753e3 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 28 May 2016 17:55:31 +0100 Subject: [PATCH 253/374] Add CCxxware macros for AUX ADC --- cpu/cc26xx-cc13xx/ti-lib.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/cpu/cc26xx-cc13xx/ti-lib.h b/cpu/cc26xx-cc13xx/ti-lib.h index cbf9a8e61..c08d05ce3 100644 --- a/cpu/cc26xx-cc13xx/ti-lib.h +++ b/cpu/cc26xx-cc13xx/ti-lib.h @@ -139,6 +139,26 @@ #define ti_lib_aon_wuc_osc_config(...) AONWUCOscConfig(__VA_ARGS__) #define ti_lib_aon_wuc_jtag_power_off(...) AONWUCJtagPowerOff(__VA_ARGS__) /*---------------------------------------------------------------------------*/ +/* aux_adc.h */ +#include "driverlib/aux_adc.h" + +#define ti_lib_aux_adc_disable(...) AUXADCDisable(__VA_ARGS__) +#define ti_lib_aux_adc_enable_async(...) AUXADCEnableAsync(__VA_ARGS__) +#define ti_lib_aux_adc_enable_sync(...) AUXADCEnableSync(__VA_ARGS__) +#define ti_lib_aux_adc_disable_input_scaling(...) AUXADCDisableInputScaling(__VA_ARGS__) +#define ti_lib_aux_adc_flush_fifo(...) AUXADCFlushFifo(__VA_ARGS__) +#define ti_lib_aux_adc_gen_manual_trigger(...) AUXADCGenManualTrigger(__VA_ARGS__) +#define ti_lib_aux_adc_get_fifo_status(...) AUXADCGetFifoStatus(__VA_ARGS__) +#define ti_lib_aux_adc_read_fifo(...) AUXADCReadFifo(__VA_ARGS__) +#define ti_lib_aux_adc_pop_fifo(...) AUXADCPopFifo(__VA_ARGS__) +#define ti_lib_aux_adc_select_input(...) AUXADCSelectInput(__VA_ARGS__) +#define ti_lib_aux_adc_get_adjustment_gain(...) AUXADCGetAdjustmentGain(__VA_ARGS__) +#define ti_lib_aux_adc_get_adjustment_offset(...) AUXADCGetAdjustmentOffset(__VA_ARGS__) +#define ti_lib_aux_adc_value_to_microvolts(...) AUXADCValueToMicrovolts(__VA_ARGS__) +#define ti_lib_aux_adc_microvolts_to_value(...) AUXADCMicrovoltsToValue(__VA_ARGS__) +#define ti_lib_aux_adc_adjust_value_for_gain_and_offset(...) AUXADCAdjustValueForGainAndOffset(__VA_ARGS__) +#define ti_lib_aux_adc_unadjust_value_for_gain_and_offset(...) AUXADCUnadjustValueForGainAndOffset(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ /* aux_wuc.h */ #include "driverlib/aux_wuc.h" From 487547d8afb93826f12b6aa2d9a18d16a3d7d0ee Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Thu, 21 Apr 2016 16:55:01 +0300 Subject: [PATCH 254/374] Add CC13xx/CC26xx ADC driver --- cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx | 2 +- cpu/cc26xx-cc13xx/dev/adc-sensor.c | 133 +++++++++++++++++++++++ cpu/cc26xx-cc13xx/dev/adc-sensor.h | 61 +++++++++++ 3 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 cpu/cc26xx-cc13xx/dev/adc-sensor.c create mode 100644 cpu/cc26xx-cc13xx/dev/adc-sensor.h diff --git a/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx b/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx index 40638e80e..b9b755057 100644 --- a/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx +++ b/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx @@ -69,7 +69,7 @@ CONTIKI_CPU_DIRS += ../arm/common/dbg-io ### CPU-dependent source files CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c soc-rtc.c uart.c CONTIKI_CPU_SOURCEFILES += contiki-watchdog.c aux-ctrl.c -CONTIKI_CPU_SOURCEFILES += putchar.c ieee-addr.c batmon-sensor.c +CONTIKI_CPU_SOURCEFILES += putchar.c ieee-addr.c batmon-sensor.c adc-sensor.c CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c cc26xx-uart.c lpm.c CONTIKI_CPU_SOURCEFILES += gpio-interrupt.c oscillators.c CONTIKI_CPU_SOURCEFILES += rf-core.c rf-ble.c ieee-mode.c diff --git a/cpu/cc26xx-cc13xx/dev/adc-sensor.c b/cpu/cc26xx-cc13xx/dev/adc-sensor.c new file mode 100644 index 000000000..3ccf90e6d --- /dev/null +++ b/cpu/cc26xx-cc13xx/dev/adc-sensor.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2016, 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx-adc-sensor + * @{ + * + * \file + * Driver for the CC13xx/CC26xx ADC + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "lib/sensors.h" +#include "dev/adc-sensor.h" +#include "gpio-interrupt.h" +#include "sys/timer.h" +#include "lpm.h" + +#include "ti-lib.h" +#include "driverlib/aux_adc.h" +#include "aux-ctrl.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +static uint8_t channel = ADC_COMPB_IN_AUXIO0; +static bool is_active = false; + +static aux_consumer_module_t adc_aux = { + .clocks = AUX_WUC_ADI_CLOCK | AUX_WUC_ANAIF_CLOCK | AUX_WUC_SMPH_CLOCK +}; +/*---------------------------------------------------------------------------*/ +static int +config(int type, int c) +{ + switch(type) { + case SENSORS_ACTIVE: + is_active = c; + + if(is_active) { + /* Request AUX access, with ADI and SMPH clocks */ + aux_ctrl_register_consumer(&adc_aux); + + ti_lib_aux_adc_select_input(channel); + } else { + aux_ctrl_unregister_consumer(&adc_aux); + } + break; + + case ADC_SENSOR_SET_CHANNEL: + channel = c; + if(is_active) { + ti_lib_aux_adc_select_input(channel); + } + break; + + default: + break; + } + + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + if(is_active) { + return 1; + } + break; + default: + break; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + if(type == ADC_SENSOR_VALUE) { + int val; + + if(!is_active) { + puts("ADC not active"); + return 0; + } + + ti_lib_aux_adc_enable_sync(AUXADC_REF_FIXED, AUXADC_SAMPLE_TIME_2P7_US, + AUXADC_TRIGGER_MANUAL); + + ti_lib_aux_adc_gen_manual_trigger(); + val = ti_lib_aux_adc_read_fifo(); + + ti_lib_aux_adc_disable(); + + return val; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(adc_sensor, ADC_SENSOR, value, config, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/cpu/cc26xx-cc13xx/dev/adc-sensor.h b/cpu/cc26xx-cc13xx/dev/adc-sensor.h new file mode 100644 index 000000000..fd8f71537 --- /dev/null +++ b/cpu/cc26xx-cc13xx/dev/adc-sensor.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016, 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx + * @{ + * + * \defgroup cc26xx-adc-sensor CC13xx/CC26xx ADC Sensor + * @{ + * + * \file + * Header file for the CC13xx/CC26xx ADC driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef ADC_SENSOR_H_ +#define ADC_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define ADC_SENSOR "ADC" +/*---------------------------------------------------------------------------*/ +#define ADC_SENSOR_VALUE 0 +/*---------------------------------------------------------------------------*/ +/* configuration commands */ +#define ADC_SENSOR_SET_CHANNEL 1 /* takes ADC_COMPB_IN_AUXIxx as parameter */ +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor adc_sensor; +/*---------------------------------------------------------------------------*/ +#endif /* ADC_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ From 2ec9c8ccf0794b1d43cd133b53711349877f1abc Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 28 May 2016 19:40:35 +0100 Subject: [PATCH 255/374] Add ALS support for Srf06 + CC13xx/CC26xxEM This provides an example on how to use the CC13xx / CC26xx ADC --- platform/srf06-cc26xx/srf06/Makefile.srf06 | 1 + platform/srf06-cc26xx/srf06/als-sensor.c | 105 ++++++++++++++++++ platform/srf06-cc26xx/srf06/als-sensor.h | 50 +++++++++ .../srf06-cc26xx/srf06/board-peripherals.h | 2 +- platform/srf06-cc26xx/srf06/board.c | 18 +-- platform/srf06-cc26xx/srf06/srf06-sensors.c | 3 +- 6 files changed, 170 insertions(+), 9 deletions(-) create mode 100644 platform/srf06-cc26xx/srf06/als-sensor.c create mode 100644 platform/srf06-cc26xx/srf06/als-sensor.h diff --git a/platform/srf06-cc26xx/srf06/Makefile.srf06 b/platform/srf06-cc26xx/srf06/Makefile.srf06 index 3459cbadc..564a9d0ed 100644 --- a/platform/srf06-cc26xx/srf06/Makefile.srf06 +++ b/platform/srf06-cc26xx/srf06/Makefile.srf06 @@ -3,6 +3,7 @@ CFLAGS += -DBOARD_SMARTRF06EB=1 CONTIKI_TARGET_DIRS += srf06 BOARD_SOURCEFILES += leds-arch.c srf06-sensors.c button-sensor.c board.c +BOARD_SOURCEFILES += als-sensor.c PYTHON = python BSL_FLAGS += -e -w -v diff --git a/platform/srf06-cc26xx/srf06/als-sensor.c b/platform/srf06-cc26xx/srf06/als-sensor.c new file mode 100644 index 000000000..f149d16a1 --- /dev/null +++ b/platform/srf06-cc26xx/srf06/als-sensor.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2016, University of Bristol - http://www.bris.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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup srf06-common-peripherals + * @{ + * + * \file + * Driver for the SmartRF06EB ALS when a CC13xx/CC26xxEM is mounted on it + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "lib/sensors.h" +#include "srf06/als-sensor.h" +#include "sys/timer.h" +#include "dev/adc-sensor.h" +#include "dev/aux-ctrl.h" + +#include "ti-lib.h" + +#include +/*---------------------------------------------------------------------------*/ +static aux_consumer_module_t als_aux = { + .clocks = AUX_WUC_ADI_CLOCK | AUX_WUC_ANAIF_CLOCK | AUX_WUC_SMPH_CLOCK +}; +/*---------------------------------------------------------------------------*/ +static int +config(int type, int enable) +{ + switch(type) { + case SENSORS_HW_INIT: + ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_ALS_PWR); + break; + case SENSORS_ACTIVE: + ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_ALS_PWR); + ti_lib_ioc_port_configure_set(BOARD_IOID_ALS_OUT, IOC_PORT_GPIO, + IOC_STD_OUTPUT); + ti_lib_gpio_dir_mode_set(BOARD_ALS_OUT, GPIO_DIR_MODE_IN); + + if(enable) { + ti_lib_gpio_pin_write(BOARD_ALS_PWR, 1); + aux_ctrl_register_consumer(&als_aux); + ti_lib_aux_adc_select_input(ADC_COMPB_IN_AUXIO7); + clock_delay_usec(2000); + } else { + ti_lib_gpio_pin_write(BOARD_ALS_PWR, 0); + aux_ctrl_unregister_consumer(&als_aux); + } + break; + default: + break; + } + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + int val; + + ti_lib_aux_adc_enable_sync(AUXADC_REF_VDDS_REL, AUXADC_SAMPLE_TIME_2P7_US, + AUXADC_TRIGGER_MANUAL); + ti_lib_aux_adc_gen_manual_trigger(); + val = ti_lib_aux_adc_read_fifo(); + ti_lib_aux_adc_disable(); + + return val; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(als_sensor, ALS_SENSOR, value, config, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/srf06/als-sensor.h b/platform/srf06-cc26xx/srf06/als-sensor.h new file mode 100644 index 000000000..5d70478f8 --- /dev/null +++ b/platform/srf06-cc26xx/srf06/als-sensor.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2016, University of Bristol - http://www.bris.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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup srf06-common-peripherals + * @{ + * + * \file + * Header file for the SmartRF06EB + CC13xx/CC26xxEM ALS Driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef ALS_SENSOR_H_ +#define ALS_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define ALS_SENSOR "ALS" +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor als_sensor; +/*---------------------------------------------------------------------------*/ +#endif /* ALS_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/srf06/board-peripherals.h b/platform/srf06-cc26xx/srf06/board-peripherals.h index d76936c2d..c709ec963 100644 --- a/platform/srf06-cc26xx/srf06/board-peripherals.h +++ b/platform/srf06-cc26xx/srf06/board-peripherals.h @@ -45,7 +45,7 @@ #ifndef BOARD_PERIPHERALS_H_ #define BOARD_PERIPHERALS_H_ /*---------------------------------------------------------------------------*/ -/* ToDo: Include things here */ +#include "als-sensor.h" /*---------------------------------------------------------------------------*/ #endif /* BOARD_PERIPHERALS_H_ */ /*---------------------------------------------------------------------------*/ diff --git a/platform/srf06-cc26xx/srf06/board.c b/platform/srf06-cc26xx/srf06/board.c index 9f53e8ae8..15528f79a 100644 --- a/platform/srf06-cc26xx/srf06/board.c +++ b/platform/srf06-cc26xx/srf06/board.c @@ -46,6 +46,16 @@ #include /*---------------------------------------------------------------------------*/ static void +lpm_handler(uint8_t mode) +{ + /* Ambient light sensor (off, output low) */ + ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_ALS_PWR); + ti_lib_gpio_pin_write(BOARD_ALS_PWR, 0); + ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_ALS_OUT); + ti_lib_ioc_io_port_pull_set(BOARD_IOID_ALS_OUT, IOC_NO_IOPULL); +} +/*---------------------------------------------------------------------------*/ +static void wakeup_handler(void) { /* Turn on the PERIPH PD */ @@ -60,7 +70,7 @@ wakeup_handler(void) * getting notified before deep sleep. All we need is to be notified when we * wake up so we can turn power domains back on */ -LPM_MODULE(srf_module, NULL, NULL, wakeup_handler, LPM_DOMAIN_NONE); +LPM_MODULE(srf_module, NULL, lpm_handler, wakeup_handler, LPM_DOMAIN_NONE); /*---------------------------------------------------------------------------*/ static void configure_unused_pins(void) @@ -72,12 +82,6 @@ configure_unused_pins(void) /* Accelerometer (PWR output low, CSn output, high) */ ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_ACC_PWR); ti_lib_gpio_pin_write(BOARD_ACC_PWR, 0); - - /* Ambient light sensor (off, output low) */ - ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_ALS_PWR); - ti_lib_gpio_pin_write(BOARD_ALS_PWR, 0); - ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_ALS_OUT); - ti_lib_ioc_io_port_pull_set(BOARD_IOID_ALS_OUT, IOC_NO_IOPULL); } /*---------------------------------------------------------------------------*/ void diff --git a/platform/srf06-cc26xx/srf06/srf06-sensors.c b/platform/srf06-cc26xx/srf06/srf06-sensors.c index 9f05c1917..5f65a0cb2 100644 --- a/platform/srf06-cc26xx/srf06/srf06-sensors.c +++ b/platform/srf06-cc26xx/srf06/srf06-sensors.c @@ -39,11 +39,12 @@ /*---------------------------------------------------------------------------*/ #include "contiki.h" #include "srf06/button-sensor.h" +#include "srf06/als-sensor.h" #include /*---------------------------------------------------------------------------*/ /** \brief Exports a global symbol to be used by the sensor API */ SENSORS(&button_select_sensor, &button_left_sensor, &button_right_sensor, - &button_up_sensor, &button_down_sensor); + &button_up_sensor, &button_down_sensor, &als_sensor); /*---------------------------------------------------------------------------*/ /** @} */ From 5a39df143962f010f07609cfdccae42b4b7973d6 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 28 May 2016 19:40:52 +0100 Subject: [PATCH 256/374] Demonstrate ALS support in the CC26xx demo --- examples/cc26xx/cc26xx-demo.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/cc26xx/cc26xx-demo.c b/examples/cc26xx/cc26xx-demo.c index 53c607837..50d2190d3 100644 --- a/examples/cc26xx/cc26xx-demo.c +++ b/examples/cc26xx/cc26xx-demo.c @@ -337,6 +337,15 @@ get_sync_sensor_readings(void) value = batmon_sensor.value(BATMON_SENSOR_TYPE_VOLT); printf("Bat: Volt=%d mV\n", (value * 125) >> 5); +#if BOARD_SMARTRF06EB + SENSORS_ACTIVATE(als_sensor); + + value = als_sensor.value(0); + printf("ALS: %d raw\n", value); + + SENSORS_DEACTIVATE(als_sensor); +#endif + return; } /*---------------------------------------------------------------------------*/ From 334e38339eba2607c6560c09cb914d01cd0e7986 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Thu, 3 Mar 2016 20:42:27 +0100 Subject: [PATCH 257/374] Fixed rssi-scanner example --- examples/rssi-scanner/rssi-scanner-cc2420.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/rssi-scanner/rssi-scanner-cc2420.c b/examples/rssi-scanner/rssi-scanner-cc2420.c index fbbfddf00..94c9056b9 100644 --- a/examples/rssi-scanner/rssi-scanner-cc2420.c +++ b/examples/rssi-scanner/rssi-scanner-cc2420.c @@ -77,7 +77,7 @@ do_rssi(void) printf("RSSI:"); for(channel = 0; channel <= 85; ++channel) { set_frq(channel); - printf("%d ", cc2420_rssi() + 55); + printf("%d ", cc2420_rssi() + 100); } printf("\n"); } From d70c75914aed2499d95eba9ba8cb0f7f0a09d4b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Sat, 28 May 2016 22:47:58 +0200 Subject: [PATCH 258/374] cfs-coffee: Fix build warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix this build warning, which is generated if micro logs are enabled: In file included from ../../core/cfs/cfs-coffee.c:59:0: ../../core/cfs/cfs-coffee.c: In function 'read_log_page': ../../cpu/cc2538/./cfs-coffee-arch.h:145:24: warning: passing argument 1 of 'cfs_coffee_arch_read' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers] cfs_coffee_arch_read((buf), (size), (offset)) ^ ../../core/cfs/cfs-coffee.c:757:3: note: in expansion of macro 'COFFEE_READ' COFFEE_READ(lp->buf, lp->size, base); ^ ../../cpu/cc2538/./cfs-coffee-arch.h:176:6: note: expected 'void *' but argument is of type 'const char *' void cfs_coffee_arch_read(void *buf, unsigned int size, cfs_offset_t offset); ^ COFFEE_READ() needs to write to lp->buf, so the target type of this pointer cannot be qualified as "const". Signed-off-by: Benoît Thébaudeau --- core/cfs/cfs-coffee.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/cfs/cfs-coffee.c b/core/cfs/cfs-coffee.c index 37b1a707e..374b3419f 100644 --- a/core/cfs/cfs-coffee.c +++ b/core/cfs/cfs-coffee.c @@ -196,7 +196,7 @@ struct file_header { /* This is needed because of a buggy compiler. */ struct log_param { cfs_offset_t offset; - const char *buf; + char *buf; uint16_t size; }; @@ -1198,7 +1198,7 @@ cfs_write(int fd, const void *buf, unsigned size) need_dummy_write = 0; for(bytes_left = size; bytes_left > 0;) { lp.offset = fdp->offset; - lp.buf = buf; + lp.buf = (void *)buf; lp.size = bytes_left; i = write_log_page(file, &lp); if(i < 0) { From 4ed5c50a4e81006ebcbba930a1ef4585bd034e63 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Fri, 29 Jan 2016 20:56:34 +0100 Subject: [PATCH 259/374] Make CFS and Coffee examples platform-independent Move the CFS and Coffee examples from sky to a common cfs-coffee folder in order to have unified examples for multiple platforms. --- examples/cfs-coffee/Makefile | 11 +++ examples/cfs-coffee/README.md | 26 +++++++ examples/{sky => cfs-coffee}/example-coffee.c | 2 +- examples/{sky => cfs-coffee}/test-cfs.c | 0 examples/{sky => cfs-coffee}/test-coffee.c | 74 +++++++++---------- examples/sky/Makefile | 2 +- regression-tests/01-compile-base/Makefile | 7 +- regression-tests/03-base/02-sky-coffee.csc | 4 +- 8 files changed, 83 insertions(+), 43 deletions(-) create mode 100644 examples/cfs-coffee/Makefile create mode 100644 examples/cfs-coffee/README.md rename examples/{sky => cfs-coffee}/example-coffee.c (99%) rename examples/{sky => cfs-coffee}/test-cfs.c (100%) rename examples/{sky => cfs-coffee}/test-coffee.c (91%) diff --git a/examples/cfs-coffee/Makefile b/examples/cfs-coffee/Makefile new file mode 100644 index 000000000..543cb8c3d --- /dev/null +++ b/examples/cfs-coffee/Makefile @@ -0,0 +1,11 @@ +CONTIKI = ../.. + +all: test-cfs test-coffee example-coffee + +CONTIKI_WITH_RIME = 1 + +ifeq ($(TARGET),avr-raven) + COFFEE_FILES = 4 +endif + +include $(CONTIKI)/Makefile.include diff --git a/examples/cfs-coffee/README.md b/examples/cfs-coffee/README.md new file mode 100644 index 000000000..672376ef8 --- /dev/null +++ b/examples/cfs-coffee/README.md @@ -0,0 +1,26 @@ +Contiki File System (CFS) and Coffee Examples +============================================= + +Coffee is a very simple, relatively small and easy to use file system that you +are most likely going to be very familiar with if you have done any C file +access in the past. The notion is the same as on a normal PC: you open a file, +read and write to it and close it. Contiki will take care of the underlying +flash memory, giving you more time to focus on the real issues. + +Coffee is a full implementation of the CFS API. + +An extended explanation on CFS and Coffee internals and how they work can be +found at the [CFS](https://github.com/contiki-os/contiki/wiki/File-systems) and +[Coffee](https://github.com/contiki-os/contiki/wiki/Coffee-filesystem-example) +wiki pages. + +Supported Hardware (tested or known to work) +-------------------------------------------- +* sky +* z1 +* wismote +* avr-raven + +The examples are known to build for the 'avr-raven' platform. However, +some of them currently fail at runtime due to file system overflow. +Tweaking the file sizes in the examples is necessary. diff --git a/examples/sky/example-coffee.c b/examples/cfs-coffee/example-coffee.c similarity index 99% rename from examples/sky/example-coffee.c rename to examples/cfs-coffee/example-coffee.c index ee77849e4..998afa4de 100644 --- a/examples/sky/example-coffee.c +++ b/examples/cfs-coffee/example-coffee.c @@ -37,7 +37,7 @@ */ #include - +#include #include "contiki.h" #include "cfs/cfs.h" #include "cfs/cfs-coffee.h" diff --git a/examples/sky/test-cfs.c b/examples/cfs-coffee/test-cfs.c similarity index 100% rename from examples/sky/test-cfs.c rename to examples/cfs-coffee/test-cfs.c diff --git a/examples/sky/test-coffee.c b/examples/cfs-coffee/test-coffee.c similarity index 91% rename from examples/sky/test-coffee.c rename to examples/cfs-coffee/test-coffee.c index b4152b2a8..4ec06f3cd 100644 --- a/examples/sky/test-coffee.c +++ b/examples/cfs-coffee/test-coffee.c @@ -49,7 +49,7 @@ PROCESS(testcoffee_process, "Test CFS/Coffee process"); AUTOSTART_PROCESSES(&testcoffee_process); -#define FAIL(x) error = (x); goto end; +#define TEST_FAIL(x) error = (x); goto end; #define FILE_SIZE 4096 @@ -73,64 +73,64 @@ coffee_test_basic(void) /* Test 1: Open for writing. */ wfd = cfs_open("T1", CFS_WRITE); if(wfd < 0) { - FAIL(1); + TEST_FAIL(1); } /* Test 2 and 3: Write buffer. */ r = cfs_write(wfd, buf, sizeof(buf)); if(r < 0) { - FAIL(2); + TEST_FAIL(2); } else if(r < sizeof(buf)) { - FAIL(3); + TEST_FAIL(3); } /* Test 4: Deny reading. */ r = cfs_read(wfd, buf, sizeof(buf)); if(r >= 0) { - FAIL(4); + TEST_FAIL(4); } /* Test 5: Open for reading. */ rfd = cfs_open("T1", CFS_READ); if(rfd < 0) { - FAIL(5); + TEST_FAIL(5); } /* Test 6: Write to read-only file. */ r = cfs_write(rfd, buf, sizeof(buf)); if(r >= 0) { - FAIL(6); + TEST_FAIL(6); } /* Test 7 and 8: Read the buffer written in Test 2. */ memset(buf, 0, sizeof(buf)); r = cfs_read(rfd, buf, sizeof(buf)); if(r < 0) { - FAIL(7); + TEST_FAIL(7); } else if(r < sizeof(buf)) { printf("r=%d\n", r); - FAIL(8); + TEST_FAIL(8); } /* Test 9: Verify that the buffer is correct. */ for(r = 0; r < sizeof(buf); r++) { if(buf[r] != r) { printf("r=%d. buf[r]=%d\n", r, buf[r]); - FAIL(9); + TEST_FAIL(9); } } /* Test 10: Seek to beginning. */ if(cfs_seek(wfd, 0, CFS_SEEK_SET) != 0) { - FAIL(10); + TEST_FAIL(10); } /* Test 11 and 12: Write to the log. */ r = cfs_write(wfd, buf, sizeof(buf)); if(r < 0) { - FAIL(11); + TEST_FAIL(11); } else if(r < sizeof(buf)) { - FAIL(12); + TEST_FAIL(12); } /* Test 13 and 14: Read the data from the log. */ @@ -138,15 +138,15 @@ coffee_test_basic(void) memset(buf, 0, sizeof(buf)); r = cfs_read(rfd, buf, sizeof(buf)); if(r < 0) { - FAIL(14); + TEST_FAIL(14); } else if(r < sizeof(buf)) { - FAIL(15); + TEST_FAIL(15); } /* Test 16: Verify that the data is correct. */ for(r = 0; r < sizeof(buf); r++) { if(buf[r] != r) { - FAIL(16); + TEST_FAIL(16); } } @@ -155,16 +155,16 @@ coffee_test_basic(void) buf[r] = sizeof(buf) - r - 1; } if(cfs_seek(wfd, 0, CFS_SEEK_SET) != 0) { - FAIL(17); + TEST_FAIL(17); } r = cfs_write(wfd, buf, sizeof(buf)); if(r < 0) { - FAIL(18); + TEST_FAIL(18); } else if(r < sizeof(buf)) { - FAIL(19); + TEST_FAIL(19); } if(cfs_seek(rfd, 0, CFS_SEEK_SET) != 0) { - FAIL(20); + TEST_FAIL(20); } /* Test 21 and 22: Read the reversed buffer. */ @@ -172,16 +172,16 @@ coffee_test_basic(void) memset(buf, 0, sizeof(buf)); r = cfs_read(rfd, buf, sizeof(buf)); if(r < 0) { - FAIL(21); + TEST_FAIL(21); } else if(r < sizeof(buf)) { printf("r = %d\n", r); - FAIL(22); + TEST_FAIL(22); } /* Test 23: Verify that the data is correct. */ for(r = 0; r < sizeof(buf); r++) { if(buf[r] != sizeof(buf) - r - 1) { - FAIL(23); + TEST_FAIL(23); } } @@ -208,14 +208,14 @@ coffee_test_append(void) for(i = 0; i < APPEND_BYTES; i += BULK_SIZE) { afd = cfs_open("T3", CFS_WRITE | CFS_APPEND); if(afd < 0) { - FAIL(1); + TEST_FAIL(1); } for(j = 0; j < BULK_SIZE; j++) { buf[j] = 1 + ((i + j) & 0x7f); } if((r = cfs_write(afd, buf, BULK_SIZE)) != BULK_SIZE) { printf("r=%d\n", r); - FAIL(2); + TEST_FAIL(2); } cfs_close(afd); } @@ -224,22 +224,22 @@ coffee_test_append(void) is correct. */ afd = cfs_open("T3", CFS_READ); if(afd < 0) { - FAIL(3); + TEST_FAIL(3); } total_read = 0; while((r = cfs_read(afd, buf2, sizeof(buf2))) > 0) { for(j = 0; j < r; j++) { if(buf2[j] != 1 + ((total_read + j) & 0x7f)) { - FAIL(4); + TEST_FAIL(4); } } total_read += r; } if(r < 0) { - FAIL(5); + TEST_FAIL(5); } if(total_read != APPEND_BYTES) { - FAIL(6); + TEST_FAIL(6); } cfs_close(afd); @@ -262,18 +262,18 @@ coffee_test_modify(void) wfd = -1; if(cfs_coffee_reserve("T3", FILE_SIZE) < 0) { - FAIL(1); + TEST_FAIL(1); } if(cfs_coffee_configure_log("T3", FILE_SIZE / 2, 11) < 0) { - FAIL(2); + TEST_FAIL(2); } /* Test 16: Test multiple writes at random offset. */ for(r = 0; r < 100; r++) { wfd = cfs_open("T2", CFS_WRITE | CFS_READ); if(wfd < 0) { - FAIL(3); + TEST_FAIL(3); } offset = random_rand() % FILE_SIZE; @@ -283,26 +283,26 @@ coffee_test_modify(void) } if(cfs_seek(wfd, offset, CFS_SEEK_SET) != offset) { - FAIL(4); + TEST_FAIL(4); } if(cfs_write(wfd, buf, sizeof(buf)) != sizeof(buf)) { - FAIL(5); + TEST_FAIL(5); } if(cfs_seek(wfd, offset, CFS_SEEK_SET) != offset) { - FAIL(6); + TEST_FAIL(6); } memset(buf, 0, sizeof(buf)); if(cfs_read(wfd, buf, sizeof(buf)) != sizeof(buf)) { - FAIL(7); + TEST_FAIL(7); } for(i = 0; i < sizeof(buf); i++) { if(buf[i] != i) { printf("buf[%d] != %d\n", i, buf[i]); - FAIL(8); + TEST_FAIL(8); } } } diff --git a/examples/sky/Makefile b/examples/sky/Makefile index dd09f0792..6d17fd421 100644 --- a/examples/sky/Makefile +++ b/examples/sky/Makefile @@ -3,7 +3,7 @@ ifndef TARGET TARGET=sky endif -all: blink sky-collect #rt-leds test-button test-cfs tcprudolph0 +all: blink sky-collect #rt-leds test-button tcprudolph0 %.tgz: %.ihex mkdir $(basename $<) ; \ diff --git a/regression-tests/01-compile-base/Makefile b/regression-tests/01-compile-base/Makefile index bbfbd0c6b..bc38a9777 100644 --- a/regression-tests/01-compile-base/Makefile +++ b/regression-tests/01-compile-base/Makefile @@ -37,8 +37,11 @@ settings-example/avr-raven \ ipv6/multicast/sky \ ipv6/rpl-tsch/z1 \ ipv6/rpl-tsch/z1:MAKE_WITH_ORCHESTRA=1 \ -ipv6/rpl-tsch/z1:MAKE_WITH_SECURITY=1 - +ipv6/rpl-tsch/z1:MAKE_WITH_SECURITY=1 \ +cfs-coffee/sky \ +cfs-coffee/z1 \ +cfs-coffee/wismote \ +cfs-coffee/avr-raven TOOLS= diff --git a/regression-tests/03-base/02-sky-coffee.csc b/regression-tests/03-base/02-sky-coffee.csc index f017a3e7d..035f72843 100644 --- a/regression-tests/03-base/02-sky-coffee.csc +++ b/regression-tests/03-base/02-sky-coffee.csc @@ -24,10 +24,10 @@ org.contikios.cooja.mspmote.SkyMoteType sky1 Sky Mote Type #1 - [CONTIKI_DIR]/examples/sky/test-coffee.c + [CONTIKI_DIR]/examples/cfs-coffee/test-coffee.c make clean TARGET=sky make test-coffee.sky TARGET=sky - [CONTIKI_DIR]/examples/sky/test-coffee.sky + [CONTIKI_DIR]/examples/cfs-coffee/test-coffee.sky org.contikios.cooja.interfaces.Position org.contikios.cooja.interfaces.IPAddress org.contikios.cooja.interfaces.Mote2MoteRelations From e23c1756990cba162f6db9f8e2ab685d541fa22e Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Fri, 29 Jan 2016 20:56:34 +0100 Subject: [PATCH 260/374] cfs-coffee: examples: Fix coding style --- examples/cfs-coffee/example-coffee.c | 28 ++++++++++++++-------------- examples/cfs-coffee/test-cfs.c | 7 +++---- examples/cfs-coffee/test-coffee.c | 14 ++++++-------- 3 files changed, 23 insertions(+), 26 deletions(-) diff --git a/examples/cfs-coffee/example-coffee.c b/examples/cfs-coffee/example-coffee.c index 998afa4de..7adc8d62c 100644 --- a/examples/cfs-coffee/example-coffee.c +++ b/examples/cfs-coffee/example-coffee.c @@ -28,31 +28,31 @@ * * This file is part of the Contiki operating system. */ - +/*---------------------------------------------------------------------------*/ /** * \file * Example on how to use CFS/Coffee. * \author * Nicolas Tsiftes */ - +/*---------------------------------------------------------------------------*/ #include #include #include "contiki.h" #include "cfs/cfs.h" #include "cfs/cfs-coffee.h" - +/*---------------------------------------------------------------------------*/ PROCESS(example_coffee_process, "Coffee example"); AUTOSTART_PROCESSES(&example_coffee_process); - +/*---------------------------------------------------------------------------*/ #define FILENAME "test" -/* Formatting is needed if the storage device is in an unknown state; +/* Formatting is needed if the storage device is in an unknown state; e.g., when using Coffee on the storage device for the first time. */ #ifndef NEED_FORMATTING #define NEED_FORMATTING 0 #endif - +/*---------------------------------------------------------------------------*/ static int file_test(const char *filename, char *msg) { @@ -65,12 +65,12 @@ file_test(const char *filename, char *msg) } record; /* - * Coffee determines the file length by finding the last non-zero byte - * of the file. This I/O semantic requires that each record should end - * with a non-zero, if we are writing multiple records and closing the + * Coffee determines the file length by finding the last non-zero byte + * of the file. This I/O semantic requires that each record should end + * with a non-zero, if we are writing multiple records and closing the * file descriptor in between. * - * In this example, in which the file_test function can be called + * In this example, in which the file_test function can be called * multiple times, we ensure that the sequence counter starts at 1. */ @@ -84,7 +84,7 @@ file_test(const char *filename, char *msg) record.message[sizeof(record.message) - 1] = '\0'; record.sequence = sequence; - /* Obtain a file descriptor for the file, capable of handling both + /* Obtain a file descriptor for the file, capable of handling both reads and writes. */ fd = cfs_open(FILENAME, CFS_WRITE | CFS_APPEND | CFS_READ); if(fd < 0) { @@ -103,7 +103,7 @@ file_test(const char *filename, char *msg) printf("Wrote message \"%s\", sequence %u\n", record.message, record.sequence); - /* To read back the message, we need to move the file pointer to the + /* To read back the message, we need to move the file pointer to the beginning of the file. */ if(cfs_seek(fd, 0, CFS_SEEK_SET) != 0) { printf("seek failed\n"); @@ -133,7 +133,7 @@ file_test(const char *filename, char *msg) return 1; } - +/*---------------------------------------------------------------------------*/ static int dir_test(void) { @@ -156,7 +156,7 @@ dir_test(void) return 1; } - +/*---------------------------------------------------------------------------*/ PROCESS_THREAD(example_coffee_process, ev, data) { PROCESS_BEGIN(); diff --git a/examples/cfs-coffee/test-cfs.c b/examples/cfs-coffee/test-cfs.c index 68c91e720..b5068aaa2 100644 --- a/examples/cfs-coffee/test-cfs.c +++ b/examples/cfs-coffee/test-cfs.c @@ -29,19 +29,18 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** * \file * A quick program for testing the CFS xmem driver * \author * Adam Dunkels */ - +/*---------------------------------------------------------------------------*/ #include "contiki.h" #include "cfs/cfs.h" - #include - +/*---------------------------------------------------------------------------*/ PROCESS(cfs_process, "Test CFS process"); AUTOSTART_PROCESSES(&cfs_process); /*---------------------------------------------------------------------------*/ diff --git a/examples/cfs-coffee/test-coffee.c b/examples/cfs-coffee/test-coffee.c index 4ec06f3cd..c274e5b81 100644 --- a/examples/cfs-coffee/test-coffee.c +++ b/examples/cfs-coffee/test-coffee.c @@ -29,14 +29,14 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** * \file * Basic test for CFS/Coffee. * \author * Nicolas Tsiftes */ - +/*---------------------------------------------------------------------------*/ #include "contiki.h" #include "cfs/cfs.h" #include "cfs/cfs-coffee.h" @@ -45,14 +45,12 @@ #include #include - +/*---------------------------------------------------------------------------*/ PROCESS(testcoffee_process, "Test CFS/Coffee process"); AUTOSTART_PROCESSES(&testcoffee_process); - +/*---------------------------------------------------------------------------*/ #define TEST_FAIL(x) error = (x); goto end; - #define FILE_SIZE 4096 - /*---------------------------------------------------------------------------*/ static int coffee_test_basic(void) @@ -220,7 +218,7 @@ coffee_test_append(void) cfs_close(afd); } - /* Test 3-6: Read back the data written previously and verify that it + /* Test 3-6: Read back the data written previously and verify that it is correct. */ afd = cfs_open("T3", CFS_READ); if(afd < 0) { @@ -376,7 +374,7 @@ PROCESS_THREAD(testcoffee_process, ev, data) result = coffee_test_gc(); print_result("Garbage collection", result); - printf("Coffee test finished. Duration: %d seconds\n", + printf("Coffee test finished. Duration: %d seconds\n", (int)(clock_seconds() - start)); PROCESS_END(); From 5d227b92a3619aa6330fb3a45dc2ec5e2b4ac9e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Sun, 29 May 2016 21:43:11 +0200 Subject: [PATCH 261/374] test-cfs: Fix possible test failure after reboot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the file at the beginning of the test, before opening it for writing, in order to start the test with an empty file system, not only after flashing the test, but also following every reboot. Signed-off-by: Benoît Thébaudeau --- examples/cfs-coffee/test-cfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/cfs-coffee/test-cfs.c b/examples/cfs-coffee/test-cfs.c index b5068aaa2..2d44b6696 100644 --- a/examples/cfs-coffee/test-cfs.c +++ b/examples/cfs-coffee/test-cfs.c @@ -54,6 +54,7 @@ PROCESS_THREAD(cfs_process, ev, data) uint16_t filesize = 65000; #define CHUNKSIZE 128 + cfs_remove("hej"); fd = cfs_open("hej", CFS_WRITE); if(fd < 0) { printf("could not open file for writing, aborting\n"); From 76429e4f0e8858e094f5e6a2423833974ffc9a18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Sun, 29 May 2016 22:01:40 +0200 Subject: [PATCH 262/374] test-coffee: Fix numbering of test failure cases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Benoît Thébaudeau --- examples/cfs-coffee/test-coffee.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/cfs-coffee/test-coffee.c b/examples/cfs-coffee/test-coffee.c index c274e5b81..c2a34d2c3 100644 --- a/examples/cfs-coffee/test-coffee.c +++ b/examples/cfs-coffee/test-coffee.c @@ -136,15 +136,15 @@ coffee_test_basic(void) memset(buf, 0, sizeof(buf)); r = cfs_read(rfd, buf, sizeof(buf)); if(r < 0) { - TEST_FAIL(14); + TEST_FAIL(13); } else if(r < sizeof(buf)) { - TEST_FAIL(15); + TEST_FAIL(14); } /* Test 16: Verify that the data is correct. */ for(r = 0; r < sizeof(buf); r++) { if(buf[r] != r) { - TEST_FAIL(16); + TEST_FAIL(15); } } @@ -153,16 +153,16 @@ coffee_test_basic(void) buf[r] = sizeof(buf) - r - 1; } if(cfs_seek(wfd, 0, CFS_SEEK_SET) != 0) { - TEST_FAIL(17); + TEST_FAIL(16); } r = cfs_write(wfd, buf, sizeof(buf)); if(r < 0) { - TEST_FAIL(18); + TEST_FAIL(17); } else if(r < sizeof(buf)) { - TEST_FAIL(19); + TEST_FAIL(18); } if(cfs_seek(rfd, 0, CFS_SEEK_SET) != 0) { - TEST_FAIL(20); + TEST_FAIL(19); } /* Test 21 and 22: Read the reversed buffer. */ @@ -170,16 +170,16 @@ coffee_test_basic(void) memset(buf, 0, sizeof(buf)); r = cfs_read(rfd, buf, sizeof(buf)); if(r < 0) { - TEST_FAIL(21); + TEST_FAIL(20); } else if(r < sizeof(buf)) { printf("r = %d\n", r); - TEST_FAIL(22); + TEST_FAIL(21); } /* Test 23: Verify that the data is correct. */ for(r = 0; r < sizeof(buf); r++) { if(buf[r] != sizeof(buf) - r - 1) { - TEST_FAIL(23); + TEST_FAIL(22); } } From 150b9fbd8b5c0061f86604c86d4938f6d0ef2517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Sun, 29 May 2016 22:09:20 +0200 Subject: [PATCH 263/374] test-coffee: Fix test filenames MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The filenames were mixed up between some of the tests, thus breaking the purpose of these tests. Signed-off-by: Benoît Thébaudeau --- examples/cfs-coffee/test-coffee.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/cfs-coffee/test-coffee.c b/examples/cfs-coffee/test-coffee.c index c2a34d2c3..9f134ae44 100644 --- a/examples/cfs-coffee/test-coffee.c +++ b/examples/cfs-coffee/test-coffee.c @@ -204,7 +204,7 @@ coffee_test_append(void) /* Test 1 and 2: Append data to the same file many times. */ for(i = 0; i < APPEND_BYTES; i += BULK_SIZE) { - afd = cfs_open("T3", CFS_WRITE | CFS_APPEND); + afd = cfs_open("T2", CFS_WRITE | CFS_APPEND); if(afd < 0) { TEST_FAIL(1); } @@ -220,7 +220,7 @@ coffee_test_append(void) /* Test 3-6: Read back the data written previously and verify that it is correct. */ - afd = cfs_open("T3", CFS_READ); + afd = cfs_open("T2", CFS_READ); if(afd < 0) { TEST_FAIL(3); } @@ -269,7 +269,7 @@ coffee_test_modify(void) /* Test 16: Test multiple writes at random offset. */ for(r = 0; r < 100; r++) { - wfd = cfs_open("T2", CFS_WRITE | CFS_READ); + wfd = cfs_open("T3", CFS_WRITE | CFS_READ); if(wfd < 0) { TEST_FAIL(3); } From 003b4b0d6345f94fdc5b3f13e0f061252b67e01d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Sun, 29 May 2016 22:23:15 +0200 Subject: [PATCH 264/374] test-coffee: Fix the file modification test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The r variable was used instead of i to fill the buffer, resulting in the end of the test loop after only a single iteration. The file was not even closed at the end of each iteration although it is opened at the beginning of each iteration, so the available file descriptors would very quickly be exhausted. Signed-off-by: Benoît Thébaudeau --- examples/cfs-coffee/test-coffee.c | 6 ++++-- regression-tests/03-base/02-sky-coffee.csc | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/cfs-coffee/test-coffee.c b/examples/cfs-coffee/test-coffee.c index 9f134ae44..28cd3b5c6 100644 --- a/examples/cfs-coffee/test-coffee.c +++ b/examples/cfs-coffee/test-coffee.c @@ -276,8 +276,8 @@ coffee_test_modify(void) offset = random_rand() % FILE_SIZE; - for(r = 0; r < sizeof(buf); r++) { - buf[r] = r; + for(i = 0; i < sizeof(buf); i++) { + buf[i] = i; } if(cfs_seek(wfd, offset, CFS_SEEK_SET) != offset) { @@ -303,6 +303,8 @@ coffee_test_modify(void) TEST_FAIL(8); } } + + cfs_close(wfd); } error = 0; diff --git a/regression-tests/03-base/02-sky-coffee.csc b/regression-tests/03-base/02-sky-coffee.csc index 035f72843..050b4abc9 100644 --- a/regression-tests/03-base/02-sky-coffee.csc +++ b/regression-tests/03-base/02-sky-coffee.csc @@ -89,7 +89,7 @@ make test-coffee.sky TARGET=sky org.contikios.cooja.plugins.ScriptRunner - + true + + 962 + 0 + 596 + 603 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/02-rpl-root-reboot.csc b/regression-tests/23-rpl-non-storing/02-rpl-root-reboot.csc new file mode 100644 index 000000000..14f87c7a9 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/02-rpl-root-reboot.csc @@ -0,0 +1,344 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype958 + Sender + [CONTIKI_DIR]/regression-tests/12-rpl/code/sender-node.c + make TARGET=cooja clean +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype837 + RPL root + [CONTIKI_DIR]/regression-tests/12-rpl/code/root-node.c + make TARGET=cooja clean +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype358 + Receiver + [CONTIKI_DIR]/regression-tests/12-rpl/code/receiver-node.c + make TARGET=cooja clean +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -22.5728586847096 + 123.9358664968653 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype358 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype958 + + + + org.contikios.cooja.interfaces.Position + -1.39303771455413 + 100.21446701029119 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype358 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype358 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype358 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype358 + + + + org.contikios.cooja.interfaces.Position + 10.931583432822638 + 69.848248459216 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype358 + + + + org.contikios.cooja.interfaces.Position + 0.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype837 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 3 + 240 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 962 + 1 + 596 + 603 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/03-rpl-28-hours.csc b/regression-tests/23-rpl-non-storing/03-rpl-28-hours.csc new file mode 100644 index 000000000..1cf2c5e43 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/03-rpl-28-hours.csc @@ -0,0 +1,293 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype110 + Sender + [CONTIKI_DIR]/regression-tests/12-rpl/code/sender-node.c + make TARGET=cooja clean +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype792 + RPL root + [CONTIKI_DIR]/regression-tests/12-rpl/code/root-node.c + make TARGET=cooja clean +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype964 + Receiver + [CONTIKI_DIR]/regression-tests/12-rpl/code/receiver-node.c + make TARGET=cooja clean +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + 7.772906112657773 + 86.396910401861 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype964 + + + + org.contikios.cooja.interfaces.Position + 75.54361692539452 + 14.292026223193414 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype110 + + + + org.contikios.cooja.interfaces.Position + 47.962513687652844 + 7.199742533488408 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype964 + + + + org.contikios.cooja.interfaces.Position + 1.8626697045702818 + 47.783365869022624 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype964 + + + + org.contikios.cooja.interfaces.Position + 0.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype792 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 78.27260101976275 40.72727272727276 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 3 + 240 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 962 + 1 + 596 + 603 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/04-rpl-large-network.csc b/regression-tests/23-rpl-non-storing/04-rpl-large-network.csc new file mode 100644 index 000000000..e40b7a339 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/04-rpl-large-network.csc @@ -0,0 +1,7058 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype710 + Sender + [CONTIKI_DIR]/regression-tests/12-rpl/code/sender-node.c + make TARGET=cooja clean +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype709 + RPL root + [CONTIKI_DIR]/regression-tests/12-rpl/code/root-node.c + make TARGET=cooja clean +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype332 + Receiver + [CONTIKI_DIR]/regression-tests/12-rpl/code/receiver-node.c + make TARGET=cooja clean +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -15.604889524290883 + -27.272920930192623 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 218.29521040499824 + 216.70287561143516 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype710 + + + + org.contikios.cooja.interfaces.Position + 0.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype709 + + + + org.contikios.cooja.interfaces.Position + 27.44274795318258 + 36.980443988209856 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 185.6055859234863 + 192.99166984979271 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 7.827315175624361 + 107.95833747378225 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 82.49199862549197 + 34.72851022020231 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 35.671428723363064 + 125.82590119075962 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 33.044376889885754 + 62.443378727185774 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 9 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 152.53659733643553 + 165.87608708149403 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 10 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 22.023077232445942 + 18.41094139254531 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 11 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 41.19368867821842 + 49.201157808285224 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 12 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 114.62128502432532 + 88.58807114217633 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 13 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 61.21405469314478 + 188.6851979777661 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 14 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 104.78326932115709 + 100.84889281105585 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 15 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 90.26861048950052 + 40.550864496421404 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 16 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 137.39112328314076 + 126.5333637365394 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 17 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 14.07616766247768 + 99.85572366133869 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 18 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 192.30563307960443 + 66.83563821262344 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 19 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 129.08253247651874 + 117.20437669309078 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 20 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 21.82717410659969 + 47.523771402541335 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 21 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 35.95102103988239 + 21.74677482276881 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 22 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 61.71108896268191 + 79.91617509627334 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 23 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 16.029809485043288 + 171.05935835280616 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 24 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 138.8418552766128 + 61.418703448852185 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 25 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 151.23299942414673 + 92.41820871538522 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 26 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 197.33157775573343 + 20.6013482653864 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 27 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 121.20762229879878 + 184.81107462083565 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 28 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 102.32432527534694 + 91.9912435435037 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 29 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 88.10909646999544 + 191.21251904898142 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 30 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 72.19774934085703 + 113.58131529956069 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 31 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 53.49967737007204 + 72.45172156882643 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 32 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 172.07186411958625 + 51.47715718716961 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 33 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 185.41983532466634 + 85.60078269414 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 34 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 83.34993971740548 + 193.98111239532744 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 35 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 105.03752362550378 + 131.24078026424087 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 36 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 176.09318670322102 + 41.46760901468247 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 37 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 76.80689915307215 + 47.13815728542057 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 38 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 155.907739287817 + 15.24009422994106 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 39 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 45.992463430523436 + 124.573811024683 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 40 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 159.11361032671832 + 81.65319598335425 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 41 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 41.838657583001314 + 163.47591213471193 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 42 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 25.560001904073125 + 147.48610852243928 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 43 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 139.56489350213488 + 191.15379557180913 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 44 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 105.71342550700061 + 136.09089690661503 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 45 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 122.59378462201298 + 196.22862961645998 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 46 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 147.61372446125088 + 55.314287700435536 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 47 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 77.70218628780312 + 95.59561907133107 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 48 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 71.88244578562713 + 168.57963926907163 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 49 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 6.722298767036894 + 101.09668965729898 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 50 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 62.96680217979964 + 77.66951408660954 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 51 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 162.49011735601982 + 199.07086470932003 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 52 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 87.87526390617558 + 114.39424478293958 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 53 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 74.29230372180815 + 36.995699473573836 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 54 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 77.34619341407321 + 60.070446577058576 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 55 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 76.32695571818826 + 135.82669004433725 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 56 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 68.10326013650814 + 5.04157445893032 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 57 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 95.76993029214962 + 45.046282401332945 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 58 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 79.87963205080952 + 110.7023948653882 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 59 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 195.90349780899223 + 132.38904172009444 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 60 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 80.40108440304007 + 25.86673418569547 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 61 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 52.268877618080744 + 176.12888723955277 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 62 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 40.545541404899765 + 166.9450252729589 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 63 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 10.676184465528205 + 0.9871174057552334 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 64 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 87.35673216830257 + 23.25131234780027 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 65 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 26.745126931691352 + 87.3101256645554 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 66 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 183.2724008541638 + 167.69026002459069 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 67 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 5.934720840855223 + 77.21248812623693 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 68 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 76.49604470599058 + 108.80963795015302 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 69 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 86.10145414955488 + 12.798582653303603 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 70 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 32.435370110193816 + 29.344591306898813 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 71 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 163.72950518161596 + 154.15283820759655 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 72 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 143.96396308843373 + 132.40312602892786 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 73 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 139.20530179839795 + 144.18958011498225 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 74 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 75.22453368236212 + 119.69913560274786 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 75 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 21.83836116635087 + 191.21696522067728 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 76 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 187.94640511976667 + 113.95684826994561 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 77 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 114.61289565250618 + 27.61001303446735 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 78 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 70.83569869750504 + 113.88992677636021 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 79 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 11.616059362048992 + 45.59401384110464 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 80 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 3.4282454263252937 + 35.97653370545284 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 81 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 54.33122057405715 + 1.9759087814547494 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 82 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 69.6612091444155 + 0.45982758130533874 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 83 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 169.98417155202168 + 87.76678058442593 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 84 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 148.98441194234616 + 104.32820155415494 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 85 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 66.23883124891583 + 162.92685536074129 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 86 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 181.6348837921769 + 183.07267240808343 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 87 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 88.9829570206748 + 119.72520333459575 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 88 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 179.1527012143494 + 84.25685075020328 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 89 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 117.82537007493707 + 41.10319533518651 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 90 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 52.611633540398486 + 94.71918054798351 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 91 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 128.22088664324633 + 115.50290142480077 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 92 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 102.53841128002531 + 11.784449645612295 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 93 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 187.69871925603667 + 131.28317666772048 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 94 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 71.13897508938263 + 106.29335632876602 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 95 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 71.2216469861295 + 148.38612859488788 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 96 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 36.152562577928784 + 67.541796718348 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 97 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 118.84793016344604 + 0.49906433835273933 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 98 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 135.20417096106954 + 170.20704631856816 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 99 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 156.082359043526 + 57.62103450217495 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 100 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 180.58695188377737 + 80.75266645775669 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 101 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 38.93889890269273 + 138.60259660238856 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 102 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 159.5172788118917 + 192.24950143209503 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 103 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 154.02096825135868 + 139.67175722659056 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 104 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 38.480826888323904 + 5.502866276505292 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 105 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 27.95908088015704 + 193.85188308665965 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 106 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 198.61700949829074 + 171.1877312716402 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 107 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 106.30468818084609 + 25.058380770654654 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 108 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 40.335672117825624 + 179.59080234641004 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 109 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 22.316357638510897 + 158.94323888090028 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 110 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 99.56281553229194 + 85.64260133077535 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 111 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 60.71556414510035 + 121.53040248649711 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 112 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 27.08600745576586 + 38.17025720346818 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 113 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 147.03642509910586 + 39.51320588416096 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 114 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 180.2031547656297 + 141.5646561330238 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 115 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 73.12314629214424 + 167.80783320779847 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 116 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 167.93567452922767 + 10.060141001139144 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 117 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 163.99198875105768 + 147.48735207074026 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 118 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 154.98654737808127 + 121.17266324007643 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 119 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 57.898499791676386 + 149.3487194893122 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 120 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 64.82082963563904 + 174.0100480348673 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 121 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 114.13623920898752 + 15.754246175503095 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 122 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 0.00848902940355778 + 195.50701335573908 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 123 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 182.81764401709623 + 78.57837811285111 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 124 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 11.462145876504714 + 95.37444120802225 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 125 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 115.5020283241771 + 28.49431396939579 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 126 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 62.463952359877275 + 77.78913013330184 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 127 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 9.766778039117696 + 136.7421944039438 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 128 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 35.320514349220055 + 100.56248258192493 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 129 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 56.26732169234614 + 3.095097140731262 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 130 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 76.90164393617998 + 3.5671096386384216 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 131 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 81.97549075841862 + 13.020422155003475 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 132 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 54.87200208203389 + 77.29445717372947 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 133 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 193.47651032749548 + 144.9357554583657 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 134 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 51.65288193591992 + 126.16687604535504 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 135 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 151.66849746442173 + 158.7699863850836 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 136 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 32.469410974826005 + 113.10993021698361 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 137 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 33.04622512107349 + 25.425445944702794 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 138 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 33.53444748873715 + 112.25721598241579 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 139 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 128.9401580272291 + 100.73482184242926 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 140 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 194.6592727528704 + 102.73664509470841 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 141 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 125.47343036050516 + 106.53155237731285 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 142 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 147.40129296416038 + 12.37607345376115 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 143 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 113.32045045397959 + 126.79285457987103 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 144 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 27.174837677715825 + 66.84349985536826 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 145 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 164.20252670136998 + 51.635539499142524 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 146 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 39.351673884988394 + 65.05462325698123 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 147 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 143.91486202542433 + 171.28435110465497 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 148 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 30.926988343440186 + 130.3647571119649 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 149 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 19.897357003413617 + 22.905473451246785 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 150 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 128.36369031733133 + 170.71462512320227 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 151 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 172.1648617546042 + 184.1928317689217 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 152 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 148.16672573170842 + 107.99684523382686 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 153 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 83.90300186263724 + 169.4761782218257 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 154 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 90.86887922361453 + 142.8036645841288 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 155 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 23.18966921326753 + 69.42635534680753 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 156 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 134.59433377860168 + 37.633119904417796 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 157 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 127.97132285920065 + 158.57917470101572 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 158 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 166.2450456558778 + 108.67197275397042 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 159 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 167.334034200758 + 22.173554305333166 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 160 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 163.54194527237107 + 189.41605447848966 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 161 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 14.863357513573018 + 93.36644051662617 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 162 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 178.4370382798651 + 191.48348446587636 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 163 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 172.96087703915273 + 183.78535300027013 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 164 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 2.45779137738229 + 58.750309492130114 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 165 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 15.730601618735495 + 96.52335072173565 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 166 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 19.890833428932165 + 56.993000152370364 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 167 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 154.69166608840504 + 164.8598339150269 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 168 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 199.77196118880582 + 26.034321005016903 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 169 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 5.216343266336931 + 17.867912968799615 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 170 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 138.71273406283296 + 55.31024592694844 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 171 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 168.21144361519595 + 163.1843284579423 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 172 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 61.82504434646854 + 134.03197926926038 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 173 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 14.007317972338473 + 146.98475859141027 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 174 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 108.44210606040488 + 127.81076428732186 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 175 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 133.41957560864708 + 122.91534078890439 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 176 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 184.89266828168118 + 195.7201293014503 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 177 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 121.10492556426465 + 78.54418709376823 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 178 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 42.05271519544296 + 183.14259881514795 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 179 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 92.12119616387746 + 44.853464007589714 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 180 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 136.44039199596196 + 1.111619893261917 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 181 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 64.37440878278696 + 188.3078368775181 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 182 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 37.774149552594594 + 73.81683900641865 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 183 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 24.618589360988175 + 164.89708336795567 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 184 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 152.5950797265111 + 140.96774353352123 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 185 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 37.96933854365052 + 131.92434845994435 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 186 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 14.05145808951862 + 26.159084136809916 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 187 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 61.47558158857349 + 68.73507104275693 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 188 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 35.420404733112385 + 108.47794695541302 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 189 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 129.0179255565185 + 176.46977408461998 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 190 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 4.437687657989087 + 191.43801818673953 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 191 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 132.39232886927158 + 105.56546037448346 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 192 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 193.9356389936735 + 76.8987220921185 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 193 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 123.49672189705024 + 16.28922647444049 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 194 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 40.44058024960566 + 94.77629608096818 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 195 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 93.54168452285269 + 102.10342793159373 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 196 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 176.91858637781746 + 81.80773827257306 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 197 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 182.5062159995403 + 10.047631291589564 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 198 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 151.3211952231698 + 160.98807517681706 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 199 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 167.8826595707132 + 160.3686256248768 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 200 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 93.38491122055773 + 61.04322963139093 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 201 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 155.20211039479165 + 104.99915002371228 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 202 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 154.56882959476744 + 192.77647809954323 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 203 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 119.88029558288524 + 48.71837870038327 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 204 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 8.237800167806908 + 123.56280331420268 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 205 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 53.424877837249696 + 87.33638375233281 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 206 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 199.25320093864096 + 66.76343110330383 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 207 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 166.7255674935148 + 165.31992478582075 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 208 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 135.9334286576811 + 130.36986226660702 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 209 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 65.60950768388696 + 14.081940005079275 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 210 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 56.68133966983844 + 196.61338214776293 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 211 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 2.562777529582072 + 66.73129709411079 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 212 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 34.10919172462936 + 176.31986637140767 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 213 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 33.846173186403306 + 142.33660392777279 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 214 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 128.76326079790124 + 90.05136184351706 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 215 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 80.39617891964872 + 111.48714907972395 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 216 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 21.97338508940303 + 61.032785792453815 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 217 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 158.00182839254427 + 175.79991821384095 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 218 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 64.21702017661488 + 197.8650659620092 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 219 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 58.261430108425174 + 69.56229252260285 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 220 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 114.85635789777962 + 130.3021189977344 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 221 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 24.601661057872736 + 196.33046445845073 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 222 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 136.22037670133446 + 18.019579846123435 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 223 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 71.91168973841357 + 193.3123397692768 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 224 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 76.67497322258676 + 156.30488619961912 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 225 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 85.70841880772959 + 39.914700874835106 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 226 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 142.3427145819395 + 76.80244108802334 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 227 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 45.6821653485997 + 33.96733547026549 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 228 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 146.16353499121948 + 5.58117117441268 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 229 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 34.32680631388174 + 111.76495490887346 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 230 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 138.5676204843924 + 161.4559204389253 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 231 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 196.36096598095253 + 19.9809316402896 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 232 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 190.5761031572042 + 118.16570999859783 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 233 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 137.89894164409372 + 114.36842366282201 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 234 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 13.942927177934262 + 25.042265908173977 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 235 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 21.808225381827363 + 89.51408500063611 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 236 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 82.1665299576559 + 89.41818802221223 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 237 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 100.24631818801446 + 85.16089691564225 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 238 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 150.87166478995505 + 124.32687790892683 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 239 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 196.72953604773366 + 89.0589559016778 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 240 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 178.10423185724105 + 108.01295472332721 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 241 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 24.852336661830865 + 107.10027825925053 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 242 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 198.2838988728342 + 185.2533889301396 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 243 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 122.42366366542863 + 13.685145107609165 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 244 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 113.58516359448151 + 59.212889358544054 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 245 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 148.6689453992514 + 65.76664113968091 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 246 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 110.90604811956779 + 118.12368970120251 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 247 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 195.48877933255176 + 71.61703558744803 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 248 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 90.74911177135543 + 151.9662290090636 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 249 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 5.669662023293154 + 80.71705944385323 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 250 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 77.57071934873466 + 25.884947016521597 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 251 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 172.38535892291588 + 6.827522113737539 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 252 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 62.61595677732154 + 171.52926299696654 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 253 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 163.1605182212256 + 136.67511261098457 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 254 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 174.98684717123461 + 163.9648526025463 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 255 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 112.4179766207543 + 108.05999669756379 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 256 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 71.60510656526031 + 96.23183516652448 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 257 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 51.39949089302518 + 181.73639564248649 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 258 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 140.61625635482116 + 118.88528060437326 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 259 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 81.11235868256772 + 71.16703221921186 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 260 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 106.30383323544051 + 47.66664077552125 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 261 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 78.36392430481997 + 145.12300889005226 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 262 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 159.2795584664916 + 175.42365153724947 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 263 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 89.12806123792214 + 163.88074620615808 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 264 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 188.00194321004403 + 167.99738752402368 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 265 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 186.544702443713 + 156.12158395696437 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 266 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 2.8406717287810412 + 38.380349570314664 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 267 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 28.76119804764801 + 168.10637626762275 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 268 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 190.1115654346047 + 36.24498374070968 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 269 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 67.43484884843447 + 118.69086680825731 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 270 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 50.7959234692023 + 165.04960719272802 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 271 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 50.75575271798458 + 144.55723570362358 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 272 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 128.94257968083764 + 47.32490472068322 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 273 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 1.9193343221312942 + 112.82658785936086 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 274 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 51.82023785974064 + 148.28034473499338 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 275 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 98.55603081185546 + 178.02566808501155 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 276 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 143.40572664084078 + 183.27302398341982 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 277 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 141.0619733646239 + 54.122738136324955 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 278 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 162.29942916334053 + 67.55247227617933 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 279 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 185.29686875363197 + 118.81126461905944 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 280 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 104.06690998854779 + 5.511220514887172 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 281 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 181.82429252421596 + 47.0700962247878 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 282 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 17.604228655775245 + 96.78328313290936 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 283 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 60.74231839144737 + 136.8041677309854 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 284 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 158.57791000335715 + 90.16811700419458 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 285 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 26.040369760119475 + 115.48428978095157 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 286 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 155.33825554510548 + 122.61758874267335 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 287 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 171.04754637183774 + 49.44780022857469 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 288 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 130.8601631228818 + 115.38443324744807 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 289 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 138.51066172926747 + 85.05731662406394 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 290 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 17.01860916014879 + 85.74431631403492 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 291 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 63.632763185894994 + 73.28193598294403 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 292 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 145.51992557600448 + 190.19645657449914 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 293 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 141.3669225587347 + 128.37798094188392 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 294 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 5.624436269305666 + 10.321359475496084 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 295 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 32.62210104212715 + 80.99365929301005 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 296 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 146.82462375206796 + 189.00512676494264 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 297 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 96.89937776974169 + 61.868257009019125 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 298 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 71.17532023107206 + 32.87953533289934 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 299 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 37.21430187397199 + 21.880189704400976 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 300 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 123.17178528937387 + 23.802492560334287 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 301 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 139.8264101859233 + 106.93416114169838 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 302 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 34.97792194896952 + 182.11554692137054 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 303 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 156.016327676095 + 83.35423896139108 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 304 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 33.33352678715003 + 148.24111721535743 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 305 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 22.525965053498552 + 94.23130431241577 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 306 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 145.40586007739483 + 194.77296443866655 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 307 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 64.78487058910738 + 34.59908782949142 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 308 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 59.86114357954142 + 143.29623794752337 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 309 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 133.03711837762597 + 0.29677881350260726 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 310 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 184.05437940334514 + 80.34917749334691 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 311 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 43.18494391360306 + 0.7070568470557648 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 312 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 87.88579984985796 + 183.6845166360299 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 313 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 35.679149788796785 + 59.900754257451624 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 314 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 10.837936713278706 + 68.65555543408139 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 315 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 28.088726188466005 + 66.6117410256945 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 316 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 24.15305881985441 + 127.36722357863377 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 317 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 167.92463302345024 + 95.32246240241238 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 318 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 150.07537910034364 + 189.29680149689028 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 319 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 36.60193942102408 + 4.850860928459388 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 320 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 131.4804357164766 + 107.37981261172979 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 321 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 4.702056299253576 + 145.3571381517292 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 322 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 76.83393335740108 + 40.92489706855471 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 323 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 81.41902810900726 + 59.67311069186907 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 324 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 157.9286881274713 + 35.89390157980119 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 325 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 172.59261547136273 + 162.21173966194792 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 326 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 63.77983240079481 + 110.66181735649987 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 327 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 94.27259269172448 + 102.22907067171563 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 328 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 87.82927755519094 + 154.83172363042706 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 329 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 61.424763006386954 + 73.54903523332621 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 330 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 193.50994444846046 + 100.37438735826956 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 331 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 160.15646353486886 + 197.56265442862397 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 332 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 33.41179410209567 + 85.51716211010236 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 333 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 39.55932830334419 + 79.79114070992594 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 334 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 29.81531743952457 + 106.52370973616816 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 335 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 145.66591758403607 + 93.84627277397392 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 336 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 121.12689025085304 + 141.7616054105135 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 337 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 31.696932817539736 + 73.39512842700171 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 338 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 73.55413175311341 + 184.10063535264334 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 339 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 179.21266954315877 + 157.77936426661222 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 340 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 5.861701400590658 + 176.44679868441557 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 341 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 164.32858198885157 + 127.1649251930171 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 342 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 104.78813885934602 + 2.6978015525372934 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 343 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 9.036210189825722 + 37.29651951364714 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 344 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 69.09633192708777 + 131.08113653458605 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 345 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 23.989325789242024 + 102.76529191595212 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 346 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 32.563144827068456 + 174.05783874991164 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 347 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 26.84717981820497 + 33.708035418260465 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 348 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 23.651571274100892 + 150.9696150146202 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 349 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 7.263970263317554 + 178.4551746541966 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 350 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 137.19080046610807 + 195.47642758858956 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 351 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 100.60258790901588 + 10.122226122279043 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 352 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 158.02955707421086 + 15.552042272281575 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 353 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 69.03288347183658 + 86.65939835169405 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 354 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 197.11534487465465 + 12.227887489891408 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 355 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 109.32664513099861 + 51.47545505189106 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 356 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 7.450618560323541 + 114.12792666368863 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 357 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 96.73499758330652 + 87.34903664585806 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 358 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 143.42568088659735 + 154.7201550387036 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 359 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 16.055115327242596 + 23.72235108907279 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 360 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 36.54118641672248 + 71.60060131854802 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 361 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 153.4641555525212 + 182.30266241969497 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 362 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 179.79961054026052 + 52.374917374947486 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 363 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 51.89511924887278 + 55.715278818289924 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 364 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 160.22911392558143 + 197.03727711739174 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 365 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 141.50401865962175 + 198.17183635084353 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 366 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 144.1436553724308 + 66.26788567722302 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 367 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 114.85639238072662 + 187.02866922391485 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 368 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 14.754418142216963 + 189.75568091879705 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 369 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 40.445861020644756 + 132.87622199437286 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 370 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 70.41846318684537 + 16.353121961748673 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 371 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 11.524098377391411 + 188.46037552576104 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 372 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 19.80490164758435 + 193.31200682922997 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 373 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 170.32256510777594 + 170.204813941954 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 374 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 35.11638379627671 + 106.63452905636245 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 375 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 87.80726944100199 + 69.16884374165753 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 376 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 45.63781115512378 + 137.1790704392972 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 377 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 120.23124867416645 + 21.60172442725463 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 378 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 42.584241021086264 + 172.9365035614701 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 379 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 106.9111221907689 + 35.38132573733432 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 380 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 115.65012523180343 + 149.06748739273075 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 381 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 66.70597176653999 + 151.96624665556067 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 382 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 116.86108695969573 + 92.96503821223025 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 383 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 138.3454858274232 + 60.335069940591254 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 384 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 35.21169262537829 + 57.75683948274251 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 385 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 183.64109836494706 + 187.89865943504947 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 386 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 124.92709985349823 + 7.139364140447135 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 387 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 121.19563498360651 + 163.5898829983739 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 388 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 141.67701483198246 + 36.967824799613645 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 389 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 116.85490603618803 + 192.1746914581395 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 390 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 157.23646122348265 + 101.21354943885676 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 391 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 58.04596641555313 + 180.0770488919343 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 392 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 118.342960728573 + 65.22048911724025 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 393 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 61.42203823259405 + 117.333210601775 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 394 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 136.13358028390385 + 97.99627507346685 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 395 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 82.86089860898949 + 25.22615052347874 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 396 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 6.721379593879373 + 94.78763681182285 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 397 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 38.69266957378596 + 24.113141554020046 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 398 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 111.22857295130957 + 95.51634459331788 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 399 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 126.7915415569141 + 32.23798771734878 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 400 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 186.84699461455236 + 34.76662976923288 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 401 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 122.45497909139493 + 167.0773654715768 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 402 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 33.03449972907999 + 172.77024458531486 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 403 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 1.1671649566739442 0.0 0.0 1.1671649566739442 66.21348020552065 40.83199757586018 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 0 + 240 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 962 + 1 + 596 + 603 + 43 + + \ No newline at end of file diff --git a/regression-tests/23-rpl-non-storing/05-rpl-up-and-down-routes.csc b/regression-tests/23-rpl-non-storing/05-rpl-up-and-down-routes.csc new file mode 100644 index 000000000..c2b3cb506 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/05-rpl-up-and-down-routes.csc @@ -0,0 +1,342 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype743 + Sender + [CONFIG_DIR]/code/sender-node.c + make clean TARGET=cooja +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype452 + RPL root + [CONFIG_DIR]/code/root-node.c + make clean TARGET=cooja +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype782 + Receiver + [CONFIG_DIR]/code/receiver-node.c + make clean TARGET=cooja +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -22.5728586847096 + 123.9358664968653 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype782 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype743 + + + + org.contikios.cooja.interfaces.Position + -1.39303771455413 + 100.21446701029119 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype782 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype782 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype782 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype782 + + + + org.contikios.cooja.interfaces.Position + 10.931583432822638 + 69.848248459216 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype782 + + + + org.contikios.cooja.interfaces.Position + 0.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype452 + + + + org.contikios.cooja.plugins.SimControl + 280 + 1 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + 1184 + 3 + 240 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 962 + 0 + 596 + 603 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/06-rpl-temporary-root-loss.csc b/regression-tests/23-rpl-non-storing/06-rpl-temporary-root-loss.csc new file mode 100644 index 000000000..6b5c91e54 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/06-rpl-temporary-root-loss.csc @@ -0,0 +1,348 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype951 + Sender + [CONFIG_DIR]/code/sender-node.c + make clean TARGET=cooja +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype170 + RPL root + [CONFIG_DIR]/code/root-node.c + make clean TARGET=cooja +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype767 + Receiver + [CONFIG_DIR]/code/receiver-node.c + make clean TARGET=cooja +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -22.5728586847096 + 123.9358664968653 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype767 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype951 + + + + org.contikios.cooja.interfaces.Position + -1.39303771455413 + 100.21446701029119 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype767 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype767 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype767 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype767 + + + + org.contikios.cooja.interfaces.Position + 10.931583432822638 + 69.848248459216 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype767 + + + + org.contikios.cooja.interfaces.Position + 0.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype170 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + 1184 + 3 + 240 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 962 + 1 + 596 + 603 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/07-rpl-random-rearrangement.csc b/regression-tests/23-rpl-non-storing/07-rpl-random-rearrangement.csc new file mode 100644 index 000000000..cdb62c420 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/07-rpl-random-rearrangement.csc @@ -0,0 +1,647 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype419 + Sender + [CONFIG_DIR]/code/sender-node.c + make clean TARGET=cooja +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype484 + RPL root + [CONFIG_DIR]/code/root-node.c + make clean TARGET=cooja +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype718 + Receiver + [CONFIG_DIR]/code/receiver-node.c + make clean TARGET=cooja +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -0.4799968467515439 + 98.79087181374759 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 99.56423154395364 + 50.06466731257512 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype419 + + + + org.contikios.cooja.interfaces.Position + -0.4799968467515439 + 0.30173505605854883 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype484 + + + + org.contikios.cooja.interfaces.Position + 12.779318616702257 + 8.464865358169643 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 9.391922400291703 + 49.22878206790311 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 48.16367625505583 + 33.27520746599595 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 16.582742473429345 + 24.932911331640646 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 8.445564421140666 + 6.770205395698742 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 87.04968129458189 + 34.46536562612724 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 9 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 94.47123252519145 + 18.275940194868184 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 10 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 95.28044254364556 + 17.683438211793558 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 11 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 56.124622439456076 + 33.88966252832571 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 12 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 98.33149749474546 + 37.448034626592744 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 13 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 58.75337436025891 + 68.64082018992522 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 14 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 66.83816496627988 + 68.38008376830592 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 15 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 90.88648665466316 + 50.942053906416575 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 16 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 68.80089833632896 + 84.17294684073734 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 17 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 73.6760846183129 + 81.76699743886633 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 18 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 0.2960103456537466 + 98.5587829617092 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 19 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 8.130479493904208 + 57.642099520821645 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 20 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 30.550120982984865 + 85.58346736403402 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 21 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 29.65300377698182 + 63.50257213104861 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 22 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 34.92110687576687 + 70.71381297232249 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 23 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.plugins.SimControl + 280 + 1 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 1.92914676942954 0.0 0.0 1.92914676942954 75.9259843662471 55.41790879138101 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 3 + 500 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 612 + 0 + 726 + 953 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-0.csc b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-0.csc new file mode 100644 index 000000000..b5aeac9b2 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-0.csc @@ -0,0 +1,360 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype921 + Sender + [CONFIG_DIR]/code/sender-node.c + make clean TARGET=cooja +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype873 + RPL root + [CONFIG_DIR]/code/root-node.c + make clean TARGET=cooja +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype812 + Receiver + [CONFIG_DIR]/code/receiver-node.c + make clean TARGET=cooja +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -7.199692787830563 + 98.21738321803603 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype921 + + + + org.contikios.cooja.interfaces.Position + 12.0 + 68.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 58.0 + 108.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + -40.352178879596096 + 102.66976131212861 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype873 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 1.6480321712565114 0.0 0.0 1.6480321712565114 98.5016889738719 55.796930342384904 + + 400 + 0 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 2 + 500 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 612 + 1 + 726 + 953 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-1.csc b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-1.csc new file mode 100644 index 000000000..d17bc193c --- /dev/null +++ b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-1.csc @@ -0,0 +1,360 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype672 + Sender + [CONFIG_DIR]/code/sender-node.c + make clean TARGET=cooja +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype780 + RPL root + [CONFIG_DIR]/code/root-node.c + make clean TARGET=cooja +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype36 + Receiver + [CONFIG_DIR]/code/receiver-node.c + make clean TARGET=cooja +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -7.199692787830563 + 98.21738321803603 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype672 + + + + org.contikios.cooja.interfaces.Position + 12.0 + 68.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 58.0 + 108.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + -25.71843353317142 + 43.05517674255262 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype780 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 1 + 500 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 612 + 0 + 726 + 953 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-2.csc b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-2.csc new file mode 100644 index 000000000..fe3db3dc3 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-2.csc @@ -0,0 +1,360 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype672 + Sender + [CONFIG_DIR]/code/sender-node.c + make clean TARGET=cooja +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype780 + RPL root + [CONFIG_DIR]/code/root-node.c + make clean TARGET=cooja +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype36 + Receiver + [CONFIG_DIR]/code/receiver-node.c + make clean TARGET=cooja +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -7.199692787830563 + 98.21738321803603 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype672 + + + + org.contikios.cooja.interfaces.Position + 12.0 + 68.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 58.0 + 108.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 16.0472370839803 + 6.017695251870905 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype780 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757 + + 400 + 0 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 2 + 500 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 612 + 1 + 726 + 953 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-3.csc b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-3.csc new file mode 100644 index 000000000..7ee838b2c --- /dev/null +++ b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-3.csc @@ -0,0 +1,360 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype672 + Sender + [CONFIG_DIR]/code/sender-node.c + make clean TARGET=cooja +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype780 + RPL root + [CONFIG_DIR]/code/root-node.c + make clean TARGET=cooja +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype36 + Receiver + [CONFIG_DIR]/code/receiver-node.c + make clean TARGET=cooja +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -7.199692787830563 + 98.21738321803603 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype672 + + + + org.contikios.cooja.interfaces.Position + 12.0 + 68.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 58.0 + 108.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 79.48377453078622 + 4.835647970253402 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype780 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 70.27260101976269 60.72727272727276 + + 400 + 0 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 2 + 500 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 612 + 1 + 726 + 953 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-4.csc b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-4.csc new file mode 100644 index 000000000..35c5bd753 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-4.csc @@ -0,0 +1,360 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype192 + Sender + [CONFIG_DIR]/code/sender-node.c + make clean TARGET=cooja +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype575 + RPL root + [CONFIG_DIR]/code/root-node.c + make clean TARGET=cooja +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype912 + Receiver + [CONFIG_DIR]/code/receiver-node.c + make clean TARGET=cooja +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -7.199692787830563 + 98.21738321803603 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype912 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype192 + + + + org.contikios.cooja.interfaces.Position + 12.0 + 68.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype912 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype912 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype912 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype912 + + + + org.contikios.cooja.interfaces.Position + 58.0 + 108.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype912 + + + + org.contikios.cooja.interfaces.Position + 122.82550819009461 + 29.658640884220933 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype575 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 70.27260101976269 60.72727272727276 + + 400 + 0 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 2 + 500 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 612 + 1 + 726 + 953 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-5.csc b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-5.csc new file mode 100644 index 000000000..4dc5038bc --- /dev/null +++ b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-5.csc @@ -0,0 +1,360 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype372 + Sender + [CONFIG_DIR]/code/sender-node.c + make clean TARGET=cooja +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype229 + RPL root + [CONFIG_DIR]/code/root-node.c + make clean TARGET=cooja +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype424 + Receiver + [CONFIG_DIR]/code/receiver-node.c + make clean TARGET=cooja +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -7.199692787830563 + 98.21738321803603 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype424 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype372 + + + + org.contikios.cooja.interfaces.Position + 12.0 + 68.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype424 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype424 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype424 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype424 + + + + org.contikios.cooja.interfaces.Position + 58.0 + 108.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype424 + + + + org.contikios.cooja.interfaces.Position + 145.93059238811136 + 111.16474110935306 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype229 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 1.6480321712565114 0.0 0.0 1.6480321712565114 98.5016889738719 55.796930342384904 + + 400 + 0 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 2 + 500 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 612 + 1 + 726 + 953 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/09-rpl-probing.csc b/regression-tests/23-rpl-non-storing/09-rpl-probing.csc new file mode 100644 index 000000000..5206f1cfd --- /dev/null +++ b/regression-tests/23-rpl-non-storing/09-rpl-probing.csc @@ -0,0 +1,256 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype190 + Sender + [CONTIKI_DIR]/regression-tests/12-rpl/code/sender-node.c + make clean TARGET=cooja +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype481 + RPL root + [CONTIKI_DIR]/regression-tests/12-rpl/code/root-node.c + make clean TARGET=cooja +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype692 + Receiver + [CONTIKI_DIR]/regression-tests/12-rpl/code/receiver-node.c + make clean TARGET=cooja +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + 8.0 + 2.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype481 + + + + org.contikios.cooja.interfaces.Position + -7.19071602882406 + 34.96668248624779 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype190 + + + + org.contikios.cooja.interfaces.Position + -17.870288882812428 + 4.581754854333804 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype692 + + + + org.contikios.cooja.plugins.SimControl + 280 + 2 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.494541140753371 0.0 0.0 2.494541140753371 168.25302383129448 116.2254386098645 + + 400 + 3 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 597 + 0 + 428 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 605 + 1 + 684 + 604 + 14 + + + diff --git a/regression-tests/23-rpl-non-storing/10-rpl-multi-dodag.csc b/regression-tests/23-rpl-non-storing/10-rpl-multi-dodag.csc new file mode 100644 index 000000000..fa015e8d9 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/10-rpl-multi-dodag.csc @@ -0,0 +1,389 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + [APPS_DIR]/serial2pty + [APPS_DIR]/radiologger-headless + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype301 + Sender + [CONTIKI_DIR]/regression-tests/12-rpl/code/sender-node.c + make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype820 + RPL root + [CONTIKI_DIR]/regression-tests/12-rpl/code/root-node.c + make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype306 + Receiver + [CONTIKI_DIR]/regression-tests/12-rpl/code/receiver-node.c + make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + 9.767954940345236 + 88.75813939592845 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype306 + + + + org.contikios.cooja.interfaces.Position + 63.36720084537501 + 75.88456991067605 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype301 + + + + org.contikios.cooja.interfaces.Position + -20.684049350551753 + 60.49767834794315 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype306 + + + + org.contikios.cooja.interfaces.Position + 64.61229064867878 + 39.88729002781773 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype306 + + + + org.contikios.cooja.interfaces.Position + 37.157272454309606 + 19.60335867526139 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype306 + + + + org.contikios.cooja.interfaces.Position + -21.976612887408603 + 30.69884249204435 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype306 + + + + org.contikios.cooja.interfaces.Position + 43 + 98 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype820 + + + + org.contikios.cooja.interfaces.Position + 0.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype820 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 1.7624788498159916 0.0 0.0 1.7624788498159916 97.6893062637241 8.72727272727273 + + 400 + 0 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 2 + 240 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 962 + 1 + 596 + 603 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/Makefile b/regression-tests/23-rpl-non-storing/Makefile new file mode 100644 index 000000000..272bc7da1 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/Makefile @@ -0,0 +1 @@ +include ../Makefile.simulation-test diff --git a/regression-tests/23-rpl-non-storing/code/Makefile b/regression-tests/23-rpl-non-storing/code/Makefile new file mode 100644 index 000000000..616341592 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/code/Makefile @@ -0,0 +1,7 @@ +all: sender-node receiver-node root-node +CONTIKI=../../.. + +CFLAGS+=-DPROJECT_CONF_H=\"project-conf.h\" + +CONTIKI_WITH_IPV6 = 1 +include $(CONTIKI)/Makefile.include diff --git a/regression-tests/23-rpl-non-storing/code/project-conf.h b/regression-tests/23-rpl-non-storing/code/project-conf.h new file mode 100644 index 000000000..2097e5f67 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/code/project-conf.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016, Inria. + * 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. + */ +#define TCPIP_CONF_ANNOTATE_TRANSMISSIONS 1 + +#undef RPL_CONF_WITH_NON_STORING +#define RPL_CONF_WITH_NON_STORING 1 + +#undef RPL_CONF_WITH_STORING +#define RPL_CONF_WITH_STORING 0 + +#undef RPL_CONF_MOP +#define RPL_CONF_MOP RPL_MOP_NON_STORING + +/* Add a bit of extra probing in the non-storing case to compensate for reduced DAO traffic */ +#undef RPL_CONF_PROBING_INTERVAL +#define RPL_CONF_PROBING_INTERVAL (60 * CLOCK_SECOND) diff --git a/regression-tests/23-rpl-non-storing/code/receiver-node.c b/regression-tests/23-rpl-non-storing/code/receiver-node.c new file mode 100644 index 000000000..4ba3cb148 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/code/receiver-node.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2012, Thingsquare, www.thingsquare.com. + * 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. + */ + +#include "contiki.h" +#include "lib/random.h" +#include "sys/ctimer.h" +#include "sys/etimer.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "net/ip/uip-debug.h" + +#include "simple-udp.h" + +#include "net/rpl/rpl.h" +#include "dev/leds.h" + +#include +#include + +#define UDP_PORT 1234 + +static struct simple_udp_connection unicast_connection; + +/*---------------------------------------------------------------------------*/ +PROCESS(receiver_node_process, "Receiver node"); +AUTOSTART_PROCESSES(&receiver_node_process); +/*---------------------------------------------------------------------------*/ +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) +{ + printf("Data received from "); + uip_debug_ipaddr_print(sender_addr); + printf(" on port %d from port %d with length %d: '%s'\n", + receiver_port, sender_port, datalen, data); +} +/*---------------------------------------------------------------------------*/ +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; +} +/*---------------------------------------------------------------------------*/ +uint8_t should_blink = 1; +static void +route_callback(int event, uip_ipaddr_t *route, uip_ipaddr_t *ipaddr, int num_routes) +{ + if(event == UIP_DS6_NOTIFICATION_DEFRT_ADD) { + should_blink = 0; + } else if(event == UIP_DS6_NOTIFICATION_DEFRT_RM) { + should_blink = 1; + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(receiver_node_process, ev, data) +{ + static struct etimer et; + static struct uip_ds6_notification n; + + PROCESS_BEGIN(); + + set_global_address(); + + uip_ds6_notification_add(&n, route_callback); + + simple_udp_register(&unicast_connection, UDP_PORT, + NULL, UDP_PORT, receiver); + + etimer_set(&et, CLOCK_SECOND); + while(1) { + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + etimer_reset(&et); + if(should_blink) { + leds_on(LEDS_ALL); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + etimer_reset(&et); + leds_off(LEDS_ALL); + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/regression-tests/23-rpl-non-storing/code/root-node.c b/regression-tests/23-rpl-non-storing/code/root-node.c new file mode 100644 index 000000000..0609e1bd8 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/code/root-node.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2012, Thingsquare, www.thingsquare.com. + * 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. + */ + + +#include "contiki.h" +#include "lib/random.h" +#include "sys/ctimer.h" +#include "sys/etimer.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "net/ip/uip-debug.h" + +#include "simple-udp.h" + +#include "net/rpl/rpl.h" + +#include +#include + +#define UDP_PORT 1234 +#define SERVICE_ID 190 + +#define SEND_INTERVAL (10 * CLOCK_SECOND) +#define SEND_TIME (random_rand() % (SEND_INTERVAL)) + +static struct simple_udp_connection unicast_connection; + +/*---------------------------------------------------------------------------*/ +PROCESS(unicast_receiver_process, "Unicast receiver example process"); +AUTOSTART_PROCESSES(&unicast_receiver_process); +/*---------------------------------------------------------------------------*/ +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) +{ + printf("Data received from "); + uip_debug_ipaddr_print(sender_addr); + printf(" on port %d from port %d with length %d: '%s'\n", + receiver_port, sender_port, datalen, data); +} +/*---------------------------------------------------------------------------*/ +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(RPL_DEFAULT_INSTANCE, ipaddr); + dag = rpl_get_any_dag(); + 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"); + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(unicast_receiver_process, ev, data) +{ + uip_ipaddr_t *ipaddr; + + PROCESS_BEGIN(); + + ipaddr = set_global_address(); + + create_rpl_dag(ipaddr); + + simple_udp_register(&unicast_connection, UDP_PORT, + NULL, UDP_PORT, receiver); + + while(1) { + PROCESS_WAIT_EVENT(); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/regression-tests/23-rpl-non-storing/code/sender-node.c b/regression-tests/23-rpl-non-storing/code/sender-node.c new file mode 100644 index 000000000..08d81b62d --- /dev/null +++ b/regression-tests/23-rpl-non-storing/code/sender-node.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2012, Thingsquare, www.thingsquare.com. + * 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. + */ + + +#include "contiki.h" +#include "lib/random.h" +#include "sys/ctimer.h" +#include "sys/etimer.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "net/ip/uip-debug.h" + +#include "simple-udp.h" + +#include +#include + +#define UDP_PORT 1234 + +#define SEND_INTERVAL (60 * CLOCK_SECOND) +#define SEND_TIME (random_rand() % (SEND_INTERVAL)) + +static struct simple_udp_connection unicast_connection; + +/*---------------------------------------------------------------------------*/ +PROCESS(sender_node_process, "Sender node process"); +AUTOSTART_PROCESSES(&sender_node_process); +/*---------------------------------------------------------------------------*/ +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) +{ + printf("Sender received data on port %d from port %d with length %d\n", + receiver_port, sender_port, datalen); +} +/*---------------------------------------------------------------------------*/ +static void +set_global_address(void) +{ + 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"); + } + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(sender_node_process, ev, data) +{ + static struct etimer periodic_timer; + static struct etimer send_timer; + uip_ipaddr_t addr; + + PROCESS_BEGIN(); + + set_global_address(); + + simple_udp_register(&unicast_connection, UDP_PORT, + NULL, UDP_PORT, receiver); + + etimer_set(&periodic_timer, SEND_INTERVAL); + while(1) { + + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&periodic_timer)); + etimer_reset(&periodic_timer); + etimer_set(&send_timer, SEND_TIME); + + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&send_timer)); + + uip_ip6addr(&addr, 0xaaaa, 0, 0, 0, 0x0201, 0x001, 0x001, 0x001); + + { + static unsigned int message_number; + char buf[20]; + + printf("Sending unicast to "); + uip_debug_ipaddr_print(&addr); + printf("\n"); + sprintf(buf, "Message %d", message_number); + message_number++; + simple_udp_sendto(&unicast_connection, buf, strlen(buf) + 1, &addr); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ From 1a7133bbf28058393dca9450b8d91da7b2c28ac1 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 25 Apr 2016 14:51:25 +0200 Subject: [PATCH 324/374] Simplified configuration of RPL non-storing mode --- core/contiki-default-conf.h | 13 ++++++ core/net/rpl/rpl-conf.h | 21 ---------- core/net/rpl/rpl-private.h | 40 +++++++++++++++++++ .../ipv6/rpl-border-router/project-conf.h | 18 +++++---- examples/ipv6/rpl-collect/project-conf.h | 20 +++++----- examples/ipv6/rpl-udp/project-conf.h | 16 +++++--- .../23-rpl-non-storing/code/project-conf.h | 6 --- 7 files changed, 85 insertions(+), 49 deletions(-) diff --git a/core/contiki-default-conf.h b/core/contiki-default-conf.h index 36bf6afe1..c26a2b8df 100644 --- a/core/contiki-default-conf.h +++ b/core/contiki-default-conf.h @@ -148,12 +148,25 @@ #endif /* NBR_TABLE_FIND_REMOVABLE */ #endif /* UIP_CONF_IPV6_RPL */ +/* RPL_CONF_MOP specifies the RPL mode of operation that will be + * advertised by the RPL root. Possible values: RPL_MOP_NO_DOWNWARD_ROUTES, + * RPL_MOP_NON_STORING, RPL_MOP_STORING_NO_MULTICAST, RPL_MOP_STORING_MULTICAST */ +#ifndef RPL_CONF_MOP +#define RPL_CONF_MOP RPL_MOP_STORING_NO_MULTICAST +#endif /* RPL_CONF_MOP */ + /* UIP_CONF_MAX_ROUTES specifies the maximum number of routes that each node will be able to handle. */ #ifndef UIP_CONF_MAX_ROUTES #define UIP_CONF_MAX_ROUTES 20 #endif /* UIP_CONF_MAX_ROUTES */ +/* RPL_NS_CONF_LINK_NUM specifies the maximum number of links a RPL root + * will maintain in non-storing mode. */ +#ifndef RPL_NS_CONF_LINK_NUM +#define RPL_NS_CONF_LINK_NUM 20 +#endif /* RPL_NS_CONF_LINK_NUM */ + /* UIP_CONF_UDP specifies if UDP support should be included or not. Disabling UDP saves memory but breaks a lot of stuff. */ #ifndef UIP_CONF_UDP diff --git a/core/net/rpl/rpl-conf.h b/core/net/rpl/rpl-conf.h index 0148e11e5..6479dd374 100644 --- a/core/net/rpl/rpl-conf.h +++ b/core/net/rpl/rpl-conf.h @@ -235,27 +235,6 @@ #define RPL_PREFERENCE 0 #endif -/* - * Embed support for storing mode - */ -#ifdef RPL_CONF_WITH_STORING -#define RPL_WITH_STORING RPL_CONF_WITH_STORING -#else /* RPL_CONF_WITH_STORING */ -#define RPL_WITH_STORING 1 -#endif /* RPL_CONF_WITH_STORING */ - -/* - * Embed support for non-storing mode - */ -#ifdef RPL_CONF_WITH_NON_STORING -#define RPL_WITH_NON_STORING RPL_CONF_WITH_NON_STORING -#else /* RPL_CONF_WITH_NON_STORING */ -#define RPL_WITH_NON_STORING 0 -#endif /* RPL_CONF_WITH_NON_STORING */ - -#define RPL_IS_STORING(instance) (RPL_WITH_STORING && ((instance) != NULL) && ((instance)->mop > RPL_MOP_NON_STORING)) -#define RPL_IS_NON_STORING(instance) (RPL_WITH_NON_STORING && ((instance) != NULL) && ((instance)->mop == RPL_MOP_NON_STORING)) - /* * RPL DAO ACK support. When enabled, DAO ACK will be sent and requested. * This will also enable retransmission of DAO when no ack is received. diff --git a/core/net/rpl/rpl-private.h b/core/net/rpl/rpl-private.h index 72ac12198..34d2e4445 100644 --- a/core/net/rpl/rpl-private.h +++ b/core/net/rpl/rpl-private.h @@ -44,6 +44,8 @@ #include "sys/clock.h" #include "sys/ctimer.h" #include "net/ipv6/uip-ds6.h" +#include "net/ipv6/uip-ds6-route.h" +#include "net/rpl/rpl-ns.h" #include "net/ipv6/multicast/uip-mcast6.h" /*---------------------------------------------------------------------------*/ @@ -197,6 +199,7 @@ #define RPL_MOP_STORING_NO_MULTICAST 2 #define RPL_MOP_STORING_MULTICAST 3 +/* RPL Mode of operation */ #ifdef RPL_CONF_MOP #define RPL_MOP_DEFAULT RPL_CONF_MOP #else /* RPL_CONF_MOP */ @@ -207,6 +210,43 @@ #endif /* UIP_IPV6_MULTICAST_RPL */ #endif /* RPL_CONF_MOP */ +/* + * Embed support for storing mode + */ +#ifdef RPL_CONF_WITH_STORING +#define RPL_WITH_STORING RPL_CONF_WITH_STORING +#else /* RPL_CONF_WITH_STORING */ +/* By default: embed support for non-storing if and only if the configured MOP is not non-storing */ +#define RPL_WITH_STORING (RPL_MOP_DEFAULT != RPL_MOP_NON_STORING) +#endif /* RPL_CONF_WITH_STORING */ + +/* + * Embed support for non-storing mode + */ +#ifdef RPL_CONF_WITH_NON_STORING +#define RPL_WITH_NON_STORING RPL_CONF_WITH_NON_STORING +#else /* RPL_CONF_WITH_NON_STORING */ +/* By default: embed support for non-storing if and only if the configured MOP is non-storing */ +#define RPL_WITH_NON_STORING (RPL_MOP_DEFAULT == RPL_MOP_NON_STORING) +#endif /* RPL_CONF_WITH_NON_STORING */ + +#if RPL_WITH_STORING && (UIP_DS6_ROUTE_NB == 0) +#error "RPL with storing mode included but #routes == 0. Set UIP_CONF_MAX_ROUTES accordingly." +#if !RPL_WITH_NON_STORING && (RPL_NS_LINK_NUM > 0) +#error "You might also want to set RPL_NS_CONF_LINK_NUM to 0." +#endif +#endif + +#if RPL_WITH_NON_STORING && (RPL_NS_LINK_NUM == 0) +#error "RPL with non-storing mode included but #links == 0. Set RPL_NS_CONF_LINK_NUM accordingly." +#if !RPL_WITH_STORING && (UIP_DS6_ROUTE_NB > 0) +#error "You might also want to set UIP_CONF_MAX_ROUTES to 0." +#endif +#endif + +#define RPL_IS_STORING(instance) (RPL_WITH_STORING && ((instance) != NULL) && ((instance)->mop > RPL_MOP_NON_STORING)) +#define RPL_IS_NON_STORING(instance) (RPL_WITH_NON_STORING && ((instance) != NULL) && ((instance)->mop == RPL_MOP_NON_STORING)) + /* Emit a pre-processor error if the user configured multicast with bad MOP */ #if RPL_CONF_MULTICAST && (RPL_MOP_DEFAULT != RPL_MOP_STORING_MULTICAST) #error "RPL Multicast requires RPL_MOP_DEFAULT==3. Check contiki-conf.h" diff --git a/examples/ipv6/rpl-border-router/project-conf.h b/examples/ipv6/rpl-border-router/project-conf.h index c73735be6..ec3eb3f00 100644 --- a/examples/ipv6/rpl-border-router/project-conf.h +++ b/examples/ipv6/rpl-border-router/project-conf.h @@ -31,16 +31,18 @@ #ifndef PROJECT_ROUTER_CONF_H_ #define PROJECT_ROUTER_CONF_H_ -#ifndef RPL_CONF_WITH_NON_STORING -#define RPL_CONF_WITH_NON_STORING 0 /* Set this to run with non-storing mode */ -#endif /* RPL_CONF_WITH_NON_STORING */ +#ifndef WITH_NON_STORING +#define WITH_NON_STORING 0 /* Set this to run with non-storing mode */ +#endif /* WITH_NON_STORING */ -#if RPL_CONF_WITH_NON_STORING -#undef RPL_CONF_WITH_STORING -#define RPL_CONF_WITH_STORING 0 +#if WITH_NON_STORING +#undef RPL_NS_CONF_LINK_NUM +#define RPL_NS_CONF_LINK_NUM 40 /* Number of links maintained at the root */ +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 0 /* No need for routes */ #undef RPL_CONF_MOP -#define RPL_CONF_MOP RPL_MOP_NON_STORING -#endif /* RPL_CONF_WITH_NON_STORING */ +#define RPL_CONF_MOP RPL_MOP_NON_STORING /* Mode of operation*/ +#endif /* WITH_NON_STORING */ #ifndef UIP_FALLBACK_INTERFACE #define UIP_FALLBACK_INTERFACE rpl_interface diff --git a/examples/ipv6/rpl-collect/project-conf.h b/examples/ipv6/rpl-collect/project-conf.h index e45518b73..a143b07cd 100644 --- a/examples/ipv6/rpl-collect/project-conf.h +++ b/examples/ipv6/rpl-collect/project-conf.h @@ -30,6 +30,10 @@ #ifndef PROJECT_CONF_H_ #define PROJECT_CONF_H_ +#ifndef WITH_NON_STORING +#define WITH_NON_STORING 0 /* Set this to run with non-storing mode */ +#endif /* WITH_NON_STORING */ + #undef NBR_TABLE_CONF_MAX_NEIGHBORS #undef UIP_CONF_MAX_ROUTES @@ -63,15 +67,13 @@ #undef SICSLOWPAN_CONF_FRAG #define SICSLOWPAN_CONF_FRAG 0 -#ifndef RPL_CONF_WITH_NON_STORING -#define RPL_CONF_WITH_NON_STORING 0 /* Set this to run with non-storing mode */ -#endif /* RPL_CONF_WITH_NON_STORING */ - -#if RPL_CONF_WITH_NON_STORING -#undef RPL_CONF_WITH_STORING -#define RPL_CONF_WITH_STORING 0 +#if WITH_NON_STORING +#undef RPL_NS_CONF_LINK_NUM +#define RPL_NS_CONF_LINK_NUM 40 /* Number of links maintained at the root. Can be set to 0 at non-root nodes. */ +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 0 /* No need for routes */ #undef RPL_CONF_MOP -#define RPL_CONF_MOP RPL_MOP_NON_STORING -#endif /* RPL_CONF_WITH_NON_STORING */ +#define RPL_CONF_MOP RPL_MOP_NON_STORING /* Mode of operation*/ +#endif /* WITH_NON_STORING */ #endif /* PROJECT_CONF_H_ */ diff --git a/examples/ipv6/rpl-udp/project-conf.h b/examples/ipv6/rpl-udp/project-conf.h index 0217200b4..794897a46 100644 --- a/examples/ipv6/rpl-udp/project-conf.h +++ b/examples/ipv6/rpl-udp/project-conf.h @@ -30,6 +30,10 @@ #ifndef PROJECT_CONF_H_ #define PROJECT_CONF_H_ +#ifndef WITH_NON_STORING +#define WITH_NON_STORING 0 /* Set this to run with non-storing mode */ +#endif /* WITH_NON_STORING */ + #undef NBR_TABLE_CONF_MAX_NEIGHBORS #undef UIP_CONF_MAX_ROUTES @@ -60,11 +64,13 @@ #define RPL_CONF_WITH_NON_STORING 0 /* Set this to run with non-storing mode */ #endif /* RPL_CONF_WITH_NON_STORING */ -#if RPL_CONF_WITH_NON_STORING -#undef RPL_CONF_WITH_STORING -#define RPL_CONF_WITH_STORING 0 +#if WITH_NON_STORING +#undef RPL_NS_CONF_LINK_NUM +#define RPL_NS_CONF_LINK_NUM 40 /* Number of links maintained at the root. Can be set to 0 at non-root nodes. */ +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 0 /* No need for routes */ #undef RPL_CONF_MOP -#define RPL_CONF_MOP RPL_MOP_NON_STORING -#endif /* RPL_CONF_WITH_NON_STORING */ +#define RPL_CONF_MOP RPL_MOP_NON_STORING /* Mode of operation*/ +#endif /* WITH_NON_STORING */ #endif diff --git a/regression-tests/23-rpl-non-storing/code/project-conf.h b/regression-tests/23-rpl-non-storing/code/project-conf.h index 2097e5f67..9270334fb 100644 --- a/regression-tests/23-rpl-non-storing/code/project-conf.h +++ b/regression-tests/23-rpl-non-storing/code/project-conf.h @@ -28,12 +28,6 @@ */ #define TCPIP_CONF_ANNOTATE_TRANSMISSIONS 1 -#undef RPL_CONF_WITH_NON_STORING -#define RPL_CONF_WITH_NON_STORING 1 - -#undef RPL_CONF_WITH_STORING -#define RPL_CONF_WITH_STORING 0 - #undef RPL_CONF_MOP #define RPL_CONF_MOP RPL_MOP_NON_STORING From b32b3f66660b12020d632f069e2e500b6c32f5a4 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 25 Apr 2016 14:55:18 +0200 Subject: [PATCH 325/374] RPL non-storing: add compile-test to also check for warnings --- examples/ipv6/rpl-border-router/Makefile | 4 ++++ examples/ipv6/rpl-collect/Makefile | 4 ++++ examples/ipv6/rpl-udp/Makefile | 4 ++++ regression-tests/18-compile-arm-ports/Makefile | 1 + 4 files changed, 13 insertions(+) diff --git a/examples/ipv6/rpl-border-router/Makefile b/examples/ipv6/rpl-border-router/Makefile index 6595186be..d325918ec 100644 --- a/examples/ipv6/rpl-border-router/Makefile +++ b/examples/ipv6/rpl-border-router/Makefile @@ -21,6 +21,10 @@ PROJECT_SOURCEFILES += slip-bridge.c #of the slip connection. Large MSS together with low baud rates without flow #control will overrun the transmit buffer when the style sheet is requested. +ifeq ($(MAKE_WITH_NON_STORING),1) +CFLAGS += -DWITH_NON_STORING=1 +endif + WITH_WEBSERVER=1 ifeq ($(WITH_WEBSERVER),1) CFLAGS += -DUIP_CONF_TCP=1 diff --git a/examples/ipv6/rpl-collect/Makefile b/examples/ipv6/rpl-collect/Makefile index e2a1021a0..13813ed44 100644 --- a/examples/ipv6/rpl-collect/Makefile +++ b/examples/ipv6/rpl-collect/Makefile @@ -5,6 +5,10 @@ PROJECT_SOURCEFILES += collect-common.c CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +ifeq ($(MAKE_WITH_NON_STORING),1) +CFLAGS += -DWITH_NON_STORING=1 +endif + ifdef PERIOD CFLAGS=-DPERIOD=$(PERIOD) endif diff --git a/examples/ipv6/rpl-udp/Makefile b/examples/ipv6/rpl-udp/Makefile index fbf9a589e..d7330821a 100644 --- a/examples/ipv6/rpl-udp/Makefile +++ b/examples/ipv6/rpl-udp/Makefile @@ -15,5 +15,9 @@ ifdef PERIOD CFLAGS+=-DPERIOD=$(PERIOD) endif +ifeq ($(MAKE_WITH_NON_STORING),1) +CFLAGS += -DWITH_NON_STORING=1 +endif + CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include diff --git a/regression-tests/18-compile-arm-ports/Makefile b/regression-tests/18-compile-arm-ports/Makefile index 826365828..e0addfa9f 100644 --- a/regression-tests/18-compile-arm-ports/Makefile +++ b/regression-tests/18-compile-arm-ports/Makefile @@ -16,6 +16,7 @@ cc26xx/cc26xx-web-demo/srf06-cc26xx:BOARD=launchpad/cc1310 \ cc26xx/very-sleepy-demo/srf06-cc26xx \ hello-world/cc2538dk \ ipv6/rpl-border-router/cc2538dk \ +ipv6/rpl-border-router/cc2538dk:MAKE_WITH_NON_STORING=1 \ er-rest-example/cc2538dk \ ipso-objects/cc2538dk \ webserver-ipv6/cc2538dk \ From ded71a7400ec312bfbbf85c8971fcc9bfdd17fca Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 25 Apr 2016 17:13:10 +0200 Subject: [PATCH 326/374] RPL: add neighbor to cache on incoming DIO also at the root --- core/net/rpl/rpl-dag.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index ced73990f..2077c4eb4 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -1527,6 +1527,11 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) } } + if(!add_nbr_from_dio(from, dio)) { + PRINTF("RPL: Could not add parent based on DIO\n"); + return; + } + if(dag->rank == ROOT_RANK(instance)) { if(dio->rank != INFINITE_RANK) { instance->dio_counter++; @@ -1547,11 +1552,6 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) * whether to keep it in the set. */ - if(!add_nbr_from_dio(from, dio)) { - PRINTF("RPL: Could not add parent based on DIO\n"); - return; - } - p = rpl_find_parent(dag, from); if(p == NULL) { previous_dag = find_parent_dag(instance, from); From c3ea1f9fc6689992a8b833cd80b2eb1bf181fce2 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 29 Apr 2016 22:12:06 +0200 Subject: [PATCH 327/374] Orchestra: added support for RPL non-storing mode --- apps/orchestra/Makefile.orchestra | 2 +- apps/orchestra/orchestra-conf.h | 8 +- ...chestra-rule-unicast-per-neighbor-rpl-ns.c | 119 ++++++++++++++++++ ...a-rule-unicast-per-neighbor-rpl-storing.c} | 10 +- apps/orchestra/orchestra.h | 3 +- 5 files changed, 132 insertions(+), 10 deletions(-) create mode 100644 apps/orchestra/orchestra-rule-unicast-per-neighbor-rpl-ns.c rename apps/orchestra/{orchestra-rule-unicast-per-neighbor.c => orchestra-rule-unicast-per-neighbor-rpl-storing.c} (96%) diff --git a/apps/orchestra/Makefile.orchestra b/apps/orchestra/Makefile.orchestra index 314fdac23..8c30a816e 100644 --- a/apps/orchestra/Makefile.orchestra +++ b/apps/orchestra/Makefile.orchestra @@ -1 +1 @@ -orchestra_src = orchestra.c orchestra-rule-default-common.c orchestra-rule-eb-per-time-source.c orchestra-rule-unicast-per-neighbor.c +orchestra_src = orchestra.c orchestra-rule-default-common.c orchestra-rule-eb-per-time-source.c orchestra-rule-unicast-per-neighbor-rpl-storing.c orchestra-rule-unicast-per-neighbor-rpl-ns.c diff --git a/apps/orchestra/orchestra-conf.h b/apps/orchestra/orchestra-conf.h index 910917620..d8116ff16 100644 --- a/apps/orchestra/orchestra-conf.h +++ b/apps/orchestra/orchestra-conf.h @@ -46,10 +46,10 @@ * - a sender-based or receiver-based slotframe for unicast to RPL parents and children * - a common shared slotframe for any other traffic (mostly broadcast) * */ -#define ORCHESTRA_RULES { &eb_per_time_source, \ - &unicast_per_neighbor, \ - &default_common, \ - } +#define ORCHESTRA_RULES { &eb_per_time_source, &unicast_per_neighbor_rpl_storing, &default_common } +/* Example configuration for RPL non-storing mode: */ +/* #define ORCHESTRA_RULES { &eb_per_time_source, &unicast_per_neighbor_rpl_ns, &default_common } */ + #endif /* ORCHESTRA_CONF_RULES */ /* Length of the various slotframes. Tune to balance network capacity, diff --git a/apps/orchestra/orchestra-rule-unicast-per-neighbor-rpl-ns.c b/apps/orchestra/orchestra-rule-unicast-per-neighbor-rpl-ns.c new file mode 100644 index 000000000..d72646e1d --- /dev/null +++ b/apps/orchestra/orchestra-rule-unicast-per-neighbor-rpl-ns.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2016, Inria. + * 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 + * Orchestra: a slotframe dedicated to unicast data transmission. Designed primarily + * for RPL non-storing mode but would work with any mode-of-operation. Does not require + * any knowledge of the children. Works only as received-base, and as follows: + * Nodes listen at a timeslot defined as hash(MAC) % ORCHESTRA_SB_UNICAST_PERIOD + * Nodes transmit at: for any neighbor, hash(nbr.MAC) % ORCHESTRA_SB_UNICAST_PERIOD + * + * \author Simon Duquennoy + */ + +#include "contiki.h" +#include "orchestra.h" +#include "net/ipv6/uip-ds6-route.h" +#include "net/packetbuf.h" + +static uint16_t slotframe_handle = 0; +static uint16_t channel_offset = 0; +static struct tsch_slotframe *sf_unicast; + +/*---------------------------------------------------------------------------*/ +static uint16_t +get_node_timeslot(const linkaddr_t *addr) +{ + if(addr != NULL && ORCHESTRA_UNICAST_PERIOD > 0) { + return ORCHESTRA_LINKADDR_HASH(addr) % ORCHESTRA_UNICAST_PERIOD; + } else { + return 0xffff; + } +} +/*---------------------------------------------------------------------------*/ +static void +child_added(const linkaddr_t *linkaddr) +{ +} +/*---------------------------------------------------------------------------*/ +static void +child_removed(const linkaddr_t *linkaddr) +{ +} +/*---------------------------------------------------------------------------*/ +static int +select_packet(uint16_t *slotframe, uint16_t *timeslot) +{ + /* Select data packets we have a unicast link to */ + const linkaddr_t *dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER); + if(packetbuf_attr(PACKETBUF_ATTR_FRAME_TYPE) == FRAME802154_DATAFRAME + && !linkaddr_cmp(dest, &linkaddr_null)) { + if(slotframe != NULL) { + *slotframe = slotframe_handle; + } + if(timeslot != NULL) { + *timeslot = get_node_timeslot(dest); + } + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +new_time_source(const struct tsch_neighbor *old, const struct tsch_neighbor *new) +{ +} +/*---------------------------------------------------------------------------*/ +static void +init(uint16_t sf_handle) +{ + int i; + uint16_t rx_timeslot; + slotframe_handle = sf_handle; + channel_offset = sf_handle; + /* Slotframe for unicast transmissions */ + sf_unicast = tsch_schedule_add_slotframe(slotframe_handle, ORCHESTRA_UNICAST_PERIOD); + rx_timeslot = get_node_timeslot(&linkaddr_node_addr); + /* Add a Tx link at each available timeslot. Make the link Rx at our own timeslot. */ + for(i = 0; i < ORCHESTRA_UNICAST_PERIOD; i++) { + tsch_schedule_add_link(sf_unicast, + LINK_OPTION_SHARED | LINK_OPTION_TX | ( i == rx_timeslot ? LINK_OPTION_RX : 0 ), + LINK_TYPE_NORMAL, &tsch_broadcast_address, + i, channel_offset); + } +} +/*---------------------------------------------------------------------------*/ +struct orchestra_rule unicast_per_neighbor_rpl_ns = { + init, + new_time_source, + select_packet, + child_added, + child_removed, +}; diff --git a/apps/orchestra/orchestra-rule-unicast-per-neighbor.c b/apps/orchestra/orchestra-rule-unicast-per-neighbor-rpl-storing.c similarity index 96% rename from apps/orchestra/orchestra-rule-unicast-per-neighbor.c rename to apps/orchestra/orchestra-rule-unicast-per-neighbor-rpl-storing.c index 58f5dcc42..76e039f09 100644 --- a/apps/orchestra/orchestra-rule-unicast-per-neighbor.c +++ b/apps/orchestra/orchestra-rule-unicast-per-neighbor-rpl-storing.c @@ -29,12 +29,13 @@ */ /** * \file - * Orchestra: a slotframe dedicated to unicast data transmission. - * If sender-based: + * Orchestra: a slotframe dedicated to unicast data transmission. Designed for + * RPL storing mode only, as this is based on the knowledge of the children (and parent). + * If receiver-based: * Nodes listen at a timeslot defined as hash(MAC) % ORCHESTRA_SB_UNICAST_PERIOD * Nodes transmit at: for each nbr in RPL children and RPL preferred parent, * hash(nbr.MAC) % ORCHESTRA_SB_UNICAST_PERIOD - * If receiver-based: the opposite + * If sender-based: the opposite * * \author Simon Duquennoy */ @@ -43,6 +44,7 @@ #include "orchestra.h" #include "net/ipv6/uip-ds6-route.h" #include "net/packetbuf.h" +#include "net/rpl/rpl-conf.h" #if ORCHESTRA_UNICAST_SENDER_BASED && ORCHESTRA_COLLISION_FREE_HASH #define UNICAST_SLOT_SHARED_FLAG ((ORCHESTRA_UNICAST_PERIOD < (ORCHESTRA_MAX_HASH + 1)) ? LINK_OPTION_SHARED : 0) @@ -202,7 +204,7 @@ init(uint16_t sf_handle) timeslot, channel_offset); } /*---------------------------------------------------------------------------*/ -struct orchestra_rule unicast_per_neighbor = { +struct orchestra_rule unicast_per_neighbor_rpl_storing = { init, new_time_source, select_packet, diff --git a/apps/orchestra/orchestra.h b/apps/orchestra/orchestra.h index a895335b5..b948a2985 100644 --- a/apps/orchestra/orchestra.h +++ b/apps/orchestra/orchestra.h @@ -53,7 +53,8 @@ struct orchestra_rule { }; struct orchestra_rule eb_per_time_source; -struct orchestra_rule unicast_per_neighbor; +struct orchestra_rule unicast_per_neighbor_rpl_storing; +struct orchestra_rule unicast_per_neighbor_rpl_ns; struct orchestra_rule default_common; extern linkaddr_t orchestra_parent_linkaddr; From 343c2743599f8b88ad53c4335551496dd39afd6c Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 3 Jun 2016 21:17:05 +0200 Subject: [PATCH 328/374] RPL: re-enable RPL_DIO_REFRESH_DAO_ROUTES by default as it is needed with DAO-ACK disabled. Now increments the DTSN only at the root --- core/net/rpl/rpl-conf.h | 11 ++++++----- core/net/rpl/rpl-icmp6.c | 4 +++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/core/net/rpl/rpl-conf.h b/core/net/rpl/rpl-conf.h index 6479dd374..97ab8f49d 100644 --- a/core/net/rpl/rpl-conf.h +++ b/core/net/rpl/rpl-conf.h @@ -257,15 +257,16 @@ #endif /* RPL_CONF_RPL_REPAIR_ON_DAO_NACK */ /* - * Setting the DIO_REFRESH_DAO_ROUTES will make RPL always increase - * the DTSN (Destination Advertisement Trigger Sequence Number) when - * sending broadcast DIO. This is to get all children to re-register - * their DAO route. + * Setting the DIO_REFRESH_DAO_ROUTES will make the RPL root always + * increase the DTSN (Destination Advertisement Trigger Sequence Number) + * when sending multicast DIO. This is to get all children to re-register + * their DAO route. This is needed when DAO-ACK is not enabled to add + * reliability to route maintenance. * */ #ifdef RPL_CONF_DIO_REFRESH_DAO_ROUTES #define RPL_DIO_REFRESH_DAO_ROUTES RPL_CONF_DIO_REFRESH_DAO_ROUTES #else -#define RPL_DIO_REFRESH_DAO_ROUTES 0 +#define RPL_DIO_REFRESH_DAO_ROUTES 1 #endif /* RPL_CONF_DIO_REFRESH_DAO_ROUTES */ /* diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index b900c6d5b..5bf4fc3d1 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -479,6 +479,7 @@ dio_output(rpl_instance_t *instance, uip_ipaddr_t *uc_addr) { unsigned char *buffer; int pos; + int is_root; rpl_dag_t *dag = instance->current_dag; #if !RPL_LEAF_ONLY uip_ipaddr_t addr; @@ -499,6 +500,7 @@ dio_output(rpl_instance_t *instance, uip_ipaddr_t *uc_addr) buffer = UIP_ICMP_PAYLOAD; buffer[pos++] = instance->instance_id; buffer[pos++] = dag->version; + is_root = (dag->rank == ROOT_RANK(instance)); #if RPL_LEAF_ONLY PRINTF("RPL: LEAF ONLY DIO rank set to INFINITE_RANK\n"); @@ -519,7 +521,7 @@ dio_output(rpl_instance_t *instance, uip_ipaddr_t *uc_addr) buffer[pos++] = instance->dtsn_out; - if(RPL_DIO_REFRESH_DAO_ROUTES && uc_addr == NULL) { + if(RPL_DIO_REFRESH_DAO_ROUTES && is_root && uc_addr == NULL) { /* Request new DAO to refresh route. We do not do this for unicast DIO * in order to avoid DAO messages after a DIS-DIO update, * or upon unicast DIO probing. */ From 6cdec707985f6a5e2272271370bf533a6f323e35 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 3 Jun 2016 21:18:15 +0200 Subject: [PATCH 329/374] rpl_verify_header: do not select DAG in storing mode after updating neighbor rank, as this may result in a No-Path DAO being sent, which will drop the current packet. --- core/net/rpl/rpl-ext-header.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/net/rpl/rpl-ext-header.c b/core/net/rpl/rpl-ext-header.c index 6015fcb57..41da2149e 100644 --- a/core/net/rpl/rpl-ext-header.c +++ b/core/net/rpl/rpl-ext-header.c @@ -136,7 +136,12 @@ rpl_verify_hbh_header(int uip_ext_opt_offset) /* A rank error was signalled, attempt to repair it by updating * the sender's rank from ext header */ sender->rank = sender_rank; - rpl_select_dag(instance, sender); + if(RPL_IS_NON_STORING(instance)) { + /* Select DAG and preferred parent only in non-storing mode. In storing mode, + * a parent switch would result in an immediate No-path DAO transmission, dropping + * current incoming packet. */ + rpl_select_dag(instance, sender); + } } sender_closer = sender_rank < instance->current_dag->rank; From 4208973017fe64fecf3b1c57188a005238a76337 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 3 Jun 2016 21:19:08 +0200 Subject: [PATCH 330/374] Fix DAO-ACK support for non-storing --- core/net/rpl/rpl-icmp6.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 5bf4fc3d1..5531f6100 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -1061,7 +1061,7 @@ handle_dao_retransmission(void *ptr) return; } - if(instance->of->dao_ack_callback) { + if(RPL_IS_STORING(instance) && instance->of->dao_ack_callback) { /* Inform the objective function about the timeout. */ instance->of->dao_ack_callback(parent, RPL_DAO_ACK_TIMEOUT); } @@ -1274,11 +1274,15 @@ dao_ack_input(void) return; } - parent = rpl_find_parent(instance->current_dag, &UIP_IP_BUF->srcipaddr); - if(parent == NULL) { - /* not a known instance - drop the packet and ignore */ - uip_clear_buf(); - return; + if(RPL_IS_STORING(instance)) { + parent = rpl_find_parent(instance->current_dag, &UIP_IP_BUF->srcipaddr); + if(parent == NULL) { + /* not a known instance - drop the packet and ignore */ + uip_clear_buf(); + return; + } + } else { + parent = NULL; } PRINTF("RPL: Received a DAO %s with sequence number %d (%d) and status %d from ", @@ -1294,7 +1298,7 @@ dao_ack_input(void) ctimer_stop(&instance->dao_retransmit_timer); /* Inform objective function on status of the DAO ACK */ - if(instance->of->dao_ack_callback) { + if(RPL_IS_STORING(instance) && instance->of->dao_ack_callback) { instance->of->dao_ack_callback(parent, status); } @@ -1308,7 +1312,7 @@ dao_ack_input(void) } #endif - } else { + } else if(RPL_IS_STORING(instance)) { /* this DAO ACK should be forwarded to another recently registered route */ uip_ds6_route_t *re; uip_ipaddr_t *nexthop; From 6c4d5312aef77c9e952d2b6e5cbefc88e59db0ec Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 3 Jun 2016 22:06:05 +0200 Subject: [PATCH 331/374] uip-icmp6.c: call rpl_insert_header only when UIP_CONF_IPV6_RPL is set --- core/net/ipv6/uip-icmp6.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/net/ipv6/uip-icmp6.c b/core/net/ipv6/uip-icmp6.c index 582f49ba3..d246a4d58 100644 --- a/core/net/ipv6/uip-icmp6.c +++ b/core/net/ipv6/uip-icmp6.c @@ -301,7 +301,9 @@ uip_icmp6_send(const uip_ipaddr_t *dest, int type, int code, int payload_len) UIP_STAT(++uip_stat.icmp.sent); UIP_STAT(++uip_stat.ip.sent); +#if UIP_CONF_IPV6_RPL rpl_insert_header(); +#endif /* UIP_CONF_IPV6_RPL */ tcpip_ipv6_output(); } /*---------------------------------------------------------------------------*/ From 0f5e3413fadc1fe581ff4291ea641a60beaf0bcc Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 8 Jun 2016 14:04:47 +0200 Subject: [PATCH 332/374] Simplify dao_input --- core/net/rpl/rpl-icmp6.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 5531f6100..9ffc61dea 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -1020,14 +1020,10 @@ dao_input(void) goto discard; } - if(instance->mop != RPL_MOP_NON_STORING) { - if(RPL_IS_STORING(instance)) { - dao_input_storing(); - } - } else { - if(RPL_IS_NON_STORING(instance)) { - dao_input_nonstoring(); - } + if(RPL_IS_STORING(instance)) { + dao_input_storing(); + } else if(RPL_IS_NON_STORING(instance)) { + dao_input_nonstoring(); } discard: From d5e74b9579bd323997350d37fb03a3569f7637f9 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 8 Jun 2016 14:05:37 +0200 Subject: [PATCH 333/374] Code style --- core/net/rpl/rpl-ns.c | 12 +++++++----- core/net/rpl/rpl-ns.h | 6 +++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/core/net/rpl/rpl-ns.c b/core/net/rpl/rpl-ns.c index fecd6767e..221abefc3 100644 --- a/core/net/rpl/rpl-ns.c +++ b/core/net/rpl/rpl-ns.c @@ -65,7 +65,7 @@ MEMB(nodememb, rpl_ns_node_t, RPL_NS_LINK_NUM); /*---------------------------------------------------------------------------*/ int -rpl_ns_num_nodes() +rpl_ns_num_nodes(void) { return num_nodes; } @@ -154,19 +154,21 @@ rpl_ns_update_node(rpl_dag_t *dag, const uip_ipaddr_t *child, const uip_ipaddr_t } /*---------------------------------------------------------------------------*/ void -rpl_ns_init() +rpl_ns_init(void) { num_nodes = 0; memb_init(&nodememb); list_init(nodelist); } /*---------------------------------------------------------------------------*/ -rpl_ns_node_t *rpl_ns_node_head() +rpl_ns_node_t * +rpl_ns_node_head(void) { return list_head(nodelist); } /*---------------------------------------------------------------------------*/ -rpl_ns_node_t *rpl_ns_node_next(rpl_ns_node_t *item) +rpl_ns_node_t * +rpl_ns_node_next(rpl_ns_node_t *item) { return list_item_next(item); } @@ -181,7 +183,7 @@ rpl_ns_get_node_global_addr(uip_ipaddr_t *addr, rpl_ns_node_t *node) } /*---------------------------------------------------------------------------*/ void -rpl_ns_periodic() +rpl_ns_periodic(void) { rpl_ns_node_t *l; /* First pass, decrement lifetime for all nodes with non-infinite lifetime */ diff --git a/core/net/rpl/rpl-ns.h b/core/net/rpl/rpl-ns.h index 8abc68df2..66f911f77 100644 --- a/core/net/rpl/rpl-ns.h +++ b/core/net/rpl/rpl-ns.h @@ -58,11 +58,11 @@ typedef struct rpl_ns_node { struct rpl_ns_node *parent; } rpl_ns_node_t; -int rpl_ns_num_nodes(); +int rpl_ns_num_nodes(void); void rpl_ns_expire_parent(rpl_dag_t *dag, const uip_ipaddr_t *child, const uip_ipaddr_t *parent); rpl_ns_node_t *rpl_ns_update_node(rpl_dag_t *dag, const uip_ipaddr_t *child, const uip_ipaddr_t *parent, uint32_t lifetime); -void rpl_ns_init(); -rpl_ns_node_t *rpl_ns_node_head(); +void rpl_ns_init(void); +rpl_ns_node_t *rpl_ns_node_head(void); rpl_ns_node_t *rpl_ns_node_next(rpl_ns_node_t *item); rpl_ns_node_t *rpl_ns_get_node(const rpl_dag_t *dag, const uip_ipaddr_t *addr); int rpl_ns_is_node_reachable(const rpl_dag_t *dag, const uip_ipaddr_t *addr); From 819916668e277aef5438780d5d8915e9d0ee9884 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 8 Jun 2016 14:09:43 +0200 Subject: [PATCH 334/374] Incorporate latest changes on rpl tests to 23-rpl-non-storing --- regression-tests/23-rpl-non-storing/01-rpl-up-route.csc | 4 ++-- regression-tests/23-rpl-non-storing/02-rpl-root-reboot.csc | 4 ++-- regression-tests/23-rpl-non-storing/03-rpl-28-hours.csc | 4 ++-- regression-tests/23-rpl-non-storing/04-rpl-large-network.csc | 4 ++-- .../23-rpl-non-storing/05-rpl-up-and-down-routes.csc | 4 ++-- .../23-rpl-non-storing/06-rpl-temporary-root-loss.csc | 4 ++-- .../23-rpl-non-storing/08-rpl-dao-route-loss-0.csc | 4 ++-- .../23-rpl-non-storing/08-rpl-dao-route-loss-1.csc | 4 ++-- .../23-rpl-non-storing/08-rpl-dao-route-loss-2.csc | 4 ++-- .../23-rpl-non-storing/08-rpl-dao-route-loss-3.csc | 4 ++-- .../23-rpl-non-storing/08-rpl-dao-route-loss-4.csc | 4 ++-- .../23-rpl-non-storing/08-rpl-dao-route-loss-5.csc | 4 ++-- regression-tests/23-rpl-non-storing/09-rpl-probing.csc | 4 ++-- regression-tests/23-rpl-non-storing/10-rpl-multi-dodag.csc | 4 ++-- regression-tests/23-rpl-non-storing/code/receiver-node.c | 2 +- regression-tests/23-rpl-non-storing/code/root-node.c | 4 ++-- regression-tests/23-rpl-non-storing/code/sender-node.c | 4 ++-- 17 files changed, 33 insertions(+), 33 deletions(-) diff --git a/regression-tests/23-rpl-non-storing/01-rpl-up-route.csc b/regression-tests/23-rpl-non-storing/01-rpl-up-route.csc index fc79cfc27..da4743d44 100644 --- a/regression-tests/23-rpl-non-storing/01-rpl-up-route.csc +++ b/regression-tests/23-rpl-non-storing/01-rpl-up-route.csc @@ -323,11 +323,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/23-rpl-non-storing/02-rpl-root-reboot.csc b/regression-tests/23-rpl-non-storing/02-rpl-root-reboot.csc index 14f87c7a9..6c4ce9d28 100644 --- a/regression-tests/23-rpl-non-storing/02-rpl-root-reboot.csc +++ b/regression-tests/23-rpl-non-storing/02-rpl-root-reboot.csc @@ -323,11 +323,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/23-rpl-non-storing/03-rpl-28-hours.csc b/regression-tests/23-rpl-non-storing/03-rpl-28-hours.csc index 1cf2c5e43..3ebc7adda 100644 --- a/regression-tests/23-rpl-non-storing/03-rpl-28-hours.csc +++ b/regression-tests/23-rpl-non-storing/03-rpl-28-hours.csc @@ -272,11 +272,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/23-rpl-non-storing/04-rpl-large-network.csc b/regression-tests/23-rpl-non-storing/04-rpl-large-network.csc index e40b7a339..f4ea0fda8 100644 --- a/regression-tests/23-rpl-non-storing/04-rpl-large-network.csc +++ b/regression-tests/23-rpl-non-storing/04-rpl-large-network.csc @@ -7038,11 +7038,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/23-rpl-non-storing/05-rpl-up-and-down-routes.csc b/regression-tests/23-rpl-non-storing/05-rpl-up-and-down-routes.csc index c2b3cb506..0dd110738 100644 --- a/regression-tests/23-rpl-non-storing/05-rpl-up-and-down-routes.csc +++ b/regression-tests/23-rpl-non-storing/05-rpl-up-and-down-routes.csc @@ -321,11 +321,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/23-rpl-non-storing/06-rpl-temporary-root-loss.csc b/regression-tests/23-rpl-non-storing/06-rpl-temporary-root-loss.csc index 6b5c91e54..6c29c643f 100644 --- a/regression-tests/23-rpl-non-storing/06-rpl-temporary-root-loss.csc +++ b/regression-tests/23-rpl-non-storing/06-rpl-temporary-root-loss.csc @@ -327,11 +327,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-0.csc b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-0.csc index b5aeac9b2..0fc6e032d 100644 --- a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-0.csc +++ b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-0.csc @@ -339,11 +339,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-1.csc b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-1.csc index d17bc193c..2c0ce41ff 100644 --- a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-1.csc +++ b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-1.csc @@ -339,11 +339,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-2.csc b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-2.csc index fe3db3dc3..cdb2bd748 100644 --- a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-2.csc +++ b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-2.csc @@ -339,11 +339,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-3.csc b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-3.csc index 7ee838b2c..34b930c0d 100644 --- a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-3.csc +++ b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-3.csc @@ -339,11 +339,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-4.csc b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-4.csc index 35c5bd753..ff9a400c1 100644 --- a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-4.csc +++ b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-4.csc @@ -339,11 +339,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-5.csc b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-5.csc index 4dc5038bc..e491b666f 100644 --- a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-5.csc +++ b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-5.csc @@ -339,11 +339,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/23-rpl-non-storing/09-rpl-probing.csc b/regression-tests/23-rpl-non-storing/09-rpl-probing.csc index 5206f1cfd..66a156e9c 100644 --- a/regression-tests/23-rpl-non-storing/09-rpl-probing.csc +++ b/regression-tests/23-rpl-non-storing/09-rpl-probing.csc @@ -234,12 +234,12 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } lastMsgHops = hops; - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/23-rpl-non-storing/10-rpl-multi-dodag.csc b/regression-tests/23-rpl-non-storing/10-rpl-multi-dodag.csc index fa015e8d9..0f446cc65 100644 --- a/regression-tests/23-rpl-non-storing/10-rpl-multi-dodag.csc +++ b/regression-tests/23-rpl-non-storing/10-rpl-multi-dodag.csc @@ -368,11 +368,11 @@ while(true) { lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { - packets = packets.substr(0, lastMsg + i + 1) + "_"; + packets = packets.substr(0, lastMsg + i + 1).concat("_"); } } } - packets = packets.substr(0, num) + "*"; + packets = packets.substr(0, num).concat("*"); log.log("" + hops + " " + packets + "\n"); lastMsg = num; } diff --git a/regression-tests/23-rpl-non-storing/code/receiver-node.c b/regression-tests/23-rpl-non-storing/code/receiver-node.c index 4ba3cb148..727a23f84 100644 --- a/regression-tests/23-rpl-non-storing/code/receiver-node.c +++ b/regression-tests/23-rpl-non-storing/code/receiver-node.c @@ -73,7 +73,7 @@ set_global_address(void) int i; uint8_t state; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); diff --git a/regression-tests/23-rpl-non-storing/code/root-node.c b/regression-tests/23-rpl-non-storing/code/root-node.c index 0609e1bd8..fdea828f8 100644 --- a/regression-tests/23-rpl-non-storing/code/root-node.c +++ b/regression-tests/23-rpl-non-storing/code/root-node.c @@ -77,7 +77,7 @@ set_global_address(void) int i; uint8_t state; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); @@ -106,7 +106,7 @@ create_rpl_dag(uip_ipaddr_t *ipaddr) rpl_set_root(RPL_DEFAULT_INSTANCE, ipaddr); dag = rpl_get_any_dag(); - uip_ip6addr(&prefix, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&prefix, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); rpl_set_prefix(dag, &prefix, 64); PRINTF("created a new RPL dag\n"); } else { diff --git a/regression-tests/23-rpl-non-storing/code/sender-node.c b/regression-tests/23-rpl-non-storing/code/sender-node.c index 08d81b62d..55dfdd15f 100644 --- a/regression-tests/23-rpl-non-storing/code/sender-node.c +++ b/regression-tests/23-rpl-non-storing/code/sender-node.c @@ -72,7 +72,7 @@ set_global_address(void) int i; uint8_t state; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); @@ -109,7 +109,7 @@ PROCESS_THREAD(sender_node_process, ev, data) PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&send_timer)); - uip_ip6addr(&addr, 0xaaaa, 0, 0, 0, 0x0201, 0x001, 0x001, 0x001); + uip_ip6addr(&addr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0x0201, 0x001, 0x001, 0x001); { static unsigned int message_number; From 535ff25da2a38fcc63b8e4513c5ec09e492b5c36 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 8 Jun 2016 14:14:03 +0200 Subject: [PATCH 335/374] RPL non-storing defensive link update: make sure the topology is loop-free at all times --- core/net/rpl/rpl-ns.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/core/net/rpl/rpl-ns.c b/core/net/rpl/rpl-ns.c index 221abefc3..68969cef4 100644 --- a/core/net/rpl/rpl-ns.c +++ b/core/net/rpl/rpl-ns.c @@ -122,6 +122,7 @@ rpl_ns_update_node(rpl_dag_t *dag, const uip_ipaddr_t *child, const uip_ipaddr_t { rpl_ns_node_t *child_node = rpl_ns_get_node(dag, child); rpl_ns_node_t *parent_node = rpl_ns_get_node(dag, parent); + rpl_ns_node_t *old_parent_node; if(parent != NULL) { /* No node for the parent, add one with infinite lifetime */ @@ -140,6 +141,7 @@ rpl_ns_update_node(rpl_dag_t *dag, const uip_ipaddr_t *child, const uip_ipaddr_t if(child_node == NULL) { return NULL; } + child_node->parent = NULL; list_add(nodelist, child_node); num_nodes++; } @@ -147,9 +149,24 @@ rpl_ns_update_node(rpl_dag_t *dag, const uip_ipaddr_t *child, const uip_ipaddr_t /* Initialize node */ child_node->dag = dag; child_node->lifetime = lifetime; - child_node->parent = parent_node; memcpy(child_node->link_identifier, ((const unsigned char *)child) + 8, 8); + /* Is the node reachable before the update? */ + if(rpl_ns_is_node_reachable(dag, child)) { + old_parent_node = child_node->parent; + /* Update node */ + child_node->parent = parent_node; + /* Has the node become unreachable? May happen if we create a loop. */ + if(!rpl_ns_is_node_reachable(dag, child)) { + /* The new parent makes the node unreachable, restore old parent. + * We will take the update next time, with chances we know more of + * the topology and the loop is gone. */ + child_node->parent = old_parent_node; + } + } else { + child_node->parent = parent_node; + } + return child_node; } /*---------------------------------------------------------------------------*/ From 27cceda1e87a75b4bfa9fff471f649c2538663af Mon Sep 17 00:00:00 2001 From: Tommy Sparber Date: Mon, 30 May 2016 10:30:43 +0200 Subject: [PATCH 336/374] rpl-ext-header: Use 8-octet unit for HBHO length According to RFC 2460 the length field of the Hop-by-Hop options header should use a 8-octet unit (multiple of 8 byte). In a normal configuration the RPL_HOP_BY_HOP_LEN define is 8, so the current implementation works, but if RPL_HOP_BY_HOP_LEN is a multiple of 8 the length is not calculated correctly. --- core/net/rpl/rpl-ext-header.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/net/rpl/rpl-ext-header.c b/core/net/rpl/rpl-ext-header.c index 41da2149e..b6d17d4a9 100644 --- a/core/net/rpl/rpl-ext-header.c +++ b/core/net/rpl/rpl-ext-header.c @@ -78,7 +78,7 @@ rpl_verify_hbh_header(int uip_ext_opt_offset) uip_ds6_route_t *route; rpl_parent_t *sender = NULL; - if(UIP_HBHO_BUF->len != RPL_HOP_BY_HOP_LEN - 8) { + if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)) { PRINTF("RPL: Hop-by-hop extension header has wrong size\n"); return 1; } @@ -492,7 +492,7 @@ update_hbh_header(void) switch(UIP_IP_BUF->proto) { case UIP_PROTO_HBHO: - if(UIP_HBHO_BUF->len != RPL_HOP_BY_HOP_LEN - 8) { + if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)) { PRINTF("RPL: Hop-by-hop extension header has wrong size\n"); uip_ext_len = last_uip_ext_len; return 1; @@ -604,7 +604,7 @@ insert_hbh_header(void) UIP_EXT_HDR_OPT_RPL_BUF->senderrank = 0; uip_len += RPL_HOP_BY_HOP_LEN; temp_len = UIP_IP_BUF->len[1]; - UIP_IP_BUF->len[1] += UIP_HBHO_BUF->len + 8; + UIP_IP_BUF->len[1] += RPL_HOP_BY_HOP_LEN; if(UIP_IP_BUF->len[1] < temp_len) { UIP_IP_BUF->len[0]++; } @@ -625,7 +625,7 @@ rpl_finalize_header(uip_ipaddr_t *addr) uip_ext_opt_offset = 2; if(UIP_IP_BUF->proto == UIP_PROTO_HBHO) { - if(UIP_HBHO_BUF->len != RPL_HOP_BY_HOP_LEN - 8) { + if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)) { PRINTF("RPL: Non RPL Hop-by-hop options support not implemented\n"); uip_ext_len = last_uip_ext_len; return 1; From 092f0e62fe28e51e2d32ecc1a82deb7002bf0202 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Thu, 9 Jun 2016 15:53:25 +0200 Subject: [PATCH 337/374] Added generic relay driver for the zoul-based platforms --- examples/zolertia/zoul/Makefile | 2 +- examples/zolertia/zoul/test-relay.c | 89 ++++++++++++++++++++ platform/zoul/dev/relay.c | 124 ++++++++++++++++++++++++++++ platform/zoul/dev/relay.h | 92 +++++++++++++++++++++ 4 files changed, 306 insertions(+), 1 deletion(-) create mode 100644 examples/zolertia/zoul/test-relay.c create mode 100644 platform/zoul/dev/relay.c create mode 100644 platform/zoul/dev/relay.h diff --git a/examples/zolertia/zoul/Makefile b/examples/zolertia/zoul/Makefile index 2b70773d9..ddd89f4ca 100644 --- a/examples/zolertia/zoul/Makefile +++ b/examples/zolertia/zoul/Makefile @@ -9,7 +9,7 @@ CONTIKI_PROJECT += test-zonik CONTIKI_TARGET_SOURCEFILES += tsl2563.c sht25.c bmpx8x.c motion-sensor.c CONTIKI_TARGET_SOURCEFILES += adc-sensors.c weather-meter.c grove-gyro.c -CONTIKI_TARGET_SOURCEFILES += rgb-bl-lcd.c pm10-sensor.c iaq.c zonik.c +CONTIKI_TARGET_SOURCEFILES += rgb-bl-lcd.c pm10-sensor.c iaq.c zonik.c relay.c all: $(CONTIKI_PROJECT) diff --git a/examples/zolertia/zoul/test-relay.c b/examples/zolertia/zoul/test-relay.c new file mode 100644 index 000000000..cd743919d --- /dev/null +++ b/examples/zolertia/zoul/test-relay.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2016, Zolertia + * 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. + * + */ +/** + * \addtogroup zoul-examples + * @{ + * + * \defgroup zoul-relay-test A simple program to test a generic relay + * + * Demonstrates the use of a generic relay, connected by default at the ADC1 + * connector of the RE-Mote + * + * @{ + * + * \file + * A quick program to test a generic relay + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/relay.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +PROCESS(remote_relay_process, "Generic relay test"); +AUTOSTART_PROCESSES(&remote_relay_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(remote_relay_process, ev, data) +{ + PROCESS_BEGIN(); + SENSORS_ACTIVATE(relay); + + /* Activate the relay and wait for 5 seconds */ + relay.value(RELAY_ON); + etimer_set(&et, CLOCK_SECOND * 5); + printf("\nRelay: switch should be ON --> %u\n", relay.status(SENSORS_ACTIVE)); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + /* Now turn off and wait 5 seconds more */ + relay.value(RELAY_OFF); + etimer_set(&et, CLOCK_SECOND * 5); + printf("Relay: switch should be OFF --> %u\n\n", relay.status(SENSORS_ACTIVE)); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + /* Let it spin and toggle each second */ + while(1) { + etimer_set(&et, CLOCK_SECOND); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + relay.value(RELAY_TOGGLE); + printf("Relay: switch is now --> %u\n", relay.status(SENSORS_ACTIVE)); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/zoul/dev/relay.c b/platform/zoul/dev/relay.c new file mode 100644 index 000000000..aa4f88dd5 --- /dev/null +++ b/platform/zoul/dev/relay.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-relay + * @{ + * + * \file + * Driver for a relay actuator + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "relay.h" +#include "dev/gpio.h" +#include "lib/sensors.h" +#include "dev/ioc.h" +/*---------------------------------------------------------------------------*/ +#define RELAY_PORT_BASE GPIO_PORT_TO_BASE(RELAY_PORT) +#define RELAY_PIN_MASK GPIO_PIN_MASK(RELAY_PIN) +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; +/*---------------------------------------------------------------------------*/ +static int +relay_on(void) +{ + if(enabled) { + GPIO_SET_PIN(RELAY_PORT_BASE, RELAY_PIN_MASK); + return RELAY_SUCCESS; + } + return RELAY_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +relay_off(void) +{ + if(enabled) { + GPIO_CLR_PIN(RELAY_PORT_BASE, RELAY_PIN_MASK); + return RELAY_SUCCESS; + } + return RELAY_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + return GPIO_READ_PIN(RELAY_PORT_BASE, RELAY_PIN_MASK); + case SENSORS_READY: + return enabled; + } + return RELAY_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + switch(type) { + case RELAY_OFF: + return relay_on(); + case RELAY_ON: + return relay_off(); + case RELAY_TOGGLE: + if(status(SENSORS_ACTIVE)) { + return relay_off(); + } else { + return relay_on(); + } + default: + return RELAY_ERROR; + } +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type != SENSORS_ACTIVE) { + return RELAY_ERROR; + } + + if(value) { + GPIO_SOFTWARE_CONTROL(RELAY_PORT_BASE, RELAY_PIN_MASK); + GPIO_SET_OUTPUT(RELAY_PORT_BASE, RELAY_PIN_MASK); + ioc_set_over(RELAY_PORT, RELAY_PIN, IOC_OVERRIDE_OE); + GPIO_CLR_PIN(RELAY_PORT_BASE, RELAY_PIN_MASK); + enabled = 1; + return RELAY_SUCCESS; + } + + GPIO_SET_INPUT(RELAY_PORT_BASE, RELAY_PIN_MASK); + enabled = 0; + return RELAY_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(relay, RELAY_ACTUATOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/zoul/dev/relay.h b/platform/zoul/dev/relay.h new file mode 100644 index 000000000..4123f9e99 --- /dev/null +++ b/platform/zoul/dev/relay.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-relay Generic relay driver + * + * Driver for a generic relay driver + * @{ + * + * \file + * Header file for the generic relay driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef RELAY_H_ +#define RELAY_H_ +/* -------------------------------------------------------------------------- */ +/** + * \name Relay default pin and port + * @{ + */ +#ifdef RELAY_CONF_PIN +#define RELAY_PIN RELAY_CONF_PIN +#else +#define RELAY_PIN 5 +#endif +#ifdef RELAY_CONF_PORT +#define RELAY_PORT RELAY_CONF_PORT +#else +#define RELAY_PORT GPIO_A_NUM +#endif +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Relay available commands + * @{ + */ +#define RELAY_OFF 0x00 +#define RELAY_ON 0x01 +#define RELAY_TOGGLE 0x02 +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Relay return types + * @{ + */ +#define RELAY_ERROR (-1) +#define RELAY_SUCCESS 0x00 +/** @} */ +/* -------------------------------------------------------------------------- */ +#define RELAY_ACTUATOR "Generic Relay" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor relay; +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ +#endif /* RELAY_H_ */ +/* -------------------------------------------------------------------------- */ +/** + * @} + * @} + */ From 0cb222e6e1faa99bc40889408841cd401d672044 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Mon, 25 Apr 2016 17:09:42 +0300 Subject: [PATCH 338/374] add 2-channel TSCH hopping sequence --- core/net/mac/tsch/tsch-conf.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/net/mac/tsch/tsch-conf.h b/core/net/mac/tsch/tsch-conf.h index 8e091a235..83fde5a71 100644 --- a/core/net/mac/tsch/tsch-conf.h +++ b/core/net/mac/tsch/tsch-conf.h @@ -53,6 +53,8 @@ #define TSCH_HOPPING_SEQUENCE_4_16 (uint8_t[]){ 20, 26, 25, 26, 15, 15, 25, 20, 26, 15, 26, 25, 20, 15, 20, 25 } /* 4 channels, sequence length 4 */ #define TSCH_HOPPING_SEQUENCE_4_4 (uint8_t[]){ 15, 25, 26, 20 } +/* 2 channels, sequence length 2 */ +#define TSCH_HOPPING_SEQUENCE_2_2 (uint8_t[]){ 20, 25 } /* 1 channel, sequence length 1 */ #define TSCH_HOPPING_SEQUENCE_1_1 (uint8_t[]){ 20 } From b3afd65b1dbc9feed793883b18fb2afab46eb4be Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Mon, 25 Apr 2016 17:13:46 +0300 Subject: [PATCH 339/374] fix a few comments in TSCH --- core/net/mac/tsch/tsch-conf.h | 2 +- core/net/mac/tsch/tsch-rpl.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/net/mac/tsch/tsch-conf.h b/core/net/mac/tsch/tsch-conf.h index 83fde5a71..ffd99dc98 100644 --- a/core/net/mac/tsch/tsch-conf.h +++ b/core/net/mac/tsch/tsch-conf.h @@ -122,7 +122,7 @@ #define TSCH_DEFAULT_TS_TIMESLOT_LENGTH 10000 #elif TSCH_CONF_DEFAULT_TIMESLOT_LENGTH == 15000 -/* Default timeslot timing for platfroms requiring 15ms slots */ +/* Default timeslot timing for platforms requiring 15ms slots */ #define TSCH_DEFAULT_TS_CCA_OFFSET 1800 #define TSCH_DEFAULT_TS_CCA 128 diff --git a/core/net/mac/tsch/tsch-rpl.c b/core/net/mac/tsch/tsch-rpl.c index 960f757f6..4558c4366 100644 --- a/core/net/mac/tsch/tsch-rpl.c +++ b/core/net/mac/tsch/tsch-rpl.c @@ -73,7 +73,7 @@ tsch_rpl_callback_leaving_network(void) } /*---------------------------------------------------------------------------*/ /* Set TSCH EB period based on current RPL DIO period. - * To use, set #define RPL_CALLBACK_PARENT_SWITCH tsch_rpl_callback_new_dio_interval */ + * To use, set #define RPL_CALLBACK_NEW_DIO_INTERVAL tsch_rpl_callback_new_dio_interval */ void tsch_rpl_callback_new_dio_interval(uint8_t dio_interval) { From 723c7e1117e7505145f3f69b362b03889e577f21 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Mon, 25 Apr 2016 17:15:10 +0300 Subject: [PATCH 340/374] print TSCH clock drift ppm whenever updated --- core/net/mac/tsch/tsch-adaptive-timesync.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/net/mac/tsch/tsch-adaptive-timesync.c b/core/net/mac/tsch/tsch-adaptive-timesync.c index 0b4601621..6677c690d 100644 --- a/core/net/mac/tsch/tsch-adaptive-timesync.c +++ b/core/net/mac/tsch/tsch-adaptive-timesync.c @@ -92,6 +92,10 @@ timesync_learn_drift_ticks(uint32_t time_delta_asn, int32_t drift_ticks) int32_t last_drift_ppm = (int32_t)((int64_t)real_drift_ticks * TSCH_DRIFT_UNIT / time_delta_ticks); drift_ppm = timesync_entry_add(last_drift_ppm, time_delta_ticks); + + TSCH_LOG_ADD(tsch_log_message, + snprintf(log->message, sizeof(log->message), + "drift %ld", drift_ppm / 256)); } /*---------------------------------------------------------------------------*/ /* Either reset or update the neighbor's drift */ From 45510f57fa817fce541b6fbadfefb42f3adecff0 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Mon, 25 Apr 2016 17:40:36 +0300 Subject: [PATCH 341/374] TSCH: add option to not to turn off radio during active TSCH timeslots --- core/net/mac/tsch/tsch-conf.h | 7 ++ core/net/mac/tsch/tsch-slot-operation.c | 152 ++++++++++++++++++------ 2 files changed, 125 insertions(+), 34 deletions(-) diff --git a/core/net/mac/tsch/tsch-conf.h b/core/net/mac/tsch/tsch-conf.h index ffd99dc98..631f47d03 100644 --- a/core/net/mac/tsch/tsch-conf.h +++ b/core/net/mac/tsch/tsch-conf.h @@ -184,4 +184,11 @@ #define TSCH_HW_FRAME_FILTERING 1 #endif /* TSCH_CONF_HW_FRAME_FILTERING */ +/* Keep radio always on within TSCH timeslot (1) or turn it off between packet and ACK? (0) */ +#ifdef TSCH_CONF_RADIO_ON_DURING_TIMESLOT +#define TSCH_RADIO_ON_DURING_TIMESLOT TSCH_CONF_RADIO_ON_DURING_TIMESLOT +#else +#define TSCH_RADIO_ON_DURING_TIMESLOT 0 +#endif + #endif /* __TSCH_CONF_H__ */ diff --git a/core/net/mac/tsch/tsch-slot-operation.c b/core/net/mac/tsch/tsch-slot-operation.c index 5f0701895..54f1b7e65 100644 --- a/core/net/mac/tsch/tsch-slot-operation.c +++ b/core/net/mac/tsch/tsch-slot-operation.c @@ -36,6 +36,7 @@ * \author * Simon Duquennoy * Beshr Al Nahas + * Atis Elsts * */ @@ -109,6 +110,18 @@ #define RTIMER_GUARD 2u #endif +enum tsch_radio_state_on_cmd { + TSCH_RADIO_CMD_ON_START_OF_TIMESLOT, + TSCH_RADIO_CMD_ON_WITHIN_TIMESLOT, + TSCH_RADIO_CMD_ON_FORCE, +}; + +enum tsch_radio_state_off_cmd { + TSCH_RADIO_CMD_OFF_END_OF_TIMESLOT, + TSCH_RADIO_CMD_OFF_WITHIN_TIMESLOT, + TSCH_RADIO_CMD_OFF_FORCE, +}; + /* A ringbuf storing outgoing packets after they were dequeued. * Will be processed layer by tsch_tx_process_pending */ struct ringbufindex dequeued_ringbuf; @@ -370,6 +383,68 @@ update_neighbor_state(struct tsch_neighbor *n, struct tsch_packet *p, return in_queue; } /*---------------------------------------------------------------------------*/ +/** + * This function turns on the radio. Its semantics is dependent on + * the value of TSCH_RADIO_ON_DURING_TIMESLOT constant: + * - if enabled, the radio is turned on at the start of the slot + * - if disabled, the radio is turned on within the slot, + * directly before the packet Rx guard time and ACK Rx guard time. + */ +static void +tsch_radio_on(enum tsch_radio_state_on_cmd command) +{ + int do_it = 0; + switch(command) { + case TSCH_RADIO_CMD_ON_START_OF_TIMESLOT: + if(TSCH_RADIO_ON_DURING_TIMESLOT) { + do_it = 1; + } + break; + case TSCH_RADIO_CMD_ON_WITHIN_TIMESLOT: + if(!TSCH_RADIO_ON_DURING_TIMESLOT) { + do_it = 1; + } + break; + case TSCH_RADIO_CMD_ON_FORCE: + do_it = 1; + break; + } + if(do_it) { + NETSTACK_RADIO.on(); + } +} +/*---------------------------------------------------------------------------*/ +/** + * This function turns off the radio. In the same way as for tsch_radio_on(), + * it depends on the value of TSCH_RADIO_ON_DURING_TIMESLOT constant: + * - if enabled, the radio is turned off at the end of the slot + * - if disabled, the radio is turned off within the slot, + * directly after Tx'ing or Rx'ing a packet or Tx'ing an ACK. + */ +static void +tsch_radio_off(enum tsch_radio_state_off_cmd command) +{ + int do_it = 0; + switch(command) { + case TSCH_RADIO_CMD_OFF_END_OF_TIMESLOT: + if(TSCH_RADIO_ON_DURING_TIMESLOT) { + do_it = 1; + } + break; + case TSCH_RADIO_CMD_OFF_WITHIN_TIMESLOT: + if(!TSCH_RADIO_ON_DURING_TIMESLOT) { + do_it = 1; + } + break; + case TSCH_RADIO_CMD_OFF_FORCE: + do_it = 1; + break; + } + if(do_it) { + NETSTACK_RADIO.off(); + } +} +/*---------------------------------------------------------------------------*/ static PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) { @@ -456,7 +531,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) /* delay before CCA */ TSCH_SCHEDULE_AND_YIELD(pt, t, current_slot_start, TS_CCA_OFFSET, "cca"); TSCH_DEBUG_TX_EVENT(); - NETSTACK_RADIO.on(); + tsch_radio_on(TSCH_RADIO_CMD_ON_WITHIN_TIMESLOT); /* CCA */ BUSYWAIT_UNTIL_ABS(!(cca_status |= NETSTACK_RADIO.channel_clear()), current_slot_start, TS_CCA_OFFSET + TS_CCA); @@ -480,7 +555,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) /* limit tx_time to its max value */ tx_duration = MIN(tx_duration, tsch_timing[tsch_ts_max_tx]); /* turn tadio off -- will turn on again to wait for ACK if needed */ - NETSTACK_RADIO.off(); + tsch_radio_off(TSCH_RADIO_CMD_OFF_WITHIN_TIMESLOT); if(mac_tx_status == RADIO_TX_OK) { if(!is_broadcast) { @@ -502,7 +577,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) TSCH_SCHEDULE_AND_YIELD(pt, t, current_slot_start, tsch_timing[tsch_ts_tx_offset] + tx_duration + tsch_timing[tsch_ts_rx_ack_delay] - RADIO_DELAY_BEFORE_RX, "TxBeforeAck"); TSCH_DEBUG_TX_EVENT(); - NETSTACK_RADIO.on(); + tsch_radio_on(TSCH_RADIO_CMD_ON_WITHIN_TIMESLOT); /* Wait for ACK to come */ BUSYWAIT_UNTIL_ABS(NETSTACK_RADIO.receiving_packet(), tx_start_time, tx_duration + tsch_timing[tsch_ts_rx_ack_delay] + tsch_timing[tsch_ts_ack_wait]); @@ -514,7 +589,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) BUSYWAIT_UNTIL_ABS(!NETSTACK_RADIO.receiving_packet(), ack_start_time, tsch_timing[tsch_ts_max_ack]); TSCH_DEBUG_TX_EVENT(); - NETSTACK_RADIO.off(); + tsch_radio_off(TSCH_RADIO_CMD_OFF_WITHIN_TIMESLOT); #if TSCH_HW_FRAME_FILTERING /* Leaving promiscuous mode */ @@ -588,6 +663,8 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) } } + tsch_radio_off(TSCH_RADIO_CMD_OFF_END_OF_TIMESLOT); + current_packet->transmissions++; current_packet->ret = mac_tx_status; @@ -671,27 +748,26 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t)) TSCH_DEBUG_RX_EVENT(); /* Start radio for at least guard time */ - NETSTACK_RADIO.on(); - packet_seen = NETSTACK_RADIO.receiving_packet(); + tsch_radio_on(TSCH_RADIO_CMD_ON_WITHIN_TIMESLOT); + packet_seen = NETSTACK_RADIO.receiving_packet() || NETSTACK_RADIO.pending_packet(); if(!packet_seen) { /* Check if receiving within guard time */ BUSYWAIT_UNTIL_ABS((packet_seen = NETSTACK_RADIO.receiving_packet()), current_slot_start, tsch_timing[tsch_ts_rx_offset] + tsch_timing[tsch_ts_rx_wait]); } - if(packet_seen) { + if(!packet_seen) { + /* no packets on air */ + tsch_radio_off(TSCH_RADIO_CMD_OFF_FORCE); + } else { TSCH_DEBUG_RX_EVENT(); /* Save packet timestamp */ rx_start_time = RTIMER_NOW() - RADIO_DELAY_BEFORE_DETECT; - } - if(!NETSTACK_RADIO.receiving_packet() && !NETSTACK_RADIO.pending_packet()) { - NETSTACK_RADIO.off(); - /* no packets on air */ - } else { + /* Wait until packet is received, turn radio off */ BUSYWAIT_UNTIL_ABS(!NETSTACK_RADIO.receiving_packet(), current_slot_start, tsch_timing[tsch_ts_rx_offset] + tsch_timing[tsch_ts_rx_wait] + tsch_timing[tsch_ts_max_tx]); TSCH_DEBUG_RX_EVENT(); - NETSTACK_RADIO.off(); + tsch_radio_off(TSCH_RADIO_CMD_OFF_WITHIN_TIMESLOT); #if TSCH_RESYNC_WITH_SFD_TIMESTAMPS /* At the end of the reception, get an more accurate estimate of SFD arrival time */ @@ -784,7 +860,7 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t)) packet_duration + tsch_timing[tsch_ts_tx_ack_delay] - RADIO_DELAY_BEFORE_TX, "RxBeforeAck"); TSCH_DEBUG_RX_EVENT(); NETSTACK_RADIO.transmit(ack_len); - NETSTACK_RADIO.off(); + tsch_radio_off(TSCH_RADIO_CMD_OFF_WITHIN_TIMESLOT); } /* If the sender is a time source, proceed to clock drift compensation */ @@ -820,6 +896,8 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t)) process_poll(&tsch_pending_events_process); } } + + tsch_radio_off(TSCH_RADIO_CMD_OFF_END_OF_TIMESLOT); } if(input_queue_drop != 0) { @@ -860,8 +938,12 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr)) } else { uint8_t current_channel; + int is_active_slot; TSCH_DEBUG_SLOT_START(); tsch_in_slot_operation = 1; + /* Reset drift correction */ + drift_correction = 0; + is_drift_correction_used = 0; /* Get a packet ready to be sent */ current_packet = get_packet_and_neighbor_for_link(current_link, ¤t_neighbor); /* There is no packet to send, and this link does not have Rx flag. Instead of doing @@ -870,26 +952,28 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr)) current_link = backup_link; current_packet = get_packet_and_neighbor_for_link(current_link, ¤t_neighbor); } - /* Hop channel */ - current_channel = tsch_calculate_channel(¤t_asn, current_link->channel_offset); - NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, current_channel); - /* Reset drift correction */ - drift_correction = 0; - is_drift_correction_used = 0; - /* Decide whether it is a TX/RX/IDLE or OFF slot */ - /* Actual slot operation */ - if(current_packet != NULL) { - /* We have something to transmit, do the following: - * 1. send - * 2. update_backoff_state(current_neighbor) - * 3. post tx callback - **/ - static struct pt slot_tx_pt; - PT_SPAWN(&slot_operation_pt, &slot_tx_pt, tsch_tx_slot(&slot_tx_pt, t)); - } else if((current_link->link_options & LINK_OPTION_RX)) { - /* Listen */ - static struct pt slot_rx_pt; - PT_SPAWN(&slot_operation_pt, &slot_rx_pt, tsch_rx_slot(&slot_rx_pt, t)); + is_active_slot = current_packet != NULL || (current_link->link_options & LINK_OPTION_RX); + if(is_active_slot) { + /* Hop channel */ + current_channel = tsch_calculate_channel(¤t_asn, current_link->channel_offset); + NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, current_channel); + /* Turn the radio on already here if configured so; necessary for radios with slow startup */ + tsch_radio_on(TSCH_RADIO_CMD_ON_START_OF_TIMESLOT); + /* Decide whether it is a TX/RX/IDLE or OFF slot */ + /* Actual slot operation */ + if(current_packet != NULL) { + /* We have something to transmit, do the following: + * 1. send + * 2. update_backoff_state(current_neighbor) + * 3. post tx callback + **/ + static struct pt slot_tx_pt; + PT_SPAWN(&slot_operation_pt, &slot_tx_pt, tsch_tx_slot(&slot_tx_pt, t)); + } else { + /* Listen */ + static struct pt slot_rx_pt; + PT_SPAWN(&slot_operation_pt, &slot_rx_pt, tsch_rx_slot(&slot_rx_pt, t)); + } } TSCH_DEBUG_SLOT_END(); } From f6967c1f58abde06dd5e5d44d36e69c3041498c0 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Mon, 25 Apr 2016 17:41:56 +0300 Subject: [PATCH 342/374] read RADIO_PARAM_LAST_RSSI and RADIO_PARAM_LAST_PACKET_TIMESTAMP only after the last packet has been read in TSCH: reading the packet might update these values --- core/net/mac/tsch/tsch-slot-operation.c | 12 ++++++------ core/net/mac/tsch/tsch.c | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/net/mac/tsch/tsch-slot-operation.c b/core/net/mac/tsch/tsch-slot-operation.c index 54f1b7e65..9f51210a7 100644 --- a/core/net/mac/tsch/tsch-slot-operation.c +++ b/core/net/mac/tsch/tsch-slot-operation.c @@ -769,20 +769,15 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t)) TSCH_DEBUG_RX_EVENT(); tsch_radio_off(TSCH_RADIO_CMD_OFF_WITHIN_TIMESLOT); -#if TSCH_RESYNC_WITH_SFD_TIMESTAMPS - /* At the end of the reception, get an more accurate estimate of SFD arrival time */ - NETSTACK_RADIO.get_object(RADIO_PARAM_LAST_PACKET_TIMESTAMP, &rx_start_time, sizeof(rtimer_clock_t)); -#endif - if(NETSTACK_RADIO.pending_packet()) { static int frame_valid; static int header_len; static frame802154_t frame; radio_value_t radio_last_rssi; - NETSTACK_RADIO.get_value(RADIO_PARAM_LAST_RSSI, &radio_last_rssi); /* Read packet */ current_input->len = NETSTACK_RADIO.read((void *)current_input->payload, TSCH_PACKET_MAX_LEN); + NETSTACK_RADIO.get_value(RADIO_PARAM_LAST_RSSI, &radio_last_rssi); current_input->rx_asn = current_asn; current_input->rssi = (signed)radio_last_rssi; header_len = frame802154_parse((uint8_t *)current_input->payload, current_input->len, &frame); @@ -790,6 +785,11 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t)) frame802154_check_dest_panid(&frame) && frame802154_extract_linkaddr(&frame, &source_address, &destination_address); +#if TSCH_RESYNC_WITH_SFD_TIMESTAMPS + /* At the end of the reception, get an more accurate estimate of SFD arrival time */ + NETSTACK_RADIO.get_object(RADIO_PARAM_LAST_PACKET_TIMESTAMP, &rx_start_time, sizeof(rtimer_clock_t)); +#endif + packet_duration = TSCH_PACKET_DURATION(current_input->len); #if LLSEC802154_ENABLED diff --git a/core/net/mac/tsch/tsch.c b/core/net/mac/tsch/tsch.c index 2085f39ff..de6619dc5 100644 --- a/core/net/mac/tsch/tsch.c +++ b/core/net/mac/tsch/tsch.c @@ -649,12 +649,12 @@ PT_THREAD(tsch_scan(struct pt *pt)) } if(is_packet_pending) { - /* Save packet timestamp */ - NETSTACK_RADIO.get_object(RADIO_PARAM_LAST_PACKET_TIMESTAMP, &t0, sizeof(rtimer_clock_t)); - /* Read packet */ input_eb.len = NETSTACK_RADIO.read(input_eb.payload, TSCH_PACKET_MAX_LEN); + /* Save packet timestamp */ + NETSTACK_RADIO.get_object(RADIO_PARAM_LAST_PACKET_TIMESTAMP, &t0, sizeof(rtimer_clock_t)); + /* Parse EB and attempt to associate */ PRINTF("TSCH: association: received packet (%u bytes) on channel %u\n", input_eb.len, current_channel); From 03d511c2be6f59249b58436b2141ef29ab1dcf94 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Mon, 25 Apr 2016 17:47:38 +0300 Subject: [PATCH 343/374] tsch-slot-operation.c: use ABS() instead of abs() for consistency with the rest of Contiki --- core/net/mac/tsch/tsch-slot-operation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/net/mac/tsch/tsch-slot-operation.c b/core/net/mac/tsch/tsch-slot-operation.c index 9f51210a7..36c841ea4 100644 --- a/core/net/mac/tsch/tsch-slot-operation.c +++ b/core/net/mac/tsch/tsch-slot-operation.c @@ -821,7 +821,7 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t)) #if TSCH_TIMESYNC_REMOVE_JITTER /* remove jitter due to measurement errors */ - if(abs(estimated_drift) <= TSCH_TIMESYNC_MEASUREMENT_ERROR) { + if(ABS(estimated_drift) <= TSCH_TIMESYNC_MEASUREMENT_ERROR) { estimated_drift = 0; } else if(estimated_drift > 0) { estimated_drift -= TSCH_TIMESYNC_MEASUREMENT_ERROR; From b57009e56454ae8d74e2a6893f10eaefebc0ca7e Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Mon, 6 Jun 2016 23:11:34 +0300 Subject: [PATCH 344/374] TSCH: fix signedness in adaptive timesync --- core/net/mac/tsch/tsch-adaptive-timesync.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/net/mac/tsch/tsch-adaptive-timesync.c b/core/net/mac/tsch/tsch-adaptive-timesync.c index 6677c690d..08d4df2ee 100644 --- a/core/net/mac/tsch/tsch-adaptive-timesync.c +++ b/core/net/mac/tsch/tsch-adaptive-timesync.c @@ -86,8 +86,8 @@ timesync_entry_add(int32_t val, uint32_t time_delta) static void timesync_learn_drift_ticks(uint32_t time_delta_asn, int32_t drift_ticks) { - /* should fit in 32-bit unsigned integer */ - uint32_t time_delta_ticks = time_delta_asn * tsch_timing[tsch_ts_timeslot_length]; + /* should fit in a 32-bit integer */ + int32_t time_delta_ticks = time_delta_asn * tsch_timing[tsch_ts_timeslot_length]; int32_t real_drift_ticks = drift_ticks + compensated_ticks; int32_t last_drift_ppm = (int32_t)((int64_t)real_drift_ticks * TSCH_DRIFT_UNIT / time_delta_ticks); From fbb66f9cd5fe15637d11f16c0eb4f6dbcb5b5213 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Mon, 6 Jun 2016 23:12:09 +0300 Subject: [PATCH 345/374] TSCH: allow to configure channel scanning duration during the join phase --- core/net/mac/tsch/tsch-conf.h | 7 +++++++ core/net/mac/tsch/tsch.c | 13 +++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/core/net/mac/tsch/tsch-conf.h b/core/net/mac/tsch/tsch-conf.h index 631f47d03..d8d58f0ff 100644 --- a/core/net/mac/tsch/tsch-conf.h +++ b/core/net/mac/tsch/tsch-conf.h @@ -191,4 +191,11 @@ #define TSCH_RADIO_ON_DURING_TIMESLOT 0 #endif +/* How long to scan each channel in the scanning phase */ +#ifdef TSCH_CONF_CHANNEL_SCAN_DURATION +#define TSCH_CHANNEL_SCAN_DURATION TSCH_CONF_CHANNEL_SCAN_DURATION +#else +#define TSCH_CHANNEL_SCAN_DURATION CLOCK_SECOND +#endif + #endif /* __TSCH_CONF_H__ */ diff --git a/core/net/mac/tsch/tsch.c b/core/net/mac/tsch/tsch.c index de6619dc5..292744ecc 100644 --- a/core/net/mac/tsch/tsch.c +++ b/core/net/mac/tsch/tsch.c @@ -609,24 +609,25 @@ PT_THREAD(tsch_scan(struct pt *pt)) static struct input_packet input_eb; static struct etimer scan_timer; + /* Time when we started scanning on current_channel */ + static clock_time_t current_channel_since; ASN_INIT(current_asn, 0, 0); etimer_set(&scan_timer, CLOCK_SECOND / TSCH_ASSOCIATION_POLL_FREQUENCY); + current_channel_since = clock_time(); while(!tsch_is_associated && !tsch_is_coordinator) { /* Hop to any channel offset */ - static int current_channel = 0; - /* Time when we started scanning on current_channel */ - static clock_time_t current_channel_since = 0; + static uint8_t current_channel = 0; /* We are not coordinator, try to associate */ rtimer_clock_t t0; int is_packet_pending = 0; - clock_time_t now_seconds = clock_seconds(); + clock_time_t now_time = clock_time(); /* Switch to a (new) channel for scanning */ - if(current_channel == 0 || now_seconds != current_channel_since) { + if(current_channel == 0 || now_time - current_channel_since > TSCH_CHANNEL_SCAN_DURATION) { /* Pick a channel at random in TSCH_JOIN_HOPPING_SEQUENCE */ uint8_t scan_channel = TSCH_JOIN_HOPPING_SEQUENCE[ random_rand() % sizeof(TSCH_JOIN_HOPPING_SEQUENCE)]; @@ -635,7 +636,7 @@ PT_THREAD(tsch_scan(struct pt *pt)) current_channel = scan_channel; PRINTF("TSCH: scanning on channel %u\n", scan_channel); } - current_channel_since = now_seconds; + current_channel_since = now_time; } /* Turn radio on and wait for EB */ From 5b728691adc7779d2746d40c219eb1962878fbb1 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Tue, 26 Apr 2016 16:40:56 +0300 Subject: [PATCH 346/374] TSCH: add missing include --- core/net/mac/tsch/tsch-queue.h | 1 + 1 file changed, 1 insertion(+) diff --git a/core/net/mac/tsch/tsch-queue.h b/core/net/mac/tsch/tsch-queue.h index c350ab063..676619a3a 100644 --- a/core/net/mac/tsch/tsch-queue.h +++ b/core/net/mac/tsch/tsch-queue.h @@ -39,6 +39,7 @@ #include "lib/ringbufindex.h" #include "net/linkaddr.h" #include "net/mac/tsch/tsch-schedule.h" +#include "net/mac/mac.h" /******** Configuration *******/ From f0fcff2d1a6dbe96011035e00cc6803c6fd9a036 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Fri, 10 Jun 2016 15:03:25 +0300 Subject: [PATCH 347/374] TSCH: declare `radio_rx_mode` only when HW timestamps are enabled to avoid warnings --- core/net/mac/tsch/tsch-slot-operation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/net/mac/tsch/tsch-slot-operation.c b/core/net/mac/tsch/tsch-slot-operation.c index 36c841ea4..be83da4ab 100644 --- a/core/net/mac/tsch/tsch-slot-operation.c +++ b/core/net/mac/tsch/tsch-slot-operation.c @@ -563,12 +563,12 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) int ack_len; rtimer_clock_t ack_start_time; int is_time_source; - radio_value_t radio_rx_mode; struct ieee802154_ies ack_ies; uint8_t ack_hdrlen; frame802154_t frame; #if TSCH_HW_FRAME_FILTERING + radio_value_t radio_rx_mode; /* Entering promiscuous mode so that the radio accepts the enhanced ACK */ NETSTACK_RADIO.get_value(RADIO_PARAM_RX_MODE, &radio_rx_mode); NETSTACK_RADIO.set_value(RADIO_PARAM_RX_MODE, radio_rx_mode & (~RADIO_RX_MODE_ADDRESS_FILTER)); From b3ea790449c7709b2334fee5ff9c976b9c101ff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Sat, 11 Jun 2016 22:56:58 +0200 Subject: [PATCH 348/374] cc2538: sys-ctrl: Provide last reset cause MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add functions providing the last reset cause, one as an integer (ID), and one as a string. Signed-off-by: Benoît Thébaudeau --- cpu/cc2538/dev/sys-ctrl.c | 20 ++++++++++++++++++++ cpu/cc2538/dev/sys-ctrl.h | 16 ++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/cpu/cc2538/dev/sys-ctrl.c b/cpu/cc2538/dev/sys-ctrl.c index c2e8777ad..92592b942 100644 --- a/cpu/cc2538/dev/sys-ctrl.c +++ b/cpu/cc2538/dev/sys-ctrl.c @@ -50,6 +50,26 @@ #define SYS_CTRL_OSCS SYS_CTRL_CLOCK_CTRL_OSC32K #endif /*---------------------------------------------------------------------------*/ +int +sys_ctrl_get_reset_cause(void) +{ + return (REG(SYS_CTRL_CLOCK_STA) & SYS_CTRL_CLOCK_STA_RST) >> + SYS_CTRL_CLOCK_STA_RST_S; +} +/*---------------------------------------------------------------------------*/ +const char * +sys_ctrl_get_reset_cause_str(void) +{ + static const char *reset_cause[] = { + "POR", + "External reset", + "WDT", + "CLD or software reset" + }; + + return reset_cause[sys_ctrl_get_reset_cause()]; +} +/*---------------------------------------------------------------------------*/ void sys_ctrl_init() { diff --git a/cpu/cc2538/dev/sys-ctrl.h b/cpu/cc2538/dev/sys-ctrl.h index 3fda071fe..22dece434 100644 --- a/cpu/cc2538/dev/sys-ctrl.h +++ b/cpu/cc2538/dev/sys-ctrl.h @@ -115,6 +115,11 @@ #define SYS_CTRL_CLOCK_STA_OSC32K_CALDIS 0x02000000 #define SYS_CTRL_CLOCK_STA_OSC32K 0x01000000 #define SYS_CTRL_CLOCK_STA_RST 0x00C00000 +#define SYS_CTRL_CLOCK_STA_RST_S 22 +#define SYS_CTRL_CLOCK_STA_RST_POR 0 +#define SYS_CTRL_CLOCK_STA_RST_EXT 1 +#define SYS_CTRL_CLOCK_STA_RST_WDT 2 +#define SYS_CTRL_CLOCK_STA_RST_CLD_SW 3 #define SYS_CTRL_CLOCK_STA_SOURCE_CHANGE 0x00100000 #define SYS_CTRL_CLOCK_STA_XOSC_STB 0x00080000 #define SYS_CTRL_CLOCK_STA_HSOSC_STB 0x00040000 @@ -302,6 +307,17 @@ /** \name SysCtrl functions * @{ */ + +/** \brief Gets the cause of the last reset + * \return A \c SYS_CTRL_CLOCK_STA_RST_x reset cause + */ +int sys_ctrl_get_reset_cause(void); + +/** \brief Gets a string describing the cause of the last reset + * \return Last reset cause as a string + */ +const char *sys_ctrl_get_reset_cause_str(void); + /** \brief Initialises the System Control Driver. The main purpose of this * function is to power up and select clocks and oscillators * \note This function depends on ioc_init() having been called beforehand. */ From b655d92aa4368ed4088d7a651acac54c842e453b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Sat, 11 Jun 2016 23:15:22 +0200 Subject: [PATCH 349/374] cc2538: Provide SoC information MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add functions providing the SoC revision, SRAM size, and enabled hardware features, as well as a function printing SoC information. Signed-off-by: Benoît Thébaudeau --- cpu/cc2538/Makefile.cc2538 | 2 +- cpu/cc2538/soc.c | 108 +++++++++++++++++++++++++++++++++++++ cpu/cc2538/soc.h | 87 ++++++++++++++++++++++++++++++ 3 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 cpu/cc2538/soc.c create mode 100644 cpu/cc2538/soc.h diff --git a/cpu/cc2538/Makefile.cc2538 b/cpu/cc2538/Makefile.cc2538 index f28a77d11..218f05200 100644 --- a/cpu/cc2538/Makefile.cc2538 +++ b/cpu/cc2538/Makefile.cc2538 @@ -51,7 +51,7 @@ CONTIKI_CPU_DIRS += ../arm/common/dbg-io CONTIKI_CPU_DIRS += ../cc253x/usb/common ../cc253x/usb/common/cdc-acm ### CPU-dependent source files -CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c uart.c watchdog.c +CONTIKI_CPU_SOURCEFILES += soc.c clock.c rtimer-arch.c uart.c watchdog.c CONTIKI_CPU_SOURCEFILES += nvic.c cpu.c sys-ctrl.c gpio.c ioc.c spi.c adc.c CONTIKI_CPU_SOURCEFILES += crypto.c aes.c ecb.c cbc.c ctr.c cbc-mac.c gcm.c CONTIKI_CPU_SOURCEFILES += ccm.c sha256.c diff --git a/cpu/cc2538/soc.c b/cpu/cc2538/soc.c new file mode 100644 index 000000000..58ebb3692 --- /dev/null +++ b/cpu/cc2538/soc.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2016, Benoît Thébaudeau + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/** + * \addtogroup cc2538-soc + * @{ + * + * \file + * Implementation of the cc2538 SoC driver + */ +#include "contiki-conf.h" +#include "dev/rom-util.h" +#include "dev/sys-ctrl.h" +#include "reg.h" +#include "soc.h" + +#include +#include +/*----------------------------------------------------------------------------*/ +#define DIECFG0 0x400d3014 +#define DIECFG0_SRAM_SIZE_OFS 7 +#define DIECFG0_SRAM_SIZE_SZ 3 +#define DIECFG0_SRAM_SIZE_MSK (((1 << DIECFG0_SRAM_SIZE_SZ) - 1) << \ + DIECFG0_SRAM_SIZE_OFS) +#define DIECFG2 0x400d301c +#define DIECFG2_DIE_REV_OFS 8 +#define DIECFG2_DIE_REV_SZ 8 +#define DIECFG2_DIE_REV_MSK (((1 << DIECFG2_DIE_REV_SZ) - 1) << \ + DIECFG2_DIE_REV_OFS) +#define DIECFG2_AES_EN 0x00000002 +#define DIECFG2_PKA_EN 0x00000001 +/*----------------------------------------------------------------------------*/ +uint8_t +soc_get_rev(void) +{ + uint8_t rev = (REG(DIECFG2) & DIECFG2_DIE_REV_MSK) >> DIECFG2_DIE_REV_OFS; + + /* PG1.0 is encoded as 0x00. */ + if(!(rev >> 4)) + rev += 0x10; + return rev; +} +/*----------------------------------------------------------------------------*/ +uint32_t +soc_get_sram_size(void) +{ + uint32_t size_code = (REG(DIECFG0) & DIECFG0_SRAM_SIZE_MSK) >> + DIECFG0_SRAM_SIZE_OFS; + + return size_code <= 1 ? (2 - size_code) << 13 : 32 << 10; +} +/*----------------------------------------------------------------------------*/ +uint32_t +soc_get_features(void) +{ + return REG(DIECFG2) & (DIECFG2_AES_EN | DIECFG2_PKA_EN); +} +/*----------------------------------------------------------------------------*/ +void +soc_print_info(void) +{ + uint8_t rev = soc_get_rev(); + uint32_t features = soc_get_features(); + + printf("CC2538: ID: 0x%04lx, rev.: PG%d.%d, Flash: %lu KiB, SRAM: %lu KiB, " + "AES/SHA: %u, ECC/RSA: %u\n" + "System clock: %lu Hz\n" + "I/O clock: %lu Hz\n" + "Reset cause: %s\n", + rom_util_get_chip_id(), + rev >> 4, rev & 0x0f, + rom_util_get_flash_size() >> 10, + soc_get_sram_size() >> 10, + !!(features & SOC_FEATURE_AES_SHA), + !!(features & SOC_FEATURE_ECC_RSA), + sys_ctrl_get_sys_clock(), + sys_ctrl_get_io_clock(), + sys_ctrl_get_reset_cause_str()); +} + +/** @} */ diff --git a/cpu/cc2538/soc.h b/cpu/cc2538/soc.h new file mode 100644 index 000000000..d8bf939de --- /dev/null +++ b/cpu/cc2538/soc.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2016, Benoît Thébaudeau + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ +/** + * \addtogroup cc2538 + * @{ + * + * \defgroup cc2538-soc cc2538 SoC + * + * Driver for the cc2538 SoC + * @{ + * + * \file + * Header file with macro and function declarations for the cc2538 SoC + */ +#ifndef SOC_H_ +#define SOC_H_ + +#include "contiki-conf.h" + +#include +/*----------------------------------------------------------------------------*/ +/** \name SoC features + * @{ + */ +#define SOC_FEATURE_AES_SHA 0x00000002 /**< Security HW AES/SHA */ +#define SOC_FEATURE_ECC_RSA 0x00000001 /**< Security HW ECC/RSA */ +/** @} */ +/*----------------------------------------------------------------------------*/ +/** \name SoC functions + * @{ + */ + +/** \brief Gets the SoC revision + * \return The SoC revision as a byte with nibbles representing the major and + * minor revisions + */ +uint8_t soc_get_rev(void); + +/** \brief Gets the SRAM size of the SoC + * \return The SRAM size in bytes + */ +uint32_t soc_get_sram_size(void); + +/** \brief Gets the hardware features of the SoC that are enabled + * \return The enabled hardware features as a bitmask of \c SOC_FEATURE_x values + */ +uint32_t soc_get_features(void); + +/** \brief Prints SoC information */ +void soc_print_info(void); + +/** @} */ + +#endif /* SOC_H_ */ + +/** + * @} + * @} + */ From 9845973971d13fd0ed9960614c5cf13500a2f4d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Sat, 11 Jun 2016 23:19:21 +0200 Subject: [PATCH 350/374] cc2538: Print SoC information upon startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If STARTUP_CONF_VERBOSE is enabled, print SoC information upon startup. Signed-off-by: Benoît Thébaudeau --- platform/cc2538dk/contiki-main.c | 4 ++++ platform/openmote-cc2538/contiki-main.c | 4 ++++ platform/zoul/contiki-main.c | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/platform/cc2538dk/contiki-main.c b/platform/cc2538dk/contiki-main.c index 8d55dc1d0..6534b103c 100644 --- a/platform/cc2538dk/contiki-main.c +++ b/platform/cc2538dk/contiki-main.c @@ -64,6 +64,7 @@ #include "net/ip/tcpip.h" #include "net/ip/uip.h" #include "net/mac/frame802154.h" +#include "soc.h" #include "cpu.h" #include "reg.h" #include "ieee-addr.h" @@ -185,6 +186,9 @@ main(void) PUTS(CONTIKI_VERSION_STRING); PUTS(BOARD_STRING); +#if STARTUP_CONF_VERBOSE + soc_print_info(); +#endif PRINTF(" Net: "); PRINTF("%s\n", NETSTACK_NETWORK.name); diff --git a/platform/openmote-cc2538/contiki-main.c b/platform/openmote-cc2538/contiki-main.c index 39736463e..580f84f56 100644 --- a/platform/openmote-cc2538/contiki-main.c +++ b/platform/openmote-cc2538/contiki-main.c @@ -67,6 +67,7 @@ #include "net/ip/tcpip.h" #include "net/ip/uip.h" #include "net/mac/frame802154.h" +#include "soc.h" #include "cpu.h" #include "reg.h" #include "ieee-addr.h" @@ -181,6 +182,9 @@ main(void) PUTS(CONTIKI_VERSION_STRING); PUTS(BOARD_STRING); +#if STARTUP_CONF_VERBOSE + soc_print_info(); +#endif random_init(0); diff --git a/platform/zoul/contiki-main.c b/platform/zoul/contiki-main.c index fc9ed91e9..0779681d0 100644 --- a/platform/zoul/contiki-main.c +++ b/platform/zoul/contiki-main.c @@ -65,6 +65,7 @@ #include "net/ip/tcpip.h" #include "net/ip/uip.h" #include "net/mac/frame802154.h" +#include "soc.h" #include "cpu.h" #include "reg.h" #include "ieee-addr.h" @@ -185,6 +186,9 @@ main(void) PUTS(CONTIKI_VERSION_STRING); PUTS(BOARD_STRING); +#if STARTUP_CONF_VERBOSE + soc_print_info(); +#endif /* Initialise the H/W RNG engine. */ random_init(0); From 373fda46f7b7a20462005299ea565cafffdcdce9 Mon Sep 17 00:00:00 2001 From: Sumankumar Panchal Date: Thu, 9 Jun 2016 20:17:00 +0530 Subject: [PATCH 351/374] TSCH port for Zolertia ReMote/Zoul. --- core/net/mac/tsch/README.md | 5 ++-- examples/ipv6/rpl-tsch/node.c | 46 ++++++++++++++++++++--------------- platform/zoul/contiki-conf.h | 8 ++++++ 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/core/net/mac/tsch/README.md b/core/net/mac/tsch/README.md index 021bdf346..ae8f7dcba 100644 --- a/core/net/mac/tsch/README.md +++ b/core/net/mac/tsch/README.md @@ -37,6 +37,7 @@ It has been tested on the following platforms: * Tmote Sky (`sky`, tested on hardware and in cooja) * Zolertia Z1 (`z1`, tested in cooja only) * CC2538DK (`cc2538dk`, tested on hardware) + * Zolertia Zoul (`zoul`, tested on hardware) This implementation was present at the ETSI Plugtest 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`. 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 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 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 diff --git a/examples/ipv6/rpl-tsch/node.c b/examples/ipv6/rpl-tsch/node.c index af0db8845..35852b608 100644 --- a/examples/ipv6/rpl-tsch/node.c +++ b/examples/ipv6/rpl-tsch/node.c @@ -71,7 +71,7 @@ print_network_status(void) uip_ds6_route_t *route; PRINTA("--- Network status ---\n"); - + /* Our IPv6 addresses */ PRINTA("- Server IPv6 addresses:\n"); for(i = 0; i < UIP_DS6_ADDR_NB; i++) { @@ -83,13 +83,13 @@ print_network_status(void) PRINTA("\n"); } } - + /* Our default route */ PRINTA("- Default route:\n"); default_route = uip_ds6_defrt_lookup(uip_ds6_defrt_choose()); if(default_route != NULL) { 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); } else { PRINTA("-- None\n"); @@ -104,9 +104,9 @@ print_network_status(void) PRINTA(" via "); uip_debug_ipaddr_print(uip_ds6_route_nexthop(route)); PRINTA(" (lifetime: %lu seconds)\n", (unsigned long)route->state.lifetime); - route = uip_ds6_route_next(route); + route = uip_ds6_route_next(route); } - + PRINTA("----------------------\n"); } /*---------------------------------------------------------------------------*/ @@ -134,16 +134,23 @@ PROCESS_THREAD(node_process, ev, data) PROCESS_BEGIN(); /* 3 possible roles: - * - role_6ln: simple node, will join any network, secured or not - * - role_6dr: DAG root, will advertise (unsecured) beacons - * - role_6dr_sec: DAG root, will advertise secured beacons - * */ + * - role_6ln: simple node, will join any network, secured or not + * - role_6dr: DAG root, will advertise (unsecured) beacons + * - role_6dr_sec: DAG root, will advertise secured beacons + * */ static int is_coordinator = 0; static enum { role_6ln, role_6dr, role_6dr_sec } node_role; node_role = role_6ln; - - /* Set node with ID == 1 as coordinator, convenient in Cooja. */ - if(node_id == 1) { + + /* Set node with MAC address c1:0c:00:00:00:00:01 as coordinator, + * 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) { node_role = role_6dr_sec; } else { @@ -152,6 +159,7 @@ PROCESS_THREAD(node_process, ev, data) } else { node_role = role_6ln; } +#endif #if CONFIG_VIA_BUTTON { @@ -162,8 +170,8 @@ PROCESS_THREAD(node_process, ev, data) while(!etimer_expired(&et)) { 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", - CONFIG_WAIT_TIME); + node_role == role_6ln ? "6ln" : (node_role == role_6dr) ? "6dr" : "6dr-sec", + CONFIG_WAIT_TIME); PROCESS_WAIT_EVENT_UNTIL(((ev == sensors_event) && (data == &button_sensor) && button_sensor.value(0) > 0) || etimer_expired(&et)); @@ -180,7 +188,7 @@ PROCESS_THREAD(node_process, ev, data) #endif /* CONFIG_VIA_BUTTON */ 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)); is_coordinator = node_role > role_6ln; @@ -192,19 +200,19 @@ PROCESS_THREAD(node_process, ev, data) } else { net_init(NULL); } - + #if WITH_ORCHESTRA orchestra_init(); #endif /* WITH_ORCHESTRA */ - + /* Print out routing tables every minute */ etimer_set(&et, CLOCK_SECOND * 60); - while(1) { + while(1) { print_network_status(); PROCESS_YIELD_UNTIL(etimer_expired(&et)); etimer_reset(&et); } - + PROCESS_END(); } /*---------------------------------------------------------------------------*/ diff --git a/platform/zoul/contiki-conf.h b/platform/zoul/contiki-conf.h index c28d789d3..59463f691 100644 --- a/platform/zoul/contiki-conf.h +++ b/platform/zoul/contiki-conf.h @@ -77,6 +77,14 @@ typedef uint32_t rtimer_clock_t; #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 * From 7853a7434bea7a12800e4e983e05f8bfc0146559 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Sun, 12 Jun 2016 11:32:12 +0200 Subject: [PATCH 352/374] fix for compilation with clang - issue reported by Olaf Bergmann --- core/net/rpl/rpl-timers.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/core/net/rpl/rpl-timers.c b/core/net/rpl/rpl-timers.c index 1a159e5bb..8149401b4 100644 --- a/core/net/rpl/rpl-timers.c +++ b/core/net/rpl/rpl-timers.c @@ -84,11 +84,13 @@ handle_periodic_timer(void *ptr) rpl_dag_t *dag = rpl_get_any_dag(); rpl_purge_dags(); - if(dag != NULL && RPL_IS_STORING(dag->instance)) { - rpl_purge_routes(); - } - if(dag != NULL && RPL_IS_NON_STORING(dag->instance)) { - rpl_ns_periodic(); + if(dag != NULL) { + if(RPL_IS_STORING(dag->instance)) { + rpl_purge_routes(); + } + if(RPL_IS_NON_STORING(dag->instance)) { + rpl_ns_periodic(); + } } rpl_recalculate_ranks(); From f99511f49427f0163131c7d576a558ac98a70363 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Tue, 7 Jun 2016 00:09:02 +0300 Subject: [PATCH 353/374] srf06-cc26xx: add default TSCH configuration for the platform --- platform/srf06-cc26xx/contiki-conf.h | 49 ++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/platform/srf06-cc26xx/contiki-conf.h b/platform/srf06-cc26xx/contiki-conf.h index 6e52b5c0c..62e807524 100644 --- a/platform/srf06-cc26xx/contiki-conf.h +++ b/platform/srf06-cc26xx/contiki-conf.h @@ -329,6 +329,55 @@ typedef uint32_t uip_stats_t; */ typedef uint32_t rtimer_clock_t; #define RTIMER_CLOCK_DIFF(a, b) ((int32_t)((a) - (b))) + +/* --------------------------------------------------------------------- */ +/* TSCH related defines */ + +/* Delay between GO signal and SFD */ +#define RADIO_DELAY_BEFORE_TX ((unsigned)US_TO_RTIMERTICKS(81)) +/* Delay between GO signal and start listening. + * This value is so small because the radio is constantly on within each timeslot. */ +#define RADIO_DELAY_BEFORE_RX ((unsigned)US_TO_RTIMERTICKS(15)) +/* Delay between the SFD finishes arriving and it is detected in software. + * Not important on this platform as it uses hardware timestamps for SFD */ +#define RADIO_DELAY_BEFORE_DETECT ((unsigned)US_TO_RTIMERTICKS(0)) + +/* Timer conversion; radio is running at 4 MHz */ +#define RADIO_TIMER_SECOND 4000000u +#if (RTIMER_SECOND % 256) || (RADIO_TIMER_SECOND % 256) +#error RADIO_TO_RTIMER macro must be fixed! +#endif +#define RADIO_TO_RTIMER(X) ((uint32_t)(((uint64_t)(X) * (RTIMER_SECOND / 256)) / (RADIO_TIMER_SECOND / 256))) +#define USEC_TO_RADIO(X) ((X) * 4) + +/* The PHY header (preamble + SFD, 4+1 bytes) duration is equivalent to 10 symbols */ +#define RADIO_IEEE_802154_PHY_HEADER_DURATION_USEC 160 + +/* Do not turn off TSCH within a timeslot: not enough time */ +#define TSCH_CONF_RADIO_ON_DURING_TIMESLOT 1 + +/* Disable TSCH frame filtering */ +#define TSCH_CONF_HW_FRAME_FILTERING 0 + +/* Disable turning off HF oscillator when radio is off; + enable this for TSCH, disable to save more energy. */ +#ifndef CC2650_FAST_RADIO_STARTUP +#define CC2650_FAST_RADIO_STARTUP 1 +#endif + +/* Use hardware timestamps */ +#ifndef TSCH_CONF_RESYNC_WITH_SFD_TIMESTAMPS +#define TSCH_CONF_RESYNC_WITH_SFD_TIMESTAMPS 1 +#define TSCH_CONF_TIMESYNC_REMOVE_JITTER 0 +#endif + +/* The drift compared to "true" 10ms slots. + Enable adaptive sync to enable compensation for this. */ +#define TSCH_CONF_BASE_DRIFT_PPM -977 + +/* 10 times per second */ +#define TSCH_CONF_ASSOCIATION_CHANNEL_SWITCH_FREQUENCY 10 + /** @} */ /*---------------------------------------------------------------------------*/ /* board.h assumes that basic configuration is done */ From 3ff8aa8ad84d3a25f97ed5b73dbdfccf2842126b Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Mon, 25 Apr 2016 18:00:19 +0300 Subject: [PATCH 354/374] srf06-cc26xx: add node_id variable --- platform/srf06-cc26xx/contiki-main.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/platform/srf06-cc26xx/contiki-main.c b/platform/srf06-cc26xx/contiki-main.c index 9e91cec5d..b3d64f24a 100644 --- a/platform/srf06-cc26xx/contiki-main.c +++ b/platform/srf06-cc26xx/contiki-main.c @@ -59,6 +59,7 @@ #include "uart.h" #include "sys/clock.h" #include "sys/rtimer.h" +#include "sys/node-id.h" #include "lib/sensors.h" #include "button-sensor.h" #include "dev/serial-line.h" @@ -68,6 +69,8 @@ #include /*---------------------------------------------------------------------------*/ +unsigned short node_id = 0; +/*---------------------------------------------------------------------------*/ /** \brief Board specific iniatialisation */ void board_init(void); /*---------------------------------------------------------------------------*/ @@ -123,6 +126,10 @@ set_rf_params(void) printf("%02x\n", linkaddr_node_addr.u8[i]); } #endif + + /* also set the global node id */ + node_id = short_addr; + printf(" Node ID: %d\n", node_id); } /*---------------------------------------------------------------------------*/ /** From ac6f8008fd8e4cf9c3802353de1c1ddebd6b7d63 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Mon, 25 Apr 2016 17:58:24 +0300 Subject: [PATCH 355/374] cc26xx: implement poll mode, hardware timestamps, and other minor changes in the IEEE radio driver --- cpu/cc26xx-cc13xx/rf-core/ieee-mode.c | 245 +++++++++++++++++++++----- cpu/cc26xx-cc13xx/rf-core/prop-mode.c | 6 +- cpu/cc26xx-cc13xx/rf-core/rf-core.c | 121 ++++++++++--- cpu/cc26xx-cc13xx/rf-core/rf-core.h | 28 ++- 4 files changed, 328 insertions(+), 72 deletions(-) diff --git a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c index f26d57939..9cc614433 100644 --- a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c +++ b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c @@ -51,6 +51,7 @@ #include "sys/energest.h" #include "sys/clock.h" #include "sys/rtimer.h" +#include "sys/ctimer.h" #include "sys/cc.h" #include "lpm.h" #include "ti-lib.h" @@ -102,6 +103,9 @@ #define IEEE_MODE_RSSI_THRESHOLD 0xA6 #endif /* IEEE_MODE_CONF_RSSI_THRESHOLD */ /*---------------------------------------------------------------------------*/ +#define STATUS_CRC_OK 0x80 +#define STATUS_CORRELATION 0x7f +/*---------------------------------------------------------------------------*/ /* Data entry status field constants */ #define DATA_ENTRY_STATUS_PENDING 0x00 /* Not in use by the Radio CPU */ #define DATA_ENTRY_STATUS_ACTIVE 0x01 /* Open for r/w by the radio CPU */ @@ -186,6 +190,35 @@ static const output_config_t output_power[] = { /* Default TX Power - position in output_power[] */ const output_config_t *tx_power_current = &output_power[0]; /*---------------------------------------------------------------------------*/ +static volatile int8_t last_rssi = 0; +static volatile uint8_t last_corr_lqi = 0; + +extern int32_t rat_offset; + +/*---------------------------------------------------------------------------*/ +/* SFD timestamp in RTIMER ticks */ +static volatile uint32_t last_packet_timestamp = 0; +/* SFD timestamp in RAT ticks (but 64 bits) */ +static uint64_t last_rat_timestamp64 = 0; + +/* For RAT overflow handling */ +static struct ctimer rat_overflow_timer; +static uint32_t rat_overflow_counter = 0; +static rtimer_clock_t last_rat_overflow = 0; + +/* RAT has 32-bit register, overflows once 18 minutes */ +#define RAT_RANGE 4294967296ull +/* approximate value */ +#define RAT_OVERFLOW_PERIOD_SECONDS (60 * 18) + +/* XXX: don't know what exactly is this, looks like the time to Tx 3 octets */ +#define TIMESTAMP_OFFSET -(USEC_TO_RADIO(32 * 3) - 1) /* -95.75 usec */ +/*---------------------------------------------------------------------------*/ +/* Are we currently in poll mode? */ +static uint8_t poll_mode = 0; + +static rfc_CMD_IEEE_MOD_FILT_t filter_cmd; +/*---------------------------------------------------------------------------*/ /* * Buffers used to send commands to the RF core (generic and IEEE commands). * Some of those buffers are re-usable, some are not. @@ -202,7 +235,7 @@ static uint8_t cmd_ieee_rx_buf[RF_CMD_BUFFER_SIZE] CC_ALIGN(4); #define DATA_ENTRY_LENSZ_BYTE 1 #define DATA_ENTRY_LENSZ_WORD 2 /* 2 bytes */ -#define RX_BUF_SIZE 140 +#define RX_BUF_SIZE 144 /* Four receive buffers entries with room for 1 IEEE802.15.4 frame in each */ static uint8_t rx_buf_0[RX_BUF_SIZE] CC_ALIGN(4); static uint8_t rx_buf_1[RX_BUF_SIZE] CC_ALIGN(4); @@ -544,7 +577,7 @@ init_rf_params(void) cmd->rxConfig.bAppendRssi = 1; cmd->rxConfig.bAppendCorrCrc = 1; cmd->rxConfig.bAppendSrcInd = 0; - cmd->rxConfig.bAppendTimestamp = 0; + cmd->rxConfig.bAppendTimestamp = 1; cmd->pRxQ = &rx_data_queue; cmd->pOutput = (rfc_ieeeRxOutput_t *)rf_stats; @@ -647,13 +680,14 @@ rx_off(void) if(RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf) == IEEE_DONE_STOPPED || RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf) == IEEE_DONE_ABORT) { /* Stopped gracefully */ - ENERGEST_OFF(ENERGEST_TYPE_LISTEN); ret = RF_CORE_CMD_OK; } else { PRINTF("RX off: BG status=0x%04x\n", RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf)); ret = RF_CORE_CMD_ERROR; } + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + return ret; } /*---------------------------------------------------------------------------*/ @@ -712,6 +746,55 @@ static const rf_core_primary_mode_t mode_ieee = { soft_on, }; /*---------------------------------------------------------------------------*/ +static void +check_rat_overflow(bool first_time) +{ + static uint32_t last_value; + uint32_t current_value; + uint8_t interrupts_enabled; + + interrupts_enabled = ti_lib_int_master_disable(); + if(first_time) { + last_value = HWREG(RFC_RAT_BASE + RATCNT); + } else { + current_value = HWREG(RFC_RAT_BASE + RATCNT); + if(current_value + RAT_RANGE / 4 < last_value) { + /* overflow detected */ + last_rat_overflow = RTIMER_NOW(); + rat_overflow_counter++; + } + last_value = current_value; + } + if(interrupts_enabled) { + ti_lib_int_master_enable(); + } +} +/*---------------------------------------------------------------------------*/ +static void +handle_rat_overflow(void *unused) +{ + uint8_t was_off = 0; + + if(!rf_is_on()) { + was_off = 1; + if(on() != RF_CORE_CMD_OK) { + PRINTF("overflow: on() failed\n"); + ctimer_set(&rat_overflow_timer, RAT_OVERFLOW_PERIOD_SECONDS * CLOCK_SECOND / 2, + handle_rat_overflow, NULL); + return; + } + } + + check_rat_overflow(false); + + if(was_off) { + off(); + } + + ctimer_set(&rat_overflow_timer, RAT_OVERFLOW_PERIOD_SECONDS * CLOCK_SECOND / 2, + handle_rat_overflow, NULL); +} +/*---------------------------------------------------------------------------*/ static int init(void) { @@ -745,6 +828,10 @@ init(void) rf_core_primary_mode_register(&mode_ieee); + check_rat_overflow(true); + ctimer_set(&rat_overflow_timer, RAT_OVERFLOW_PERIOD_SECONDS * CLOCK_SECOND / 2, + handle_rat_overflow, NULL); + process_start(&rf_core_process, NULL); return 1; } @@ -768,6 +855,7 @@ transmit(unsigned short transmit_len) uint8_t tx_active = 0; rtimer_clock_t t0; volatile rfc_CMD_IEEE_TX_t cmd; + uint8_t interrupts_enabled; if(!rf_is_on()) { was_off = 1; @@ -805,8 +893,19 @@ transmit(unsigned short transmit_len) cmd.payloadLen = transmit_len; cmd.pPayload = &tx_buf[TX_BUF_HDR_LEN]; + cmd.startTime = 0; + cmd.startTrigger.triggerType = TRIG_NOW; + + /* XXX: there seems to be no function that gets interrupt state w/o changing it */ + interrupts_enabled = ti_lib_int_master_disable(); + if(interrupts_enabled) { + ti_lib_int_master_enable(); + } + /* Enable the LAST_FG_COMMAND_DONE interrupt, which will wake us up */ - rf_core_cmd_done_en(true); + if(interrupts_enabled) { + rf_core_cmd_done_en(true, poll_mode); + } ret = rf_core_send_cmd((uint32_t)&cmd, &cmd_status); @@ -818,7 +917,14 @@ transmit(unsigned short transmit_len) /* Idle away while the command is running */ while((cmd.status & RF_CORE_RADIO_OP_MASKED_STATUS) == RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING) { - lpm_sleep(); + /* Note: for now sleeping while Tx'ing in polling mode is disabled. + * To enable it: + * 1) make the `lpm_sleep()` call here unconditional; + * 2) change the radio ISR priority to allow radio ISR to interrupt rtimer ISR. + */ + if(interrupts_enabled) { + lpm_sleep(); + } } stat = cmd.status; @@ -848,12 +954,13 @@ transmit(unsigned short transmit_len) ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); ENERGEST_ON(ENERGEST_TYPE_LISTEN); - /* - * Disable LAST_FG_COMMAND_DONE interrupt. We don't really care about it - * except when we are transmitting - */ - rf_core_cmd_done_dis(); - + if(interrupts_enabled) { + /* + * Disable LAST_FG_COMMAND_DONE interrupt. We don't really care about it + * except when we are transmitting + */ + rf_core_cmd_done_dis(poll_mode); + } if(was_off) { off(); @@ -880,13 +987,48 @@ release_data_entry(void) /* Set status to 0 "Pending" in element */ entry->status = DATA_ENTRY_STATUS_PENDING; rx_read_entry = entry->pNextEntry; -}/*---------------------------------------------------------------------------*/ +} +/*---------------------------------------------------------------------------*/ +static uint32_t +calc_last_packet_timestamp(uint32_t rat_timestamp) +{ + uint64_t rat_timestamp64; + uint32_t adjusted_overflow_counter = rat_overflow_counter; + + /* if the timestamp is large and the last oveflow was recently, + assume that the timestamp refers to the time before the overflow */ + if(rat_timestamp > (uint32_t)(RAT_RANGE * 3 / 4)) { + if(RTIMER_CLOCK_LT(RTIMER_NOW(), + last_rat_overflow + RAT_OVERFLOW_PERIOD_SECONDS * RTIMER_SECOND / 4)) { + adjusted_overflow_counter--; + } + } + + /* add the overflowed time to the timestamp */ + rat_timestamp64 = rat_timestamp + RAT_RANGE * adjusted_overflow_counter; + /* correct timestamp so that it refers to the end of the SFD */ + rat_timestamp64 += TIMESTAMP_OFFSET; + + last_rat_timestamp64 = rat_timestamp64 - rat_offset; + + return RADIO_TO_RTIMER(rat_timestamp64 - rat_offset); +} +/*---------------------------------------------------------------------------*/ static int read_frame(void *buf, unsigned short buf_len) { - int8_t rssi; int len = 0; rfc_dataEntryGeneral_t *entry = (rfc_dataEntryGeneral_t *)rx_read_entry; + uint32_t rat_timestamp; + + if(rf_is_on()) { + check_rat_overflow(false); + } + + /* wait for entry to become finished */ + rtimer_clock_t t0 = RTIMER_NOW(); + while(entry->status == DATA_ENTRY_STATUS_BUSY + && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (RTIMER_SECOND / 250))); if(entry->status != DATA_ENTRY_STATUS_FINISHED) { /* No available data */ @@ -901,7 +1043,7 @@ read_frame(void *buf, unsigned short buf_len) return 0; } - len = rx_read_entry[8] - 4; + len = rx_read_entry[8] - 8; if(len > buf_len) { PRINTF("RF: too long\n"); @@ -913,9 +1055,21 @@ read_frame(void *buf, unsigned short buf_len) memcpy(buf, (char *)&rx_read_entry[9], len); - rssi = (int8_t)rx_read_entry[9 + len + 2]; + last_rssi = (int8_t)rx_read_entry[9 + len + 2]; + last_corr_lqi = (uint8_t)rx_read_entry[9 + len + 2] & STATUS_CORRELATION; - packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi); + /* get the timestamp */ + memcpy(&rat_timestamp, (char *)rx_read_entry + 9 + len + 4, 4); + + last_packet_timestamp = calc_last_packet_timestamp(rat_timestamp); + + if(!poll_mode) { + /* Not in poll mode: packetbuf should not be accessed in interrupt context. + * In poll mode, the last packet RSSI and link quality can be obtained through + * RADIO_PARAM_LAST_RSSI and RADIO_PARAM_LAST_LINK_QUALITY */ + packetbuf_set_attr(PACKETBUF_ATTR_RSSI, last_rssi); + packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, last_corr_lqi); + } RIMESTATS_ADD(llrx); release_data_entry(); @@ -983,9 +1137,7 @@ channel_clear(void) static int receiving_packet(void) { - int ret = 0; uint8_t cca_info; - uint8_t was_off = 0; /* * If we are in the middle of a BLE operation, we got called by ContikiMAC @@ -1035,7 +1187,9 @@ pending_packet(void) do { if(entry->status == DATA_ENTRY_STATUS_FINISHED) { rv = 1; - process_poll(&rf_core_process); + if(!poll_mode) { + process_poll(&rf_core_process); + } } entry = (rfc_dataEntry_t *)entry->pNextEntry; @@ -1076,7 +1230,7 @@ on(void) init_rx_buffers(); - rf_core_setup_interrupts(); + rf_core_setup_interrupts(poll_mode); /* * Trigger a switch to the XOSC, so that we can subsequently use the RF FS @@ -1162,6 +1316,9 @@ get_value(radio_param_t param, radio_value_t *value) if(cmd->frameFiltOpt.autoAckEn) { *value |= RADIO_RX_MODE_AUTOACK; } + if(poll_mode) { + *value |= RADIO_RX_MODE_POLL_MODE; + } return RADIO_RESULT_OK; case RADIO_PARAM_TXPOWER: @@ -1222,6 +1379,7 @@ set_value(radio_param_t param, radio_value_t value) return RADIO_RESULT_INVALID_VALUE; } + /* Note: this return may lead to long periods when RAT and RTC are not resynchronized */ if(cmd->channel == (uint8_t)value) { /* We already have that very same channel configured. * Nothing to do here. */ @@ -1239,7 +1397,7 @@ set_value(radio_param_t param, radio_value_t value) case RADIO_PARAM_RX_MODE: { if(value & ~(RADIO_RX_MODE_ADDRESS_FILTER | - RADIO_RX_MODE_AUTOACK)) { + RADIO_RX_MODE_AUTOACK | RADIO_RX_MODE_POLL_MODE)) { return RADIO_RESULT_INVALID_VALUE; } @@ -1252,6 +1410,8 @@ set_value(radio_param_t param, radio_value_t value) cmd->frameFiltOpt.bPendDataReqOnly = 0; cmd->frameFiltOpt.bPanCoord = 0; cmd->frameFiltOpt.bStrictLenFilter = 0; + + poll_mode = (value & RADIO_RX_MODE_POLL_MODE) != 0; break; } case RADIO_PARAM_TXPOWER: @@ -1269,30 +1429,28 @@ set_value(radio_param_t param, radio_value_t value) return RADIO_RESULT_NOT_SUPPORTED; } - /* If we reach here we had no errors. Apply new settings */ + /* If off, the new configuration will be applied the next time radio is started */ if(!rf_is_on()) { - was_off = 1; - if(on() != RF_CORE_CMD_OK) { - PRINTF("set_value: on() failed (2)\n"); - return RADIO_RESULT_ERROR; - } + return RADIO_RESULT_OK; } + /* If we reach here we had no errors. Apply new settings */ if(rx_off() != RF_CORE_CMD_OK) { PRINTF("set_value: rx_off() failed\n"); rv = RADIO_RESULT_ERROR; } + /* Restart the radio timer (RAT). + This causes resynchronization between RAT and RTC: useful for TSCH. */ + rf_core_restart_rat(); + + check_rat_overflow(false); + if(rx_on() != RF_CORE_CMD_OK) { PRINTF("set_value: rx_on() failed\n"); rv = RADIO_RESULT_ERROR; } - /* If we were off, turn back off */ - if(was_off) { - off(); - } - return rv; } /*---------------------------------------------------------------------------*/ @@ -1318,13 +1476,22 @@ get_object(radio_param_t param, void *dest, size_t size) return RADIO_RESULT_OK; } + + if(param == RADIO_PARAM_LAST_PACKET_TIMESTAMP) { + if(size != sizeof(rtimer_clock_t) || !dest) { + return RADIO_RESULT_INVALID_VALUE; + } + *(rtimer_clock_t *)dest = last_packet_timestamp; + + return RADIO_RESULT_OK; + } + return RADIO_RESULT_NOT_SUPPORTED; } /*---------------------------------------------------------------------------*/ static radio_result_t set_object(radio_param_t param, const void *src, size_t size) { - uint8_t was_off = 0; radio_result_t rv; int i; uint8_t *dst; @@ -1341,12 +1508,9 @@ set_object(radio_param_t param, const void *src, size_t size) dst[i] = ((uint8_t *)src)[7 - i]; } + /* If off, the new configuration will be applied the next time radio is started */ if(!rf_is_on()) { - was_off = 1; - if(on() != RF_CORE_CMD_OK) { - PRINTF("set_object: on() failed\n"); - return RADIO_RESULT_ERROR; - } + return RADIO_RESULT_OK; } if(rx_off() != RF_CORE_CMD_OK) { @@ -1359,11 +1523,6 @@ set_object(radio_param_t param, const void *src, size_t size) rv = RADIO_RESULT_ERROR; } - /* If we were off, turn back off */ - if(was_off) { - off(); - } - return rv; } return RADIO_RESULT_NOT_SUPPORTED; diff --git a/cpu/cc26xx-cc13xx/rf-core/prop-mode.c b/cpu/cc26xx-cc13xx/rf-core/prop-mode.c index 419a7b9d2..54102f164 100644 --- a/cpu/cc26xx-cc13xx/rf-core/prop-mode.c +++ b/cpu/cc26xx-cc13xx/rf-core/prop-mode.c @@ -683,7 +683,7 @@ transmit(unsigned short transmit_len) rx_off_prop(); /* Enable the LAST_COMMAND_DONE interrupt to wake us up */ - rf_core_cmd_done_en(false); + rf_core_cmd_done_en(false, false); ret = rf_core_send_cmd((uint32_t)cmd_tx_adv, &cmd_status); @@ -728,7 +728,7 @@ transmit(unsigned short transmit_len) * Disable LAST_FG_COMMAND_DONE interrupt. We don't really care about it * except when we are transmitting */ - rf_core_cmd_done_dis(); + rf_core_cmd_done_dis(false); /* Workaround. Set status to IDLE */ cmd_tx_adv->status = RF_CORE_RADIO_OP_STATUS_IDLE; @@ -933,7 +933,7 @@ on(void) } } - rf_core_setup_interrupts(); + rf_core_setup_interrupts(false); /* * Trigger a switch to the XOSC, so that we can subsequently use the RF FS diff --git a/cpu/cc26xx-cc13xx/rf-core/rf-core.c b/cpu/cc26xx-cc13xx/rf-core/rf-core.c index 8efe41dac..15fc8e3bc 100644 --- a/cpu/cc26xx-cc13xx/rf-core/rf-core.c +++ b/cpu/cc26xx-cc13xx/rf-core/rf-core.c @@ -92,6 +92,8 @@ #define ENABLED_IRQS (RX_FRAME_IRQ | ERROR_IRQ) #endif +#define ENABLED_IRQS_POLL_MODE (ENABLED_IRQS & ~(RX_FRAME_IRQ | ERROR_IRQ)) + #define cc26xx_rf_cpe0_isr RFCCPE0IntHandler #define cc26xx_rf_cpe1_isr RFCCPE1IntHandler /*---------------------------------------------------------------------------*/ @@ -101,6 +103,10 @@ static rfc_radioOp_t *last_radio_op = NULL; /* A struct holding pointers to the primary mode's abort() and restore() */ static const rf_core_primary_mode_t *primary_mode = NULL; /*---------------------------------------------------------------------------*/ +/* Radio timer (RAT) offset as compared to the rtimer counter (RTC) */ +int32_t rat_offset = 0; +static bool rat_offset_known = false; +/*---------------------------------------------------------------------------*/ PROCESS(rf_core_process, "CC13xx / CC26xx RF driver"); /*---------------------------------------------------------------------------*/ #define RF_CORE_CLOCKS_MASK (RFC_PWR_PWMCLKEN_RFC_M | RFC_PWR_PWMCLKEN_CPE_M \ @@ -265,6 +271,66 @@ rf_core_power_up() return RF_CORE_CMD_OK; } /*---------------------------------------------------------------------------*/ +uint8_t +rf_core_start_rat(void) +{ + uint32_t cmd_status; + rfc_CMD_SYNC_START_RAT_t cmd_start; + + /* Start radio timer (RAT) */ + rf_core_init_radio_op((rfc_radioOp_t *)&cmd_start, sizeof(cmd_start), CMD_SYNC_START_RAT); + + /* copy the value and send back */ + cmd_start.rat0 = rat_offset; + + if(rf_core_send_cmd((uint32_t)&cmd_start, &cmd_status) != RF_CORE_CMD_OK) { + PRINTF("rf_core_get_rat_rtc_offset: SYNC_START_RAT fail, CMDSTA=0x%08lx\n", + cmd_status); + return RF_CORE_CMD_ERROR; + } + + /* Wait until done (?) */ + if(rf_core_wait_cmd_done(&cmd_start) != RF_CORE_CMD_OK) { + PRINTF("rf_core_cmd_ok: SYNC_START_RAT wait, CMDSTA=0x%08lx, status=0x%04x\n", + cmd_status, cmd_start.status); + return RF_CORE_CMD_ERROR; + } + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +uint8_t +rf_core_stop_rat(void) +{ + rfc_CMD_SYNC_STOP_RAT_t cmd_stop; + uint32_t cmd_status; + + rf_core_init_radio_op((rfc_radioOp_t *)&cmd_stop, sizeof(cmd_stop), CMD_SYNC_STOP_RAT); + + int ret = rf_core_send_cmd((uint32_t)&cmd_stop, &cmd_status); + if(ret != RF_CORE_CMD_OK) { + PRINTF("rf_core_get_rat_rtc_offset: SYNC_STOP_RAT fail, ret %d CMDSTA=0x%08lx\n", + ret, cmd_status); + return ret; + } + + /* Wait until done */ + ret = rf_core_wait_cmd_done(&cmd_stop); + if(ret != RF_CORE_CMD_OK) { + PRINTF("rf_core_cmd_ok: SYNC_STOP_RAT wait, CMDSTA=0x%08lx, status=0x%04x\n", + cmd_status, cmd_stop.status); + return ret; + } + + if(!rat_offset_known) { + /* save the offset, but only if this is the first time */ + rat_offset_known = true; + rat_offset = cmd_stop.rat0; + } + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ void rf_core_power_down() { @@ -280,6 +346,8 @@ rf_core_power_down() fs_powerdown(); } + rf_core_stop_rat(); + /* Shut down the RFCORE clock domain in the MCU VD */ ti_lib_prcm_domain_disable(PRCM_DOMAIN_RFCORE); ti_lib_prcm_load_set(); @@ -329,22 +397,6 @@ rf_core_set_modesel() } /*---------------------------------------------------------------------------*/ uint8_t -rf_core_start_rat() -{ - uint32_t cmd_status; - - /* Start radio timer (RAT) */ - if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_START_RAT), &cmd_status) - != RF_CORE_CMD_OK) { - PRINTF("rf_core_apply_patches: START_RAT fail, CMDSTA=0x%08lx\n", - cmd_status); - return RF_CORE_CMD_ERROR; - } - - return RF_CORE_CMD_OK; -} -/*---------------------------------------------------------------------------*/ -uint8_t rf_core_boot() { if(rf_core_power_up() != RF_CORE_CMD_OK) { @@ -366,10 +418,31 @@ rf_core_boot() return RF_CORE_CMD_OK; } /*---------------------------------------------------------------------------*/ +uint8_t +rf_core_restart_rat(void) +{ + if(rf_core_stop_rat() != RF_CORE_CMD_OK) { + PRINTF("rf_core_restart_rat: rf_core_stop_rat() failed\n"); + + return RF_CORE_CMD_ERROR; + } + + if(rf_core_start_rat() != RF_CORE_CMD_OK) { + PRINTF("rf_core_restart_rat: rf_core_start_rat() failed\n"); + + rf_core_power_down(); + + return RF_CORE_CMD_ERROR; + } + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ void -rf_core_setup_interrupts() +rf_core_setup_interrupts(bool poll_mode) { bool interrupts_disabled; + const uint32_t enabled_irqs = poll_mode ? ENABLED_IRQS_POLL_MODE : ENABLED_IRQS; /* We are already turned on by the caller, so this should not happen */ if(!rf_core_is_accessible()) { @@ -384,7 +457,7 @@ rf_core_setup_interrupts() HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEISL) = ERROR_IRQ; /* Acknowledge configured interrupts */ - HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = ENABLED_IRQS; + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = enabled_irqs; /* Clear interrupt flags, active low clear(?) */ HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0; @@ -400,18 +473,20 @@ rf_core_setup_interrupts() } /*---------------------------------------------------------------------------*/ void -rf_core_cmd_done_en(bool fg) +rf_core_cmd_done_en(bool fg, bool poll_mode) { uint32_t irq = fg ? IRQ_LAST_FG_COMMAND_DONE : IRQ_LAST_COMMAND_DONE; + const uint32_t enabled_irqs = poll_mode ? ENABLED_IRQS_POLL_MODE : ENABLED_IRQS; - HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = ENABLED_IRQS; - HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = ENABLED_IRQS | irq; + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = enabled_irqs; + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = enabled_irqs | irq; } /*---------------------------------------------------------------------------*/ void -rf_core_cmd_done_dis() +rf_core_cmd_done_dis(bool poll_mode) { - HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = ENABLED_IRQS; + const uint32_t enabled_irqs = poll_mode ? ENABLED_IRQS_POLL_MODE : ENABLED_IRQS; + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = enabled_irqs; } /*---------------------------------------------------------------------------*/ rfc_radioOp_t * diff --git a/cpu/cc26xx-cc13xx/rf-core/rf-core.h b/cpu/cc26xx-cc13xx/rf-core/rf-core.h index 42c6edb90..474de4a87 100644 --- a/cpu/cc26xx-cc13xx/rf-core/rf-core.h +++ b/cpu/cc26xx-cc13xx/rf-core/rf-core.h @@ -228,6 +228,9 @@ typedef struct rf_core_primary_mode_s { #define RF_CORE_COMMAND_PROTOCOL_IEEE 0x2000 #define RF_CORE_COMMAND_PROTOCOL_PROP 0x3000 /*---------------------------------------------------------------------------*/ +/* Radio timer register */ +#define RATCNT 0x00000004 +/*---------------------------------------------------------------------------*/ /* Make the main driver process visible to mode drivers */ PROCESS_NAME(rf_core_process); /*---------------------------------------------------------------------------*/ @@ -310,6 +313,24 @@ uint8_t rf_core_set_modesel(void); */ uint8_t rf_core_start_rat(void); +/** + * \brief Stop the CM0 RAT synchronously + * \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR + * + * This function is not strictly necessary, but through calling it it's possibly + * to learn the RAT / RTC offset, which useful to get accurate radio timestamps. + */ +uint8_t rf_core_stop_rat(void); + +/** + * \brief Restart the CM0 RAT + * \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR + * + * This function restarts the CM0 RAT and therefore resynchornizes it with RTC. + * To achieve good timing accuracy, it should be called periodically. + */ +uint8_t rf_core_restart_rat(void); + /** * \brief Boot the RF Core * \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR @@ -327,19 +348,20 @@ uint8_t rf_core_boot(void); /** * \brief Setup RF core interrupts */ -void rf_core_setup_interrupts(void); +void rf_core_setup_interrupts(bool poll_mode); /** * \brief Enable interrupt on command done. * \param fg set true to enable irq on foreground command done and false for * background commands or if not in ieee mode. + * \param poll_mode true if the driver is in poll mode * * This is used within TX routines in order to be able to sleep the CM3 and * wake up after TX has finished * * \sa rf_core_cmd_done_dis() */ -void rf_core_cmd_done_en(bool fg); +void rf_core_cmd_done_en(bool fg, bool poll_mode); /** * \brief Disable the LAST_CMD_DONE and LAST_FG_CMD_DONE interrupts. @@ -348,7 +370,7 @@ void rf_core_cmd_done_en(bool fg); * * \sa rf_core_cmd_done_en() */ -void rf_core_cmd_done_dis(void); +void rf_core_cmd_done_dis(bool poll_mode); /** * \brief Returns a pointer to the most recent proto-dependent Radio Op From 95b66657aab656e3ca9b2a44d3c2e8cf093ff4d2 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Mon, 25 Apr 2016 17:57:46 +0300 Subject: [PATCH 356/374] cc26xx: add TSCH-related rtimer defines --- cpu/cc26xx-cc13xx/rtimer-arch.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/cpu/cc26xx-cc13xx/rtimer-arch.h b/cpu/cc26xx-cc13xx/rtimer-arch.h index 0d54d227c..128461c8d 100644 --- a/cpu/cc26xx-cc13xx/rtimer-arch.h +++ b/cpu/cc26xx-cc13xx/rtimer-arch.h @@ -50,6 +50,21 @@ #define RTIMER_ARCH_SECOND 65536 /*---------------------------------------------------------------------------*/ rtimer_clock_t rtimer_arch_now(void); + +/* HW oscillator frequency is 32 kHz, not 64 kHz and RTIMER_NOW() never returns + * an odd value; so US_TO_RTIMERTICKS always rounds to the nearest even number. + */ +#define US_TO_RTIMERTICKS(US) (2 * ((US) >= 0 ? \ + (((int32_t)(US) * (RTIMER_ARCH_SECOND / 2) + 500000) / 1000000L) : \ + ((int32_t)(US) * (RTIMER_ARCH_SECOND / 2) - 500000) / 1000000L)) + +#define RTIMERTICKS_TO_US(T) ((T) >= 0 ? \ + (((int32_t)(T) * 1000000L + ((RTIMER_ARCH_SECOND) / 2)) / (RTIMER_ARCH_SECOND)) : \ + ((int32_t)(T) * 1000000L - ((RTIMER_ARCH_SECOND) / 2)) / (RTIMER_ARCH_SECOND)) + +/* A 64-bit version because the 32-bit one cannot handle T >= 4295 ticks. + Intended only for positive values of T. */ +#define RTIMERTICKS_TO_US_64(T) ((uint32_t)(((uint64_t)(T) * 1000000 + ((RTIMER_ARCH_SECOND) / 2)) / (RTIMER_ARCH_SECOND))) /*---------------------------------------------------------------------------*/ #endif /* RTIMER_ARCH_H_ */ /*---------------------------------------------------------------------------*/ From a47fb723e468368808f44e48712552c52519a31a Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Mon, 25 Apr 2016 18:02:26 +0300 Subject: [PATCH 357/374] cc26xx: enable sync between radio timer and RTC, useful for TSCH --- cpu/cc26xx-cc13xx/clock.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cpu/cc26xx-cc13xx/clock.c b/cpu/cc26xx-cc13xx/clock.c index 4f6df056f..85ea6e444 100644 --- a/cpu/cc26xx-cc13xx/clock.c +++ b/cpu/cc26xx-cc13xx/clock.c @@ -118,6 +118,9 @@ clock_init(void) /* GPT0 / Timer B: One shot, PWM interrupt enable */ HWREG(GPT0_BASE + GPT_O_TBMR) = ((TIMER_CFG_B_ONE_SHOT >> 8) & 0xFF) | GPT_TBMR_TBPWMIE; + + /* enable sync with radio timer */ + HWREGBITW(AON_RTC_BASE + AON_RTC_O_CTL, AON_RTC_CTL_RTC_UPD_EN_BITN) = 1; } /*---------------------------------------------------------------------------*/ static void From 3a99639294bef07938ed9ccb54603060ef9226c1 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Mon, 25 Apr 2016 18:08:34 +0300 Subject: [PATCH 358/374] cc26xx: implement CC2650_FAST_RADIO_STARTUP option, required for TSCH --- cpu/cc26xx-cc13xx/dev/soc-rtc.c | 12 +- cpu/cc26xx-cc13xx/lpm.c | 235 ++++++++++++++------------- platform/srf06-cc26xx/contiki-main.c | 5 + 3 files changed, 139 insertions(+), 113 deletions(-) diff --git a/cpu/cc26xx-cc13xx/dev/soc-rtc.c b/cpu/cc26xx-cc13xx/dev/soc-rtc.c index 08d9a7cce..398f14d6a 100644 --- a/cpu/cc26xx-cc13xx/dev/soc-rtc.c +++ b/cpu/cc26xx-cc13xx/dev/soc-rtc.c @@ -81,11 +81,13 @@ soc_rtc_init(void) ti_lib_aon_rtc_event_clear(AON_RTC_CH0); ti_lib_aon_rtc_event_clear(AON_RTC_CH1); + ti_lib_aon_rtc_event_clear(AON_RTC_CH2); /* Setup the wakeup event */ ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU0, AON_EVENT_RTC_CH0); ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU1, AON_EVENT_RTC_CH1); - ti_lib_aon_rtc_combined_event_config(AON_RTC_CH0 | AON_RTC_CH1); + ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU2, AON_EVENT_RTC_CH2); + ti_lib_aon_rtc_combined_event_config(AON_RTC_CH0 | AON_RTC_CH1 | AON_RTC_CH2); HWREG(AON_RTC_BASE + AON_RTC_O_SEC) = SOC_RTC_START_TICK_COUNT; @@ -123,7 +125,7 @@ soc_rtc_get_next_trigger() void soc_rtc_schedule_one_shot(uint32_t channel, uint32_t ticks) { - if((channel != AON_RTC_CH0) && (channel != AON_RTC_CH1)) { + if((channel != AON_RTC_CH0) && (channel != AON_RTC_CH1) && (channel != AON_RTC_CH2)) { return; } @@ -170,6 +172,12 @@ soc_rtc_isr(void) rtimer_run_next(); } + if(ti_lib_aon_rtc_event_get(AON_RTC_CH2)) { + /* after sleep; since a rtimer is already scheduled, do nothing */ + ti_lib_aon_rtc_channel_disable(AON_RTC_CH2); + HWREG(AON_RTC_BASE + AON_RTC_O_EVFLAGS) = AON_RTC_EVFLAGS_CH2; + } + ENERGEST_OFF(ENERGEST_TYPE_IRQ); } /*---------------------------------------------------------------------------*/ diff --git a/cpu/cc26xx-cc13xx/lpm.c b/cpu/cc26xx-cc13xx/lpm.c index 686065c73..3253202c2 100644 --- a/cpu/cc26xx-cc13xx/lpm.c +++ b/cpu/cc26xx-cc13xx/lpm.c @@ -77,12 +77,13 @@ LIST(modules_list); * Don't consider standby mode if the next AON RTC event is scheduled to fire * in less than STANDBY_MIN_DURATION rtimer ticks */ -#define STANDBY_MIN_DURATION (RTIMER_SECOND >> 11) -#define MINIMAL_SAFE_SCHEDUAL 8u +#define STANDBY_MIN_DURATION (RTIMER_SECOND / 100) /* 10.0 ms */ + +/* Wake up this much time earlier before the next rtimer */ +#define SLEEP_GUARD_TIME (RTIMER_SECOND / 1000) /* 1.0 ms */ + #define MAX_SLEEP_TIME RTIMER_SECOND -#define DEFAULT_SLEEP_TIME RTIMER_SECOND -/*---------------------------------------------------------------------------*/ -#define CLK_TO_RT(c) ((c) * (RTIMER_SECOND / CLOCK_SECOND)) +#define MINIMAL_SAFE_SCHEDULE 8u /*---------------------------------------------------------------------------*/ /* Prototype of a function in clock.c. Called every time we come out of DS */ void clock_update(void); @@ -241,14 +242,124 @@ wake_up(void) module->wakeup(); } } + +#if CC2650_FAST_RADIO_STARTUP + /* + * Trigger a switch to the XOSC, so that we can subsequently use the RF FS + */ + oscillators_request_hf_xosc(); +#endif +} +/*---------------------------------------------------------------------------*/ +static int +setup_sleep_mode(rtimer_clock_t *next_timer) +{ + lpm_registered_module_t *module; + uint8_t max_pm = LPM_MODE_MAX_SUPPORTED; + + rtimer_clock_t now = RTIMER_NOW(); + const rtimer_clock_t max_sleep = now + MAX_SLEEP_TIME; + + /* next_timer will hold the time of the next system wakeup due to a timer*/ + *next_timer = max_sleep; + + /* Check if any events fired before we turned interrupts off. If so, abort */ + if(LPM_MODE_MAX_SUPPORTED == LPM_MODE_AWAKE || process_nevents()) { + return LPM_MODE_AWAKE; + } + + if(ti_lib_aon_rtc_channel_active(AON_RTC_CH0)) { + rtimer_clock_t next_rtimer; + /* find out the timer of the next rtimer interrupt */ + next_rtimer = ti_lib_aon_rtc_compare_value_get(AON_RTC_CH0); + if(RTIMER_CLOCK_LT(next_rtimer, now + 2)) { + return LPM_MODE_AWAKE; + } + if(RTIMER_CLOCK_LT(next_rtimer, now + STANDBY_MIN_DURATION)) { + return LPM_MODE_SLEEP; + } + *next_timer = next_rtimer; + } + + /* also find out the timer of the next etimer */ + if(etimer_pending()) { + int32_t until_next_etimer; + rtimer_clock_t next_etimer; + + until_next_etimer = (int32_t)etimer_next_expiration_time() - (int32_t)clock_time(); + if(until_next_etimer < 1) { + return LPM_MODE_AWAKE; + } + + next_etimer = soc_rtc_last_isr_time() + (until_next_etimer * (RTIMER_SECOND / CLOCK_SECOND)); + if(RTIMER_CLOCK_LT(next_etimer, now + STANDBY_MIN_DURATION)) { + /* ensure that we schedule sleep a minimal number of ticks into the + future */ + soc_rtc_schedule_one_shot(AON_RTC_CH1, now + MINIMAL_SAFE_SCHEDULE); + return LPM_MODE_SLEEP; + } + + if(RTIMER_CLOCK_LT(max_sleep, next_etimer)) { + /* if max_pm is LPM_MODE_SLEEP, we could trigger the watchdog if we slept + for too long. */ + if(RTIMER_CLOCK_LT(max_sleep, *next_timer)) { + soc_rtc_schedule_one_shot(AON_RTC_CH1, max_sleep); + } + } else { + /* Reschedule AON RTC CH1 to fire just in time for the next etimer event */ + soc_rtc_schedule_one_shot(AON_RTC_CH1, next_etimer); + } + + if(RTIMER_CLOCK_LT(next_etimer, *next_timer)) { + /* set `next_timer` to the time the first etimer fires */ + *next_timer = next_etimer; + } + } + + /* Collect max allowed PM permission from interested modules */ + for(module = list_head(modules_list); module != NULL; + module = module->next) { + if(module->request_max_pm) { + uint8_t module_pm = module->request_max_pm(); + if(module_pm < max_pm) { + max_pm = module_pm; + } + } + } + + return max_pm; +} +/*---------------------------------------------------------------------------*/ +void +lpm_sleep(void) +{ + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); + + /* We are only interested in IRQ energest while idle or in LPM */ + ENERGEST_IRQ_RESTORE(irq_energest); + + /* Just to be on the safe side, explicitly disable Deep Sleep */ + HWREG(NVIC_SYS_CTRL) &= ~(NVIC_SYS_CTRL_SLEEPDEEP); + + ti_lib_prcm_sleep(); + + /* Remember IRQ energest for next pass */ + ENERGEST_IRQ_SAVE(irq_energest); + + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); } /*---------------------------------------------------------------------------*/ static void -deep_sleep(void) +deep_sleep(rtimer_clock_t next_timer) { uint32_t domains = LOCKABLE_DOMAINS; lpm_registered_module_t *module; +#if CC2650_FAST_RADIO_STARTUP + /* schedule a wakeup briefly before the next etimer/rtimer to wake up the system */ + soc_rtc_schedule_one_shot(AON_RTC_CH2, next_timer - SLEEP_GUARD_TIME); +#endif + /* * Notify all registered modules that we are dropping to mode X. We do not * need to do this for simple sleep. @@ -304,7 +415,8 @@ deep_sleep(void) * turn back off. * * If the radio is on, we won't even reach here, and if it's off the HF - * clock source should already be the HF RC. + * clock source should already be the HF RC, unless CC2650_FAST_RADIO_STARTUP + * is defined. * * Nevertheless, request the switch to the HF RC explicitly here. */ @@ -370,131 +482,32 @@ deep_sleep(void) * unpending events so the handlers can fire */ wake_up(); -} -/*---------------------------------------------------------------------------*/ -static void -safe_schedule_rtimer(rtimer_clock_t time, rtimer_clock_t now, int pm) -{ - rtimer_clock_t min_sleep; - rtimer_clock_t max_sleep; - min_sleep = now + MINIMAL_SAFE_SCHEDUAL; - max_sleep = now + MAX_SLEEP_TIME; - - if(RTIMER_CLOCK_LT(time, min_sleep)) { - /* ensure that we schedule sleep a minimal number of ticks into the - future */ - soc_rtc_schedule_one_shot(AON_RTC_CH1, min_sleep); - } else if((pm == LPM_MODE_SLEEP) && RTIMER_CLOCK_LT(max_sleep, time)) { - /* if max_pm is LPM_MODE_SLEEP, we could trigger the watchdog if we slept - for too long. */ - soc_rtc_schedule_one_shot(AON_RTC_CH1, max_sleep); - } else { - soc_rtc_schedule_one_shot(AON_RTC_CH1, time); - } -} -/*---------------------------------------------------------------------------*/ -static int -setup_sleep_mode(void) -{ - rtimer_clock_t et_distance = 0; - - lpm_registered_module_t *module; - int max_pm; - int module_pm; - int etimer_is_pending; - rtimer_clock_t now; - rtimer_clock_t et_time; - rtimer_clock_t next_trig; - - max_pm = LPM_MODE_MAX_SUPPORTED; - now = RTIMER_NOW(); - - if((LPM_MODE_MAX_SUPPORTED == LPM_MODE_AWAKE) || process_nevents()) { - return LPM_MODE_AWAKE; - } - - etimer_is_pending = etimer_pending(); - - if(etimer_is_pending) { - et_distance = CLK_TO_RT(etimer_next_expiration_time() - clock_time()); - - if(RTIMER_CLOCK_LT(et_distance, 1)) { - /* there is an etimer which is already expired; we shouldn't go to - sleep at all */ - return LPM_MODE_AWAKE; - } - } - - next_trig = soc_rtc_get_next_trigger(); - if(RTIMER_CLOCK_LT(next_trig, now + STANDBY_MIN_DURATION)) { - return LPM_MODE_SLEEP; - } - - /* Collect max allowed PM permission from interested modules */ - for(module = list_head(modules_list); module != NULL; - module = module->next) { - if(module->request_max_pm) { - module_pm = module->request_max_pm(); - if(module_pm < max_pm) { - max_pm = module_pm; - } - } - } - - /* Reschedule AON RTC CH1 to fire just in time for the next etimer event */ - if(etimer_is_pending) { - et_time = soc_rtc_last_isr_time() + et_distance; - - safe_schedule_rtimer(et_time, now, max_pm); - } else { - /* set a maximal sleep period if no etimers are queued */ - soc_rtc_schedule_one_shot(AON_RTC_CH1, now + DEFAULT_SLEEP_TIME); - } - - return max_pm; + ti_lib_int_master_enable(); } /*---------------------------------------------------------------------------*/ void lpm_drop() { uint8_t max_pm; + rtimer_clock_t next_timer; /* Critical. Don't get interrupted! */ ti_lib_int_master_disable(); - max_pm = setup_sleep_mode(); + max_pm = setup_sleep_mode(&next_timer); /* Drop */ if(max_pm == LPM_MODE_SLEEP) { lpm_sleep(); } else if(max_pm == LPM_MODE_DEEP_SLEEP) { - deep_sleep(); + deep_sleep(next_timer); } ti_lib_int_master_enable(); } /*---------------------------------------------------------------------------*/ void -lpm_sleep(void) -{ - ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); - - /* We are only interested in IRQ energest while idle or in LPM */ - ENERGEST_IRQ_RESTORE(irq_energest); - - /* Just to be on the safe side, explicitly disable Deep Sleep */ - HWREG(NVIC_SYS_CTRL) &= ~(NVIC_SYS_CTRL_SLEEPDEEP); - - ti_lib_prcm_sleep(); - - /* Remember IRQ energest for next pass */ - ENERGEST_IRQ_SAVE(irq_energest); - - ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); -} -/*---------------------------------------------------------------------------*/ -void lpm_register_module(lpm_registered_module_t *module) { list_add(modules_list, module); @@ -512,7 +525,7 @@ lpm_init() list_init(modules_list); /* Always wake up on any DIO edge detection */ - ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU2, AON_EVENT_IO); + ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU3, AON_EVENT_IO); } /*---------------------------------------------------------------------------*/ void diff --git a/platform/srf06-cc26xx/contiki-main.c b/platform/srf06-cc26xx/contiki-main.c index b3d64f24a..b3f5c37f7 100644 --- a/platform/srf06-cc26xx/contiki-main.c +++ b/platform/srf06-cc26xx/contiki-main.c @@ -149,6 +149,11 @@ main(void) /* Set the LF XOSC as the LF system clock source */ oscillators_select_lf_xosc(); +#if CC2650_FAST_RADIO_STARTUP + /* Also request HF XOSC to start up */ + oscillators_request_hf_xosc(); +#endif + lpm_init(); board_init(); From e19fbc996e240c0222409ac2b51a44645f7caf89 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Mon, 25 Apr 2016 19:10:38 +0300 Subject: [PATCH 359/374] cc26xx: use CMD_IEEE_MOD_FILT to change address filtering instead of fully restarting the radio --- cpu/cc26xx-cc13xx/rf-core/ieee-mode.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c index 9cc614433..03c4ab2fc 100644 --- a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c +++ b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c @@ -631,6 +631,11 @@ init_rf_params(void) cmd->endTrigger.triggerType = TRIG_NEVER; cmd->endTime = 0x00000000; + + /* set address filter command */ + filter_cmd.commandNo = CMD_IEEE_MOD_FILT; + memcpy(&filter_cmd.newFrameFiltOpt, &cmd->frameFiltOpt, sizeof(cmd->frameFiltOpt)); + memcpy(&filter_cmd.newFrameTypes, &cmd->frameTypes, sizeof(cmd->frameTypes)); } /*---------------------------------------------------------------------------*/ static int @@ -1355,9 +1360,9 @@ get_value(radio_param_t param, radio_value_t *value) static radio_result_t set_value(radio_param_t param, radio_value_t value) { - uint8_t was_off = 0; radio_result_t rv = RADIO_RESULT_OK; rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf; + uint8_t old_poll_mode; switch(param) { case RADIO_PARAM_POWER_MODE: @@ -1411,7 +1416,20 @@ set_value(radio_param_t param, radio_value_t value) cmd->frameFiltOpt.bPanCoord = 0; cmd->frameFiltOpt.bStrictLenFilter = 0; + old_poll_mode = poll_mode; poll_mode = (value & RADIO_RX_MODE_POLL_MODE) != 0; + if(poll_mode == old_poll_mode) { + uint32_t cmd_status; + + /* do not turn the radio on and off, just send an update command */ + memcpy(&filter_cmd.newFrameFiltOpt, &cmd->frameFiltOpt, sizeof(cmd->frameFiltOpt)); + + if(rf_core_send_cmd((uint32_t)&filter_cmd, &cmd_status) == RF_CORE_CMD_ERROR) { + PRINTF("setting address filter failed: CMDSTA=0x%08lx\n", cmd_status); + return RADIO_RESULT_ERROR; + } + return RADIO_RESULT_OK; + } break; } case RADIO_PARAM_TXPOWER: From 97c1cfc3b4fe4ea430f5ed6413a5d9867ed6728d Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Mon, 25 Apr 2016 19:22:20 +0300 Subject: [PATCH 360/374] cc26xx: return the expected value 0 from prepare() in ieee and prop mode radio --- cpu/cc26xx-cc13xx/rf-core/ieee-mode.c | 2 +- cpu/cc26xx-cc13xx/rf-core/prop-mode.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c index 03c4ab2fc..f81faf1c3 100644 --- a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c +++ b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c @@ -847,7 +847,7 @@ prepare(const void *payload, unsigned short payload_len) int len = MIN(payload_len, TX_BUF_PAYLOAD_LEN); memcpy(&tx_buf[TX_BUF_HDR_LEN], payload, len); - return RF_CORE_CMD_OK; + return 0; } /*---------------------------------------------------------------------------*/ static int diff --git a/cpu/cc26xx-cc13xx/rf-core/prop-mode.c b/cpu/cc26xx-cc13xx/rf-core/prop-mode.c index 54102f164..94aef33b9 100644 --- a/cpu/cc26xx-cc13xx/rf-core/prop-mode.c +++ b/cpu/cc26xx-cc13xx/rf-core/prop-mode.c @@ -634,7 +634,7 @@ prepare(const void *payload, unsigned short payload_len) int len = MIN(payload_len, TX_BUF_PAYLOAD_LEN); memcpy(&tx_buf[TX_BUF_HDR_LEN], payload, len); - return RF_CORE_CMD_OK; + return 0; } /*---------------------------------------------------------------------------*/ static int From 25c5f0b744970343841edd3d7d26215d60fceefc Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Mon, 25 Apr 2016 19:23:59 +0300 Subject: [PATCH 361/374] cc26xx: implement support for CC2650_FAST_RADIO_STARTUP --- cpu/cc26xx-cc13xx/rf-core/ieee-mode.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c index f81faf1c3..b67bddac0 100644 --- a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c +++ b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c @@ -1216,11 +1216,13 @@ on(void) return RF_CORE_CMD_OK; } +#if !CC2650_FAST_RADIO_STARTUP /* * Request the HF XOSC as the source for the HF clock. Needed before we can * use the FS. This will only request, it will _not_ perform the switch. */ oscillators_request_hf_xosc(); +#endif if(rf_is_on()) { PRINTF("on: We were on. PD=%u, RX=0x%04x \n", rf_core_is_accessible(), @@ -1228,22 +1230,23 @@ on(void) return RF_CORE_CMD_OK; } + init_rx_buffers(); + + /* + * Trigger a switch to the XOSC, so that we can subsequently use the RF FS + * This will block until the XOSC is actually ready, but give how we + * requested it early on, this won't be too long a wait. + * This should be done before starting the RAT. + */ + oscillators_switch_to_hf_xosc(); + if(rf_core_boot() != RF_CORE_CMD_OK) { PRINTF("on: rf_core_boot() failed\n"); return RF_CORE_CMD_ERROR; } - init_rx_buffers(); - rf_core_setup_interrupts(poll_mode); - /* - * Trigger a switch to the XOSC, so that we can subsequently use the RF FS - * This will block until the XOSC is actually ready, but give how we - * requested it early on, this won't be too long a wait/ - */ - oscillators_switch_to_hf_xosc(); - if(rf_radio_setup() != RF_CORE_CMD_OK) { PRINTF("on: radio_setup() failed\n"); return RF_CORE_CMD_ERROR; @@ -1272,8 +1275,12 @@ off(void) ENERGEST_OFF(ENERGEST_TYPE_LISTEN); - /* Switch HF clock source to the RCOSC to preserve power */ +#if !CC2650_FAST_RADIO_STARTUP + /* Switch HF clock source to the RCOSC to preserve power. + * This must be done after stopping RAT. + */ oscillators_switch_to_hf_rc(); +#endif /* We pulled the plug, so we need to restore the status manually */ ((rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf)->status = RF_CORE_RADIO_OP_STATUS_IDLE; From 80aa30c5da2aeaf2f6688930c54d6a39cb47944b Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Mon, 25 Apr 2016 19:25:38 +0300 Subject: [PATCH 362/374] cc26xx: add support for RADIO_PARAM_TX_MODE getting and setting and for LAST_RSSI and LAST_LQI reading --- cpu/cc26xx-cc13xx/rf-core/ieee-mode.c | 29 +++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c index b67bddac0..3eb46ae78 100644 --- a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c +++ b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c @@ -1297,6 +1297,17 @@ off(void) return RF_CORE_CMD_OK; } /*---------------------------------------------------------------------------*/ +/* Enable or disable CCA before sending */ +static radio_result_t +set_send_on_cca(uint8_t enable) +{ + if(enable) { + /* this driver does not have support for CCA on Tx */ + return RADIO_RESULT_NOT_SUPPORTED; + } + return RADIO_RESULT_OK; +} +/*---------------------------------------------------------------------------*/ static radio_result_t get_value(radio_param_t param, radio_value_t *value) { @@ -1332,6 +1343,9 @@ get_value(radio_param_t param, radio_value_t *value) *value |= RADIO_RX_MODE_POLL_MODE; } + return RADIO_RESULT_OK; + case RADIO_PARAM_TX_MODE: + *value = 0; return RADIO_RESULT_OK; case RADIO_PARAM_TXPOWER: *value = get_tx_power(); @@ -1359,6 +1373,12 @@ get_value(radio_param_t param, radio_value_t *value) case RADIO_CONST_TXPOWER_MAX: *value = OUTPUT_POWER_MAX; return RADIO_RESULT_OK; + case RADIO_PARAM_LAST_RSSI: + *value = last_rssi; + return RADIO_RESULT_OK; + case RADIO_PARAM_LAST_LINK_QUALITY: + *value = last_corr_lqi; + return RADIO_RESULT_OK; default: return RADIO_RESULT_NOT_SUPPORTED; } @@ -1439,6 +1459,13 @@ set_value(radio_param_t param, radio_value_t value) } break; } + + case RADIO_PARAM_TX_MODE: + if(value & ~(RADIO_TX_MODE_SEND_ON_CCA)) { + return RADIO_RESULT_INVALID_VALUE; + } + return set_send_on_cca((value & RADIO_TX_MODE_SEND_ON_CCA) != 0); + case RADIO_PARAM_TXPOWER: if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) { return RADIO_RESULT_INVALID_VALUE; @@ -1447,9 +1474,11 @@ set_value(radio_param_t param, radio_value_t value) set_tx_power(value); return RADIO_RESULT_OK; + case RADIO_PARAM_CCA_THRESHOLD: cmd->ccaRssiThr = (int8_t)value; break; + default: return RADIO_RESULT_NOT_SUPPORTED; } From 54e4b5f3510ecb9f249eaf8e465aef3344c65b99 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Mon, 25 Apr 2016 19:27:16 +0300 Subject: [PATCH 363/374] cc26xx: allow IEEE 802.15.4 frames with version 2, required for TSCH --- cpu/cc26xx-cc13xx/rf-core/ieee-mode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c index 3eb46ae78..7d4de12be 100644 --- a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c +++ b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c @@ -601,7 +601,7 @@ init_rf_params(void) cmd->frameFiltOpt.defaultPend = 0; cmd->frameFiltOpt.bPendDataReqOnly = 0; cmd->frameFiltOpt.bPanCoord = 0; - cmd->frameFiltOpt.maxFrameVersion = 1; + cmd->frameFiltOpt.maxFrameVersion = 2; cmd->frameFiltOpt.bStrictLenFilter = 0; /* Receive all frame types */ From d85667d5356b3a08773adadce69eab552b43d805 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Mon, 25 Apr 2016 19:29:35 +0300 Subject: [PATCH 364/374] cc26xx: packet queue changes: allow to read packets after radio has been turned off; make pending_packet() return true when there is a packets being received --- cpu/cc26xx-cc13xx/rf-core/ieee-mode.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c index 7d4de12be..af48a73bd 100644 --- a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c +++ b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c @@ -1190,7 +1190,8 @@ pending_packet(void) /* Go through all RX buffers and check their status */ do { - if(entry->status == DATA_ENTRY_STATUS_FINISHED) { + if(entry->status == DATA_ENTRY_STATUS_FINISHED + || entry->status == DATA_ENTRY_STATUS_BUSY) { rv = 1; if(!poll_mode) { process_poll(&rf_core_process); @@ -1289,10 +1290,18 @@ off(void) * Just in case there was an ongoing RX (which started after we begun the * shutdown sequence), we don't want to leave the buffer in state == ongoing */ - ((rfc_dataEntry_t *)rx_buf_0)->status = DATA_ENTRY_STATUS_PENDING; - ((rfc_dataEntry_t *)rx_buf_1)->status = DATA_ENTRY_STATUS_PENDING; - ((rfc_dataEntry_t *)rx_buf_2)->status = DATA_ENTRY_STATUS_PENDING; - ((rfc_dataEntry_t *)rx_buf_3)->status = DATA_ENTRY_STATUS_PENDING; + if(((rfc_dataEntry_t *)rx_buf_0)->status == DATA_ENTRY_STATUS_BUSY) { + ((rfc_dataEntry_t *)rx_buf_0)->status = DATA_ENTRY_STATUS_PENDING; + } + if(((rfc_dataEntry_t *)rx_buf_1)->status == DATA_ENTRY_STATUS_BUSY) { + ((rfc_dataEntry_t *)rx_buf_1)->status = DATA_ENTRY_STATUS_PENDING; + } + if(((rfc_dataEntry_t *)rx_buf_2)->status == DATA_ENTRY_STATUS_BUSY) { + ((rfc_dataEntry_t *)rx_buf_2)->status = DATA_ENTRY_STATUS_PENDING; + } + if(((rfc_dataEntry_t *)rx_buf_3)->status == DATA_ENTRY_STATUS_BUSY) { + ((rfc_dataEntry_t *)rx_buf_3)->status = DATA_ENTRY_STATUS_PENDING; + } return RF_CORE_CMD_OK; } From e233c3f27f9adc475e9d6d6d0b4cac560644eb0c Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Mon, 25 Apr 2016 19:31:04 +0300 Subject: [PATCH 365/374] cc26xx: change CCA logic to be standard-compatible; change receiving_packet to return true iff sync (SFD) has been seen --- cpu/cc26xx-cc13xx/rf-core/ieee-mode.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c index af48a73bd..08843d699 100644 --- a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c +++ b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c @@ -146,6 +146,13 @@ static uint8_t rf_stats[16] = { 0 }; #define RF_CMD_CCA_REQ_CCA_STATE_IDLE 0 /* 00 */ #define RF_CMD_CCA_REQ_CCA_STATE_BUSY 1 /* 01 */ #define RF_CMD_CCA_REQ_CCA_STATE_INVALID 2 /* 10 */ + +#define RF_CMD_CCA_REQ_CCA_CORR_IDLE (0 << 4) +#define RF_CMD_CCA_REQ_CCA_CORR_BUSY (1 << 4) +#define RF_CMD_CCA_REQ_CCA_CORR_INVALID (3 << 4) +#define RF_CMD_CCA_REQ_CCA_CORR_MASK (3 << 4) + +#define RF_CMD_CCA_REQ_CCA_SYNC_BUSY (1 << 6) /*---------------------------------------------------------------------------*/ #define IEEE_MODE_CHANNEL_MIN 11 #define IEEE_MODE_CHANNEL_MAX 26 @@ -617,9 +624,9 @@ init_rf_params(void) /* Configure CCA settings */ cmd->ccaOpt.ccaEnEnergy = 1; cmd->ccaOpt.ccaEnCorr = 1; - cmd->ccaOpt.ccaEnSync = 0; + cmd->ccaOpt.ccaEnSync = 1; cmd->ccaOpt.ccaCorrOp = 1; - cmd->ccaOpt.ccaSyncOp = 1; + cmd->ccaOpt.ccaSyncOp = 0; cmd->ccaOpt.ccaCorrThr = 3; cmd->ccaRssiThr = IEEE_MODE_RSSI_THRESHOLD; @@ -1167,19 +1174,17 @@ receiving_packet(void) cca_info = get_cca_info(); + /* If we can't read CCA info, return "not receiving" */ if(cca_info == RF_GET_CCA_INFO_ERROR) { - /* If we can't read CCA info, return "not receiving" */ - ret = 0; - } else { - /* Return 1 (receiving) if ccaState is busy */ - ret = (cca_info & 0x03) == RF_CMD_CCA_REQ_CCA_STATE_BUSY; + return 0; } - if(was_off) { - off(); + /* If sync has been seen, return 1 (receiving) */ + if(cca_info & RF_CMD_CCA_REQ_CCA_SYNC_BUSY) { + return 1; } - return ret; + return 0; } /*---------------------------------------------------------------------------*/ static int From 6800f9502e4e64d07cd0a43afc2d6df58aab63b7 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Tue, 7 Jun 2016 01:06:15 +0300 Subject: [PATCH 366/374] Update the list of supported platforms in TSCH README file --- core/net/mac/tsch/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/net/mac/tsch/README.md b/core/net/mac/tsch/README.md index ae8f7dcba..0b7c54ef3 100644 --- a/core/net/mac/tsch/README.md +++ b/core/net/mac/tsch/README.md @@ -38,6 +38,7 @@ It has been tested on the following platforms: * Zolertia Z1 (`z1`, tested in cooja only) * CC2538DK (`cc2538dk`, tested on hardware) * Zolertia Zoul (`zoul`, tested on hardware) + * CC2650 (`srf06-cc26xx`, tested on hardware) This implementation was present at the ETSI Plugtest event in Prague in July 2015, and did successfully inter-operate with all @@ -78,7 +79,7 @@ Orchestra is implemented in: A simple TSCH+RPL example is included under `examples/ipv6/rpl-tsch`. To use TSCH, first make sure your platform supports it. -Currently, `jn516x`, `sky`, `z1`, `cc2538dk` and `zoul` are the supported platforms. +Currently, `jn516x`, `sky`, `z1`, `cc2538dk`, `zoul` and `srf06-cc26xx` are the supported platforms. 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: @@ -164,7 +165,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 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`, `zoul`. +The easiest is probably to start from one of the existing port: `jn516x`, `sky`, `z1`, `cc2538dk`, `zoul`, `srf06-cc26xx`. ### Radio features required for TSCH From 5010309005388d327e7a0087ed8d30d3e8180111 Mon Sep 17 00:00:00 2001 From: Nicolas Tsiftes Date: Mon, 13 Jun 2016 15:55:58 +0200 Subject: [PATCH 367/374] Make the I/O semantics functionality in Coffee unconditional so that the API becomes consistent across platforms. Change certain CPP conditionals into C conditionals, which should be possible for the compiler to optimize at runtime. This makes the source code easier to read. --- core/cfs/cfs-coffee.c | 87 ++++++++++++------------------- platform/native/cfs-coffee-arch.h | 1 - platform/sky/cfs-coffee-arch.h | 1 - 3 files changed, 32 insertions(+), 57 deletions(-) diff --git a/core/cfs/cfs-coffee.c b/core/cfs/cfs-coffee.c index 374b3419f..3acd0480b 100644 --- a/core/cfs/cfs-coffee.c +++ b/core/cfs/cfs-coffee.c @@ -75,12 +75,6 @@ #error "Cannot have COFFEE_APPEND_ONLY set when COFFEE_MICRO_LOGS is set." #endif -/* I/O semantics can be set on file descriptors in order to optimize - file access on certain storage types. */ -#ifndef COFFEE_IO_SEMANTICS -#define COFFEE_IO_SEMANTICS 0 -#endif - /* * Prevent sectors from being erased directly after file removal. * This will level the wear across sectors better, but may lead @@ -94,24 +88,29 @@ #error COFFEE_START must point to the first byte in a sector. #endif +/* File descriptor flags. */ #define COFFEE_FD_FREE 0x0 #define COFFEE_FD_READ 0x1 #define COFFEE_FD_WRITE 0x2 #define COFFEE_FD_APPEND 0x4 +/* File object flags. */ #define COFFEE_FILE_MODIFIED 0x1 -#define INVALID_PAGE ((coffee_page_t)-1) +/* Internal Coffee markers. */ +#define INVALID_PAGE ((coffee_page_t)-1) #define UNKNOWN_OFFSET ((cfs_offset_t)-1) -#define REMOVE_LOG 1 -#define CLOSE_FDS 1 -#define ALLOW_GC 1 +/* File removal actions. They can have the same values because + they are passed as separate parameters. */ +#define REMOVE_LOG 1 +#define CLOSE_FDS 1 +#define ALLOW_GC 1 /* "Greedy" garbage collection erases as many sectors as possible. */ -#define GC_GREEDY 0 +#define GC_GREEDY 0 /* "Reluctant" garbage collection stops after erasing one sector. */ -#define GC_RELUCTANT 1 +#define GC_RELUCTANT 1 /* File descriptor macros. */ #define FD_VALID(fd) ((fd) >= 0 && (fd) < COFFEE_FD_SET_SIZE && \ @@ -176,9 +175,7 @@ struct file_desc { cfs_offset_t offset; struct file *file; uint8_t flags; -#if COFFEE_IO_SEMANTICS uint8_t io_flags; -#endif }; /* The file header structure mimics the representation of file headers @@ -221,11 +218,9 @@ static void read_header(struct file_header *hdr, coffee_page_t page) { COFFEE_READ(hdr, sizeof(*hdr), page * COFFEE_PAGE_SIZE); -#if DEBUG - if(HDR_ACTIVE(*hdr) && !HDR_VALID(*hdr)) { - PRINTF("Invalid header at page %u!\n", (unsigned)page); + if(DEBUG && HDR_ACTIVE(*hdr) && !HDR_VALID(*hdr)) { + PRINTF("Coffee: Invalid header at page %u!\n", (unsigned)page); } -#endif } /*---------------------------------------------------------------------------*/ static cfs_offset_t @@ -561,8 +556,8 @@ find_contiguous_pages(coffee_page_t amount) } /*---------------------------------------------------------------------------*/ static int -remove_by_page(coffee_page_t page, int remove_log, int close_fds, - int gc_allowed) +remove_by_page(coffee_page_t page, int remove_log, + int close_fds, int gc_allowed) { struct file_header hdr; int i; @@ -600,11 +595,9 @@ remove_by_page(coffee_page_t page, int remove_log, int close_fds, } } -#if !COFFEE_EXTENDED_WEAR_LEVELLING - if(gc_allowed) { + if(!COFFEE_EXTENDED_WEAR_LEVELLING && gc_allowed) { collect_garbage(GC_RELUCTANT); } -#endif return 0; } @@ -1104,19 +1097,13 @@ cfs_read(int fd, void *buf, unsigned size) fdp = &coffee_fd_set[fd]; file = fdp->file; -#if COFFEE_IO_SEMANTICS if(fdp->io_flags & CFS_COFFEE_IO_ENSURE_READ_LENGTH) { while(fdp->offset + size > file->end) { - ((char*)buf)[--size] = 0; + ((char *)buf)[--size] = '\0'; } - } else { -#endif - if(fdp->offset + size > file->end) { - size = file->end - fdp->offset; - } -#if COFFEE_IO_SEMANTICS + } else if(fdp->offset + size > file->end) { + size = file->end - fdp->offset; } -#endif /* If the file is not modified, read directly from the file extent. */ if(!FILE_MODIFIED(file)) { @@ -1173,28 +1160,20 @@ cfs_write(int fd, const void *buf, unsigned size) file = fdp->file; /* Attempt to extend the file if we try to write past the end. */ -#if COFFEE_IO_SEMANTICS if(!(fdp->io_flags & CFS_COFFEE_IO_FIRM_SIZE)) { -#endif - while(size + fdp->offset + sizeof(struct file_header) > - (file->max_pages * COFFEE_PAGE_SIZE)) { - if(merge_log(file->page, 1) < 0) { - return -1; + while(size + fdp->offset + sizeof(struct file_header) > + (file->max_pages * COFFEE_PAGE_SIZE)) { + if(merge_log(file->page, 1) < 0) { + return -1; + } + file = fdp->file; + PRINTF("Extended the file at page %u\n", (unsigned)file->page); } - file = fdp->file; - PRINTF("Extended the file at page %u\n", (unsigned)file->page); } -#if COFFEE_IO_SEMANTICS -} -#endif #if COFFEE_MICRO_LOGS -#if COFFEE_IO_SEMANTICS if(!(fdp->io_flags & CFS_COFFEE_IO_FLASH_AWARE) && (FILE_MODIFIED(file) || fdp->offset < file->end)) { -#else - if(FILE_MODIFIED(file) || fdp->offset < file->end) { -#endif need_dummy_write = 0; for(bytes_left = size; bytes_left > 0;) { lp.offset = fdp->offset; @@ -1236,16 +1215,14 @@ cfs_write(int fd, const void *buf, unsigned size) } } else { #endif /* COFFEE_MICRO_LOGS */ -#if COFFEE_APPEND_ONLY - if(fdp->offset < file->end) { - return -1; - } -#endif /* COFFEE_APPEND_ONLY */ + if(COFFEE_APPEND_ONLY && fdp->offset < file->end) { + return -1; + } - COFFEE_WRITE(buf, size, absolute_offset(file->page, fdp->offset)); - fdp->offset += size; + COFFEE_WRITE(buf, size, absolute_offset(file->page, fdp->offset)); + fdp->offset += size; #if COFFEE_MICRO_LOGS -} + } #endif /* COFFEE_MICRO_LOGS */ if(fdp->offset > file->end) { diff --git a/platform/native/cfs-coffee-arch.h b/platform/native/cfs-coffee-arch.h index d7622cd46..763e1ebae 100644 --- a/platform/native/cfs-coffee-arch.h +++ b/platform/native/cfs-coffee-arch.h @@ -55,7 +55,6 @@ #define COFFEE_LOG_SIZE 8192 #define COFFEE_LOG_TABLE_LIMIT 256 #define COFFEE_MICRO_LOGS 0 -#define COFFEE_IO_SEMANTICS 1 #define COFFEE_WRITE(buf, size, offset) \ xmem_pwrite((char *)(buf), (size), COFFEE_START + (offset)) diff --git a/platform/sky/cfs-coffee-arch.h b/platform/sky/cfs-coffee-arch.h index 08373c5e9..5eb183a42 100644 --- a/platform/sky/cfs-coffee-arch.h +++ b/platform/sky/cfs-coffee-arch.h @@ -59,7 +59,6 @@ #endif #define COFFEE_LOG_SIZE 1024 -#define COFFEE_IO_SEMANTICS 1 #define COFFEE_APPEND_ONLY 0 #define COFFEE_MICRO_LOGS 1 From a06110e5edc3e847430a01ecba41c40508fbfeb0 Mon Sep 17 00:00:00 2001 From: Nicolas Tsiftes Date: Mon, 13 Jun 2016 17:00:20 +0200 Subject: [PATCH 368/374] Renamed the internal dummy_space variable, since it contains useful information. --- core/cfs/cfs-coffee.c | 12 +++++------- core/cfs/cfs.h | 4 +++- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/cfs/cfs-coffee.c b/core/cfs/cfs-coffee.c index 3acd0480b..9aa5726b7 100644 --- a/core/cfs/cfs-coffee.c +++ b/core/cfs/cfs-coffee.c @@ -445,10 +445,7 @@ load_file(coffee_page_t start, struct file_header *hdr) file->page = start; file->end = UNKNOWN_OFFSET; file->max_pages = hdr->max_pages; - file->flags = 0; - if(HDR_MODIFIED(*hdr)) { - file->flags |= COFFEE_FILE_MODIFIED; - } + file->flags = HDR_MODIFIED(*hdr) ? COFFEE_FILE_MODIFIED : 0; /* We don't know the amount of records yet. */ file->record_count = -1; @@ -990,6 +987,7 @@ cfs_open(const char *name, int flags) fdp = &coffee_fd_set[fd]; fdp->flags = 0; + fdp->io_flags = 0; fdp->file = find_file(name); if(fdp->file == NULL) { @@ -1239,7 +1237,7 @@ cfs_opendir(struct cfs_dir *dir, const char *name) * Coffee is only guaranteed to support the directory names "/" and ".", * but it does not enforce this currently. */ - memset(dir->dummy_space, 0, sizeof(coffee_page_t)); + memset(dir->state, 0, sizeof(coffee_page_t)); return 0; } /*---------------------------------------------------------------------------*/ @@ -1250,7 +1248,7 @@ cfs_readdir(struct cfs_dir *dir, struct cfs_dirent *record) coffee_page_t page; coffee_page_t next_page; - memcpy(&page, dir->dummy_space, sizeof(coffee_page_t)); + memcpy(&page, dir->state, sizeof(coffee_page_t)); while(page < COFFEE_PAGE_COUNT) { read_header(&hdr, page); @@ -1260,7 +1258,7 @@ cfs_readdir(struct cfs_dir *dir, struct cfs_dirent *record) record->size = file_end(page); next_page = next_file(page, &hdr); - memcpy(dir->dummy_space, &next_page, sizeof(coffee_page_t)); + memcpy(dir->state, &next_page, sizeof(coffee_page_t)); return 0; } page = next_file(page, &hdr); diff --git a/core/cfs/cfs.h b/core/cfs/cfs.h index a0426b9ff..3e2452c61 100644 --- a/core/cfs/cfs.h +++ b/core/cfs/cfs.h @@ -68,7 +68,9 @@ typedef CFS_CONF_OFFSET_TYPE cfs_offset_t; #endif struct cfs_dir { - char dummy_space[32]; + /* Iteration state, which is implementation-defined and should not be + accessed externally. */ + char state[32]; }; struct cfs_dirent { From 67e0575bd38b3d332797d75d7ce3d3ae5e81fb27 Mon Sep 17 00:00:00 2001 From: cedric-d Date: Sun, 24 Apr 2016 12:06:09 +0200 Subject: [PATCH 369/374] Prevent uIP buffer over-read with big UDP packets When an UDP packet too big to fit in the uIP packet buffer is to be sent, the part fitting in the uIP buffer is copied to it (so no buffer overflow occurs) but uIP actually sends a packet of the original size therefore a buffer over-read occurs. This modification makes uIP discard the UDP packets that do not fit in the uIP packet buffer. --- core/net/ip/uip-udp-packet.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/core/net/ip/uip-udp-packet.c b/core/net/ip/uip-udp-packet.c index 923661709..b40d7cc9f 100644 --- a/core/net/ip/uip-udp-packet.c +++ b/core/net/ip/uip-udp-packet.c @@ -51,12 +51,10 @@ void uip_udp_packet_send(struct uip_udp_conn *c, const void *data, int len) { #if UIP_UDP - if(data != NULL) { + if(data != NULL && len <= (UIP_BUFSIZE - (UIP_LLH_LEN + UIP_IPUDPH_LEN))) { uip_udp_conn = c; uip_slen = len; - memmove(&uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN], data, - len > UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN? - UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN: len); + memmove(&uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN], data, len); uip_process(UIP_UDP_SEND_CONN); #if UIP_CONF_IPV6_MULTICAST From 8a273a248e33cb57a16650aeb8ea4b911a3e5809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Sun, 19 Jun 2016 22:57:36 +0200 Subject: [PATCH 370/374] cc2538: Add configuration for firmware location MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce FLASH_CONF_FW_ADDR and FLASH_CONF_FW_SIZE in order to make it possible to place the firmware anywhere, regardless of Coffee, and without having to write a custom linker script. Also, handle the default values properly in order to fix the link breakage reported by Arthur Fabre with COFFEE_CONF_CUSTOM_PORT. Signed-off-by: Benoît Thébaudeau --- cpu/cc2538/cc2538.lds | 3 +-- cpu/cc2538/dev/flash.h | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/cpu/cc2538/cc2538.lds b/cpu/cc2538/cc2538.lds index 189968717..ef465409e 100644 --- a/cpu/cc2538/cc2538.lds +++ b/cpu/cc2538/cc2538.lds @@ -35,8 +35,7 @@ */ MEMORY { - FLASH_FW (rx) : ORIGIN = COFFEE_START + COFFEE_SIZE, - LENGTH = FLASH_CCA_ADDR - (COFFEE_START + COFFEE_SIZE) + FLASH_FW (rx) : ORIGIN = FLASH_FW_ADDR, LENGTH = FLASH_FW_SIZE FLASH_CCA (RX) : ORIGIN = FLASH_CCA_ADDR, LENGTH = FLASH_CCA_SIZE /* diff --git a/cpu/cc2538/dev/flash.h b/cpu/cc2538/dev/flash.h index 6af19723e..49db85b20 100644 --- a/cpu/cc2538/dev/flash.h +++ b/cpu/cc2538/dev/flash.h @@ -48,6 +48,7 @@ #define FLASH_H_ #include "dev/cc2538-dev.h" +#include "cfs-coffee-arch.h" #include /*---------------------------------------------------------------------------*/ @@ -90,6 +91,23 @@ #define FLASH_CCA_LOCK_DEBUG_BIT 7 /**< Debug lock bit position in the corresponding lock byte */ /** @} */ /*---------------------------------------------------------------------------*/ +/** \name Firmware location in flash memory + * @{ + */ +#ifdef FLASH_CONF_FW_ADDR +#define FLASH_FW_ADDR FLASH_CONF_FW_ADDR +#elif !defined(COFFEE_CONF_CUSTOM_PORT) +#define FLASH_FW_ADDR (COFFEE_START + COFFEE_SIZE) +#else +#define FLASH_FW_ADDR CC2538_DEV_FLASH_ADDR +#endif +#ifdef FLASH_CONF_FW_SIZE +#define FLASH_FW_SIZE FLASH_CONF_FW_SIZE +#else +#define FLASH_FW_SIZE (FLASH_CCA_ADDR - FLASH_FW_ADDR) +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ /** \name Flash lock bit page and CCA layout * @{ */ From 8fd7719c073b8c6ec4c7fdd178b266bb8e327064 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Thu, 23 Jun 2016 22:10:43 +0200 Subject: [PATCH 371/374] noncoresec: Fix build errors with DEBUG set to 1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix these build errors, which are generated if DEBUG is set to 1: ../../core/net/llsec/noncoresec/noncoresec.c: In function 'parse': ../../core/net/llsec/noncoresec/noncoresec.c:198:54: error: expected ')' before 'PRIu32' PRINTF("noncoresec: received unauthentic frame %"PRIu32"\n", ^ ../../core/net/llsec/noncoresec/noncoresec.c:88:28: note: in definition of macro 'PRINTF' #define PRINTF(...) printf(__VA_ARGS__) ^ ../../core/net/llsec/noncoresec/noncoresec.c:198:12: warning: spurious trailing '%' in format [-Wformat=] PRINTF("noncoresec: received unauthentic frame %"PRIu32"\n", ^ ../../core/net/llsec/noncoresec/noncoresec.c:88:28: note: in definition of macro 'PRINTF' #define PRINTF(...) printf(__VA_ARGS__) ^ ../../core/net/llsec/noncoresec/noncoresec.c:198:12: warning: spurious trailing '%' in format [-Wformat=] PRINTF("noncoresec: received unauthentic frame %"PRIu32"\n", ^ ../../core/net/llsec/noncoresec/noncoresec.c:88:28: note: in definition of macro 'PRINTF' #define PRINTF(...) printf(__VA_ARGS__) ^ ../../core/net/llsec/noncoresec/noncoresec.c:231:54: error: expected ')' before 'PRIu32' PRINTF("noncoresec: received replayed frame %"PRIu32"\n", ^ ../../core/net/llsec/noncoresec/noncoresec.c:88:28: note: in definition of macro 'PRINTF' #define PRINTF(...) printf(__VA_ARGS__) ^ ../../core/net/llsec/noncoresec/noncoresec.c:231:15: warning: spurious trailing '%' in format [-Wformat=] PRINTF("noncoresec: received replayed frame %"PRIu32"\n", ^ ../../core/net/llsec/noncoresec/noncoresec.c:88:28: note: in definition of macro 'PRINTF' #define PRINTF(...) printf(__VA_ARGS__) ^ ../../core/net/llsec/noncoresec/noncoresec.c:231:15: warning: spurious trailing '%' in format [-Wformat=] PRINTF("noncoresec: received replayed frame %"PRIu32"\n", ^ ../../core/net/llsec/noncoresec/noncoresec.c:88:28: note: in definition of macro 'PRINTF' #define PRINTF(...) printf(__VA_ARGS__) ^ PRIu32 is not defined, so replace it with a standard format directive. Signed-off-by: Benoît Thébaudeau --- core/net/llsec/noncoresec/noncoresec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/net/llsec/noncoresec/noncoresec.c b/core/net/llsec/noncoresec/noncoresec.c index 71a1cb82a..f9d442651 100644 --- a/core/net/llsec/noncoresec/noncoresec.c +++ b/core/net/llsec/noncoresec/noncoresec.c @@ -195,7 +195,7 @@ parse(void) packetbuf_set_datalen(packetbuf_datalen() - MIC_LEN); if(!aead(result, 0)) { - PRINTF("noncoresec: received unauthentic frame %"PRIu32"\n", + PRINTF("noncoresec: received unauthentic frame %lu\n", anti_replay_get_counter()); return FRAMER_FAILED; } @@ -228,7 +228,7 @@ parse(void) anti_replay_init_info(info); } else { if(anti_replay_was_replayed(info)) { - PRINTF("noncoresec: received replayed frame %"PRIu32"\n", + PRINTF("noncoresec: received replayed frame %lu\n", anti_replay_get_counter()); return FRAMER_FAILED; } From 1da00a482fe91e4e4af2324202439a799cc02f89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Thu, 23 Jun 2016 22:25:27 +0200 Subject: [PATCH 372/374] cc2538: aes: Fix possibly missing result available status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Depending on the use case and on the timings, aes_auth_crypt_check_status() sometimes never reported an available result, leading to a deadlock of any protothread waiting for this event, and to a WDT reset if a protothread was polling it. This was caused by aes_auth_crypt_start() clearing the result available interrupt after operations that may rightfully trigger it, leading to a missed interrupt. Signed-off-by: Benoît Thébaudeau --- cpu/cc2538/dev/aes.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/cpu/cc2538/dev/aes.c b/cpu/cc2538/dev/aes.c index 429def67b..2b9e11a17 100644 --- a/cpu/cc2538/dev/aes.c +++ b/cpu/cc2538/dev/aes.c @@ -226,12 +226,14 @@ aes_auth_crypt_start(uint32_t ctrl, uint8_t key_area, const void *iv, REG(AES_CTRL_ALG_SEL) = 0x00000000; return CRYPTO_DMA_BUS_ERROR; } + + /* Clear interrupt status */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE; } } - /* Clear interrupt status */ - REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE | - AES_CTRL_INT_CLR_RESULT_AV; + /* Enable result available bit in interrupt enable */ + REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_RESULT_AV; if(process != NULL) { crypto_register_process_notification(process); @@ -239,9 +241,6 @@ aes_auth_crypt_start(uint32_t ctrl, uint8_t key_area, const void *iv, nvic_interrupt_enable(NVIC_INT_AES); } - /* Enable result available bit in interrupt enable */ - REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_RESULT_AV; - if(data_len != 0) { /* Configure DMAC * Enable DMA channel 0 */ From c28b6fb7ba8973749b548ccb6720395d49bfd6f6 Mon Sep 17 00:00:00 2001 From: kkrentz Date: Sun, 29 May 2016 04:29:43 -0700 Subject: [PATCH 373/374] CC2538: Reboot if the crypto engine fails (error handling is too hard) --- cpu/cc2538/dev/cc2538-aes-128.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cpu/cc2538/dev/cc2538-aes-128.c b/cpu/cc2538/dev/cc2538-aes-128.c index a1031c2c8..aa5b5e8e6 100644 --- a/cpu/cc2538/dev/cc2538-aes-128.c +++ b/cpu/cc2538/dev/cc2538-aes-128.c @@ -40,6 +40,7 @@ #include "contiki.h" #include "dev/ecb.h" #include "dev/cc2538-aes-128.h" +#include "dev/sys-ctrl.h" #include #include @@ -82,6 +83,7 @@ set_key(const uint8_t *key) CC2538_AES_128_KEY_AREA); if(ret != CRYPTO_SUCCESS) { PRINTF("%s: aes_load_keys() error %u\n", MODULE_NAME, ret); + sys_ctrl_reset(); } restore_crypto(crypto_enabled); @@ -99,13 +101,13 @@ encrypt(uint8_t *plaintext_and_result) plaintext_and_result, AES_128_BLOCK_SIZE, NULL); if(ret != CRYPTO_SUCCESS) { PRINTF("%s: ecb_crypt_start() error %u\n", MODULE_NAME, ret); - restore_crypto(crypto_enabled); - return; + sys_ctrl_reset(); } while((res = ecb_crypt_check_status()) == CRYPTO_PENDING); if(res != CRYPTO_SUCCESS) { PRINTF("%s: ecb_crypt_check_status() error %d\n", MODULE_NAME, res); + sys_ctrl_reset(); } restore_crypto(crypto_enabled); From bc8b6cd8ed2ee431c9b80ab93548b15fa265fd22 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Fri, 24 Jun 2016 22:10:39 +0200 Subject: [PATCH 374/374] Updated cc2538-bsl to version 2.1 (c6100a7) --- tools/cc2538-bsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/cc2538-bsl b/tools/cc2538-bsl index 434054237..c6100a779 160000 --- a/tools/cc2538-bsl +++ b/tools/cc2538-bsl @@ -1 +1 @@ -Subproject commit 4340542370d3e319d692f9f969c5683231fce438 +Subproject commit c6100a7794c7b530923145c03e37412013a4551e