diff --git a/examples/cc26xx/very-sleepy-demo/Makefile b/examples/cc26xx/very-sleepy-demo/Makefile new file mode 100644 index 000000000..a1e794957 --- /dev/null +++ b/examples/cc26xx/very-sleepy-demo/Makefile @@ -0,0 +1,12 @@ +DEFINES+=PROJECT_CONF_H=\"project-conf.h\" +CONTIKI_PROJECT = very-sleepy-demo + +all: $(CONTIKI_PROJECT) + +CONTIKI_WITH_IPV6 = 1 + +APPS += er-coap +APPS += rest-engine + +CONTIKI = ../../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/cc26xx/very-sleepy-demo/Makefile.target b/examples/cc26xx/very-sleepy-demo/Makefile.target new file mode 100644 index 000000000..15890aa6a --- /dev/null +++ b/examples/cc26xx/very-sleepy-demo/Makefile.target @@ -0,0 +1 @@ +TARGET = srf06-cc26xx diff --git a/examples/cc26xx/very-sleepy-demo/README.md b/examples/cc26xx/very-sleepy-demo/README.md new file mode 100644 index 000000000..fcdedf77f --- /dev/null +++ b/examples/cc26xx/very-sleepy-demo/README.md @@ -0,0 +1,91 @@ +# CC13xx/CC26xx Very Sleepy Demo + +This example demonstrates a way of deploying a very low-consuming, very sleepy +node. The node has two modes of operation: + +* Normal: ContikiMAC duty-cycles the radio as usual. The node is reachable. +* Very Sleepy: Radio cycling mostly off, except when we need to perform network + maintenance tasks. In this mode, the node is unreachable for most of the time. + +The node will operate in RPL leaf mode. This means that it will be reachable +downwards, but it will not advertise the DODAG and it will not participate in +routing. + +After booting, the node will enter "normal" mode. + +The node exposes an OBSERVEable CoAP resource. It will notify subscribers with +a new value for this resource every `interval` seconds. It will then stay in +normal mode for `duration` seconds. During this time window, it will be +reachable over the network in order to e.g. receive a new configuration. +When this time window expires, the node will switch back to very sleepy mode. +This will only happen if very sleepy mode has been enabled by setting `mode=1` +as per the instructions below. + +When the node is duty-cycling the radio, either because it is in normal mode or +because network maintenance is taking place, it will keep its green LED on thus +providing an indication that it is reachable. + +A normal mode stint can be manually triggered by pressing the left button. + +## Requirements + +To run this example you will need: + +* A border router operating with the same RDC, same channel, same radio mode + (e.g. IEEE or sub-ghz), same PAN ID. Alternatively, you can + use [6lbr](https://github.com/cetic/6lbr) with a suitable slip-radio. +* The [Copper (Cu)](https://addons.mozilla.org/en-US/firefox/addon/copper-270430/) + addon for Firefox + +## Configuration + +To configure the node, send a CoAP POST message to the `very_sleepy_config` +resource. The POST message's payload must specify _at least one_ of: + +* `mode=0|1`: Send `mode=1` to enable very sleepy mode, `mode=0` to disable it. +* `interval=n` where `n` is the number of seconds between two consecutive normal + mode periods. This interval also dictates the OBSERVEr notification period. +* `duration=n` where `n` is the number of seconds that the node will stay in + normal mode before dropping to very sleepy mode. This value is only relevant + if `mode==1`. + +A POST request must contain at least one of the above, but they are otherwise +all optional. So, for example, a POST may simply specify `interval=n`. To send +multiple values, delimit them with `&`. So you can send something like +`mode=1&interval=60&duration=20` + +The current running configuration can be retrieved by sending a GET request to +the same CoAP resource. + +## Running the example + +* Deploy your border router or 6lbr +* Turn on the very sleepy node. +* Fire up the Copper addon +* Select `.well-known/core` and hit `GET` +* Configure very sleepy operation: + * Select the `very_sleepy_config` resource + * In the `Outgoing` pane, type your POST payload as per the instructions + above. For example, you can type: `mode=1&interval=30&duration=10` + * Hit `POST` +* Select the `sen/readings` resource and hit `OBSERVE` + +## Caveats + +If you click on a resource in the Copper resources tree while you are observing +a different resource, the OBSERVEr for the latter will be stopped without +notifying the CoAP server. This will result in the server sending out OBSERVE +notifications that will be responded to with port unreachable ICMPv6 messages. +This will continue for quite a while, until the server detects that the +OBSERVEr has been lost (a test currently performed once every 20 notifications). +In order to prevent this from happening, hit the "Cancel" button for the +OBSERVE before switching views to a different resource. This will unregister +the observer. + +In very sleepy mode, the radio is not truly always off. The contiki core needs +to perform other periodic tasks in order to maintain network connectivity. For +that reason, this example will allow the radio to turn on periodically even +while in very sleepy mode. Thus, you may see that the node becomes briefly +reachable every now and then. However, do not count on those periods of +reachability to perform any tasks, as they will be brief and will be disrupted +without warning. diff --git a/examples/cc26xx/very-sleepy-demo/project-conf.h b/examples/cc26xx/very-sleepy-demo/project-conf.h new file mode 100644 index 000000000..477a535bf --- /dev/null +++ b/examples/cc26xx/very-sleepy-demo/project-conf.h @@ -0,0 +1,51 @@ +/* + * 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. + */ +/*---------------------------------------------------------------------------*/ +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ +/*---------------------------------------------------------------------------*/ +/* Change to match your configuration */ +#define IEEE802154_CONF_PANID 0xABCD +#define RF_CORE_CONF_CHANNEL 25 +/*---------------------------------------------------------------------------*/ +/* For very sleepy operation */ +#define RF_BLE_CONF_ENABLED 0 +#define UIP_DS6_CONF_PERIOD CLOCK_SECOND +#define UIP_CONF_TCP 0 +#define RPL_CONF_LEAF_ONLY 1 + +/* + * We'll fail without RPL probing, so turn it on explicitly even though it's + * on by default + */ +#define RPL_CONF_WITH_PROBING 1 +/*---------------------------------------------------------------------------*/ +#endif /* PROJECT_CONF_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/cc26xx/very-sleepy-demo/very-sleepy-demo.c b/examples/cc26xx/very-sleepy-demo/very-sleepy-demo.c new file mode 100644 index 000000000..5719e11ce --- /dev/null +++ b/examples/cc26xx/very-sleepy-demo/very-sleepy-demo.c @@ -0,0 +1,423 @@ +/* + * 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. + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "sys/etimer.h" +#include "sys/stimer.h" +#include "sys/process.h" +#include "dev/leds.h" +#include "dev/watchdog.h" +#include "button-sensor.h" +#include "batmon-sensor.h" +#include "board-peripherals.h" +#include "net/netstack.h" +#include "net/ipv6/uip-ds6-nbr.h" +#include "net/ipv6/uip-ds6-route.h" +#include "net/rpl/rpl.h" +#include "net/rpl/rpl-private.h" +#include "rest-engine.h" +#include "er-coap.h" + +#include "ti-lib.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +/* Normal mode duration params in seconds */ +#define NORMAL_OP_DURATION_DEFAULT 10 +#define NORMAL_OP_DURATION_MIN 10 +#define NORMAL_OP_DURATION_MAX 60 +/*---------------------------------------------------------------------------*/ +/* Observer notification period params in seconds */ +#define PERIODIC_INTERVAL_DEFAULT 30 +#define PERIODIC_INTERVAL_MIN 30 +#define PERIODIC_INTERVAL_MAX 86400 /* 1 day */ +/*---------------------------------------------------------------------------*/ +#define VERY_SLEEPY_MODE_OFF 0 +#define VERY_SLEEPY_MODE_ON 1 +/*---------------------------------------------------------------------------*/ +#define MAC_CAN_BE_TURNED_OFF 0 +#define MAC_MUST_STAY_ON 1 + +#define KEEP_MAC_ON_MIN_PERIOD 10 /* secs */ +/*---------------------------------------------------------------------------*/ +#define PERIODIC_INTERVAL CLOCK_SECOND +/*---------------------------------------------------------------------------*/ +#define POST_STATUS_BAD 0x80 +#define POST_STATUS_HAS_MODE 0x40 +#define POST_STATUS_HAS_DURATION 0x20 +#define POST_STATUS_HAS_INTERVAL 0x10 +#define POST_STATUS_NONE 0x00 +/*---------------------------------------------------------------------------*/ +typedef struct sleepy_config_s { + unsigned long interval; + unsigned long duration; + uint8_t mode; +} sleepy_config_t; + +sleepy_config_t config; +/*---------------------------------------------------------------------------*/ +#define STATE_NORMAL 0 +#define STATE_NOTIFY_OBSERVERS 1 +#define STATE_VERY_SLEEPY 2 +/*---------------------------------------------------------------------------*/ +static struct stimer st_duration; +static struct stimer st_interval; +static struct stimer st_min_mac_on_duration; +static struct etimer et_periodic; +static process_event_t event_new_config; +static uint8_t state; +/*---------------------------------------------------------------------------*/ +const char *not_supported_msg = "Supported:text/plain,application/json"; +/*---------------------------------------------------------------------------*/ +PROCESS(very_sleepy_demo_process, "CC13xx/CC26xx very sleepy process"); +AUTOSTART_PROCESSES(&very_sleepy_demo_process); +/*---------------------------------------------------------------------------*/ +static void +readings_get_handler(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + int temp; + int voltage; + + if(request != NULL) { + REST.get_header_accept(request, &accept); + } + + temp = batmon_sensor.value(BATMON_SENSOR_TYPE_TEMP); + + voltage = batmon_sensor.value(BATMON_SENSOR_TYPE_VOLT); + + if(accept == -1 || accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, + "{\"temp\":{\"v\":%d,\"u\":\"C\"}," + "\"voltage\":{\"v\":%d,\"u\":\"mV\"}}", + temp, (voltage * 125) >> 5); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "Temp=%dC, Voltage=%dmV", + temp, (voltage * 125) >> 5); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + REST.set_response_payload(response, not_supported_msg, + strlen(not_supported_msg)); + } +} +/*---------------------------------------------------------------------------*/ +RESOURCE(readings_resource, "title=\"Sensor Readings\";obs", + readings_get_handler, NULL, NULL, NULL); +/*---------------------------------------------------------------------------*/ +static void +conf_get_handler(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + + if(request != NULL) { + REST.get_header_accept(request, &accept); + } + + if(accept == -1 || accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, + "{\"config\":{\"mode\":%u,\"duration\":%lu,\"interval\":%lu}}", + config.mode, config.duration, config.interval); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, + "Mode=%u, Duration=%lusecs, Interval=%lusecs", + config.mode, config.duration, config.interval); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + REST.set_response_payload(response, not_supported_msg, + strlen(not_supported_msg)); + } +} +/*---------------------------------------------------------------------------*/ +static void +conf_post_handler(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + const char *ptr = NULL; + char tmp_buf[16]; + unsigned long interval = 0; + unsigned long duration = 0; + uint8_t mode = VERY_SLEEPY_MODE_OFF; + uint8_t post_status = POST_STATUS_NONE; + int rv; + + rv = REST.get_post_variable(request, "mode", &ptr); + if(rv && rv < 16) { + memset(tmp_buf, 0, sizeof(tmp_buf)); + memcpy(tmp_buf, ptr, rv); + rv = atoi(tmp_buf); + + if(rv == 1) { + mode = VERY_SLEEPY_MODE_ON; + post_status |= POST_STATUS_HAS_MODE; + } else if(rv == 0) { + mode = VERY_SLEEPY_MODE_OFF; + post_status |= POST_STATUS_HAS_MODE; + } else { + post_status = POST_STATUS_BAD; + } + } + + rv = REST.get_post_variable(request, "duration", &ptr); + if(rv && rv < 16) { + memset(tmp_buf, 0, sizeof(tmp_buf)); + memcpy(tmp_buf, ptr, rv); + rv = atoi(tmp_buf); + + duration = (unsigned long)rv; + if(duration < NORMAL_OP_DURATION_MIN || duration > NORMAL_OP_DURATION_MAX) { + post_status = POST_STATUS_BAD; + } else { + post_status |= POST_STATUS_HAS_DURATION; + } + } + + rv = REST.get_post_variable(request, "interval", &ptr); + if(rv && rv < 16) { + memset(tmp_buf, 0, sizeof(tmp_buf)); + memcpy(tmp_buf, ptr, rv); + rv = atoi(tmp_buf); + interval = (unsigned long)rv; + if(interval < PERIODIC_INTERVAL_MIN || interval > PERIODIC_INTERVAL_MAX) { + post_status = POST_STATUS_BAD; + } else { + post_status |= POST_STATUS_HAS_INTERVAL; + } + } + + if((post_status & POST_STATUS_BAD) == POST_STATUS_BAD || + post_status == POST_STATUS_NONE) { + REST.set_response_status(response, REST.status.BAD_REQUEST); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, + "mode=0|1&duration=[%u,%u]&interval=[%u,%u]", + NORMAL_OP_DURATION_MIN, NORMAL_OP_DURATION_MAX, + PERIODIC_INTERVAL_MIN, PERIODIC_INTERVAL_MAX); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + return; + } + + /* Values are sane. Update the config and notify the process */ + if(post_status & POST_STATUS_HAS_MODE) { + config.mode = mode; + } + + if(post_status & POST_STATUS_HAS_INTERVAL) { + config.interval = interval; + } + + if(post_status & POST_STATUS_HAS_DURATION) { + config.duration = duration; + } + + process_post(&very_sleepy_demo_process, event_new_config, NULL); +} +/*---------------------------------------------------------------------------*/ +RESOURCE(very_sleepy_conf, + "title=\"Very sleepy conf: " + "GET|POST mode=0|1&interval=&duration=\";rt=\"Control\"", + conf_get_handler, conf_post_handler, NULL, NULL); +/*---------------------------------------------------------------------------*/ +/* + * If our preferred parent is not NBR_REACHABLE in the ND cache, NUD will send + * a unicast NS and wait for NA. If NA fails then the neighbour will be removed + * from the ND cache and the default route will be deleted. To prevent this, + * keep the MAC on until the parent becomes NBR_REACHABLE. We also keep the MAC + * on if we are about to do RPL probing. + * + * In all cases, the radio will be locked on for KEEP_MAC_ON_MIN_PERIOD secs + */ +static uint8_t +keep_mac_on(void) +{ + uip_ds6_nbr_t *nbr; + uint8_t rv = MAC_CAN_BE_TURNED_OFF; + + if(!stimer_expired(&st_min_mac_on_duration)) { + return MAC_MUST_STAY_ON; + } + +#if RPL_WITH_PROBING + /* Determine if we are about to send a RPL probe */ + if(CLOCK_LT(etimer_expiration_time( + &rpl_get_default_instance()->probing_timer.etimer), + (clock_time() + PERIODIC_INTERVAL))) { + rv = MAC_MUST_STAY_ON; + } +#endif + + /* It's OK to pass a NULL pointer, the callee checks and returns NULL */ + nbr = uip_ds6_nbr_lookup(uip_ds6_defrt_choose()); + + if(nbr == NULL) { + /* We don't have a default route, or it's not reachable (NUD likely). */ + rv = MAC_MUST_STAY_ON; + } else { + if(nbr->state != NBR_REACHABLE) { + rv = MAC_MUST_STAY_ON; + } + } + + if(rv == MAC_MUST_STAY_ON && stimer_expired(&st_min_mac_on_duration)) { + stimer_set(&st_min_mac_on_duration, KEEP_MAC_ON_MIN_PERIOD); + } + + return rv; +} +/*---------------------------------------------------------------------------*/ +static void +switch_to_normal(void) +{ + state = STATE_NOTIFY_OBSERVERS; + + /* + * Stay in normal mode for 'duration' secs. + * Transition back to normal in 'interval' secs, _including_ 'duration' + */ + stimer_set(&st_duration, config.duration); + stimer_set(&st_interval, config.interval); +} +/*---------------------------------------------------------------------------*/ +static void +switch_to_very_sleepy(void) +{ + state = STATE_VERY_SLEEPY; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(very_sleepy_demo_process, ev, data) +{ + uint8_t mac_keep_on; + + PROCESS_BEGIN(); + + SENSORS_ACTIVATE(batmon_sensor); + + config.mode = VERY_SLEEPY_MODE_OFF; + config.interval = PERIODIC_INTERVAL_DEFAULT; + config.duration = NORMAL_OP_DURATION_DEFAULT; + + state = STATE_NORMAL; + + event_new_config = process_alloc_event(); + + rest_init_engine(); + + readings_resource.flags += IS_OBSERVABLE; + rest_activate_resource(&readings_resource, "sen/readings"); + rest_activate_resource(&very_sleepy_conf, "very_sleepy_config"); + + printf("Very Sleepy Demo Process\n"); + + switch_to_normal(); + + etimer_set(&et_periodic, PERIODIC_INTERVAL); + + while(1) { + + PROCESS_YIELD(); + + if(ev == sensors_event && data == &button_left_sensor) { + switch_to_normal(); + } + + if(ev == event_new_config) { + stimer_set(&st_interval, config.interval); + stimer_set(&st_duration, config.duration); + } + + if((ev == PROCESS_EVENT_TIMER && data == &et_periodic) || + (ev == sensors_event && data == &button_left_sensor) || + (ev == event_new_config)) { + + /* + * Determine if the stack is about to do essential network maintenance + * and, if so, keep the MAC layer on + */ + mac_keep_on = keep_mac_on(); + + if(mac_keep_on == MAC_MUST_STAY_ON || state != STATE_VERY_SLEEPY) { + leds_on(LEDS_GREEN); + NETSTACK_MAC.on(); + } + + /* + * Next, switch between normal and very sleepy mode depending on config, + * send notifications to observers as required. + */ + if(state == STATE_NOTIFY_OBSERVERS) { + REST.notify_subscribers(&readings_resource); + state = STATE_NORMAL; + } + + if(state == STATE_NORMAL) { + if(stimer_expired(&st_duration)) { + stimer_set(&st_duration, config.duration); + if(config.mode == VERY_SLEEPY_MODE_ON) { + switch_to_very_sleepy(); + } + } + } else if(state == STATE_VERY_SLEEPY) { + if(stimer_expired(&st_interval)) { + switch_to_normal(); + } + } + + if(mac_keep_on == MAC_CAN_BE_TURNED_OFF && state == STATE_VERY_SLEEPY) { + leds_off(LEDS_GREEN); + NETSTACK_MAC.off(0); + } else { + leds_on(LEDS_GREEN); + NETSTACK_MAC.on(); + } + + /* Schedule next pass */ + etimer_set(&et_periodic, PERIODIC_INTERVAL); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/regression-tests/18-compile-arm-ports/Makefile b/regression-tests/18-compile-arm-ports/Makefile index 217b5eef9..222474b13 100644 --- a/regression-tests/18-compile-arm-ports/Makefile +++ b/regression-tests/18-compile-arm-ports/Makefile @@ -8,6 +8,7 @@ webserver-ipv6/ev-aducrf101mkxz \ ipv6/multicast/ev-aducrf101mkxz \ cc2538dk/sniffer/ev-aducrf101mkxz \ cc26xx/cc26xx-web-demo/srf06-cc26xx \ +cc26xx/very-sleepy-demo/srf06-cc26xx \ hello-world/cc2538dk \ ipv6/rpl-border-router/cc2538dk \ er-rest-example/cc2538dk \