From f9516eae732a58ee28da3da8d8c1f3a91e3ff9f5 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Wed, 22 Nov 2017 17:48:39 +0000 Subject: [PATCH 01/81] Add stack check library and example --- arch/cpu/cc2538/cc2538.lds | 7 + arch/cpu/cc26xx-cc13xx/cc26xx.ld | 6 + arch/cpu/msp430/Makefile.msp430 | 3 + arch/cpu/nrf52832/ld/nrf52-pca10036-sd.ld | 6 +- arch/cpu/nrf52832/ld/nrf52-pca10040-sd.ld | 6 +- arch/cpu/nrf52832/ld/nrf52.ld | 6 +- arch/platform/cooja/contiki-conf.h | 2 + arch/platform/jn516x/Makefile.jn516x | 4 + arch/platform/native/contiki-conf.h | 1 + arch/platform/sky/platform-conf.h | 8 + examples/libs/stack-check/Makefile | 5 + examples/libs/stack-check/example-sky.csc | 90 ++++++++++ .../libs/stack-check/example-stack-check.c | 88 ++++++++++ examples/libs/stack-check/project-conf.h | 44 +++++ os/contiki-main.c | 5 + os/sys/stack-check.c | 162 ++++++++++++++++++ os/sys/stack-check.h | 130 ++++++++++++++ 17 files changed, 570 insertions(+), 3 deletions(-) create mode 100644 examples/libs/stack-check/Makefile create mode 100644 examples/libs/stack-check/example-sky.csc create mode 100644 examples/libs/stack-check/example-stack-check.c create mode 100644 examples/libs/stack-check/project-conf.h create mode 100644 os/sys/stack-check.c create mode 100644 os/sys/stack-check.h diff --git a/arch/cpu/cc2538/cc2538.lds b/arch/cpu/cc2538/cc2538.lds index ef465409e..4d5031f15 100644 --- a/arch/cpu/cc2538/cc2538.lds +++ b/arch/cpu/cc2538/cc2538.lds @@ -96,11 +96,18 @@ SECTIONS _ebss = .; } > FRSRAM + _end = .; /* End of the .bss segment. */ + + /* This symbol is used by the stack check library. */ + _stack = .; + .stack (NOLOAD) : { *(.stack) } > FRSRAM + /* This symbol is used by the stack check library. */ + _stack_origin = .; _heap = .; _eheap = ORIGIN(FRSRAM) + LENGTH(FRSRAM); diff --git a/arch/cpu/cc26xx-cc13xx/cc26xx.ld b/arch/cpu/cc26xx-cc13xx/cc26xx.ld index 84601ced6..11bd9ca6f 100644 --- a/arch/cpu/cc26xx-cc13xx/cc26xx.ld +++ b/arch/cpu/cc26xx-cc13xx/cc26xx.ld @@ -90,6 +90,12 @@ SECTIONS _ebss = .; } > SRAM + _end = .; /* End of the .bss segment. */ + + /* These symbols are used by the stack check library. */ + _stack = .; + _stack_origin = ORIGIN(SRAM) + LENGTH(SRAM); + .ccfg : { KEEP(*(.ccfg)) diff --git a/arch/cpu/msp430/Makefile.msp430 b/arch/cpu/msp430/Makefile.msp430 index 97ea7f3f2..82af8d420 100644 --- a/arch/cpu/msp430/Makefile.msp430 +++ b/arch/cpu/msp430/Makefile.msp430 @@ -182,6 +182,9 @@ endif # SMALL endif # IAR +# Define the `_stack` symbol used by the stack check library to be equal to `_end` +LDFLAGS += -Wl,--defsym=_stack=_end + CFLAGS += $(CFLAGSNO) PROJECT_OBJECTFILES += ${addprefix $(OBJECTDIR)/,$(CONTIKI_TARGET_MAIN:.c=.o)} diff --git a/arch/cpu/nrf52832/ld/nrf52-pca10036-sd.ld b/arch/cpu/nrf52832/ld/nrf52-pca10036-sd.ld index 455749e29..f3bc5bc43 100644 --- a/arch/cpu/nrf52832/ld/nrf52-pca10036-sd.ld +++ b/arch/cpu/nrf52832/ld/nrf52-pca10036-sd.ld @@ -9,4 +9,8 @@ MEMORY RAM (rwx) : ORIGIN = 0x08000000, LENGTH = 0x8000 } -INCLUDE "nrf5x_common.ld" \ No newline at end of file +INCLUDE "nrf5x_common.ld" + +/* These symbols are used by the stack check library. */ +_stack = end; +_stack_origin = ORIGIN(RAM) + LENGTH(RAM); diff --git a/arch/cpu/nrf52832/ld/nrf52-pca10040-sd.ld b/arch/cpu/nrf52832/ld/nrf52-pca10040-sd.ld index f30aad455..0bc7349e3 100644 --- a/arch/cpu/nrf52832/ld/nrf52-pca10040-sd.ld +++ b/arch/cpu/nrf52832/ld/nrf52-pca10040-sd.ld @@ -9,4 +9,8 @@ MEMORY RAM (rwx) : ORIGIN = 0x20002800, LENGTH = 0xD800 } -INCLUDE "nrf5x_common.ld" \ No newline at end of file +INCLUDE "nrf5x_common.ld" + +/* These symbols are used by the stack check library. */ +_stack = end; +_stack_origin = ORIGIN(RAM) + LENGTH(RAM); diff --git a/arch/cpu/nrf52832/ld/nrf52.ld b/arch/cpu/nrf52832/ld/nrf52.ld index 268794d04..87fc9152d 100644 --- a/arch/cpu/nrf52832/ld/nrf52.ld +++ b/arch/cpu/nrf52832/ld/nrf52.ld @@ -9,4 +9,8 @@ MEMORY RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x8000 } -INCLUDE "nrf5x_common.ld" \ No newline at end of file +INCLUDE "nrf5x_common.ld" + +/* These symbols are used by the stack check library. */ +_stack = end; +_stack_origin = ORIGIN(RAM) + LENGTH(RAM); diff --git a/arch/platform/cooja/contiki-conf.h b/arch/platform/cooja/contiki-conf.h index 7dea26e17..af7582ab9 100644 --- a/arch/platform/cooja/contiki-conf.h +++ b/arch/platform/cooja/contiki-conf.h @@ -135,4 +135,6 @@ typedef uint64_t rtimer_clock_t; #define RF_CHANNEL 26 #define NETSTACK_RADIO_MAX_PAYLOAD_LEN 125 +#define PLATFORM_CONF_SUPPORTS_STACK_CHECK 0 + #endif /* CONTIKI_CONF_H_ */ diff --git a/arch/platform/jn516x/Makefile.jn516x b/arch/platform/jn516x/Makefile.jn516x index 8664f9f0a..50a008374 100644 --- a/arch/platform/jn516x/Makefile.jn516x +++ b/arch/platform/jn516x/Makefile.jn516x @@ -164,6 +164,10 @@ CFLAGS := $(patsubst -I/cygdrive/c/%,-Ic:/%,$(CFLAGS)) LDFLAGS := $(patsubst -L/cygdrive/c/%,-Lc:/%,$(LDFLAGS)) endif +# These symbols are used by the stack check library +LDFLAGS += -Wl,--defsym=_stack=_stack_low_water_mark +LDFLAGS += -Wl,--defsym=_stack_origin=_ram_top + ######################################################################## MOTELIST = python $(CONTIKI)/tools/jn516x/mote-list.py diff --git a/arch/platform/native/contiki-conf.h b/arch/platform/native/contiki-conf.h index f4f7bb1ba..c315b8e18 100644 --- a/arch/platform/native/contiki-conf.h +++ b/arch/platform/native/contiki-conf.h @@ -101,5 +101,6 @@ int strcasecmp(const char*, const char*); #define PLATFORM_CONF_PROVIDES_MAIN_LOOP 1 #define PLATFORM_CONF_MAIN_ACCEPTS_ARGS 1 +#define PLATFORM_CONF_SUPPORTS_STACK_CHECK 0 #endif /* CONTIKI_CONF_H_ */ diff --git a/arch/platform/sky/platform-conf.h b/arch/platform/sky/platform-conf.h index 7a8c584fe..73f3e7652 100644 --- a/arch/platform/sky/platform-conf.h +++ b/arch/platform/sky/platform-conf.h @@ -230,4 +230,12 @@ for SFD timestamping */ #define CC2420_SPI_DISABLE() (CC2420_CSN_PORT(OUT) |= BV(CC2420_CSN_PIN)) #define CC2420_SPI_IS_ENABLED() ((CC2420_CSN_PORT(OUT) & BV(CC2420_CSN_PIN)) != BV(CC2420_CSN_PIN)) +/* Platform-specific define for the end of the stack region */ +#define STACK_CONF_ORIGIN ((void *)0x3900) + +/* Disable the stack check library by default: .rom overflow otherwise */ +#ifndef STACK_CHECK_CONF_ENABLED +#define STACK_CHECK_CONF_ENABLED 0 +#endif + #endif /* PLATFORM_CONF_H_ */ diff --git a/examples/libs/stack-check/Makefile b/examples/libs/stack-check/Makefile new file mode 100644 index 000000000..243679d51 --- /dev/null +++ b/examples/libs/stack-check/Makefile @@ -0,0 +1,5 @@ +CONTIKI_PROJECT = example-stack-check +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/libs/stack-check/example-sky.csc b/examples/libs/stack-check/example-sky.csc new file mode 100644 index 000000000..ae09f50bb --- /dev/null +++ b/examples/libs/stack-check/example-sky.csc @@ -0,0 +1,90 @@ + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + + Stack checker example + 0 + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + node + RPL Root + [CONFIG_DIR]/example-stack-check.c + make example-stack-check.sky TARGET=sky + [CONFIG_DIR]/example-stack-check.sky + 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.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + node + + + + org.contikios.cooja.plugins.SimControl + 259 + 4 + 179 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.898638306051894 0.0 0.0 2.898638306051894 -68.40918308040007 -27.82360366026197 + + 258 + 2 + 209 + 0 + 178 + + + org.contikios.cooja.plugins.LogListener + 1024 + 3 + 311 + 0 + 385 + + diff --git a/examples/libs/stack-check/example-stack-check.c b/examples/libs/stack-check/example-stack-check.c new file mode 100644 index 000000000..8f4b0f0ae --- /dev/null +++ b/examples/libs/stack-check/example-stack-check.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2017, 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 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 + * Test of Contiki system's stack checker functionality + * \author + * Atis Elsts + */ + +#include "contiki.h" +#include "sys/stack-check.h" +#include "random.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +PROCESS(example_process, "Stack check example"); +AUTOSTART_PROCESSES(&example_process); +/*---------------------------------------------------------------------------*/ +static void +nested_function(void) +{ + printf("stack usage: %u permitted: %u\n", + stack_check_get_usage(), stack_check_get_reserved_size()); +} +/*---------------------------------------------------------------------------*/ +static void +test_function(void) +{ + void *p; + uint16_t s; + + /* allocate and fill some random bytes */ + s = random_rand() % 1000; + printf("allocating %u bytes on the stack\n", s); + p = alloca(s); + memset(p, 0, s); + + /* call the nested function to print stack usage */ + nested_function(); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(example_process, ev, data) +{ + static struct etimer et; + + PROCESS_BEGIN(); + + while(1) { + etimer_set(&et, CLOCK_SECOND * 2); + + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + test_function(); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/libs/stack-check/project-conf.h b/examples/libs/stack-check/project-conf.h new file mode 100644 index 000000000..2509dd080 --- /dev/null +++ b/examples/libs/stack-check/project-conf.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2017, 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 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 + * Project config file + * \author + * Atis Elsts + * + */ + +#ifndef __PROJECT_CONF_H__ +#define __PROJECT_CONF_H__ + +#define STACK_CHECK_CONF_ENABLED 1 + +#endif /* __PROJECT_CONF_H__ */ diff --git a/os/contiki-main.c b/os/contiki-main.c index 88bea0a10..0aeaeafa1 100644 --- a/os/contiki-main.c +++ b/os/contiki-main.c @@ -44,6 +44,7 @@ #include "contiki-net.h" #include "sys/platform.h" #include "sys/energest.h" +#include "sys/stack-check.h" #include "dev/watchdog.h" #include "services/orchestra/orchestra.h" @@ -77,6 +78,10 @@ main(void) energest_init(); +#if STACK_CHECK_ENABLED + stack_check_init(); +#endif + platform_init_stage_two(); LOG_INFO("Starting " CONTIKI_VERSION_STRING "\n"); diff --git a/os/sys/stack-check.c b/os/sys/stack-check.c new file mode 100644 index 000000000..61f8d98ab --- /dev/null +++ b/os/sys/stack-check.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2017, 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 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 stack + * @{ + */ + +/** + * \file + * Implementation of the stack checker library. + * \author + * Atis Elsts + */ + +#include "contiki.h" +#include "sys/stack-check.h" +#include "dev/watchdog.h" +#include + +#include "sys/log.h" +#define LOG_MODULE "Stack" +#define LOG_LEVEL LOG_LEVEL_MAIN + +/*---------------------------------------------------------------------------*/ +/* linker will provide a symbol for the end of the .bss segment */ +extern uint8_t _stack; + +#if STACK_CHECK_PERIODIC_CHECKS +PROCESS(stack_check_process, "Stack check"); +#endif +/*---------------------------------------------------------------------------*/ +/* The symbol with which the stack memory is initially filled */ +#define STACK_FILL 0xcd +/*---------------------------------------------------------------------------*/ +#ifdef STACK_ORIGIN +/* use the #defined value */ +#define GET_STACK_ORIGIN() STACK_ORIGIN +#else +/* use the value provided by the linker script */ +extern int _stack_origin; +#define GET_STACK_ORIGIN() (&_stack_origin) +#endif +/*---------------------------------------------------------------------------*/ +void +stack_check_init(void) +{ + uint8_t *p; + + /* Make this static to avoid destroying it in the while loop */ + static void *stack_top; + /* Use address of this local variable as a boundary */ + stack_top = &p; + + /* Note: this is expected to be called before the WDT is started! */ + p = &_stack; + while(p < (uint8_t *)stack_top) { + *p++ = STACK_FILL; + } + +#if STACK_CHECK_PERIODIC_CHECKS + /* Start the periodic checker process */ + process_start(&stack_check_process, NULL); +#endif +} +/*---------------------------------------------------------------------------*/ +uint16_t +stack_check_get_usage(void) +{ + uint8_t *p = &_stack; + + /* Make sure WDT is not triggered */ + watchdog_periodic(); + + /* Skip the bytes used after heap; it's 1 byte by default for _stack, + * more than that means dynamic memory allocation is used somewhere. + */ + while(*p != STACK_FILL && p < (uint8_t *)GET_STACK_ORIGIN()) { + p++; + } + + /* Skip the region of the memory reserved for the stack not used yet by the program */ + while(*p == STACK_FILL && p < (uint8_t *)GET_STACK_ORIGIN()) { + p++; + } + + /* Make sure WDT is not triggered */ + watchdog_periodic(); + + if(p >= (uint8_t*)GET_STACK_ORIGIN()) { + /* This means the stack is screwed. */ + return 0xffff; + } + + return (uint8_t *)GET_STACK_ORIGIN() - p; +} +/*---------------------------------------------------------------------------*/ +uint16_t +stack_check_get_reserved_size(void) +{ + return (uint8_t *)GET_STACK_ORIGIN() - &_stack; +} +/*---------------------------------------------------------------------------*/ +#if STACK_CHECK_PERIODIC_CHECKS +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(stack_check_process, ev, data) +{ + static struct etimer et; + + PROCESS_BEGIN(); + + etimer_set(&et, STACK_CHECK_PERIOD); + + while(1) { + uint16_t actual, allowed; + + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + actual = stack_check_get_usage(); + allowed = stack_check_get_reserved_size(); + if(actual > allowed) { + LOG_ERR("Check failed: %u vs. %u\n", actual, allowed); + } else { + LOG_DBG("Check ok: %u vs. %u\n", actual, allowed); + } + + etimer_reset(&et); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +#endif /* STACK_CHECK_PERIODIC_CHECKS */ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/os/sys/stack-check.h b/os/sys/stack-check.h new file mode 100644 index 000000000..a9068f216 --- /dev/null +++ b/os/sys/stack-check.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2017, 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 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 + * Stack checker library header file. + * \author + * Atis Elsts + */ + +/** \addtogroup sys + * @{ */ + +/** + * \defgroup stack Stack checker library + * + * Basic support for stack guards and stack overflow detection. + * On startup, fills the area between the stack and the heap with a known pattern. + * During execution, the fill can be checked in order to find out + * the extent to which the stack has been used. + * + * + * @{ + */ + +#ifndef STACK_CHECK_H_ +#define STACK_CHECK_H_ + +#include "contiki-conf.h" + +/* Determine whether stack checking is supported depending on the plaform. */ +#ifdef PLATFORM_CONF_SUPPORTS_STACK_CHECK +#if !PLATFORM_CONF_SUPPORTS_STACK_CHECK +/* Stack checker cannot be enabled, since the platform does not support it */ +#undef STACK_CHECK_CONF_ENABLED +#define STACK_CHECK_CONF_ENABLED 0 +#endif /* !PLATFORM_CONF_SUPPORTS_STACK_CHECK */ +#endif /* ifdef PLATFORM_CONF_SUPPORTS_STACK_CHECK */ + +/* If this is disabled, the functions are no-ops */ +#ifdef STACK_CHECK_CONF_ENABLED +#define STACK_CHECK_ENABLED STACK_CHECK_CONF_ENABLED +#else +#define STACK_CHECK_ENABLED 1 /* Enable by default */ +#endif + +/* Perform periodic stack integrity checks? */ +#ifdef STACK_CHECK_CONF_PERIODIC_CHECKS +#define STACK_CHECK_PERIODIC_CHECKS STACK_CHECK_CONF_PERIODIC_CHECKS +#else +#define STACK_CHECK_PERIODIC_CHECKS 1 /* Enable by default */ +#endif + +/* How often to do the periodic integrity checks, if enabled? */ +#ifdef STACK_CHECK_CONF_PERIOD +#define STACK_CHECK_PERIOD STACK_CHECK_CONF_PERIOD +#else +#define STACK_CHECK_PERIOD (10 * CLOCK_SECOND) +#endif + +/** + * \brief Initialize the stack area with a known pattern + * + * This function initializes the memory between the stack and heap + * areas. The function should be called by the system + * during boot-up. + */ +void stack_check_init(void); + +/** + * \brief Calculate the maximal stack usage so far. + * + * This function relies on the assumption that the stack memory + * that has been reserved by functions and local variables + * is actually overwritten with new contents. If the stack is + * just reserved, but not used, the function will fail to detect + * that usage. + * In addition, this function can warn if the stack memory range + * has been completely used, but it cannot detect + * and warn if stack overflow has already taken place. + */ +uint16_t stack_check_get_usage(void); + +/** + * \brief Calculate the maximal permitted stack usage. + * + * This function returns the number of bytes between the origin + * of the stack and the end of heap. + */ +uint16_t stack_check_get_reserved_size(void); + +/** + * \brief The origin point from which the stack grows (an optional #define) + * + */ +#ifdef STACK_CONF_ORIGIN +#define STACK_ORIGIN STACK_CONF_ORIGIN +#endif + +#endif /* STACK_CHECK_H_ */ + +/** @} */ +/** @} */ From 7233dfbbdd22418d47e03430946d9f332cd4fff7 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Tue, 28 Nov 2017 15:55:35 +0000 Subject: [PATCH 02/81] Add a regression test for the stack check library --- .../07-simulation-base/22-stack-guard-sky.csc | 81 +++++++++++++++++++ tests/07-simulation-base/js/22-stack-check.js | 25 ++++++ 2 files changed, 106 insertions(+) create mode 100644 tests/07-simulation-base/22-stack-guard-sky.csc create mode 100644 tests/07-simulation-base/js/22-stack-check.js diff --git a/tests/07-simulation-base/22-stack-guard-sky.csc b/tests/07-simulation-base/22-stack-guard-sky.csc new file mode 100644 index 000000000..5d57eb148 --- /dev/null +++ b/tests/07-simulation-base/22-stack-guard-sky.csc @@ -0,0 +1,81 @@ + + + + Stack guard test (Sky) + 123456 + 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/libs/stack-check/example-stack-check.c + make -j example-stack-check.sky TARGET=sky + [CONTIKI_DIR]/examples/libs/stack-check/example-stack-check.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 + 64.11203103628397 + 93.06735634828134 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + org.contikios.cooja.plugins.ScriptRunner + + [CONFIG_DIR]/js/22-stack-check.js + true + + 541 + 0 + 448 + 299 + 7 + + + org.contikios.cooja.plugins.SimControl + 280 + 2 + 160 + 7 + 10 + + + org.contikios.cooja.plugins.LogListener + + + + 680 + 1 + 240 + 51 + 288 + + diff --git a/tests/07-simulation-base/js/22-stack-check.js b/tests/07-simulation-base/js/22-stack-check.js new file mode 100644 index 000000000..c6915cc66 --- /dev/null +++ b/tests/07-simulation-base/js/22-stack-check.js @@ -0,0 +1,25 @@ +TIMEOUT(100000); + +/* This script checks that the stack usage is dynamically changing */ + +var re = /stack usage: (\d+)/i; + +var minusage = 10000; +var maxusage = 0; + +while(true) { + log.log("> " + msg + "\n"); + + var found = msg.match(re); + + if(found) { + var n = parseInt(found[1]); + minusage = minusage < n ? minusage : n; + maxusage = maxusage > n ? maxusage : n; + + if(minusage < 800 && maxusage >= 1000) { + log.testOK(); + } + } + YIELD(); +} From 29662d4e6d9887f49a71c1f12f510eee403134c9 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Tue, 5 Dec 2017 00:44:20 +0000 Subject: [PATCH 03/81] Clarify sensniff doc: It is also distributed as part of Contiki-NG --- examples/sensniff/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/sensniff/README.md b/examples/sensniff/README.md index 3fe1df7dd..01b3de54c 100644 --- a/examples/sensniff/README.md +++ b/examples/sensniff/README.md @@ -2,7 +2,8 @@ sensniff Contiki Project ======================== This example can be used to create an IEEE 802.15.4 wireless sniffer firmware, meant to be used in parallel with -[sensniff](https://github.com/g-oikonomou/sensniff). +[sensniff](https://github.com/g-oikonomou/sensniff). Sensniff is distributed +standalone, but also as part of Contiki-NG under `tools/sensniff`. Running ======= From 3bb60074dffc11a904edf09f3df0f2c4c8577817 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 00:27:39 +0000 Subject: [PATCH 04/81] Provide header file with configuration common to all Arm CPUs --- arch/cpu/arm/arm-def.h | 76 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 arch/cpu/arm/arm-def.h diff --git a/arch/cpu/arm/arm-def.h b/arch/cpu/arm/arm-def.h new file mode 100644 index 000000000..63a70a535 --- /dev/null +++ b/arch/cpu/arm/arm-def.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * 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 arm + * @{ + * + * \file + * Compiler and data type definitions for all ARM-based CPUs + */ +/*---------------------------------------------------------------------------*/ +#ifndef ARM_DEF_ +#define ARM_DEF_ +/*---------------------------------------------------------------------------*/ +#include +/*---------------------------------------------------------------------------*/ +/** + * \name Compiler configuration + * + * Those values are not meant to be modified by the user + * @{ + */ +#define CCIF +#define CLIF +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Macros and typedefs + * + * Those values are not meant to be modified by the user + * @{ + */ +#define CLOCK_CONF_SECOND 128 + +/* Clock (time) comparison macro */ +#define CLOCK_LT(a, b) ((signed long)((a) - (b)) < 0) + +/* Platform typedefs */ +typedef uint32_t clock_time_t; +typedef uint32_t uip_stats_t; + +typedef uint32_t rtimer_clock_t; +#define RTIMER_CLOCK_DIFF(a, b) ((int32_t)((a) - (b))) +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* ARM_DEF_ */ +/*---------------------------------------------------------------------------*/ +/** @} */ From 3a0ea7331080678629e1ef6f835089b2664d0d10 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 00:29:43 +0000 Subject: [PATCH 05/81] Provide header file with configuration common to all CM3-based CPUs --- arch/cpu/arm/cortex-m/cm3/cm3-def.h | 53 +++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 arch/cpu/arm/cortex-m/cm3/cm3-def.h diff --git a/arch/cpu/arm/cortex-m/cm3/cm3-def.h b/arch/cpu/arm/cortex-m/cm3/cm3-def.h new file mode 100644 index 000000000..041bb3d71 --- /dev/null +++ b/arch/cpu/arm/cortex-m/cm3/cm3-def.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * 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 arm + * @{ + * + * \defgroup cm3 Arm Cortex-M3 + * @{ + * + * \file + * Compiler and data type definitions for all CM3-based CPUs + */ +/*---------------------------------------------------------------------------*/ +#ifndef CM3_DEF_H_ +#define CM3_DEF_H_ +/*---------------------------------------------------------------------------*/ +#include "arm-def.h" +/*---------------------------------------------------------------------------*/ +#endif /* CM3_DEF_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ From a05db7322d5749b357220d111026d1d16fa2c322 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 00:29:54 +0000 Subject: [PATCH 06/81] Provide header file with configuration common to all CM4-based CPUs --- arch/cpu/arm/cortex-m/cm4/cm4-def.h | 53 +++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 arch/cpu/arm/cortex-m/cm4/cm4-def.h diff --git a/arch/cpu/arm/cortex-m/cm4/cm4-def.h b/arch/cpu/arm/cortex-m/cm4/cm4-def.h new file mode 100644 index 000000000..1144d9798 --- /dev/null +++ b/arch/cpu/arm/cortex-m/cm4/cm4-def.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * 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 arm + * @{ + * + * \defgroup cm4 Arm Cortex-M4 + * @{ + * + * \file + * Compiler and data type definitions for all CM4-based CPUs + */ +/*---------------------------------------------------------------------------*/ +#ifndef CM4_DEF_H_ +#define CM4_DEF_H_ +/*---------------------------------------------------------------------------*/ +#include "arm-def.h" +/*---------------------------------------------------------------------------*/ +#endif /* CM4_DEF_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ From 4b4234db403cdacff639a602b2d5a33b2efb30f5 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 00:34:47 +0000 Subject: [PATCH 07/81] Provide header file with defines for the nrf52832 --- arch/cpu/nrf52832/nrf52832-def.h | 40 ++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 arch/cpu/nrf52832/nrf52832-def.h diff --git a/arch/cpu/nrf52832/nrf52832-def.h b/arch/cpu/nrf52832/nrf52832-def.h new file mode 100644 index 000000000..f31054dda --- /dev/null +++ b/arch/cpu/nrf52832/nrf52832-def.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * 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 NRF52832_DEF_H_ +#define NRF52832_DEF_H_ +/*---------------------------------------------------------------------------*/ +#include "cm4/cm4-def.h" +/*---------------------------------------------------------------------------*/ +#define RTIMER_ARCH_SECOND 62500 +/*---------------------------------------------------------------------------*/ +#endif /* NRF52832_DEF_H_ */ +/*---------------------------------------------------------------------------*/ From 945c66b7f8514fe9dbb7a8ec8997a8225f7be0c3 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 00:35:15 +0000 Subject: [PATCH 08/81] Provide header file with defines for the CC13xx/CC26xx --- arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-def.h | 97 ++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-def.h diff --git a/arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-def.h b/arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-def.h new file mode 100644 index 000000000..283738ffe --- /dev/null +++ b/arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-def.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * 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 CC13XX_CC26XX_DEF_H_ +#define CC13XX_CC26XX_DEF_H_ +/*---------------------------------------------------------------------------*/ +#include "cm3/cm3-def.h" +/*---------------------------------------------------------------------------*/ +/* 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. */ +#define RADIO_DELAY_BEFORE_DETECT ((unsigned)US_TO_RTIMERTICKS(352)) + +/* 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 + +/* 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 + +#ifndef TSCH_CONF_BASE_DRIFT_PPM +/* The drift compared to "true" 10ms slots. + * Enable adaptive sync to enable compensation for this. + * Slot length 10000 usec + * 328 ticks + * Tick duration 30.517578125 usec + * Real slot duration 10009.765625 usec + * Target - real duration = -9.765625 usec + * TSCH_CONF_BASE_DRIFT_PPM -977 + */ +#define TSCH_CONF_BASE_DRIFT_PPM -977 +#endif + +/* 10 times per second */ +#ifndef TSCH_CONF_CHANNEL_SCAN_DURATION +#define TSCH_CONF_CHANNEL_SCAN_DURATION (CLOCK_SECOND / 10) +#endif + +/* Slightly reduce the TSCH guard time (from 2200 usec to 1800 usec) to make sure + * the CC26xx radio has sufficient time to start up. */ +#ifndef TSCH_CONF_RX_WAIT +#define TSCH_CONF_RX_WAIT 1800 +#endif +/*---------------------------------------------------------------------------*/ +#define RTIMER_ARCH_SECOND 65536 +/*---------------------------------------------------------------------------*/ +#endif /* CC13XX_CC26XX_DEF_H_ */ +/*---------------------------------------------------------------------------*/ From d66633ffc4ac8be47c0433a15ab6203cd2aa2205 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 00:38:59 +0000 Subject: [PATCH 09/81] Provide header file with defines for the CC2538 --- arch/cpu/cc2538/cc2538-def.h | 62 +++++++++++++++++++++++++++++++++++ arch/cpu/cc2538/rtimer-arch.h | 2 -- 2 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 arch/cpu/cc2538/cc2538-def.h diff --git a/arch/cpu/cc2538/cc2538-def.h b/arch/cpu/cc2538/cc2538-def.h new file mode 100644 index 000000000..11baef4ec --- /dev/null +++ b/arch/cpu/cc2538/cc2538-def.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * 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 CC2538_DEF_H_ +#define CC2538_DEF_H_ +/*---------------------------------------------------------------------------*/ +#include "cm3/cm3-def.h" +/*---------------------------------------------------------------------------*/ +#define RTIMER_ARCH_SECOND 32768 +/*---------------------------------------------------------------------------*/ +/* 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 +#ifndef TSCH_CONF_BASE_DRIFT_PPM +/* The drift compared to "true" 10ms slots. + * Enable adaptive sync to enable compensation for this. + * Slot length 10000 usec + * 328 ticks + * Tick duration 30.517578125 usec + * Real slot duration 10009.765625 usec + * Target - real duration = -9.765625 usec + * TSCH_CONF_BASE_DRIFT_PPM -977 + */ +#define TSCH_CONF_BASE_DRIFT_PPM -977 +#endif + +#if MAC_CONF_WITH_TSCH +#define TSCH_CONF_HW_FRAME_FILTERING 0 +#endif /* MAC_CONF_WITH_TSCH */ +/*---------------------------------------------------------------------------*/ +#endif /* CC2538_DEF_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/arch/cpu/cc2538/rtimer-arch.h b/arch/cpu/cc2538/rtimer-arch.h index 45ebc5c5d..37aa102da 100644 --- a/arch/cpu/cc2538/rtimer-arch.h +++ b/arch/cpu/cc2538/rtimer-arch.h @@ -63,8 +63,6 @@ #include "contiki.h" #include "dev/gptimer.h" -#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 ? \ From ea2fb7bcc1552e42bcf947f78c4383a73eb6ed8d Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 00:39:34 +0000 Subject: [PATCH 10/81] Provide header file with configuration common to all CC2538-based platforms --- arch/cpu/cc2538/cc2538-conf.h | 330 ++++++++++++++++++++++++++++++++++ 1 file changed, 330 insertions(+) create mode 100644 arch/cpu/cc2538/cc2538-conf.h diff --git a/arch/cpu/cc2538/cc2538-conf.h b/arch/cpu/cc2538/cc2538-conf.h new file mode 100644 index 000000000..725f95439 --- /dev/null +++ b/arch/cpu/cc2538/cc2538-conf.h @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * 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 + * @{ + */ +/*---------------------------------------------------------------------------*/ +#ifndef CC2538_CONF_H_ +#define CC2538_CONF_H_ +/*---------------------------------------------------------------------------*/ +/** + * \name CFS configuration + * + * @{ + */ +#ifndef COFFEE_CONF_SIZE +#define COFFEE_CONF_SIZE (4 * COFFEE_SECTOR_SIZE) +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name CC2538 System Control configuration + * + * @{ + */ +#ifndef SYS_CTRL_CONF_OSC32K_USE_XTAL +#define SYS_CTRL_CONF_OSC32K_USE_XTAL 0 /**< Use the on-board 32.768-kHz crystal */ +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Watchdog Timer configuration + * + * @{ + */ +#ifndef WATCHDOG_CONF_ENABLE +#define WATCHDOG_CONF_ENABLE 1 /**< Enable the watchdog timer */ +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name USB 'core' configuration + * + * Those values are not meant to be modified by the user, except where stated + * otherwise + * @{ + */ +#define CTRL_EP_SIZE 8 +#define USB_EP1_SIZE 32 +#define USB_EP2_SIZE 64 +#define USB_EP3_SIZE 64 +#define USB_ARCH_WRITE_NOTIFY 0 + +#ifndef USB_ARCH_CONF_DMA +#define USB_ARCH_CONF_DMA 1 /**< Change to Enable/Disable USB DMA */ + +#endif +/** @} */ +/** + * \name uDMA Configuration and channel allocations + * + * @{ + */ +#define USB_ARCH_CONF_RX_DMA_CHAN 0 /**< USB -> 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 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 !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 + +#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 + +/** + * \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 +#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) || \ + (MAC_CONF_WITH_TSCH && (SLIP_ARCH_CONF_ENABLED || BUILD_WITH_SHELL)) || \ + DBG_CONF_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_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_DBG(u) || \ + UART_IN_USE_BY_UART1(u)) \ +) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name RF configuration + * + * @{ + */ +/* RF Config */ + +#ifdef RF_CHANNEL +#define CC2538_RF_CONF_CHANNEL RF_CHANNEL +#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 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 Radio Configuration + * + * @{ + */ +#ifndef NETSTACK_CONF_RADIO +#define NETSTACK_CONF_RADIO cc2538_rf_driver +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name IEEE address configuration + * + * Used to generate our link-layer & 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 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 /* CC2538_CONF_H_ */ +/*---------------------------------------------------------------------------*/ +/** @} */ From fdde5dc66978b0a778e432128ff87057adf567ad Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 00:46:24 +0000 Subject: [PATCH 11/81] Provide header file with configuration common to all CC26xx-based platforms --- arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-conf.h | 204 ++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-conf.h diff --git a/arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-conf.h b/arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-conf.h new file mode 100644 index 000000000..6ecdafa6b --- /dev/null +++ b/arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-conf.h @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * 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 + * @{ + * + * \file + * Header with configuration defines common to all CC13xx/CC26xx platforms + */ +/*---------------------------------------------------------------------------*/ +#ifndef CC13XX_CC26XX_CONF_H_ +#define CC13XX_CC26XX_CONF_H_ +/*---------------------------------------------------------------------------*/ +/** + * \name Network Stack Configuration + * + * @{ + */ + +/* + * If set, the systems keeps the HF crystal oscillator on even when the radio is off. + * You need to set this to 1 to use TSCH with its default 2.2ms or larger guard time. + */ +#ifndef CC2650_FAST_RADIO_STARTUP +#define CC2650_FAST_RADIO_STARTUP (MAC_CONF_WITH_TSCH) +#endif + +#ifdef RF_CHANNEL +#define RF_CORE_CONF_CHANNEL RF_CHANNEL +#endif + +#ifndef RF_CORE_CONF_CHANNEL +#define RF_CORE_CONF_CHANNEL 25 +#endif + +/* Number of Prop Mode RX buffers */ +#ifndef PROP_MODE_CONF_RX_BUF_CNT +#define PROP_MODE_CONF_RX_BUF_CNT 4 +#endif + +/* + * Auto-configure Prop-mode radio if we are running on CC13xx, unless the + * project has specified otherwise. Depending on the final mode, determine a + * default channel (again, if unspecified) and configure RDC params + */ +#if CPU_FAMILY_CC13XX +#ifndef CC13XX_CONF_PROP_MODE +#define CC13XX_CONF_PROP_MODE 1 +#endif /* CC13XX_CONF_PROP_MODE */ +#endif /* CPU_FAMILY_CC13XX */ + +#if CC13XX_CONF_PROP_MODE +#define NETSTACK_CONF_RADIO prop_mode_driver + +#ifndef RF_CORE_CONF_CHANNEL +#define RF_CORE_CONF_CHANNEL 0 +#endif + +#define CSMA_CONF_ACK_WAIT_TIME (RTIMER_SECOND / 400) +#define CSMA_CONF_AFTER_ACK_DETECTED_WAIT_TIME (RTIMER_SECOND / 1000) +#define CSMA_CONF_SEND_SOFT_ACK 1 + +#else /* CC13XX_CONF_PROP_MODE */ +#define NETSTACK_CONF_RADIO ieee_mode_driver + +#define CSMA_CONF_SEND_SOFT_ACK 0 +#endif /* CC13XX_CONF_PROP_MODE */ + +#define NETSTACK_RADIO_MAX_PAYLOAD_LEN 125 + +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name IEEE address configuration + * + * Used to generate our link-local & 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 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name RF configuration + * + * @{ + */ +/* RF Config */ + +#ifndef IEEE_MODE_CONF_AUTOACK +#define IEEE_MODE_CONF_AUTOACK 1 /**< RF H/W generates ACKs */ +#endif + +#ifndef IEEE_MODE_CONF_PROMISCOUS +#define IEEE_MODE_CONF_PROMISCOUS 0 /**< 1 to enable promiscous mode */ +#endif + +#ifndef RF_BLE_CONF_ENABLED +#define RF_BLE_CONF_ENABLED 0 /**< 0 to disable BLE support */ +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Character I/O Configuration + * + * @{ + */ +#ifndef CC26XX_UART_CONF_ENABLE +#define CC26XX_UART_CONF_ENABLE 1 /**< Enable/Disable UART I/O */ +#endif + +#ifndef CC26XX_UART_CONF_BAUD_RATE +#define CC26XX_UART_CONF_BAUD_RATE 115200 /**< Default UART0 baud rate */ +#endif + +/* Enable I/O over the Debugger Devpack - Only relevant for the SensorTag */ +#ifndef BOARD_CONF_DEBUGGER_DEVPACK +#define BOARD_CONF_DEBUGGER_DEVPACK 1 +#endif + +#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 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name JTAG interface configuration + * + * Enable/Disable the JTAG DAP and TAP interfaces on the chip. + * Setting this to 0 will disable access to the debug interface + * to secure deployed images. + * @{ + */ +#ifndef CCXXWARE_CONF_JTAG_INTERFACE_ENABLE +#define CCXXWARE_CONF_JTAG_INTERFACE_ENABLE 1 +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name ROM Bootloader configuration + * + * Enable/Disable the ROM bootloader in your image, if the board supports it. + * Look in board.h to choose the DIO and corresponding level that will cause + * the chip to enter bootloader mode. + * @{ + */ +#ifndef ROM_BOOTLOADER_ENABLE +#define ROM_BOOTLOADER_ENABLE 0 +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* CC13XX_CC26XX_CONF_H_ */ +/*---------------------------------------------------------------------------*/ +/** @} */ From 5c07cb02a8738ccfc48750e5e64287fb131cdddd Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 00:56:57 +0000 Subject: [PATCH 12/81] Pull CPU-related constants from the CPU header (CC13xx/CC26xx) --- arch/cpu/cc26xx-cc13xx/rtimer-arch.h | 2 - arch/platform/srf06-cc26xx/contiki-conf.h | 87 +---------------------- 2 files changed, 1 insertion(+), 88 deletions(-) diff --git a/arch/cpu/cc26xx-cc13xx/rtimer-arch.h b/arch/cpu/cc26xx-cc13xx/rtimer-arch.h index 128461c8d..c6907ee59 100644 --- a/arch/cpu/cc26xx-cc13xx/rtimer-arch.h +++ b/arch/cpu/cc26xx-cc13xx/rtimer-arch.h @@ -47,8 +47,6 @@ /*---------------------------------------------------------------------------*/ #include "contiki.h" /*---------------------------------------------------------------------------*/ -#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 diff --git a/arch/platform/srf06-cc26xx/contiki-conf.h b/arch/platform/srf06-cc26xx/contiki-conf.h index fbe9c5059..ec7d964bc 100644 --- a/arch/platform/srf06-cc26xx/contiki-conf.h +++ b/arch/platform/srf06-cc26xx/contiki-conf.h @@ -202,6 +202,7 @@ #define ROM_BOOTLOADER_ENABLE 0 #endif /** @} */ +#include "cc13xx-cc26xx-def.h" /*---------------------------------------------------------------------------*/ /** * \name Button configurations @@ -227,92 +228,6 @@ /* Platform-specific define to signify sensor reading failure */ #define CC26XX_SENSOR_READING_ERROR 0x80000000 /*---------------------------------------------------------------------------*/ -/** - * \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) - -/* - * rtimer.h typedefs rtimer_clock_t as unsigned short. We need to define - * RTIMER_CLOCK_DIFF to override this - */ -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. */ -#define RADIO_DELAY_BEFORE_DETECT ((unsigned)US_TO_RTIMERTICKS(352)) - -/* 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 - -/* 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 - -#ifndef TSCH_CONF_BASE_DRIFT_PPM -/* The drift compared to "true" 10ms slots. - * Enable adaptive sync to enable compensation for this. - * Slot length 10000 usec - * 328 ticks - * Tick duration 30.517578125 usec - * Real slot duration 10009.765625 usec - * Target - real duration = -9.765625 usec - * TSCH_CONF_BASE_DRIFT_PPM -977 - */ -#define TSCH_CONF_BASE_DRIFT_PPM -977 -#endif - -/* 10 times per second */ -#ifndef TSCH_CONF_CHANNEL_SCAN_DURATION -#define TSCH_CONF_CHANNEL_SCAN_DURATION (CLOCK_SECOND / 10) -#endif - -/* Slightly reduce the TSCH guard time (from 2200 usec to 1800 usec) to make sure - * the CC26xx radio has sufficient time to start up. */ -#ifndef TSCH_CONF_RX_WAIT -#define TSCH_CONF_RX_WAIT 1800 -#endif - -/** @} */ -/*---------------------------------------------------------------------------*/ /* board.h assumes that basic configuration is done */ #include "board.h" /*---------------------------------------------------------------------------*/ From fb9c0beb37c6a7221c3f7b3c28d78e4ff2803f05 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 00:57:24 +0000 Subject: [PATCH 13/81] Pull CPU-related configuration from the CPU header (CC13xx/CC26xx) --- arch/platform/srf06-cc26xx/contiki-conf.h | 161 +--------------------- 1 file changed, 3 insertions(+), 158 deletions(-) diff --git a/arch/platform/srf06-cc26xx/contiki-conf.h b/arch/platform/srf06-cc26xx/contiki-conf.h index ec7d964bc..07c8f285a 100644 --- a/arch/platform/srf06-cc26xx/contiki-conf.h +++ b/arch/platform/srf06-cc26xx/contiki-conf.h @@ -44,164 +44,6 @@ #include PROJECT_CONF_PATH #endif /* PROJECT_CONF_PATH */ /*---------------------------------------------------------------------------*/ -/** - * \name Network Stack Configuration - * - * @{ - */ - -/* - * If set, the systems keeps the HF crystal oscillator on even when the radio is off. - * You need to set this to 1 to use TSCH with its default 2.2ms or larger guard time. - */ -#ifndef CC2650_FAST_RADIO_STARTUP -#define CC2650_FAST_RADIO_STARTUP (MAC_CONF_WITH_TSCH) -#endif - -#ifdef RF_CHANNEL -#define RF_CORE_CONF_CHANNEL RF_CHANNEL -#endif - -#ifndef RF_CORE_CONF_CHANNEL -#define RF_CORE_CONF_CHANNEL 25 -#endif - -/* Number of Prop Mode RX buffers */ -#ifndef PROP_MODE_CONF_RX_BUF_CNT -#define PROP_MODE_CONF_RX_BUF_CNT 4 -#endif - -/* - * Auto-configure Prop-mode radio if we are running on CC13xx, unless the - * project has specified otherwise. Depending on the final mode, determine a - * default channel (again, if unspecified) and configure RDC params - */ -#if CPU_FAMILY_CC13XX -#ifndef CC13XX_CONF_PROP_MODE -#define CC13XX_CONF_PROP_MODE 1 -#endif /* CC13XX_CONF_PROP_MODE */ -#endif /* CPU_FAMILY_CC13XX */ - -#if CC13XX_CONF_PROP_MODE -#define NETSTACK_CONF_RADIO prop_mode_driver - -#ifndef RF_CORE_CONF_CHANNEL -#define RF_CORE_CONF_CHANNEL 0 -#endif - -#define CSMA_CONF_ACK_WAIT_TIME (RTIMER_SECOND / 400) -#define CSMA_CONF_AFTER_ACK_DETECTED_WAIT_TIME (RTIMER_SECOND / 1000) -#define CSMA_CONF_SEND_SOFT_ACK 1 - -#else /* CC13XX_CONF_PROP_MODE */ -#define NETSTACK_CONF_RADIO ieee_mode_driver - -#define CSMA_CONF_SEND_SOFT_ACK 0 -#endif /* CC13XX_CONF_PROP_MODE */ - -#define NETSTACK_RADIO_MAX_PAYLOAD_LEN 125 - -/** @} */ -/*---------------------------------------------------------------------------*/ -/** - * \name IEEE address configuration - * - * Used to generate our link-local & 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 -/** @} */ -/*---------------------------------------------------------------------------*/ -/** - * \name RF configuration - * - * @{ - */ -/* RF Config */ - -#ifndef IEEE_MODE_CONF_AUTOACK -#define IEEE_MODE_CONF_AUTOACK 1 /**< RF H/W generates ACKs */ -#endif - -#ifndef IEEE_MODE_CONF_PROMISCOUS -#define IEEE_MODE_CONF_PROMISCOUS 0 /**< 1 to enable promiscous mode */ -#endif - -#ifndef RF_BLE_CONF_ENABLED -#define RF_BLE_CONF_ENABLED 0 /**< 0 to disable BLE support */ -#endif -/** @} */ -/*---------------------------------------------------------------------------*/ -/** - * \name Character I/O Configuration - * - * @{ - */ -#ifndef CC26XX_UART_CONF_ENABLE -#define CC26XX_UART_CONF_ENABLE 1 /**< Enable/Disable UART I/O */ -#endif - -#ifndef CC26XX_UART_CONF_BAUD_RATE -#define CC26XX_UART_CONF_BAUD_RATE 115200 /**< Default UART0 baud rate */ -#endif - -/* Enable I/O over the Debugger Devpack - Only relevant for the SensorTag */ -#ifndef BOARD_CONF_DEBUGGER_DEVPACK -#define BOARD_CONF_DEBUGGER_DEVPACK 1 -#endif - -#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 -/** @} */ -/*---------------------------------------------------------------------------*/ -/** - * \name JTAG interface configuration - * - * Enable/Disable the JTAG DAP and TAP interfaces on the chip. - * Setting this to 0 will disable access to the debug interface - * to secure deployed images. - * @{ - */ -#ifndef CCXXWARE_CONF_JTAG_INTERFACE_ENABLE -#define CCXXWARE_CONF_JTAG_INTERFACE_ENABLE 1 -#endif -/** @} */ -/*---------------------------------------------------------------------------*/ -/** - * \name ROM Bootloader configuration - * - * Enable/Disable the ROM bootloader in your image, if the board supports it. - * Look in board.h to choose the DIO and corresponding level that will cause - * the chip to enter bootloader mode. - * @{ - */ -#ifndef ROM_BOOTLOADER_ENABLE -#define ROM_BOOTLOADER_ENABLE 0 -#endif -/** @} */ #include "cc13xx-cc26xx-def.h" /*---------------------------------------------------------------------------*/ /** @@ -231,6 +73,9 @@ /* board.h assumes that basic configuration is done */ #include "board.h" /*---------------------------------------------------------------------------*/ +/* Include CPU-related configuration */ +#include "cc13xx-cc26xx-conf.h" +/*---------------------------------------------------------------------------*/ #endif /* CONTIKI_CONF_H */ /** @} */ From ba8f37bef4aa16580d7caedc7c527d4043bd16dd Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 01:02:22 +0000 Subject: [PATCH 14/81] Pull CPU-related constants from the CPU header (nrf52dk) --- arch/platform/nrf52dk/contiki-conf.h | 1 + arch/platform/nrf52dk/platform-conf.h | 29 --------------------------- 2 files changed, 1 insertion(+), 29 deletions(-) diff --git a/arch/platform/nrf52dk/contiki-conf.h b/arch/platform/nrf52dk/contiki-conf.h index 2ab089856..6e1529352 100644 --- a/arch/platform/nrf52dk/contiki-conf.h +++ b/arch/platform/nrf52dk/contiki-conf.h @@ -49,6 +49,7 @@ /*---------------------------------------------------------------------------*/ /* Include platform peripherals configuration */ #include "platform-conf.h" +#include "nrf52832-def.h" /*---------------------------------------------------------------------------*/ /** * \name Network Stack Configuration diff --git a/arch/platform/nrf52dk/platform-conf.h b/arch/platform/nrf52dk/platform-conf.h index d40fd2b3e..e2fd6cac0 100644 --- a/arch/platform/nrf52dk/platform-conf.h +++ b/arch/platform/nrf52dk/platform-conf.h @@ -107,35 +107,6 @@ */ #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_DIFF to override this - */ -typedef uint32_t rtimer_clock_t; -#define RTIMER_CLOCK_DIFF(a,b) ((int32_t)((a)-(b))) - /** @} */ /*---------------------------------------------------------------------------*/ /** @} From 03435d826e7a058216695890e0c20407e6280ac9 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 01:04:22 +0000 Subject: [PATCH 15/81] Pull CPU-related constants from the CPU header (CC2538DK) --- arch/platform/cc2538dk/contiki-conf.h | 46 +-------------------------- 1 file changed, 1 insertion(+), 45 deletions(-) diff --git a/arch/platform/cc2538dk/contiki-conf.h b/arch/platform/cc2538dk/contiki-conf.h index 4f7f6dc0a..b956f90e6 100644 --- a/arch/platform/cc2538dk/contiki-conf.h +++ b/arch/platform/cc2538dk/contiki-conf.h @@ -47,51 +47,7 @@ #include PROJECT_CONF_PATH #endif /* PROJECT_CONF_PATH */ /*---------------------------------------------------------------------------*/ -/** - * \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_DIFF to override this - */ -typedef uint32_t rtimer_clock_t; -#define RTIMER_CLOCK_DIFF(a,b) ((int32_t)((a)-(b))) -/** @} */ -/*---------------------------------------------------------------------------*/ -/* 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 -#ifndef TSCH_CONF_BASE_DRIFT_PPM -/* The drift compared to "true" 10ms slots. - * Enable adaptive sync to enable compensation for this. - * Slot length 10000 usec - * 328 ticks - * Tick duration 30.517578125 usec - * Real slot duration 10009.765625 usec - * Target - real duration = -9.765625 usec - * TSCH_CONF_BASE_DRIFT_PPM -977 - */ -#define TSCH_CONF_BASE_DRIFT_PPM -977 -#endif - -#if MAC_CONF_WITH_TSCH -#define TSCH_CONF_HW_FRAME_FILTERING 0 -#endif /* MAC_CONF_WITH_TSCH */ +#include "cc2538-def.h" /*---------------------------------------------------------------------------*/ /** * \name Serial Boot Loader Backdoor configuration From 88feb34ec7aa89eaeddfc3d6ff58446accd9c6e6 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 01:04:40 +0000 Subject: [PATCH 16/81] Pull CPU-related configuration from the CPU header (CC2538DK) --- arch/platform/cc2538dk/contiki-conf.h | 270 +------------------------- 1 file changed, 4 insertions(+), 266 deletions(-) diff --git a/arch/platform/cc2538dk/contiki-conf.h b/arch/platform/cc2538dk/contiki-conf.h index b956f90e6..1a463a0be 100644 --- a/arch/platform/cc2538dk/contiki-conf.h +++ b/arch/platform/cc2538dk/contiki-conf.h @@ -55,7 +55,7 @@ * @{ */ #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 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 !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 - -#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 - -/** - * \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 -#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) || \ - (MAC_CONF_WITH_TSCH && (SLIP_ARCH_CONF_ENABLED || BUILD_WITH_SHELL)) || \ - DBG_CONF_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_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_DBG(u) || \ - UART_IN_USE_BY_UART1(u)) \ -) -/** @} */ -/*---------------------------------------------------------------------------*/ /* board.h assumes that basic configuration is done */ #include "board.h" /*---------------------------------------------------------------------------*/ - -#define NETSTACK_CONF_RADIO cc2538_rf_driver -/** @} */ +/* Include CPU-related configuration */ +#include "cc2538-conf.h" /*---------------------------------------------------------------------------*/ -/** - * \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 link-layer & 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 */ -#ifdef RF_CHANNEL -#define CC2538_RF_CONF_CHANNEL RF_CHANNEL -#endif - -#ifndef CC2538_RF_CONF_CHANNEL -#define CC2538_RF_CONF_CHANNEL 25 -#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 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_ */ - +/*---------------------------------------------------------------------------*/ /** @} */ From 91c437e63142059c15935812a2b59085a11b4cad Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 01:04:58 +0000 Subject: [PATCH 17/81] Pull CPU-related constants from the CPU header (OpenMote) --- arch/platform/openmote-cc2538/contiki-conf.h | 46 +------------------- 1 file changed, 1 insertion(+), 45 deletions(-) diff --git a/arch/platform/openmote-cc2538/contiki-conf.h b/arch/platform/openmote-cc2538/contiki-conf.h index 4cc9d9dce..1370752c1 100644 --- a/arch/platform/openmote-cc2538/contiki-conf.h +++ b/arch/platform/openmote-cc2538/contiki-conf.h @@ -56,51 +56,7 @@ #include PROJECT_CONF_PATH #endif /* PROJECT_CONF_PATH */ /*---------------------------------------------------------------------------*/ -/** - * \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_DIFF to override this - */ -typedef uint32_t rtimer_clock_t; -#define RTIMER_CLOCK_DIFF(a, b) ((int32_t)((a) - (b))) -/** @} */ -/*---------------------------------------------------------------------------*/ -/* 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 -#ifndef TSCH_CONF_BASE_DRIFT_PPM -/* The drift compared to "true" 10ms slots. - * Enable adaptive sync to enable compensation for this. - * Slot length 10000 usec - * 328 ticks - * Tick duration 30.517578125 usec - * Real slot duration 10009.765625 usec - * Target - real duration = -9.765625 usec - * TSCH_CONF_BASE_DRIFT_PPM -977 - */ -#define TSCH_CONF_BASE_DRIFT_PPM -977 -#endif - -#if MAC_CONF_WITH_TSCH -#define TSCH_CONF_HW_FRAME_FILTERING 0 -#endif /* MAC_CONF_WITH_TSCH */ +#include "cc2538-def.h" /*---------------------------------------------------------------------------*/ /** * \name Serial Boot Loader Backdoor configuration From 369f58a60b0b9ef58cf4e3b7840d4177cdb4467f Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 01:06:29 +0000 Subject: [PATCH 18/81] Pull CPU-related configuration from the CPU header (OpenMote) --- arch/platform/openmote-cc2538/contiki-conf.h | 283 +------------------ 1 file changed, 2 insertions(+), 281 deletions(-) diff --git a/arch/platform/openmote-cc2538/contiki-conf.h b/arch/platform/openmote-cc2538/contiki-conf.h index 1370752c1..d9f0b047e 100644 --- a/arch/platform/openmote-cc2538/contiki-conf.h +++ b/arch/platform/openmote-cc2538/contiki-conf.h @@ -86,290 +86,11 @@ #endif /** @} */ /*---------------------------------------------------------------------------*/ -/** - * \name CFS configuration - * - * @{ - */ -#ifndef COFFEE_CONF_SIZE -#define COFFEE_CONF_SIZE (4 * COFFEE_SECTOR_SIZE) -#endif -/** @} */ -/*---------------------------------------------------------------------------*/ -/** - * \name Watchdog Timer configuration - * - * @{ - */ -#ifndef WATCHDOG_CONF_ENABLE -#define WATCHDOG_CONF_ENABLE 1 /**< Enable the watchdog timer */ -#endif -/** @} */ -/*---------------------------------------------------------------------------*/ -/** - * \name USB 'core' configuration - * - * Those values are not meant to be modified by the user, except where stated - * otherwise - * @{ - */ -#define CTRL_EP_SIZE 8 -#define USB_EP1_SIZE 32 -#define USB_EP2_SIZE 64 -#define USB_EP3_SIZE 64 -#define USB_ARCH_WRITE_NOTIFY 0 - -#ifndef USB_ARCH_CONF_DMA -#define USB_ARCH_CONF_DMA 1 /**< Change to Enable/Disable USB DMA */ - -#endif -/** @} */ - -/*---------------------------------------------------------------------------*/ -/** - * \name uDMA Configuration and channel allocations - * - * @{ - */ -#define USB_ARCH_CONF_RX_DMA_CHAN 0 /**< USB -> 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 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 !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 - -#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 - -/** - * \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 -#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) || \ - (MAC_CONF_WITH_TSCH && (SLIP_ARCH_CONF_ENABLED || BUILD_WITH_SHELL)) || \ - DBG_CONF_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_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_DBG(u) || \ - UART_IN_USE_BY_UART1(u)) \ - ) -/** @} */ -/*---------------------------------------------------------------------------*/ /* board.h assumes that basic configuration is done */ #include "board.h" /*---------------------------------------------------------------------------*/ -/** - * \name Radio Configuration - * - * @{ - */ - -#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 link-layer & 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 */ - -#ifdef RF_CHANNEL -#define CC2538_RF_CONF_CHANNEL RF_CHANNEL -#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 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 -/** @} */ +/* Include CPU-related configuration */ +#include "cc2538-conf.h" /*---------------------------------------------------------------------------*/ #endif /* CONTIKI_CONF_H_ */ /*---------------------------------------------------------------------------*/ From 458fbb1ee21b1dc756791d64ac15af4bb39032be Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 01:06:50 +0000 Subject: [PATCH 19/81] Pull CPU-related constants from the CPU header (Zoul) --- arch/platform/zoul/contiki-conf.h | 46 +------------------------------ 1 file changed, 1 insertion(+), 45 deletions(-) diff --git a/arch/platform/zoul/contiki-conf.h b/arch/platform/zoul/contiki-conf.h index 35d4ebc6d..710ad1695 100644 --- a/arch/platform/zoul/contiki-conf.h +++ b/arch/platform/zoul/contiki-conf.h @@ -53,51 +53,7 @@ #include PROJECT_CONF_PATH #endif /* PROJECT_CONF_PATH */ /*---------------------------------------------------------------------------*/ -/** - * \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_DIFF to override this - */ -typedef uint32_t rtimer_clock_t; -#define RTIMER_CLOCK_DIFF(a, b) ((int32_t)((a) - (b))) -/** @} */ -/*---------------------------------------------------------------------------*/ -/* 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 -#ifndef TSCH_CONF_BASE_DRIFT_PPM -/* The drift compared to "true" 10ms slots. - * Enable adaptive sync to enable compensation for this. - * Slot length 10000 usec - * 328 ticks - * Tick duration 30.517578125 usec - * Real slot duration 10009.765625 usec - * Target - real duration = -9.765625 usec - * TSCH_CONF_BASE_DRIFT_PPM -977 - */ -#define TSCH_CONF_BASE_DRIFT_PPM -977 -#endif - -#if MAC_CONF_WITH_TSCH -#define TSCH_CONF_HW_FRAME_FILTERING 0 -#endif /* MAC_CONF_WITH_TSCH */ +#include "cc2538-def.h" /*---------------------------------------------------------------------------*/ /** * \name Serial Boot Loader Backdoor configuration From da5d415bc1c94439a95da4d9f07d9585f3e1c607 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 01:07:04 +0000 Subject: [PATCH 20/81] Pull CPU-related configuration from the CPU header (Zoul) --- arch/platform/zoul/contiki-conf.h | 252 +----------------------------- 1 file changed, 4 insertions(+), 248 deletions(-) diff --git a/arch/platform/zoul/contiki-conf.h b/arch/platform/zoul/contiki-conf.h index 710ad1695..cfca8f9f1 100644 --- a/arch/platform/zoul/contiki-conf.h +++ b/arch/platform/zoul/contiki-conf.h @@ -83,172 +83,6 @@ #endif /** @} */ /*---------------------------------------------------------------------------*/ -/** - * \name CFS configuration - * - * @{ - */ -#ifndef COFFEE_CONF_SIZE -#define COFFEE_CONF_SIZE (4 * COFFEE_SECTOR_SIZE) -#endif -/** @} */ -/*---------------------------------------------------------------------------*/ -/** - * \name Watchdog Timer configuration - * - * @{ - */ -#ifndef WATCHDOG_CONF_ENABLE -#define WATCHDOG_CONF_ENABLE 1 /**< Enable the watchdog timer */ -#endif -/** @} */ -/*---------------------------------------------------------------------------*/ -/** - * \name USB 'core' configuration - * - * Those values are not meant to be modified by the user, except where stated - * otherwise - * @{ - */ -#define CTRL_EP_SIZE 8 -#define USB_EP1_SIZE 32 -#define USB_EP2_SIZE 64 -#define USB_EP3_SIZE 64 -#define USB_ARCH_WRITE_NOTIFY 0 - -#ifndef USB_ARCH_CONF_DMA -#define USB_ARCH_CONF_DMA 1 /**< Change to Enable/Disable USB DMA */ - -#endif -/** @} */ -/*---------------------------------------------------------------------------*/ -/** - * \name uDMA Configuration and channel allocations - * - * @{ - */ -#define USB_ARCH_CONF_RX_DMA_CHAN 0 /**< USB -> 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 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 !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 - -#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 - -/** - * \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 -#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) || \ - (MAC_CONF_WITH_TSCH && (SLIP_ARCH_CONF_ENABLED || BUILD_WITH_SHELL)) || \ - DBG_CONF_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_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_DBG(u) || \ - UART_IN_USE_BY_UART1(u)) \ -) -/** @} */ -/*---------------------------------------------------------------------------*/ /* board.h assumes that basic configuration is done */ #include "board.h" /*---------------------------------------------------------------------------*/ @@ -319,86 +153,6 @@ #endif /** @} */ /*---------------------------------------------------------------------------*/ -/** - * \name IEEE address configuration - * - * Used to generate our link-layer & 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 */ - -#ifdef RF_CHANNEL -#define CC2538_RF_CONF_CHANNEL RF_CHANNEL -#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 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 -/** @} */ -/*---------------------------------------------------------------------------*/ /** * \name RTC * @@ -420,7 +174,9 @@ #endif /** @} */ /*---------------------------------------------------------------------------*/ - +/* Include CPU-related configuration */ +#include "cc2538-conf.h" +/*---------------------------------------------------------------------------*/ #endif /* CONTIKI_CONF_H_ */ - +/*---------------------------------------------------------------------------*/ /** @} */ From 4bdc2f7513444f9d8f3d823c04a791bfca7e8c55 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Fri, 8 Dec 2017 16:22:53 +0000 Subject: [PATCH 21/81] Harmonise platform configuration files (jn516x) --- arch/platform/jn516x/contiki-conf.h | 14 +++++++++----- arch/platform/jn516x/dev/dr1174/README.md | 2 +- arch/platform/jn516x/dev/dr1175/README.md | 2 +- arch/platform/jn516x/dev/dr1199/README.md | 2 +- .../jn516x/{platform-conf.h => jn516x-def.h} | 15 ++++----------- 5 files changed, 16 insertions(+), 19 deletions(-) rename arch/platform/jn516x/{platform-conf.h => jn516x-def.h} (97%) diff --git a/arch/platform/jn516x/contiki-conf.h b/arch/platform/jn516x/contiki-conf.h index 620e55674..f8dbdc3e5 100644 --- a/arch/platform/jn516x/contiki-conf.h +++ b/arch/platform/jn516x/contiki-conf.h @@ -38,11 +38,15 @@ #include PROJECT_CONF_PATH #endif /* PROJECT_CONF_PATH */ -#ifdef PLATFORM_CONF_H -#include PLATFORM_CONF_H -#else -#include "platform-conf.h" -#endif /* PLATFORM_CONF_H */ +#include "jn516x-def.h" + +#ifdef RF_CHANNEL +#define MICROMAC_CONF_CHANNEL RF_CHANNEL +#endif + +#ifndef MICROMAC_CONF_CHANNEL +#define MICROMAC_CONF_CHANNEL 26 +#endif /* Configure radio driver */ #ifndef NETSTACK_CONF_RADIO diff --git a/arch/platform/jn516x/dev/dr1174/README.md b/arch/platform/jn516x/dev/dr1174/README.md index d3a21cbe0..60bffde14 100644 --- a/arch/platform/jn516x/dev/dr1174/README.md +++ b/arch/platform/jn516x/dev/dr1174/README.md @@ -5,4 +5,4 @@ Mapping of LEDs on JN516x DR1174: leds.h: led on DR1174: LEDS_GP0 LED D3 LEDS_GP1 LED D6 -Note: LEDS_GPx definitions included in leds.h via platform-conf.h +Note: LEDS_GPx definitions included in leds.h via jn516x-def.h diff --git a/arch/platform/jn516x/dev/dr1175/README.md b/arch/platform/jn516x/dev/dr1175/README.md index bf57a0a0e..e4fe60adf 100644 --- a/arch/platform/jn516x/dev/dr1175/README.md +++ b/arch/platform/jn516x/dev/dr1175/README.md @@ -14,4 +14,4 @@ DR1174+DR1175: LEDS_WHITE White power led with level control on DR1175 LEDS_GP0 LEDS D3 on DR1174 LEDS_GP1 LEDS D6 on DR1174 -Note: LEDS_GPx and LEDS_WHITE definitions included in leds.h via platform-conf.h +Note: LEDS_GPx and LEDS_WHITE definitions included in leds.h via jn516x-def.h diff --git a/arch/platform/jn516x/dev/dr1199/README.md b/arch/platform/jn516x/dev/dr1199/README.md index 83404a83b..c6e622652 100644 --- a/arch/platform/jn516x/dev/dr1199/README.md +++ b/arch/platform/jn516x/dev/dr1199/README.md @@ -16,4 +16,4 @@ DR1174+DR1199: LEDS_RED LED D3 on DR1199 LEDS_GP0 LED D3 on DR1174 LEDS_GP1 LED D6 on DR1174 -Note: LEDS_GPx definitions included in leds.h via platform-conf.h +Note: LEDS_GPx definitions included in leds.h via jn516x-def.h diff --git a/arch/platform/jn516x/platform-conf.h b/arch/platform/jn516x/jn516x-def.h similarity index 97% rename from arch/platform/jn516x/platform-conf.h rename to arch/platform/jn516x/jn516x-def.h index 990512ac2..357c255c0 100644 --- a/arch/platform/jn516x/platform-conf.h +++ b/arch/platform/jn516x/jn516x-def.h @@ -30,8 +30,8 @@ * */ -#ifndef PLATFORM_CONF_H -#define PLATFORM_CONF_H +#ifndef JN516X_DEF_H_ +#define JN516X_DEF_H_ #include #include @@ -56,14 +56,6 @@ #define MIRCOMAC_CONF_BUF_NUM 2 #endif -#ifdef RF_CHANNEL -#define MICROMAC_CONF_CHANNEL RF_CHANNEL -#endif - -#ifndef MICROMAC_CONF_CHANNEL -#define MICROMAC_CONF_CHANNEL 26 -#endif - /* 32kHz or 16MHz rtimers? */ #ifdef RTIMER_CONF_USE_32KHZ #define RTIMER_USE_32KHZ RTIMER_CONF_USE_32KHZ @@ -314,4 +306,5 @@ DR1174+DR1175: #define LEDS_GP2 64 #define LEDS_GP3 128 #define LEDS_CONF_ALL 255 -#endif /* PLATFORM_CONF_H */ + +#endif /* JN516X_DEF_H_ */ From abe583ed75cd14896983289dcbad19ca091f33e7 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Fri, 8 Dec 2017 16:31:50 +0000 Subject: [PATCH 22/81] Harmonise platform configuration files (nrf52dk) --- arch/cpu/nrf52832/dev/clock.c | 1 - arch/cpu/nrf52832/rtimer-arch.c | 1 - arch/platform/nrf52dk/contiki-conf.h | 2 +- arch/platform/nrf52dk/{platform-conf.h => nrf52dk-def.h} | 6 +++--- 4 files changed, 4 insertions(+), 6 deletions(-) rename arch/platform/nrf52dk/{platform-conf.h => nrf52dk-def.h} (97%) diff --git a/arch/cpu/nrf52832/dev/clock.c b/arch/cpu/nrf52832/dev/clock.c index 4ee09839d..68413c23b 100644 --- a/arch/cpu/nrf52832/dev/clock.c +++ b/arch/cpu/nrf52832/dev/clock.c @@ -53,7 +53,6 @@ #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 */ diff --git a/arch/cpu/nrf52832/rtimer-arch.c b/arch/cpu/nrf52832/rtimer-arch.c index 78f4790f2..02611ccbc 100644 --- a/arch/cpu/nrf52832/rtimer-arch.c +++ b/arch/cpu/nrf52832/rtimer-arch.c @@ -44,7 +44,6 @@ #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 */ diff --git a/arch/platform/nrf52dk/contiki-conf.h b/arch/platform/nrf52dk/contiki-conf.h index 6e1529352..f7b8b1fa1 100644 --- a/arch/platform/nrf52dk/contiki-conf.h +++ b/arch/platform/nrf52dk/contiki-conf.h @@ -48,7 +48,7 @@ #endif /* PROJECT_CONF_PATH */ /*---------------------------------------------------------------------------*/ /* Include platform peripherals configuration */ -#include "platform-conf.h" +#include "nrf52dk-def.h" #include "nrf52832-def.h" /*---------------------------------------------------------------------------*/ /** diff --git a/arch/platform/nrf52dk/platform-conf.h b/arch/platform/nrf52dk/nrf52dk-def.h similarity index 97% rename from arch/platform/nrf52dk/platform-conf.h rename to arch/platform/nrf52dk/nrf52dk-def.h index e2fd6cac0..ea4060ca2 100644 --- a/arch/platform/nrf52dk/platform-conf.h +++ b/arch/platform/nrf52dk/nrf52dk-def.h @@ -43,8 +43,8 @@ * Wojciech Bober * */ -#ifndef PLATFORM_CONF_H_ -#define PLATFORM_CONF_H_ +#ifndef NRF52DK_DEF_H_ +#define NRF52DK_DEF_H_ #include "boards.h" @@ -113,4 +113,4 @@ * @} * @} */ -#endif /* PLATFORM_CONF_H_ */ +#endif /* NRF52DK_DEF_H_ */ From 4a129fefc60776fc1ed3957d89ce7afcacbcd084 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Fri, 8 Dec 2017 16:39:40 +0000 Subject: [PATCH 23/81] Remove obsolete macro --- arch/platform/sky/platform-conf.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/platform/sky/platform-conf.h b/arch/platform/sky/platform-conf.h index 73f3e7652..c2267abda 100644 --- a/arch/platform/sky/platform-conf.h +++ b/arch/platform/sky/platform-conf.h @@ -43,9 +43,6 @@ * Definitions below are dictated by the hardware and not really * changeable! */ -/* Platform TMOTE_SKY */ -#define TMOTE_SKY 1 - /* Delay between GO signal and SFD: radio fixed delay + 4Bytes preample + 1B SFD -- 1Byte time is 32us * ~327us + 129preample = 456 us */ #define RADIO_DELAY_BEFORE_TX ((unsigned)US_TO_RTIMERTICKS(456)) From 49cb138020c26c1e9a1dd7a321aa52b5c5224961 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Fri, 8 Dec 2017 16:40:15 +0000 Subject: [PATCH 24/81] Provide header file with configuration for the msp430 --- arch/cpu/msp430/msp430-conf.h | 47 +++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 arch/cpu/msp430/msp430-conf.h diff --git a/arch/cpu/msp430/msp430-conf.h b/arch/cpu/msp430/msp430-conf.h new file mode 100644 index 000000000..ec4f49a55 --- /dev/null +++ b/arch/cpu/msp430/msp430-conf.h @@ -0,0 +1,47 @@ +/* + * 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. + */ +/*---------------------------------------------------------------------------*/ +#ifndef MSP430_CONF_H_ +#define MSP430_CONF_H_ +/*---------------------------------------------------------------------------*/ +/* default DCOSYNCH Period is 30 seconds */ +#ifdef DCOSYNCH_CONF_PERIOD +#define DCOSYNCH_PERIOD DCOSYNCH_CONF_PERIOD +#else +#define DCOSYNCH_PERIOD 30 +#endif + +#ifdef F_CPU +#define MSP430_CPU_SPEED F_CPU +#else +#define MSP430_CPU_SPEED 2457600UL +#endif +/*---------------------------------------------------------------------------*/ +#endif /* MSP430_CONF_H_ */ +/*---------------------------------------------------------------------------*/ From fdb60ab22f75aaac7a4fa683dcafa022d70ba4c6 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Fri, 8 Dec 2017 16:43:35 +0000 Subject: [PATCH 25/81] Move non-configuration macros to msp430def.h --- arch/cpu/msp430/msp430def.h | 13 +++++++++++++ arch/platform/sky/contiki-conf.h | 3 --- arch/platform/sky/platform-conf.h | 17 ----------------- 3 files changed, 13 insertions(+), 20 deletions(-) diff --git a/arch/cpu/msp430/msp430def.h b/arch/cpu/msp430/msp430def.h index 05e9b0bbc..d574697a9 100644 --- a/arch/cpu/msp430/msp430def.h +++ b/arch/cpu/msp430/msp430def.h @@ -85,14 +85,22 @@ typedef int32_t s32_t; #else #define DCOSYNCH_PERIOD 30 #endif +/* Types for clocks and uip_stats */ +typedef unsigned short uip_stats_t; +typedef unsigned long clock_time_t; +typedef long off_t; void msp430_cpu_init(void); /* Rename to cpu_init() later! */ void msp430_sync_dco(void); +/* Our clock resolution, this is the same as Unix HZ. */ +#define CLOCK_CONF_SECOND 128UL #define cpu_init() msp430_cpu_init() void *sbrk(int); +#define CCIF +#define CLIF typedef int spl_t; /* void splx_(spl_t); */ @@ -133,6 +141,11 @@ void *w_memset(void *out, int value, size_t n); #define MSP430_REQUIRE_LPM2 2 #define MSP430_REQUIRE_LPM3 3 +/* Platform-specific checksum implementation */ +#define UIP_ARCH_IPCHKSUM 1 + +#define BAUD2UBR(baud) ((F_CPU/baud)) + void msp430_add_lpm_req(int req); void msp430_remove_lpm_req(int req); diff --git a/arch/platform/sky/contiki-conf.h b/arch/platform/sky/contiki-conf.h index 52fc596a8..4b647e8b0 100644 --- a/arch/platform/sky/contiki-conf.h +++ b/arch/platform/sky/contiki-conf.h @@ -30,9 +30,6 @@ #define UIP_CONF_BUFFER_SIZE 240 #endif -/* Platform-specific checksum implementation */ -#define UIP_ARCH_IPCHKSUM 1 - /* Platform-specific (H/W) AES implementation */ #ifndef AES_128_CONF #define AES_128_CONF cc2420_aes_128_driver diff --git a/arch/platform/sky/platform-conf.h b/arch/platform/sky/platform-conf.h index c2267abda..93edd1d67 100644 --- a/arch/platform/sky/platform-conf.h +++ b/arch/platform/sky/platform-conf.h @@ -67,23 +67,6 @@ /* CPU target speed in Hz */ #define F_CPU 3900000uL /*2457600uL*/ -/* Our clock resolution, this is the same as Unix HZ. */ -#define CLOCK_CONF_SECOND 128UL - -#define BAUD2UBR(baud) ((F_CPU/baud)) - -#define CCIF -#define CLIF - -#define HAVE_STDINT_H -#include "msp430def.h" - - -/* Types for clocks and uip_stats */ -typedef unsigned short uip_stats_t; -typedef unsigned long clock_time_t; -typedef long off_t; - /* the low-level radio driver */ #define NETSTACK_CONF_RADIO cc2420_driver From ddd15692e1db769c1379643d9e69c8ac22a589af Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Fri, 8 Dec 2017 16:44:49 +0000 Subject: [PATCH 26/81] Rename and restructure the msp430 constants header --- arch/cpu/msp430/{msp430def.h => msp430-def.h} | 43 +++---------------- 1 file changed, 7 insertions(+), 36 deletions(-) rename arch/cpu/msp430/{msp430def.h => msp430-def.h} (83%) diff --git a/arch/cpu/msp430/msp430def.h b/arch/cpu/msp430/msp430-def.h similarity index 83% rename from arch/cpu/msp430/msp430def.h rename to arch/cpu/msp430/msp430-def.h index d574697a9..1d11b07c1 100644 --- a/arch/cpu/msp430/msp430def.h +++ b/arch/cpu/msp430/msp430-def.h @@ -27,8 +27,8 @@ * SUCH DAMAGE. */ -#ifndef MSP430DEF_H -#define MSP430DEF_H +#ifndef MSP430_DEF_H_ +#define MSP430_DEF_H_ #ifdef __IAR_SYSTEMS_ICC__ #include @@ -60,18 +60,7 @@ #define BV(x) (1 << x) #endif -#ifdef HAVE_STDINT_H #include -#else -#ifndef uint8_t -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned long uint32_t; -typedef signed char int8_t; -typedef short int16_t; -typedef long int32_t; -#endif -#endif /* !HAVE_STDINT_H */ /* These names are deprecated, use C99 names. */ typedef uint8_t u8_t; @@ -79,31 +68,18 @@ typedef uint16_t u16_t; typedef uint32_t u32_t; typedef int32_t s32_t; -/* default DCOSYNCH Period is 30 seconds */ -#ifdef DCOSYNCH_CONF_PERIOD -#define DCOSYNCH_PERIOD DCOSYNCH_CONF_PERIOD -#else -#define DCOSYNCH_PERIOD 30 -#endif /* Types for clocks and uip_stats */ typedef unsigned short uip_stats_t; typedef unsigned long clock_time_t; typedef long off_t; -void msp430_cpu_init(void); /* Rename to cpu_init() later! */ -void msp430_sync_dco(void); /* Our clock resolution, this is the same as Unix HZ. */ #define CLOCK_CONF_SECOND 128UL - -#define cpu_init() msp430_cpu_init() - -void *sbrk(int); #define CCIF #define CLIF typedef int spl_t; -/* void splx_(spl_t); */ spl_t splhigh_(void); #define splhigh() splhigh_() @@ -127,15 +103,6 @@ void *w_memset(void *out, int value, size_t n); #endif /* memcpy */ #endif /* __GNUC__ && __MSP430__ && MSP430_MEMCPY_WORKAROUND */ - -/* Moved from the msp430.h file with other msp430 related defines */ - -#ifdef F_CPU -#define MSP430_CPU_SPEED F_CPU -#else -#define MSP430_CPU_SPEED 2457600UL -#endif - #define MSP430_REQUIRE_CPUON 0 #define MSP430_REQUIRE_LPM1 1 #define MSP430_REQUIRE_LPM2 2 @@ -148,5 +115,9 @@ void *w_memset(void *out, int value, size_t n); void msp430_add_lpm_req(int req); void msp430_remove_lpm_req(int req); +void msp430_cpu_init(void); /* Rename to cpu_init() later! */ +void msp430_sync_dco(void); +#define cpu_init() msp430_cpu_init() +void *sbrk(int); -#endif /* MSP430DEF_H */ +#endif /* MSP430_DEF_H_ */ From d7b426c10522e08637c83b1203ee3c543044986a Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Fri, 8 Dec 2017 16:45:46 +0000 Subject: [PATCH 27/81] Move user configuration to contiki-conf.h --- arch/platform/sky/contiki-conf.h | 8 ++++++++ arch/platform/sky/platform-conf.h | 10 ---------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/arch/platform/sky/contiki-conf.h b/arch/platform/sky/contiki-conf.h index 4b647e8b0..fb1192065 100644 --- a/arch/platform/sky/contiki-conf.h +++ b/arch/platform/sky/contiki-conf.h @@ -13,6 +13,10 @@ #else #include "platform-conf.h" #endif /* PLATFORM_CONF_H */ +/* Map RF_CHANNEL to cc2420 default channel */ +#ifdef RF_CHANNEL +#define CC2420_CONF_CHANNEL RF_CHANNEL +#endif /* RF_CHANNEL */ /* Configure radio driver */ #ifndef NETSTACK_CONF_RADIO @@ -35,4 +39,8 @@ #define AES_128_CONF cc2420_aes_128_driver #endif /* AES_128_CONF */ +/* Disable the stack check library by default: .rom overflow otherwise */ +#ifndef STACK_CHECK_CONF_ENABLED +#define STACK_CHECK_CONF_ENABLED 0 +#endif #endif /* CONTIKI_CONF_H */ diff --git a/arch/platform/sky/platform-conf.h b/arch/platform/sky/platform-conf.h index 93edd1d67..8e7b5c069 100644 --- a/arch/platform/sky/platform-conf.h +++ b/arch/platform/sky/platform-conf.h @@ -59,11 +59,6 @@ #define PLATFORM_HAS_SHT11 1 #define PLATFORM_HAS_RADIO 1 -/* Map RF_CHANNEL to cc2420 default channel */ -#ifdef RF_CHANNEL -#define CC2420_CONF_CHANNEL RF_CHANNEL -#endif /* RF_CHANNEL */ - /* CPU target speed in Hz */ #define F_CPU 3900000uL /*2457600uL*/ @@ -213,9 +208,4 @@ for SFD timestamping */ /* Platform-specific define for the end of the stack region */ #define STACK_CONF_ORIGIN ((void *)0x3900) -/* Disable the stack check library by default: .rom overflow otherwise */ -#ifndef STACK_CHECK_CONF_ENABLED -#define STACK_CHECK_CONF_ENABLED 0 -#endif - #endif /* PLATFORM_CONF_H_ */ From aa016c3c298fdd024cc416ddbfee66d7042370da Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Fri, 8 Dec 2017 16:46:56 +0000 Subject: [PATCH 28/81] Pull CPU-related configuration from the CPU header (Sky) --- arch/platform/sky/contiki-conf.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/platform/sky/contiki-conf.h b/arch/platform/sky/contiki-conf.h index fb1192065..db749db43 100644 --- a/arch/platform/sky/contiki-conf.h +++ b/arch/platform/sky/contiki-conf.h @@ -43,4 +43,7 @@ #ifndef STACK_CHECK_CONF_ENABLED #define STACK_CHECK_CONF_ENABLED 0 #endif +/*---------------------------------------------------------------------------*/ +#include "msp430-conf.h" +/*---------------------------------------------------------------------------*/ #endif /* CONTIKI_CONF_H */ From df54d30a2a4a2939fb2663c2b1a78a446b1a11f1 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Fri, 8 Dec 2017 16:48:21 +0000 Subject: [PATCH 29/81] Pull CPU-related constants from the CPU header (Sky) --- arch/platform/sky/contiki-conf.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/platform/sky/contiki-conf.h b/arch/platform/sky/contiki-conf.h index db749db43..18b687500 100644 --- a/arch/platform/sky/contiki-conf.h +++ b/arch/platform/sky/contiki-conf.h @@ -13,6 +13,8 @@ #else #include "platform-conf.h" #endif /* PLATFORM_CONF_H */ +#include "msp430-def.h" +/*---------------------------------------------------------------------------*/ /* Map RF_CHANNEL to cc2420 default channel */ #ifdef RF_CHANNEL #define CC2420_CONF_CHANNEL RF_CHANNEL From 0a76ff8ee78c7ec06887fba9ac7c846491c15109 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Fri, 8 Dec 2017 16:49:33 +0000 Subject: [PATCH 30/81] Harmonise platform configuration files (Sky) --- arch/platform/sky/contiki-conf.h | 8 ++------ arch/platform/sky/{platform-conf.h => sky-def.h} | 6 +++--- 2 files changed, 5 insertions(+), 9 deletions(-) rename arch/platform/sky/{platform-conf.h => sky-def.h} (98%) diff --git a/arch/platform/sky/contiki-conf.h b/arch/platform/sky/contiki-conf.h index 18b687500..500e00e08 100644 --- a/arch/platform/sky/contiki-conf.h +++ b/arch/platform/sky/contiki-conf.h @@ -7,12 +7,8 @@ #ifdef PROJECT_CONF_PATH #include PROJECT_CONF_PATH #endif /* PROJECT_CONF_PATH */ - -#ifdef PLATFORM_CONF_H -#include PLATFORM_CONF_H -#else -#include "platform-conf.h" -#endif /* PLATFORM_CONF_H */ +/*---------------------------------------------------------------------------*/ +#include "sky-def.h" #include "msp430-def.h" /*---------------------------------------------------------------------------*/ /* Map RF_CHANNEL to cc2420 default channel */ diff --git a/arch/platform/sky/platform-conf.h b/arch/platform/sky/sky-def.h similarity index 98% rename from arch/platform/sky/platform-conf.h rename to arch/platform/sky/sky-def.h index 8e7b5c069..8640892af 100644 --- a/arch/platform/sky/platform-conf.h +++ b/arch/platform/sky/sky-def.h @@ -36,8 +36,8 @@ * Joakim Eriksson */ -#ifndef PLATFORM_CONF_H_ -#define PLATFORM_CONF_H_ +#ifndef SKY_DEF_H_ +#define SKY_DEF_H_ /* * Definitions below are dictated by the hardware and not really @@ -208,4 +208,4 @@ for SFD timestamping */ /* Platform-specific define for the end of the stack region */ #define STACK_CONF_ORIGIN ((void *)0x3900) -#endif /* PLATFORM_CONF_H_ */ +#endif /* SKY_DEF_H_ */ From 05c65f3c4a2a56c119182e31fcdea6469b63b9c5 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Fri, 8 Dec 2017 16:58:35 +0000 Subject: [PATCH 31/81] Update documentation --- os/services/ip64/ip64-dhcpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/os/services/ip64/ip64-dhcpc.c b/os/services/ip64/ip64-dhcpc.c index 3e99cd512..81d97490d 100644 --- a/os/services/ip64/ip64-dhcpc.c +++ b/os/services/ip64/ip64-dhcpc.c @@ -63,7 +63,7 @@ struct dhcp_msg { #if (UIP_BUFSIZE - UIP_UDPIP_HLEN) < 548 #error UIP_CONF_BUFFER_SIZE may be too small to accomodate DHCPv4 packets -#error Increase UIP_CONF_BUFFER_SIZE in your project-conf.h, platform-conf.h, or contiki-conf.h +#error Increase UIP_CONF_BUFFER_SIZE in your project-conf.h, or contiki-conf.h #error A good size is 600 bytes #endif From 941ddf35b858bd66a628c8c7e01196d6ab58cc08 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Fri, 8 Dec 2017 13:38:30 +0100 Subject: [PATCH 32/81] IPv6: added uipbuf attributes similar to packetbuf --- os/net/ipv6/uipbuf.c | 61 ++++++++++++++++++++++++++++++++++++++++++-- os/net/ipv6/uipbuf.h | 29 ++++++++++++++++++++- 2 files changed, 87 insertions(+), 3 deletions(-) diff --git a/os/net/ipv6/uipbuf.c b/os/net/ipv6/uipbuf.c index 074f12066..7e92283cf 100644 --- a/os/net/ipv6/uipbuf.c +++ b/os/net/ipv6/uipbuf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, RISE SICS + * Copyright (c) 2017, RISE SICS, Yanzi Networks * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,7 +31,14 @@ */ #include "contiki.h" #include "uip.h" +#include "net/ipv6/uipbuf.h" +#include +/*---------------------------------------------------------------------------*/ + +static uint16_t uipbuf_attrs[UIPBUF_ATTR_MAX]; + +/*---------------------------------------------------------------------------*/ /* Get the next header given the buffer - start indicates that this is start of the IPv6 header - needs to be set to 0 when in an ext hdr */ uint8_t* @@ -54,7 +61,7 @@ uipbuf_get_next_header(uint8_t *buffer, uint16_t size, uint8_t *protocol, uint8_ return buffer + ext_len; } } - +/*---------------------------------------------------------------------------*/ /* Get the final header given the buffer - that is assumed to be at start of an IPv6 header */ uint8_t* @@ -69,3 +76,53 @@ uipbuf_get_last_header(uint8_t *buffer, uint16_t size, uint8_t *protocol) } return nbuf; } +/*---------------------------------------------------------------------------*/ +/** + * Common functions for uipbuf (attributes, etc). + * + */ +/*---------------------------------------------------------------------------*/ +uint16_t +uipbuf_get_attr(uint8_t type) +{ + if(type < UIPBUF_ATTR_MAX) { + return uipbuf_attrs[type]; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +int +uipbuf_set_attr(uint8_t type, uint16_t value) +{ + if(type < UIPBUF_ATTR_MAX) { + uipbuf_attrs[type] = value; + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +void +uipbuf_clear_attr(void) +{ + memset(uipbuf_attrs, 0, sizeof(uipbuf_attrs)); +} +/*---------------------------------------------------------------------------*/ +void +uipbuf_set_attr_flag(uint16_t flag) +{ + /* Assume only 16-bits for flags now */ + uipbuf_attrs[UIPBUF_ATTR_FLAGS] |= flag; +} +/*---------------------------------------------------------------------------*/ +void +uipbuf_clr_attr_flag(uint16_t flag) +{ + uipbuf_attrs[UIPBUF_ATTR_FLAGS] &= ~flag; +} +/*---------------------------------------------------------------------------*/ +uint16_t +uipbuf_is_attr_flag(uint16_t flag) +{ + return (uipbuf_attrs[UIPBUF_ATTR_FLAGS] & flag) > 0; +} +/*---------------------------------------------------------------------------*/ diff --git a/os/net/ipv6/uipbuf.h b/os/net/ipv6/uipbuf.h index aaea446d7..16b201843 100644 --- a/os/net/ipv6/uipbuf.h +++ b/os/net/ipv6/uipbuf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, RISE SICS + * Copyright (c) 2017, RISE SICS, Yanzi Networks * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,6 +30,9 @@ * */ +#ifndef UIPBUF_H_ +#define UIPBUF_H_ + #include "contiki.h" /* Get the next header given the buffer - start indicates that this is @@ -39,3 +42,27 @@ uint8_t* uipbuf_get_next_header(uint8_t *buffer, uint16_t size, uint8_t *protoco /* Get the final header given the buffer - that is assumed to be at start of an IPv6 header */ uint8_t* uipbuf_get_last_header(uint8_t *buffer, uint16_t size, uint8_t *protocol); + +/* Attributes relating to the current packet in uipbuf */ +uint16_t uipbuf_get_attr(uint8_t type); +void uipbuf_set_attr_flag(uint16_t flag); +void uipbuf_clr_attr_flag(uint16_t flag); +uint16_t uipbuf_is_attr_flag(uint16_t flag); +int uipbuf_set_attr(uint8_t type, uint16_t value); +void uipbuf_clear_attr(void); + +/* These flags will be used for being */ +#define UIPBUF_ATTR_FLAGS_6LOWPAN_NO_NHC_COMPRESSION 0x01 +#define UIPBUF_ATTR_FLAGS_6LOWPAN_NO_PREFIX_COMPRESSION 0x02 + +enum { + UIPBUF_ATTR_LLSEC_LEVEL, + UIPBUF_ATTR_LLSEC_KEY_ID, + UIPBUF_ATTR_INTERFACE_ID, + UIPBUF_ATTR_PHYSICAL_NETWORK_ID, + UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS, + UIPBUF_ATTR_FLAGS, + UIPBUF_ATTR_MAX +}; + +#endif /* UIPBUF_H_ */ From 13569947953d243e000108a681bb531e3a8663d8 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Fri, 8 Dec 2017 13:44:29 +0100 Subject: [PATCH 33/81] added support for usage of the transmission count attirbute in uipbuf --- examples/rpl-udp/udp-client.c | 11 ++++++++++- os/net/ipv6/sicslowpan.c | 16 +++++----------- os/net/ipv6/tcpip.c | 26 ++++++++++++++++++++++++++ os/net/ipv6/uip.h | 23 +++-------------------- os/net/ipv6/uip6.c | 21 --------------------- os/net/ipv6/uipopt.h | 29 +++++++++++++---------------- os/net/mac/csma/csma-output.c | 4 ---- os/net/mac/tsch/tsch.c | 2 -- os/net/packetbuf.h | 2 -- 9 files changed, 57 insertions(+), 77 deletions(-) diff --git a/examples/rpl-udp/udp-client.c b/examples/rpl-udp/udp-client.c index d59b2b029..10e336dac 100644 --- a/examples/rpl-udp/udp-client.c +++ b/examples/rpl-udp/udp-client.c @@ -33,7 +33,10 @@ udp_rx_callback(struct simple_udp_connection *c, uint16_t datalen) { unsigned count = *(unsigned *)data; - LOG_INFO("Received response %u from ", count); + /* If tagging of traffic class is enabled tc will print number of + transmission - otherwise it will be 0 */ + LOG_INFO("Received response %u (tc:%d) from ", count, + uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS)); LOG_INFO_6ADDR(sender_addr); LOG_INFO_("\n"); } @@ -61,6 +64,12 @@ PROCESS_THREAD(udp_client_process, ev, data) LOG_INFO("Sending request %u to ", count); LOG_INFO_6ADDR(&dag->dag_id); LOG_INFO_("\n"); + /* Set the number of transmissions to use for this packet - + this can be used to create more reliable transmissions or + less reliable than the default. Works end-to-end if + UIP_CONF_TAG_TC_WITH_VARIABLE_RETRANSMISSIONS is set to 1. + */ + uipbuf_set_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS, 1 + count % 5); simple_udp_sendto(&udp_conn, &count, sizeof(count), &dag->dag_id); count++; } diff --git a/os/net/ipv6/sicslowpan.c b/os/net/ipv6/sicslowpan.c index 492dfe444..4509c3e08 100644 --- a/os/net/ipv6/sicslowpan.c +++ b/os/net/ipv6/sicslowpan.c @@ -68,6 +68,7 @@ #include "net/ipv6/tcpip.h" #include "net/ipv6/uip.h" #include "net/ipv6/uip-ds6.h" +#include "net/ipv6/uipbuf.h" #include "net/ipv6/sicslowpan.h" #include "net/netstack.h" #include "net/packetbuf.h" @@ -1504,17 +1505,6 @@ output(const linkaddr_t *localdest) set_packet_attrs(); } -#if UIP_WITH_VARIABLE_RETRANSMISSIONS - { - uint8_t traffic_class = (UIP_IP_BUF->vtc << 4) | (UIP_IP_BUF->tcflow >> 4); - if(traffic_class & UIP_TC_MAC_TRANSMISSION_COUNTER_BIT) { - uint8_t max_mac_transmissions = traffic_class & UIP_TC_MAC_TRANSMISSION_COUNTER_MASK; - /* propagate the MAC transmission limit to lower layers */ - packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, max_mac_transmissions); - } - } -#endif /* UIP_WITH_VARIABLE_RETRANSMISSIONS */ - /* * The destination address will be tagged to each outbound * packet. If the argument localdest is NULL, we are sending a @@ -1528,6 +1518,10 @@ output(const linkaddr_t *localdest) LOG_INFO("output: sending packet len %d\n", uip_len); + /* copy over the retransmission count from uipbuf attributes */ + packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, + uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS)); + /* Try to compress the headers */ #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6 compress_hdr_ipv6(&dest); diff --git a/os/net/ipv6/tcpip.c b/os/net/ipv6/tcpip.c index 326320909..d6207400b 100644 --- a/os/net/ipv6/tcpip.c +++ b/os/net/ipv6/tcpip.c @@ -121,6 +121,19 @@ uint8_t tcpip_output(const uip_lladdr_t *a) { int ret; + + /* Tag Traffic Class if we are using TC for variable retrans */ +#if UIP_TAG_TC_WITH_VARIABLE_RETRANSMISSIONS + if(uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS) != + UIP_MAX_MAC_TRANSMISSIONS_UNDEFINED) { + LOG_INFO("Tagging TC with retrans: %d\n", uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS)); + /* Encapsulate the MAC transmission limit in the Traffic Class field */ + UIP_IP_BUF->vtc = 0x60 | (UIP_TC_MAC_TRANSMISSION_COUNTER_BIT >> 4); + UIP_IP_BUF->tcflow = + uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS) << 4; + } +#endif + if(netstack_process_ip_callback(NETSTACK_IP_OUTPUT, (const linkaddr_t *)a) == NETSTACK_IP_PROCESS) { ret = NETSTACK_NETWORK.output((const linkaddr_t *) a); @@ -167,6 +180,19 @@ packet_input(void) { if(uip_len > 0) { check_for_tcp_syn(); + +#if UIP_TAG_TC_WITH_VARIABLE_RETRANSMISSIONS + { + uint8_t traffic_class = (UIP_IP_BUF->vtc << 4) | (UIP_IP_BUF->tcflow >> 4); + if(traffic_class & UIP_TC_MAC_TRANSMISSION_COUNTER_BIT) { + uint8_t max_mac_transmissions = traffic_class & UIP_TC_MAC_TRANSMISSION_COUNTER_MASK; + uipbuf_set_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS, max_mac_transmissions); + LOG_INFO("Received packet tagged with TC retrans: %d (%x)", + max_mac_transmissions, traffic_class); + } + } +#endif /* UIP_TAG_TC_WITH_VARIABLE_RETRANSMISSIONS */ + uip_input(); if(uip_len > 0) { tcpip_ipv6_output(); diff --git a/os/net/ipv6/uip.h b/os/net/ipv6/uip.h index 69888445e..c3c9f2b38 100755 --- a/os/net/ipv6/uip.h +++ b/os/net/ipv6/uip.h @@ -80,6 +80,7 @@ #include "net/ipv6/uipopt.h" +#include "net/ipv6/uipbuf.h" /* For memcmp */ #include @@ -820,18 +821,6 @@ CCIF void uip_send(const void *data, int len); */ #define uip_mss() (uip_conn->mss) -/** - * Set the maximal number of MAC transmissions. - * - * \hideinitializer - */ -#if UIP_WITH_VARIABLE_RETRANSMISSIONS -#define uip_set_max_mac_transmissions(conn, value) ((conn)->max_mac_transmissions = (value)) -#else -#define uip_set_max_mac_transmissions(conn, value) -#endif - - /** * Set up a new UDP connection. * @@ -1328,10 +1317,12 @@ extern uint16_t uip_urglen, uip_surglen; #define uip_clear_buf() { \ uip_len = 0; \ uip_ext_len = 0; \ + uipbuf_clear_attr();\ } #else /*NETSTACK_CONF_WITH_IPV6*/ #define uip_clear_buf() { \ uip_len = 0; \ + uipbuf_clear_attr();\ } #endif /*NETSTACK_CONF_WITH_IPV6*/ @@ -1365,10 +1356,6 @@ struct uip_conn { uint8_t timer; /**< The retransmission timer. */ uint8_t nrtx; /**< The number of retransmissions for the last segment sent. */ -#if UIP_WITH_VARIABLE_RETRANSMISSIONS - uint8_t max_mac_transmissions; /**< Number of max MAC-layer transmissions. */ -#endif - uip_tcp_appstate_t appstate; /** The application state. */ }; @@ -1405,10 +1392,6 @@ struct uip_udp_conn { uint16_t lport; /**< The local port number in network byte order. */ uint16_t rport; /**< The remote port number in network byte order. */ uint8_t ttl; /**< Default time-to-live. */ -#if UIP_WITH_VARIABLE_RETRANSMISSIONS - uint8_t max_mac_transmissions; /**< Number of max MAC-layer transmissions. */ -#endif - /** The application state. */ uip_udp_appstate_t appstate; }; diff --git a/os/net/ipv6/uip6.c b/os/net/ipv6/uip6.c index 7a29c90bb..55c7d7980 100644 --- a/os/net/ipv6/uip6.c +++ b/os/net/ipv6/uip6.c @@ -508,9 +508,6 @@ uip_connect(const uip_ipaddr_t *ripaddr, uint16_t rport) conn->rto = UIP_RTO; conn->sa = 0; conn->sv = 16; /* Initial value of the RTT variance. */ -#if UIP_WITH_VARIABLE_RETRANSMISSIONS - conn->max_mac_transmissions = UIP_MAX_MAC_TRANSMISSIONS_UNDEFINED; -#endif conn->lport = uip_htons(lastport); conn->rport = rport; uip_ipaddr_copy(&conn->ripaddr, ripaddr); @@ -584,9 +581,6 @@ uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport) uip_ipaddr_copy(&conn->ripaddr, ripaddr); } conn->ttl = uip_ds6_if.cur_hop_limit; -#if UIP_WITH_VARIABLE_RETRANSMISSIONS - conn->max_mac_transmissions = UIP_MAX_MAC_TRANSMISSIONS_UNDEFINED; -#endif return conn; } @@ -1578,14 +1572,6 @@ uip_process(uint8_t flag) UIP_IP_BUF->vtc = 0x60; UIP_IP_BUF->tcflow = 0x00; -#if UIP_WITH_VARIABLE_RETRANSMISSIONS - if(uip_udp_conn->max_mac_transmissions != UIP_MAX_MAC_TRANSMISSIONS_UNDEFINED) { - /* Encapsulate the MAC transmission limit in the Traffic Class field */ - UIP_IP_BUF->vtc = 0x60 | (UIP_TC_MAC_TRANSMISSION_COUNTER_BIT >> 4); - UIP_IP_BUF->tcflow = uip_udp_conn->max_mac_transmissions << 4; - } -#endif /* UIP_WITH_VARIABLE_RETRANSMISSIONS */ - UIP_IP_BUF->ttl = uip_udp_conn->ttl; UIP_IP_BUF->proto = UIP_PROTO_UDP; @@ -2292,13 +2278,6 @@ uip_process(uint8_t flag) UIP_IP_BUF->vtc = 0x60; UIP_IP_BUF->tcflow = 0x00; -#if UIP_WITH_VARIABLE_RETRANSMISSIONS - if(uip_connr->max_mac_transmissions != UIP_MAX_MAC_TRANSMISSIONS_UNDEFINED) { - /* Encapsulate the MAC transmission limit in the Traffic Class field */ - UIP_IP_BUF->vtc = 0x60 | (UIP_TC_MAC_TRANSMISSION_COUNTER_BIT >> 4); - UIP_IP_BUF->tcflow = uip_connr->max_mac_transmissions << 4; - } -#endif /* UIP_WITH_VARIABLE_RETRANSMISSIONS */ uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &uip_connr->ripaddr); uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); diff --git a/os/net/ipv6/uipopt.h b/os/net/ipv6/uipopt.h index d668133a8..15c79e20a 100644 --- a/os/net/ipv6/uipopt.h +++ b/os/net/ipv6/uipopt.h @@ -518,22 +518,6 @@ void uip_log(char *msg); #define UIP_DEFAULT_PREFIX_LEN 64 -/** - * Enables selection of maximal MAC-layer transmission count at application layer - */ -#ifdef UIP_CONF_WITH_VARIABLE_RETRANSMISSIONS -#define UIP_WITH_VARIABLE_RETRANSMISSIONS UIP_CONF_WITH_VARIABLE_RETRANSMISSIONS -#else -#define UIP_WITH_VARIABLE_RETRANSMISSIONS 0 -#endif - -/** - * This is the default value of MAC-layer transmissons for uIPv6 - * - * It means that the limit is selected by the MAC protocol instead of uIPv6. - */ -#define UIP_MAX_MAC_TRANSMISSIONS_UNDEFINED 0 - /** * The MAC-layer transmissons limit is encapslated in "Traffic Class" field * @@ -547,6 +531,19 @@ void uip_log(char *msg); */ #define UIP_TC_MAC_TRANSMISSION_COUNTER_MASK 0x3F +#ifdef UIP_CONF_TAG_TC_WITH_VARIABLE_RETRANSMISSIONS +#define UIP_TAG_TC_WITH_VARIABLE_RETRANSMISSIONS UIP_CONF_TAG_TC_WITH_VARIABLE_RETRANSMISSIONS +#else +#define UIP_TAG_TC_WITH_VARIABLE_RETRANSMISSIONS 0 +#endif + +/** + * This is the default value of MAC-layer transmissons for uIPv6 + * + * It means that the limit is selected by the MAC protocol instead of uIPv6. + */ +#define UIP_MAX_MAC_TRANSMISSIONS_UNDEFINED 0 + /** @} */ /*------------------------------------------------------------------------------*/ diff --git a/os/net/mac/csma/csma-output.c b/os/net/mac/csma/csma-output.c index 532b4ae7a..0bbc34fb0 100644 --- a/os/net/mac/csma/csma-output.c +++ b/os/net/mac/csma/csma-output.c @@ -506,15 +506,11 @@ csma_output_packet(mac_callback_t sent, void *ptr) if(q->buf != NULL) { struct qbuf_metadata *metadata = (struct qbuf_metadata *)q->ptr; /* Neighbor and packet successfully allocated */ -#if UIP_WITH_VARIABLE_RETRANSMISSIONS metadata->max_transmissions = packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS); if(metadata->max_transmissions == 0) { /* If not set by the application, use the default CSMA value */ metadata->max_transmissions = CSMA_MAX_FRAME_RETRIES + 1; } -#else - metadata->max_transmissions = CSMA_MAX_FRAME_RETRIES + 1; -#endif metadata->sent = sent; metadata->cptr = ptr; list_add(n->packet_queue, q); diff --git a/os/net/mac/tsch/tsch.c b/os/net/mac/tsch/tsch.c index bbaed827a..6d60f097a 100644 --- a/os/net/mac/tsch/tsch.c +++ b/os/net/mac/tsch/tsch.c @@ -1007,9 +1007,7 @@ send_packet(mac_callback_t sent, void *ptr) packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &linkaddr_node_addr); #endif -#if UIP_WITH_VARIABLE_RETRANSMISSIONS max_transmissions = packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS); -#endif if(max_transmissions == 0) { /* If not set by the application, use the default TSCH value */ max_transmissions = TSCH_MAC_MAX_FRAME_RETRIES + 1; diff --git a/os/net/packetbuf.h b/os/net/packetbuf.h index 706fe51d6..39ce4a467 100644 --- a/os/net/packetbuf.h +++ b/os/net/packetbuf.h @@ -217,9 +217,7 @@ enum { PACKETBUF_ATTR_LINK_QUALITY, PACKETBUF_ATTR_RSSI, PACKETBUF_ATTR_TIMESTAMP, -#if UIP_WITH_VARIABLE_RETRANSMISSIONS PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, -#endif /* UIP_WITH_VARIABLE_RETRANSMISSIONS */ PACKETBUF_ATTR_MAC_SEQNO, PACKETBUF_ATTR_MAC_ACK, PACKETBUF_ATTR_MAC_METADATA, From 52e012d3c17f8a0312b688d9d10f5c8f4a4dedff Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Fri, 8 Dec 2017 15:03:39 +0100 Subject: [PATCH 34/81] optimized flash usage due to fit sky --- arch/platform/sky/platform.c | 8 ++++---- os/contiki-main.c | 6 ++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/arch/platform/sky/platform.c b/arch/platform/sky/platform.c index b14858d9a..5bbce5286 100644 --- a/arch/platform/sky/platform.c +++ b/arch/platform/sky/platform.c @@ -200,18 +200,18 @@ platform_init_stage_three(void) cc2420_set_pan_addr(IEEE802154_PANID, shortaddr, longaddr); if(node_id > 0) { - LOG_INFO("Node id is set to %u.\n", node_id); + LOG_INFO("Node id: %u\n", node_id); } else { - LOG_INFO("Node id is not set.\n"); + LOG_INFO("Node id: N/A\n"); } #if NETSTACK_CONF_WITH_IPV6 - LOG_INFO("%s, radio channel %u, CCA threshold %i\n", + LOG_INFO("%s, rf channel %u, CCA threshold %i\n", NETSTACK_MAC.name, CC2420_CONF_CHANNEL, CC2420_CONF_CCA_THRESH); #else /* NETSTACK_CONF_WITH_IPV6 */ - LOG_INFO("%s, radio channel %u\n", + LOG_INFO("%s, rf channel %u\n", NETSTACK_MAC.name, CC2420_CONF_CHANNEL); #endif /* NETSTACK_CONF_WITH_IPV6 */ diff --git a/os/contiki-main.c b/os/contiki-main.c index 0aeaeafa1..62638c8a7 100644 --- a/os/contiki-main.c +++ b/os/contiki-main.c @@ -86,10 +86,8 @@ main(void) LOG_INFO("Starting " CONTIKI_VERSION_STRING "\n"); - LOG_INFO(" Net: "); - LOG_INFO_("%s\n", NETSTACK_NETWORK.name); - LOG_INFO(" MAC: "); - LOG_INFO_("%s\n", NETSTACK_MAC.name); + LOG_INFO(" Net: %s\n", NETSTACK_NETWORK.name); + LOG_INFO(" MAC: %s\n", NETSTACK_MAC.name); netstack_init(); From 85eff304beed0d37534ee7bbe8b76e17af7f7387 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Sat, 9 Dec 2017 10:21:49 +0100 Subject: [PATCH 35/81] set MAX_MAC_TRANSMISSION to undefined in uipbuf clear --- os/net/ipv6/uipbuf.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/os/net/ipv6/uipbuf.c b/os/net/ipv6/uipbuf.c index 7e92283cf..c0f9da4e2 100644 --- a/os/net/ipv6/uipbuf.c +++ b/os/net/ipv6/uipbuf.c @@ -104,7 +104,12 @@ uipbuf_set_attr(uint8_t type, uint16_t value) void uipbuf_clear_attr(void) { + /* set everything to "zero" */ memset(uipbuf_attrs, 0, sizeof(uipbuf_attrs)); + + /* And initialize anything that should be initialized */ + uipbuf_set_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS, + UIP_MAX_MAC_TRANSMISSIONS_UNDEFINED); } /*---------------------------------------------------------------------------*/ void From b339c42a093ec3b8ee242bb72ed4d56ccc2b406e Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Sat, 9 Dec 2017 08:59:32 +0100 Subject: [PATCH 36/81] RPL border router: re-enable Web-server-free compilation --- examples/rpl-border-router/common/httpd-simple.c | 9 +++------ examples/rpl-border-router/common/webserver.c | 3 +-- examples/rpl-border-router/embedded/project-conf.h | 2 ++ 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/examples/rpl-border-router/common/httpd-simple.c b/examples/rpl-border-router/common/httpd-simple.c index dbe1ac80f..d8ce76816 100644 --- a/examples/rpl-border-router/common/httpd-simple.c +++ b/examples/rpl-border-router/common/httpd-simple.c @@ -37,14 +37,11 @@ * Joakim Eriksson */ -#include -#include - +#include "contiki.h" #include "contiki-net.h" -#if UIP_CONF_TCP == 0 -#error HTTP server needs TCP enabled -#endif +#include +#include #include "httpd-simple.h" #define webserver_log_file(...) diff --git a/examples/rpl-border-router/common/webserver.c b/examples/rpl-border-router/common/webserver.c index 00adddb7c..61be96086 100644 --- a/examples/rpl-border-router/common/webserver.c +++ b/examples/rpl-border-router/common/webserver.c @@ -310,7 +310,6 @@ PT_THREAD(generate_routes(struct httpd_state *s)) PSOCK_END(&s->sout); } -#if BORDER_ROUTER_CONF_WEBSERVER /*---------------------------------------------------------------------------*/ PROCESS(webserver_nogui_process, "Web server"); PROCESS_THREAD(webserver_nogui_process, ev, data) @@ -332,4 +331,4 @@ httpd_simple_get_script(const char *name) { return generate_routes; } -#endif /* BORDER_ROUTER_CONF_WEBSERVER */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/rpl-border-router/embedded/project-conf.h b/examples/rpl-border-router/embedded/project-conf.h index b67d39e56..30ef25b90 100644 --- a/examples/rpl-border-router/embedded/project-conf.h +++ b/examples/rpl-border-router/embedded/project-conf.h @@ -44,7 +44,9 @@ #define WEBSERVER_CONF_CFS_CONNS 2 #endif +#ifndef BORDER_ROUTER_CONF_WEBSERVER #define BORDER_ROUTER_CONF_WEBSERVER 1 +#endif #if BORDER_ROUTER_CONF_WEBSERVER #define UIP_CONF_TCP 1 From e048348f6d760f3a0d60bc058204b6ccc6e5f925 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Sat, 9 Dec 2017 08:59:58 +0100 Subject: [PATCH 37/81] RPL border router: disable Web server on platform sky --- examples/rpl-border-router/embedded/sky/target-conf.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/rpl-border-router/embedded/sky/target-conf.h b/examples/rpl-border-router/embedded/sky/target-conf.h index 3b0b0fcd4..70cdab319 100644 --- a/examples/rpl-border-router/embedded/sky/target-conf.h +++ b/examples/rpl-border-router/embedded/sky/target-conf.h @@ -32,8 +32,10 @@ #ifndef TARGET_CONF_H_ #define TARGET_CONF_H_ /*---------------------------------------------------------------------------*/ -#define QUEUEBUF_CONF_NUM 4 -#define UIP_CONF_BUFFER_SIZE 140 +/* Save some RAM and ROM */ +#define QUEUEBUF_CONF_NUM 4 +#define UIP_CONF_BUFFER_SIZE 140 +#define BORDER_ROUTER_CONF_WEBSERVER 0 /*---------------------------------------------------------------------------*/ #endif /* TARGET_CONF_H_ */ /*---------------------------------------------------------------------------*/ From 21809648ad195c3d92d916ff141f33b661e6c9b2 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Wed, 22 Nov 2017 22:50:19 +0000 Subject: [PATCH 38/81] Add a master interrupt manipulation API --- os/sys/int-master.h | 120 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 os/sys/int-master.h diff --git a/os/sys/int-master.h b/os/sys/int-master.h new file mode 100644 index 000000000..1334abb1f --- /dev/null +++ b/os/sys/int-master.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * 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 sys + * @{ + * + * \defgroup interrupts Master interrupt manipulation + * @{ + * + * These functions can be used to manipulate the master interrupt in a + * platform-independent fashion + */ +/*---------------------------------------------------------------------------*/ +#ifndef INT_MASTER_H_ +#define INT_MASTER_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#ifdef INT_MASTER_CONF_STATUS_DATATYPE +#define INT_MASTER_STATUS_DATATYPE INT_MASTER_CONF_STATUS_DATATYPE +#else +#define INT_MASTER_STATUS_DATATYPE uint32_t +#endif + +/** + * \brief Master interrupt state representation data type + * + * It is possible for the platform code to change this datatype by defining + * INT_MASTER_CONF_STATUS_DATATYPE + */ +typedef INT_MASTER_STATUS_DATATYPE int_master_status_t; +/*---------------------------------------------------------------------------*/ +/** + * \brief Enable the master interrupt + * + * The platform developer must provide this function + */ +void int_master_enable(void); + +/** + * \brief Disable the master interrupt + * \return The status of the master interrupt before disabling it + * + * This function will return the status of the master interrupt as it was + * before it got disabled. + * + * The semantics of the return value are entirely platform-specific. The + * calling code should not try to determine whether the master interrupt was + * previously enabled/disabled by interpreting the return value of this + * function. The return value should only be used as an argument to + * int_master_status_set() + * + * To determine the status of the master interrupt in a platform-independent + * fashion you should use int_master_is_enabled(). + * + * The platform developer must provide this function + */ +int_master_status_t int_master_read_and_disable(void); + +/** + * \brief Set the status of the master interrupt + * \param status The new status + * + * The semantics of \e status are platform-dependent. Normally, the argument + * provided to this function will be a value previously retrieved through a + * call to int_master_read_and_disable() + * + * The platform developer must provide this function + */ +void int_master_status_set(int_master_status_t status); + +/** + * \brief Retrieve the status of the master interrupt + * \retval false Interrupts are disabled + * \retval true Interrupts are enabled + * + * This function can be used to retrieve the status of the master interrupt + * in a platform-independent fashion. + * + * The platform developer must provide this function + */ +bool int_master_is_enabled(void); +/*---------------------------------------------------------------------------*/ +#endif /* INT_MASTER_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ From f1774cc1e07b634fe6276d8beb978c80ee8b94b6 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Wed, 22 Nov 2017 22:50:37 +0000 Subject: [PATCH 39/81] Implement master interrupt manipulation (CC13xx/CC26xx) --- arch/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx | 2 +- arch/cpu/cc26xx-cc13xx/int-master.c | 81 +++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 arch/cpu/cc26xx-cc13xx/int-master.c diff --git a/arch/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx b/arch/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx index 48c08235d..9a2899ea7 100644 --- a/arch/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx +++ b/arch/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx @@ -34,7 +34,7 @@ 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 -CONTIKI_CPU_SOURCEFILES += random.c soc-trng.c +CONTIKI_CPU_SOURCEFILES += random.c soc-trng.c int-master.c DEBUG_IO_SOURCEFILES += dbg-printf.c dbg-snprintf.c dbg-sprintf.c strformat.c diff --git a/arch/cpu/cc26xx-cc13xx/int-master.c b/arch/cpu/cc26xx-cc13xx/int-master.c new file mode 100644 index 000000000..e6b513d63 --- /dev/null +++ b/arch/cpu/cc26xx-cc13xx/int-master.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * 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-interrupts CC13xx-CC26xx master interrupt manipulation + * + * Master interrupt manipulation routines for the CC13xx and CC26xx CPUs + * + * @{ + * + * \file + * Master interrupt manipulation implementation for the TI CC13xx/CC26xx + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "sys/int-master.h" +#include "cc13x0-cc26x0-cm3.h" + +#include "ti-lib.h" + +#include +/*---------------------------------------------------------------------------*/ +void +int_master_enable(void) +{ + ti_lib_int_master_enable(); +} +/*---------------------------------------------------------------------------*/ +int_master_status_t +int_master_read_and_disable(void) +{ + return ti_lib_int_master_disable(); +} +/*---------------------------------------------------------------------------*/ +void +int_master_status_set(int_master_status_t status) +{ + __set_PRIMASK(status); +} +/*---------------------------------------------------------------------------*/ +bool +int_master_is_enabled(void) +{ + return ti_lib_cpu_primask() ? false : true; +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ From 98664e99ee56bcad456b1a2809a2e4d73c1e43b7 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Wed, 22 Nov 2017 22:51:25 +0000 Subject: [PATCH 40/81] Implement master interrupt manipulation (CC2538) --- arch/cpu/cc2538/Makefile.cc2538 | 2 +- arch/cpu/cc2538/int-master.c | 82 +++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 arch/cpu/cc2538/int-master.c diff --git a/arch/cpu/cc2538/Makefile.cc2538 b/arch/cpu/cc2538/Makefile.cc2538 index f4c77c15d..18213ca74 100644 --- a/arch/cpu/cc2538/Makefile.cc2538 +++ b/arch/cpu/cc2538/Makefile.cc2538 @@ -19,7 +19,7 @@ CONTIKI_CPU_SOURCEFILES += nvic.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 CONTIKI_CPU_SOURCEFILES += cc2538-aes-128.c cc2538-ccm-star.c -CONTIKI_CPU_SOURCEFILES += cc2538-rf.c udma.c lpm.c +CONTIKI_CPU_SOURCEFILES += cc2538-rf.c udma.c lpm.c int-master.c CONTIKI_CPU_SOURCEFILES += pka.c bignum-driver.c ecc-driver.c ecc-algorithm.c CONTIKI_CPU_SOURCEFILES += ecc-curve.c CONTIKI_CPU_SOURCEFILES += dbg.c ieee-addr.c diff --git a/arch/cpu/cc2538/int-master.c b/arch/cpu/cc2538/int-master.c new file mode 100644 index 000000000..57a031667 --- /dev/null +++ b/arch/cpu/cc2538/int-master.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * 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-interrupts CC2538 master interrupt manipulation + * + * Master interrupt manipulation routines for the CC2538 CPU + * + * @{ + * + * \file + * Master interrupt manipulation implementation for the TI CC2538 + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "sys/int-master.h" + +#include +/*---------------------------------------------------------------------------*/ +void +int_master_enable(void) +{ + __enable_irq(); +} +/*---------------------------------------------------------------------------*/ +int_master_status_t +int_master_read_and_disable(void) +{ + int_master_status_t primask = __get_PRIMASK(); + + __disable_irq(); + + return primask; +} +/*---------------------------------------------------------------------------*/ +void +int_master_status_set(int_master_status_t status) +{ + __set_PRIMASK(status); +} +/*---------------------------------------------------------------------------*/ +bool +int_master_is_enabled(void) +{ + return __get_PRIMASK() ? false : true; +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ From 9396b6da6e0059bb1fd8c8f64e25883d16e0fd93 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Wed, 22 Nov 2017 23:14:43 +0000 Subject: [PATCH 41/81] Implement master interrupt manipulation (MSP430) --- arch/cpu/msp430/Makefile.msp430 | 2 +- arch/cpu/msp430/int-master.c | 67 +++++++++++++++++++++++++++++++++ arch/cpu/msp430/msp430-def.h | 3 ++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 arch/cpu/msp430/int-master.c diff --git a/arch/cpu/msp430/Makefile.msp430 b/arch/cpu/msp430/Makefile.msp430 index 82af8d420..f7267b694 100644 --- a/arch/cpu/msp430/Makefile.msp430 +++ b/arch/cpu/msp430/Makefile.msp430 @@ -37,7 +37,7 @@ endif CONTIKI_CPU_DIRS = $(CONTIKI_CPU_FAM_DIR) . dev MSP430 = msp430.c flash.c clock.c leds.c leds-arch.c \ - watchdog.c lpm.c rtimer-arch.c + watchdog.c lpm.c rtimer-arch.c int-master.c UIPDRIVERS = slip.c crc16.c CONTIKI_TARGET_SOURCEFILES += $(MSP430) \ diff --git a/arch/cpu/msp430/int-master.c b/arch/cpu/msp430/int-master.c new file mode 100644 index 000000000..5e50a563c --- /dev/null +++ b/arch/cpu/msp430/int-master.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \file + * Master interrupt manipulation implementation for the MSP430 + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "sys/int-master.h" + +#include +/*---------------------------------------------------------------------------*/ +void +int_master_enable(void) +{ + eint(); +} +/*---------------------------------------------------------------------------*/ +int_master_status_t +int_master_read_and_disable(void) +{ + __istate_t status = __get_interrupt_state(); + dint(); + return status; +} +/*---------------------------------------------------------------------------*/ +void +int_master_status_set(int_master_status_t status) +{ + __set_interrupt_state(status); +} +/*---------------------------------------------------------------------------*/ +bool +int_master_is_enabled(void) +{ + return __get_interrupt_state() & GIE ? true : false; +} +/*---------------------------------------------------------------------------*/ diff --git a/arch/cpu/msp430/msp430-def.h b/arch/cpu/msp430/msp430-def.h index 1d11b07c1..881c761e2 100644 --- a/arch/cpu/msp430/msp430-def.h +++ b/arch/cpu/msp430/msp430-def.h @@ -56,6 +56,9 @@ #endif /* __IAR_SYSTEMS_ICC__ */ +/* Master interrupt state representation data type */ +#define INT_MASTER_CONF_STATUS_DATATYPE __istate_t + #ifndef BV #define BV(x) (1 << x) #endif From 6dfc53dfb3f196dccd950e90a54ed3844c0cc868 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 26 Nov 2017 18:44:48 +0000 Subject: [PATCH 42/81] Implement master interrupt manipulation (JN516x) --- arch/platform/jn516x/Makefile.jn516x | 2 +- arch/platform/jn516x/int-master.c | 74 ++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 arch/platform/jn516x/int-master.c diff --git a/arch/platform/jn516x/Makefile.jn516x b/arch/platform/jn516x/Makefile.jn516x index 50a008374..bb654ceb8 100644 --- a/arch/platform/jn516x/Makefile.jn516x +++ b/arch/platform/jn516x/Makefile.jn516x @@ -81,7 +81,7 @@ OBJCOPY:=$(CROSS_COMPILE)-objcopy OBJDUMP:=$(CROSS_COMPILE)-objdump ARCH = jn516x-ccm-star.c exceptions.c rtimer-arch.c rtimer-arch-slow.c \ - slip_uart0.c clock.c micromac-radio.c \ + slip_uart0.c clock.c micromac-radio.c int-master.c \ node-id.c watchdog.c slip.c sprintf.c # Default uart0 for printf and slip TARGET_WITH_UART0 ?= 1 diff --git a/arch/platform/jn516x/int-master.c b/arch/platform/jn516x/int-master.c new file mode 100644 index 000000000..d86bd801b --- /dev/null +++ b/arch/platform/jn516x/int-master.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \file + * Master interrupt manipulation implementation for the JN516x + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "MicroSpecific.h" +#include "sys/int-master.h" + +#include +/*---------------------------------------------------------------------------*/ +void +int_master_enable(void) +{ + MICRO_ENABLE_INTERRUPTS(); +} +/*---------------------------------------------------------------------------*/ +int_master_status_t +int_master_read_and_disable(void) +{ + int_master_status_t status; + + MICRO_DISABLE_AND_SAVE_INTERRUPTS(status); + + return status; +} +/*---------------------------------------------------------------------------*/ +void +int_master_status_set(int_master_status_t status) +{ + MICRO_RESTORE_INTERRUPTS(status); +} +/*---------------------------------------------------------------------------*/ +bool +int_master_is_enabled(void) +{ + int_master_status_t status; + + asm volatile ("bw.mfspr %0, r0, 17;" :"=r"(status) : ); + + return status; +} +/*---------------------------------------------------------------------------*/ From 4094297d3ed007ae9918a9205a3fa9239dd22232 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 26 Nov 2017 19:06:42 +0000 Subject: [PATCH 43/81] Implement master interrupt manipulation (nrf52832) --- arch/cpu/nrf52832/Makefile.nrf52832 | 1 + arch/cpu/nrf52832/int-master.c | 70 +++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 arch/cpu/nrf52832/int-master.c diff --git a/arch/cpu/nrf52832/Makefile.nrf52832 b/arch/cpu/nrf52832/Makefile.nrf52832 index 6f35abcd5..9f76177bb 100644 --- a/arch/cpu/nrf52832/Makefile.nrf52832 +++ b/arch/cpu/nrf52832/Makefile.nrf52832 @@ -61,6 +61,7 @@ CONTIKI_CPU_DIRS += . dev ble #compat ### CPU-dependent source files CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c uart0.c putchar.c watchdog.c +CONTIKI_CPU_SOURCEFILES += int-master.c ifneq ($(NRF52_WITHOUT_SOFTDEVICE),1) CONTIKI_CPU_SOURCEFILES += ble-core.c ble-mac.c diff --git a/arch/cpu/nrf52832/int-master.c b/arch/cpu/nrf52832/int-master.c new file mode 100644 index 000000000..691b2541d --- /dev/null +++ b/arch/cpu/nrf52832/int-master.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \file + * Master interrupt manipulation implementation for the nrf52832 + */ +/*---------------------------------------------------------------------------*/ +#include "nordic_common.h" +#include "contiki.h" +#include "sys/int-master.h" + +#include +/*---------------------------------------------------------------------------*/ +void +int_master_enable(void) +{ + __enable_irq(); +} +/*---------------------------------------------------------------------------*/ +int_master_status_t +int_master_read_and_disable(void) +{ + int_master_status_t primask = __get_PRIMASK(); + + __disable_irq(); + + return primask; +} +/*---------------------------------------------------------------------------*/ +void +int_master_status_set(int_master_status_t status) +{ + __set_PRIMASK(status); +} +/*---------------------------------------------------------------------------*/ +bool +int_master_is_enabled(void) +{ + return __get_PRIMASK() ? false : true; +} +/*---------------------------------------------------------------------------*/ From a6dbc589a14a8538b594465b8f875c31d355cf51 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 17:46:48 +0000 Subject: [PATCH 44/81] Add an API for memory barriers --- os/sys/memory-barrier.h | 67 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 os/sys/memory-barrier.h diff --git a/os/sys/memory-barrier.h b/os/sys/memory-barrier.h new file mode 100644 index 000000000..a89b4384b --- /dev/null +++ b/os/sys/memory-barrier.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * 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 sys + * @{ + * + * \defgroup memory-barrier CPU/Compiler memory barriers + * @{ + * + * API for CPU/Compiler memory barriers + */ +/*---------------------------------------------------------------------------*/ +#ifndef MEMORY_BARRIER_H_ +#define MEMORY_BARRIER_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +/*---------------------------------------------------------------------------*/ +#ifdef MEMORY_BARRIER_CONF_ARCH_HEADER_PATH +#include MEMORY_BARRIER_CONF_ARCH_HEADER_PATH +#endif /* MEMORY_BARRIER_CONF_ARCH_HEADER_PATH */ +/*---------------------------------------------------------------------------*/ +#ifndef memory_barrier +/** + * \brief Insert a memory barrier + * + * It is the platform/CPU developer's responsibility to expand this macro to + * a function that creates a memory barrier. Calling this macro will otherwise + * not generate any code. + */ +#define memory_barrier() +#endif +/*---------------------------------------------------------------------------*/ +#endif /* MEMORY_BARRIER_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ From 103df5c95e4bfe0b100060f811a3a3e31c902458 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 17:47:13 +0000 Subject: [PATCH 45/81] Provide memory barrier (msp430) --- arch/cpu/msp430/msp430-def.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/cpu/msp430/msp430-def.h b/arch/cpu/msp430/msp430-def.h index 881c761e2..2f14d7236 100644 --- a/arch/cpu/msp430/msp430-def.h +++ b/arch/cpu/msp430/msp430-def.h @@ -106,6 +106,8 @@ void *w_memset(void *out, int value, size_t n); #endif /* memcpy */ #endif /* __GNUC__ && __MSP430__ && MSP430_MEMCPY_WORKAROUND */ +#define memory_barrier() asm volatile("" : : : "memory") + #define MSP430_REQUIRE_CPUON 0 #define MSP430_REQUIRE_LPM1 1 #define MSP430_REQUIRE_LPM2 2 From 690bad7d5e5fcecaa506b1fd1fbdce197e96558a Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 17:50:37 +0000 Subject: [PATCH 46/81] Allow different CPUs to specify how they hook into CMSIS --- arch/cpu/cc2538/cc2538-def.h | 3 +++ arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-def.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/arch/cpu/cc2538/cc2538-def.h b/arch/cpu/cc2538/cc2538-def.h index 11baef4ec..3d678053e 100644 --- a/arch/cpu/cc2538/cc2538-def.h +++ b/arch/cpu/cc2538/cc2538-def.h @@ -58,5 +58,8 @@ #define TSCH_CONF_HW_FRAME_FILTERING 0 #endif /* MAC_CONF_WITH_TSCH */ /*---------------------------------------------------------------------------*/ +/* Path to CMSIS header */ +#define CMSIS_CONF_HEADER_PATH "cc2538_cm3.h" +/*---------------------------------------------------------------------------*/ #endif /* CC2538_DEF_H_ */ /*---------------------------------------------------------------------------*/ diff --git a/arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-def.h b/arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-def.h index 283738ffe..6a603c762 100644 --- a/arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-def.h +++ b/arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-def.h @@ -93,5 +93,8 @@ /*---------------------------------------------------------------------------*/ #define RTIMER_ARCH_SECOND 65536 /*---------------------------------------------------------------------------*/ +/* Path to CMSIS header */ +#define CMSIS_CONF_HEADER_PATH "cc13x0-cc26x0-cm3.h" +/*---------------------------------------------------------------------------*/ #endif /* CC13XX_CC26XX_DEF_H_ */ /*---------------------------------------------------------------------------*/ From 35bd4eb1d8aec7bdf0d494132d6023a7f2ec21d2 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 17:51:10 +0000 Subject: [PATCH 47/81] Provide memory barrier for all Cortex-M CPUs --- arch/cpu/arm/cortex-m/memory-barrier-cortex.h | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 arch/cpu/arm/cortex-m/memory-barrier-cortex.h diff --git a/arch/cpu/arm/cortex-m/memory-barrier-cortex.h b/arch/cpu/arm/cortex-m/memory-barrier-cortex.h new file mode 100644 index 000000000..ae0177cf1 --- /dev/null +++ b/arch/cpu/arm/cortex-m/memory-barrier-cortex.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * 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 MEMORY_BARRIER_CORTEX_H_ +#define MEMORY_BARRIER_CORTEX_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" + +#ifdef CMSIS_CONF_HEADER_PATH +#include CMSIS_CONF_HEADER_PATH +#endif +/*---------------------------------------------------------------------------*/ +#define memory_barrier() __DMB() +/*---------------------------------------------------------------------------*/ +#endif /* MEMORY_BARRIER_CORTEX_H_ */ +/*---------------------------------------------------------------------------*/ From 755a6b88df867abbbf10e08fd55ae6112321b3aa Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 17:52:09 +0000 Subject: [PATCH 48/81] Use Cortex-M memory barriers (CC2538) --- arch/cpu/cc2538/cc2538-def.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/cpu/cc2538/cc2538-def.h b/arch/cpu/cc2538/cc2538-def.h index 3d678053e..82bdf2d86 100644 --- a/arch/cpu/cc2538/cc2538-def.h +++ b/arch/cpu/cc2538/cc2538-def.h @@ -60,6 +60,7 @@ /*---------------------------------------------------------------------------*/ /* Path to CMSIS header */ #define CMSIS_CONF_HEADER_PATH "cc2538_cm3.h" +#define MEMORY_BARRIER_CONF_ARCH_HEADER_PATH "memory-barrier-cortex.h" /*---------------------------------------------------------------------------*/ #endif /* CC2538_DEF_H_ */ /*---------------------------------------------------------------------------*/ From bdddf41ca9168535271300dbf717d4b4ef1fa61c Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 17:52:26 +0000 Subject: [PATCH 49/81] Use Cortex-M memory barriers (CC13xx/CC26xx) --- arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-def.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-def.h b/arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-def.h index 6a603c762..a11437ef3 100644 --- a/arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-def.h +++ b/arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-def.h @@ -95,6 +95,7 @@ /*---------------------------------------------------------------------------*/ /* Path to CMSIS header */ #define CMSIS_CONF_HEADER_PATH "cc13x0-cc26x0-cm3.h" +#define MEMORY_BARRIER_CONF_ARCH_HEADER_PATH "memory-barrier-cortex.h" /*---------------------------------------------------------------------------*/ #endif /* CC13XX_CC26XX_DEF_H_ */ /*---------------------------------------------------------------------------*/ From 1b89bba47ece95c0e84336492607bd905bce46df Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 17:52:59 +0000 Subject: [PATCH 50/81] Add library for critical section entry/exit --- os/sys/critical.h | 92 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 os/sys/critical.h diff --git a/os/sys/critical.h b/os/sys/critical.h new file mode 100644 index 000000000..8fb2cde82 --- /dev/null +++ b/os/sys/critical.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * 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 sys + * @{ + * + * \defgroup critical Critical sections + * @{ + * + * Platform-independent functions for critical section entry and exit + */ +/*---------------------------------------------------------------------------*/ +#ifndef CRITICAL_H_ +#define CRITICAL_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "sys/memory-barrier.h" +#include "sys/int-master.h" + +#include +/*---------------------------------------------------------------------------*/ +/** + * \brief Enter a critical section + * \return The status of the master interrupt before entering the critical + * + * This function will return the status of the master interrupt as it was + * before entering the critical section. + * + * The semantics of the return value are entirely platform-specific. The + * calling code should not try to determine whether the master interrupt was + * previously enabled/disabled by interpreting the return value of this + * function. The return value should only be used as an argument to + * critical_exit(). + */ +static inline int_master_status_t +critical_enter() +{ + int_master_status_t status = int_master_read_and_disable(); + memory_barrier(); + return status; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Exit a critical section and restore the master interrupt + * \param status The new status of the master interrupt + * + * The semantics of \e status are platform-dependent. Normally, the argument + * provided to this function will be a value previously retrieved through a + * call to critical_enter(). + */ +static inline void +critical_exit(int_master_status_t status) +{ + memory_barrier(); + int_master_status_set(status); +} +/*---------------------------------------------------------------------------*/ +#endif /* CRITICAL_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ From 7cd076a199ff0341b9bedba1ef05265f7ee319be Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 17:53:37 +0000 Subject: [PATCH 51/81] Add mutex API and generic implementation --- os/sys/mutex.c | 70 +++++++++++++++++++++++++++ os/sys/mutex.h | 129 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 199 insertions(+) create mode 100644 os/sys/mutex.c create mode 100644 os/sys/mutex.h diff --git a/os/sys/mutex.c b/os/sys/mutex.c new file mode 100644 index 000000000..54321f8e3 --- /dev/null +++ b/os/sys/mutex.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * 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 mutex + * @{ + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "sys/mutex.h" +#include "sys/critical.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +bool +mutex_generic_try_lock(volatile mutex_t *mutex) +{ + bool success = false; + int_master_status_t status = critical_enter(); + + if(*mutex == MUTEX_STATUS_UNLOCKED) { + *mutex = MUTEX_STATUS_LOCKED; + success = true; + } + + critical_exit(status); + + return success; +} +/*---------------------------------------------------------------------------*/ +void +mutex_generic_unlock(volatile mutex_t *mutex) +{ + int_master_status_t status = critical_enter(); + + *mutex = MUTEX_STATUS_UNLOCKED; + + critical_exit(status); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/os/sys/mutex.h b/os/sys/mutex.h new file mode 100644 index 000000000..6695acaa9 --- /dev/null +++ b/os/sys/mutex.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * 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 sys + * @{ + * + * \defgroup mutex Mutexes + * @{ + * + * This library provides an API and generic implementation of mutexes. + * + * Calling code should manipulate mutexes through the mutex_try_lock() and + * mutex_unlock() macros. By default, those macros will expand to the generic + * mutex manipulation implementations provided here. While these will work, + * they do reply on disabling the master interrupt in order to perform the + * lock/unlock operation. + * + * It is possible to override those generic implementation with CPU-specific + * implementations that exploit synchronisation instructions. To do so, + * create a CPU-specific header file. In this file, define mutex_try_lock() + * and mutex_unlock() to expand to the respective CPU function names. These + * can (but do not have to) be inlined. Then define MUTEX_CONF_ARCH_HEADER_PATH + * as this header's filename. + */ +/*---------------------------------------------------------------------------*/ +#ifndef MUTEX_H_ +#define MUTEX_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#define MUTEX_STATUS_LOCKED 1 /** The mutex is locked */ +#define MUTEX_STATUS_UNLOCKED 0 /** The mutex is not locked */ +/*---------------------------------------------------------------------------*/ +#ifdef MUTEX_CONF_ARCH_HEADER_PATH +#include MUTEX_CONF_ARCH_HEADER_PATH +#endif /* MUTEX_CONF_ARCH_HEADER_PATH */ +/*---------------------------------------------------------------------------*/ +#if !MUTEX_CONF_HAS_MUTEX_T +/** + * \brief Mutex data type + * + * It is possible for the platform to override this with its own typedef. In + * this scenario, make sure to also define MUTEX_CONF_HAS_MUTEX_T as 1. + */ +typedef uint_fast8_t mutex_t; +#endif +/*---------------------------------------------------------------------------*/ +#ifndef mutex_try_lock +/** + * \brief Try to lock a mutex + * \param m A pointer to the mutex to be locked + * \retval true Locking succeeded + * \retval false Locking failed (the mutex is already locked) + * + * This macro will expand to mutex_generic_try_lock() or to a CPU-provided + * implementation. Platform-independent code should use this macro instead + * of mutex_generic_try_lock(). + */ +#define mutex_try_lock(m) mutex_generic_try_lock(m) +#endif + +#ifndef mutex_unlock +/** + * \brief Unlock a previously acquired mutex + * \param m A pointer to the mutex to be unlocked + * + * This macro will expand to mutex_generic_unlock() or to a CPU-provided + * implementation. Platform-independent code should use this macro instead + * of mutex_generic_unlock(). + */ +#define mutex_unlock(m) mutex_generic_unlock(m) +#endif +/*---------------------------------------------------------------------------*/ +/** + * \brief Try to lock a mutex + * \param mutex A pointer to the mutex to be locked + * \retval true Locking succeeded + * \retval false Locking failed (the mutex is already locked) + * + * Do not call this function directly. Use the mutex_try_lock() macro instead. + */ +bool mutex_generic_try_lock(volatile mutex_t *mutex); + +/** + * \brief Unlock a previously acquired mutex + * \param mutex A pointer to the mutex to be unlocked + * + * Do not call this function directly. Use the mutex_unlock() macro instead. + */ +void mutex_generic_unlock(volatile mutex_t *mutex); +/*---------------------------------------------------------------------------*/ +#endif /* MUTEX_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ From 62a79c09fcf8de1c0a33f83c93736700ec3adf3a Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 17:53:51 +0000 Subject: [PATCH 52/81] Add mutex implementation for Cortex-M --- arch/cpu/arm/cortex-m/mutex-cortex.h | 82 ++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 arch/cpu/arm/cortex-m/mutex-cortex.h diff --git a/arch/cpu/arm/cortex-m/mutex-cortex.h b/arch/cpu/arm/cortex-m/mutex-cortex.h new file mode 100644 index 000000000..562a0528c --- /dev/null +++ b/arch/cpu/arm/cortex-m/mutex-cortex.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * 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 arm + * + * Arm Cortex-M implementation of mutexes using the LDREX, STREX and DMB + * instructions. + * + * @{ + */ +/*---------------------------------------------------------------------------*/ +#ifndef MUTEX_CORTEX_H_ +#define MUTEX_CORTEX_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" + +#ifdef CMSIS_CONF_HEADER_PATH +#include CMSIS_CONF_HEADER_PATH +#endif + +#include +#include +/*---------------------------------------------------------------------------*/ +#define mutex_try_lock(m) mutex_cortex_try_lock(m) +#define mutex_unlock(m) mutex_cortex_unlock(m) +/*---------------------------------------------------------------------------*/ +#define MUTEX_CONF_HAS_MUTEX_T 1 +typedef uint8_t mutex_t; +/*---------------------------------------------------------------------------*/ +static inline bool +mutex_cortex_try_lock(volatile mutex_t *mutex) +{ + int status = 1; + + if(__LDREXB(mutex) == 0) { + status = __STREXB(1, mutex); + } + + __DMB(); + + return status == 0 ? true : false; +} +/*---------------------------------------------------------------------------*/ +static inline void +mutex_cortex_unlock(volatile mutex_t *mutex) +{ + __DMB(); + *mutex = 0; +} +/*---------------------------------------------------------------------------*/ +#endif /* MUTEX_CORTEX_H_ */ +/*---------------------------------------------------------------------------*/ +/** @} */ From 48c10d3e30eff3a24ac9dc5b0a4160e774cd9957 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 17:54:09 +0000 Subject: [PATCH 53/81] Use Cortex-M mutexes (CC2538) --- arch/cpu/cc2538/cc2538-def.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/cpu/cc2538/cc2538-def.h b/arch/cpu/cc2538/cc2538-def.h index 82bdf2d86..39dd18c13 100644 --- a/arch/cpu/cc2538/cc2538-def.h +++ b/arch/cpu/cc2538/cc2538-def.h @@ -60,6 +60,9 @@ /*---------------------------------------------------------------------------*/ /* Path to CMSIS header */ #define CMSIS_CONF_HEADER_PATH "cc2538_cm3.h" + +/* Path to headers with implementation of mutexes and memory barriers */ +#define MUTEX_CONF_ARCH_HEADER_PATH "mutex-cortex.h" #define MEMORY_BARRIER_CONF_ARCH_HEADER_PATH "memory-barrier-cortex.h" /*---------------------------------------------------------------------------*/ #endif /* CC2538_DEF_H_ */ From 82bc3363d124a34db9aec82d4fae33a70882983b Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 3 Dec 2017 17:54:22 +0000 Subject: [PATCH 54/81] Use Cortex-M mutexes (CC13xx/CC26xx) --- arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-def.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-def.h b/arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-def.h index a11437ef3..e8720b5f4 100644 --- a/arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-def.h +++ b/arch/cpu/cc26xx-cc13xx/cc13xx-cc26xx-def.h @@ -95,6 +95,9 @@ /*---------------------------------------------------------------------------*/ /* Path to CMSIS header */ #define CMSIS_CONF_HEADER_PATH "cc13x0-cc26x0-cm3.h" + +/* Path to headers with implementation of mutexes and memory barriers */ +#define MUTEX_CONF_ARCH_HEADER_PATH "mutex-cortex.h" #define MEMORY_BARRIER_CONF_ARCH_HEADER_PATH "memory-barrier-cortex.h" /*---------------------------------------------------------------------------*/ #endif /* CC13XX_CC26XX_DEF_H_ */ From 5caff5290c653824117a8c00dca7e1991b05a7a9 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Sun, 10 Dec 2017 20:03:49 +0000 Subject: [PATCH 55/81] Readd back 'uip_stat' if UIP_STATISTICS is enabled --- os/net/ipv6/uip6.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/os/net/ipv6/uip6.c b/os/net/ipv6/uip6.c index 55c7d7980..4ae366d2f 100644 --- a/os/net/ipv6/uip6.c +++ b/os/net/ipv6/uip6.c @@ -98,6 +98,10 @@ #define LOG_MODULE "IPv6" #define LOG_LEVEL LOG_LEVEL_IPV6 +#if UIP_STATISTICS == 1 +struct uip_stats uip_stat; +#endif /* UIP_STATISTICS == 1 */ + /*---------------------------------------------------------------------------*/ /** * \name Layer 2 variables From bd6de2401f48346383ac8e0816ec7ac070e4082a Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Sun, 10 Dec 2017 20:34:50 +0100 Subject: [PATCH 56/81] added some documentation --- os/net/ipv6/uipbuf.c | 2 +- os/net/ipv6/uipbuf.h | 105 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 90 insertions(+), 17 deletions(-) diff --git a/os/net/ipv6/uipbuf.c b/os/net/ipv6/uipbuf.c index c0f9da4e2..6ccbb99aa 100644 --- a/os/net/ipv6/uipbuf.c +++ b/os/net/ipv6/uipbuf.c @@ -128,6 +128,6 @@ uipbuf_clr_attr_flag(uint16_t flag) uint16_t uipbuf_is_attr_flag(uint16_t flag) { - return (uipbuf_attrs[UIPBUF_ATTR_FLAGS] & flag) > 0; + return (uipbuf_attrs[UIPBUF_ATTR_FLAGS] & flag) == flag; } /*---------------------------------------------------------------------------*/ diff --git a/os/net/ipv6/uipbuf.h b/os/net/ipv6/uipbuf.h index 16b201843..337ffe17f 100644 --- a/os/net/ipv6/uipbuf.h +++ b/os/net/ipv6/uipbuf.h @@ -35,33 +35,106 @@ #include "contiki.h" -/* Get the next header given the buffer - start indicates that this is - start of the IPv6 header - needs to be set to 0 when in an ext hdr */ - +/** + * \brief Get the next IPv6 header. + * \param buffer A pointer to the buffer holding the IPv6 packet + * \param size The size of the data in the buffer + * \param protocol A pointer to a variable where the protocol of the header will be stored + * \param start A flag that indicates if this is expected to be the IPv6 packet header or a later header (Extension header) + * \retval returns address of the starting position of the next header + * + * This function moves to the next header in a IPv6 packet. + */ uint8_t* uipbuf_get_next_header(uint8_t *buffer, uint16_t size, uint8_t *protocol, uint8_t start); -/* Get the final header given the buffer - that is assumed to be at start - of an IPv6 header */ + + +/** + * \brief Get the last IPv6 header. + * \param buffer A pointer to the buffer holding the IPv6 packet + * \param size The size of the data in the buffer + * \param protocol A pointer to a variable where the protocol of the header will be stored + * \retval returns address of the starting position of the next header + * + * This function moves to the last header of the IPv6 packet. + */ uint8_t* uipbuf_get_last_header(uint8_t *buffer, uint16_t size, uint8_t *protocol); -/* Attributes relating to the current packet in uipbuf */ + +/** + * \brief Get the value of the attribute + * \param type The attribute to get the value of + * \retval the value of the attribute + * + * This function gets the value of a specific uipbuf attribute. + */ uint16_t uipbuf_get_attr(uint8_t type); -void uipbuf_set_attr_flag(uint16_t flag); -void uipbuf_clr_attr_flag(uint16_t flag); -uint16_t uipbuf_is_attr_flag(uint16_t flag); + + +/** + * \brief Set the value of the attribute + * \param type The attribute to set the value of + * \param value The value to set + * \retval 0 - indicates failure of setting the value + * \retval 1 - indicates success of setting the value + * + * This function sets the value of a specific uipbuf attribute. + */ int uipbuf_set_attr(uint8_t type, uint16_t value); + +/** + * \brief Set bits in the uipbuf attribute flags. + * \param flag_bits The bits to set in the flag. + * + * This function sets the uipbuf attributes flag of specified bits. + */ +void uipbuf_set_attr_flag(uint16_t flag_bits); + +/** + * \brief Clear bits in the uipbuf attribute flags. + * \param flag_bits The bits to clear in the flag. + * + * This function clears the uipbuf attributes flag of specified bits. + */ +void uipbuf_clr_attr_flag(uint16_t flag_bits); + +/** + * \brief Check if bits in the uipbuf attribute flag are set. + * \param flag_bits The bits to check in the flag. + * + * This function checks if the specified bits are set in the + * uipbuf attributes flag. + */ +uint16_t uipbuf_is_attr_flag(uint16_t flag_bits); + + +/** + * \brief Clear all attributes. + * + * This function clear all attributes in the uipbuf attributes + * including all flags. + */ void uipbuf_clear_attr(void); -/* These flags will be used for being */ +/** + * \brief The bits defined for uipbuf attributes flag. + * + */ +/* Avoid using NHC compression on the packet (6LoWPAN) */ #define UIPBUF_ATTR_FLAGS_6LOWPAN_NO_NHC_COMPRESSION 0x01 +/* Avoid using prefix compression on the packet (6LoWPAN) */ #define UIPBUF_ATTR_FLAGS_6LOWPAN_NO_PREFIX_COMPRESSION 0x02 +/** + * \brief The attributes defined for uipbuf attributes function. + * + */ enum { - UIPBUF_ATTR_LLSEC_LEVEL, - UIPBUF_ATTR_LLSEC_KEY_ID, - UIPBUF_ATTR_INTERFACE_ID, - UIPBUF_ATTR_PHYSICAL_NETWORK_ID, - UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS, - UIPBUF_ATTR_FLAGS, + UIPBUF_ATTR_LLSEC_LEVEL, /**< Control link layer security level. */ + UIPBUF_ATTR_LLSEC_KEY_ID, /**< Control link layer security key ID. */ + UIPBUF_ATTR_INTERFACE_ID, /**< The interface to output packet on */ + UIPBUF_ATTR_PHYSICAL_NETWORK_ID, /**< Physical network ID (mapped to PAN ID)*/ + UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS, /**< MAX transmissions of the packet MAC */ + UIPBUF_ATTR_FLAGS, /**< Flags that can control lower layers. see above. */ UIPBUF_ATTR_MAX }; From ed239372c1f7e4dfd1d427de5a80c146f62a60e4 Mon Sep 17 00:00:00 2001 From: Laurent Deru Date: Thu, 7 Dec 2017 14:04:53 +0100 Subject: [PATCH 57/81] Use UIP_LLH_LEN in multicast engines and add more traces --- os/net/ipv6/multicast/esmrf.c | 13 ++++++++----- os/net/ipv6/multicast/roll-tm.c | 2 +- os/net/ipv6/multicast/smrf.c | 9 +++++++-- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/os/net/ipv6/multicast/esmrf.c b/os/net/ipv6/multicast/esmrf.c index 2da8da400..adbea25e0 100644 --- a/os/net/ipv6/multicast/esmrf.c +++ b/os/net/ipv6/multicast/esmrf.c @@ -229,7 +229,7 @@ icmp_input() uip_process(UIP_UDP_SEND_CONN); - memcpy(&mcast_buf, uip_buf, uip_len); + memcpy(&mcast_buf, &uip_buf[UIP_LLH_LEN], uip_len); mcast_len = uip_len; /* pass the packet to our uip_process to check if it is allowed to * accept this packet or not */ @@ -239,7 +239,7 @@ icmp_input() uip_process(UIP_DATA); - memcpy(uip_buf, &mcast_buf, mcast_len); + memcpy(&uip_buf[UIP_LLH_LEN], &mcast_buf, mcast_len); uip_len = mcast_len; /* Return the IP of the original Multicast sender */ uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &src_ip); @@ -257,7 +257,7 @@ icmp_input() static void mcast_fwd(void *p) { - memcpy(uip_buf, &mcast_buf, mcast_len); + memcpy(&uip_buf[UIP_LLH_LEN], &mcast_buf, mcast_len); uip_len = mcast_len; UIP_IP_BUF->ttl--; tcpip_output(NULL); @@ -291,7 +291,7 @@ in() parent_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(parent_ipaddr); if(parent_lladdr == NULL) { - PRINTF("ESMRF: NO Parent exist \n"); + PRINTF("ESMRF: No Parent found\n"); UIP_MCAST6_STATS_ADD(mcast_dropped); return UIP_MCAST6_DROP; } @@ -309,6 +309,7 @@ in() if(UIP_IP_BUF->ttl <= 1) { UIP_MCAST6_STATS_ADD(mcast_dropped); + PRINTF("ESMRF: TTL too low\n"); return UIP_MCAST6_DROP; } @@ -350,12 +351,14 @@ in() fwd_delay = fwd_delay * (1 + ((random_rand() >> 11) % fwd_spread)); } - memcpy(&mcast_buf, uip_buf, uip_len); + memcpy(&mcast_buf, &uip_buf[UIP_LLH_LEN], uip_len); mcast_len = uip_len; ctimer_set(&mcast_periodic, fwd_delay, mcast_fwd, NULL); } PRINTF("ESMRF: %u bytes: fwd in %u [%u]\n", uip_len, fwd_delay, fwd_spread); + } else { + PRINTF("ESMRF: Group unknown, dropping\n"); } /* Done with this packet unless we are a member of the mcast group */ diff --git a/os/net/ipv6/multicast/roll-tm.c b/os/net/ipv6/multicast/roll-tm.c index edf86b22b..1d19512d6 100644 --- a/os/net/ipv6/multicast/roll-tm.c +++ b/os/net/ipv6/multicast/roll-tm.c @@ -1321,7 +1321,7 @@ static void out() { - if(uip_len + HBHO_TOTAL_LEN > UIP_BUFSIZE) { + if(uip_len + HBHO_TOTAL_LEN > UIP_BUFSIZE - UIP_LLH_LEN) { PRINTF("ROLL TM: Multicast Out can not add HBHO. Packet too long\n"); goto drop; } diff --git a/os/net/ipv6/multicast/smrf.c b/os/net/ipv6/multicast/smrf.c index 06167f75a..00043d60b 100644 --- a/os/net/ipv6/multicast/smrf.c +++ b/os/net/ipv6/multicast/smrf.c @@ -82,7 +82,7 @@ static uint8_t fwd_spread; static void mcast_fwd(void *p) { - memcpy(uip_buf, &mcast_buf, mcast_len); + memcpy(&uip_buf[UIP_LLH_LEN], &mcast_buf, mcast_len); uip_len = mcast_len; UIP_IP_BUF->ttl--; tcpip_output(NULL); @@ -106,6 +106,7 @@ in() */ d = rpl_get_any_dag(); if(!d) { + PRINTF("SMRF: No DODAG\n"); UIP_MCAST6_STATS_ADD(mcast_dropped); return UIP_MCAST6_DROP; } @@ -115,6 +116,7 @@ in() parent_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(parent_ipaddr); if(parent_lladdr == NULL) { + PRINTF("SMRF: No Parent found\n"); UIP_MCAST6_STATS_ADD(mcast_dropped); return UIP_MCAST6_DROP; } @@ -132,6 +134,7 @@ in() if(UIP_IP_BUF->ttl <= 1) { UIP_MCAST6_STATS_ADD(mcast_dropped); + PRINTF("SMRF: TTL too low\n"); return UIP_MCAST6_DROP; } @@ -173,12 +176,14 @@ in() fwd_delay = fwd_delay * (1 + ((random_rand() >> 11) % fwd_spread)); } - memcpy(&mcast_buf, uip_buf, uip_len); + memcpy(&mcast_buf, &uip_buf[UIP_LLH_LEN], uip_len); mcast_len = uip_len; ctimer_set(&mcast_periodic, fwd_delay, mcast_fwd, NULL); } PRINTF("SMRF: %u bytes: fwd in %u [%u]\n", uip_len, fwd_delay, fwd_spread); + } else { + PRINTF("SMRF: Group unknown, dropping\n"); } /* Done with this packet unless we are a member of the mcast group */ From 418d792a4b37f601ed9ad1db673c5812510a9d19 Mon Sep 17 00:00:00 2001 From: Laurent Deru Date: Thu, 7 Dec 2017 14:06:38 +0100 Subject: [PATCH 58/81] Sicslowpan uses twice UIP_LLH_LEN for IPPAYLOAD_BUF --- os/net/ipv6/sicslowpan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/os/net/ipv6/sicslowpan.c b/os/net/ipv6/sicslowpan.c index 4509c3e08..060699e93 100644 --- a/os/net/ipv6/sicslowpan.c +++ b/os/net/ipv6/sicslowpan.c @@ -123,7 +123,7 @@ /* NOTE: In the multiple-reassembly context there is only room for the header / first fragment */ #define SICSLOWPAN_IP_BUF(buf) ((struct uip_ip_hdr *)buf) #define SICSLOWPAN_UDP_BUF(buf) ((struct uip_udp_hdr *)&buf[UIP_IPH_LEN]) -#define SICSLOWPAN_IPPAYLOAD_BUF(buf) (&buf[UIP_LLIPH_LEN]) +#define SICSLOWPAN_IPPAYLOAD_BUF(buf) (&buf[UIP_IPH_LEN]) #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) From 2bf9031b020600184dac1735810fa3c9a479721d Mon Sep 17 00:00:00 2001 From: Laurent Deru Date: Thu, 7 Dec 2017 14:14:46 +0100 Subject: [PATCH 59/81] Update proto field in remove_ext_hdr() --- os/net/ipv6/tcpip.c | 7 +------ os/net/ipv6/uip6.c | 13 +++++++------ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/os/net/ipv6/tcpip.c b/os/net/ipv6/tcpip.c index d6207400b..e096ce44b 100644 --- a/os/net/ipv6/tcpip.c +++ b/os/net/ipv6/tcpip.c @@ -472,12 +472,7 @@ output_fallback(void) #ifdef UIP_FALLBACK_INTERFACE LOG_INFO("fallback: removing ext hdrs & setting proto %d %d\n", uip_ext_len, *((uint8_t *)UIP_IP_BUF + 40)); - if(uip_ext_len > 0) { - 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; - } + remove_ext_hdr(); /* 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 */ diff --git a/os/net/ipv6/uip6.c b/os/net/ipv6/uip6.c index 4ae366d2f..72384414a 100644 --- a/os/net/ipv6/uip6.c +++ b/os/net/ipv6/uip6.c @@ -523,6 +523,7 @@ uip_connect(const uip_ipaddr_t *ripaddr, uint16_t rport) void remove_ext_hdr(void) { + int last_uip_ext_len; /* Remove ext header before TCP/UDP processing. */ if(uip_ext_len > 0) { LOG_DBG("Cutting ext-header before processing (extlen: %d, uiplen: %d)\n", @@ -532,15 +533,17 @@ remove_ext_hdr(void) uip_clear_buf(); return; } - memmove(((uint8_t *)UIP_TCP_BUF), (uint8_t *)UIP_TCP_BUF + uip_ext_len, - uip_len - UIP_IPH_LEN - uip_ext_len); + last_uip_ext_len = uip_ext_len; + uip_ext_len = 0; + UIP_IP_BUF->proto = UIP_EXT_BUF->next; + memmove(((uint8_t *)UIP_TCP_BUF), (uint8_t *)UIP_TCP_BUF + last_uip_ext_len, + uip_len - UIP_IPH_LEN - last_uip_ext_len); - uip_len -= uip_ext_len; + uip_len -= last_uip_ext_len; /* Update the IP length. */ UIP_IP_BUF->len[0] = (uip_len - UIP_IPH_LEN) >> 8; UIP_IP_BUF->len[1] = (uip_len - UIP_IPH_LEN) & 0xff; - uip_ext_len = 0; } } /*---------------------------------------------------------------------------*/ @@ -1494,7 +1497,6 @@ uip_process(uint8_t flag) udp_input: remove_ext_hdr(); - UIP_IP_BUF->proto = UIP_PROTO_UDP; LOG_INFO("Receiving UDP packet\n"); @@ -1607,7 +1609,6 @@ uip_process(uint8_t flag) tcp_input: remove_ext_hdr(); - UIP_IP_BUF->proto = UIP_PROTO_TCP; UIP_STAT(++uip_stat.tcp.recv); LOG_INFO("Receiving TCP packet\n"); From 52f7e4a9f56d2d648124663ade949190e8425d47 Mon Sep 17 00:00:00 2001 From: Laurent Deru Date: Mon, 11 Dec 2017 17:19:02 +0100 Subject: [PATCH 60/81] Don't autoconfigure address on RPL Root --- os/net/rpl-classic/rpl-dag.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/os/net/rpl-classic/rpl-dag.c b/os/net/rpl-classic/rpl-dag.c index e4f4191b1..6bb15007d 100644 --- a/os/net/rpl-classic/rpl-dag.c +++ b/os/net/rpl-classic/rpl-dag.c @@ -522,14 +522,16 @@ rpl_set_prefix(rpl_dag_t *dag, uip_ipaddr_t *prefix, unsigned len) dag->prefix_info.length = len; dag->prefix_info.flags = UIP_ND6_RA_FLAG_AUTONOMOUS; PRINTF("RPL: Prefix set - will announce this in DIOs\n"); - /* Autoconfigure an address if this node does not already have an address - with this prefix. Otherwise, update the prefix */ - if(last_len == 0) { - PRINTF("rpl_set_prefix - prefix NULL\n"); - check_prefix(NULL, &dag->prefix_info); - } else { - PRINTF("rpl_set_prefix - prefix NON-NULL\n"); - check_prefix(&last_prefix, &dag->prefix_info); + if(dag->rank != ROOT_RANK(dag->instance)) { + /* Autoconfigure an address if this node does not already have an address + with this prefix. Otherwise, update the prefix */ + if(last_len == 0) { + PRINTF("rpl_set_prefix - prefix NULL\n"); + check_prefix(NULL, &dag->prefix_info); + } else { + PRINTF("rpl_set_prefix - prefix NON-NULL\n"); + check_prefix(&last_prefix, &dag->prefix_info); + } } return 1; } From b782cda83760ab1a630b69b2aa3d5af521469cfe Mon Sep 17 00:00:00 2001 From: Laurent Deru Date: Mon, 11 Dec 2017 17:19:51 +0100 Subject: [PATCH 61/81] Do RPL probing on all the known DAG --- os/net/rpl-classic/rpl-ns.h | 1 + os/net/rpl-classic/rpl-timers.c | 20 +++++++++++++++++++- os/net/rpl-classic/rpl.h | 1 + 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/os/net/rpl-classic/rpl-ns.h b/os/net/rpl-classic/rpl-ns.h index f6ae4c2c6..dcc7e584a 100644 --- a/os/net/rpl-classic/rpl-ns.h +++ b/os/net/rpl-classic/rpl-ns.h @@ -56,6 +56,7 @@ typedef struct rpl_ns_node { struct rpl_ns_node *next; uint32_t lifetime; + rpl_dag_t *dag; /* Store only IPv6 link identifiers as all nodes in the DAG share the same prefix */ unsigned char link_identifier[8]; struct rpl_ns_node *parent; diff --git a/os/net/rpl-classic/rpl-timers.c b/os/net/rpl-classic/rpl-timers.c index b89a1258d..9d3db3d22 100644 --- a/os/net/rpl-classic/rpl-timers.c +++ b/os/net/rpl-classic/rpl-timers.c @@ -457,11 +457,29 @@ get_probing_target(rpl_dag_t *dag) return probing_target; } /*---------------------------------------------------------------------------*/ +static rpl_dag_t * +get_next_dag(rpl_instance_t *instance) +{ + rpl_dag_t *dag = NULL; + int new_dag = instance->last_dag; + do { + new_dag++; + if(new_dag >= RPL_MAX_DAG_PER_INSTANCE) { + new_dag = 0; + } + if(instance->dag_table[new_dag].used) { + dag = &instance->dag_table[new_dag]; + } + } while(new_dag != instance->last_dag && dag == NULL); + instance->last_dag = new_dag; + return dag; +} +/*---------------------------------------------------------------------------*/ static void handle_probing_timer(void *ptr) { rpl_instance_t *instance = (rpl_instance_t *)ptr; - rpl_parent_t *probing_target = RPL_PROBING_SELECT_FUNC(instance->current_dag); + rpl_parent_t *probing_target = RPL_PROBING_SELECT_FUNC(get_next_dag(instance)); uip_ipaddr_t *target_ipaddr = rpl_parent_get_ipaddr(probing_target); /* Perform probing */ diff --git a/os/net/rpl-classic/rpl.h b/os/net/rpl-classic/rpl.h index 185bcbef2..2fe9f1dbf 100644 --- a/os/net/rpl-classic/rpl.h +++ b/os/net/rpl-classic/rpl.h @@ -252,6 +252,7 @@ struct rpl_instance { #if RPL_WITH_PROBING struct ctimer probing_timer; rpl_parent_t *urgent_probing_target; + int last_dag; #endif /* RPL_WITH_PROBING */ struct ctimer dio_timer; struct ctimer dao_timer; From ebb1f5475e20f9813bf0f7c6dfb7322f8dfd0f88 Mon Sep 17 00:00:00 2001 From: Laurent Deru Date: Mon, 11 Dec 2017 17:43:52 +0100 Subject: [PATCH 62/81] Always use uip_ds6_select_src when sending back an icmp error --- os/net/ipv6/uip-icmp6.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/os/net/ipv6/uip-icmp6.c b/os/net/ipv6/uip-icmp6.c index 0a48a134e..d46a9cd68 100644 --- a/os/net/ipv6/uip-icmp6.c +++ b/os/net/ipv6/uip-icmp6.c @@ -238,12 +238,8 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) { return; } } else { -#if UIP_CONF_ROUTER /* need to pick a source that corresponds to this node */ uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &tmp_ipaddr); -#else - uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &tmp_ipaddr); -#endif } UIP_ICMP_BUF->type = type; From a97148abd48d3aaff6472430cbfc7de359351409 Mon Sep 17 00:00:00 2001 From: Laurent Deru Date: Thu, 7 Dec 2017 14:56:12 +0100 Subject: [PATCH 63/81] Make multicast route lifetime identical to unicast routes --- os/net/rpl-classic/rpl-private.h | 7 ------- os/net/rpl-classic/rpl-timers.c | 4 ++-- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/os/net/rpl-classic/rpl-private.h b/os/net/rpl-classic/rpl-private.h index f00734821..723154cdd 100644 --- a/os/net/rpl-classic/rpl-private.h +++ b/os/net/rpl-classic/rpl-private.h @@ -199,13 +199,6 @@ #define RPL_ROUTE_FROM_MULTICAST_DAO 2 #define RPL_ROUTE_FROM_DIO 3 -/* Multicast Route Lifetime as a multiple of the lifetime unit */ -#ifdef RPL_CONF_MCAST_LIFETIME -#define RPL_MCAST_LIFETIME RPL_CONF_MCAST_LIFETIME -#else -#define RPL_MCAST_LIFETIME 3 -#endif - /* DIS related */ #define RPL_DIS_SEND 1 diff --git a/os/net/rpl-classic/rpl-timers.c b/os/net/rpl-classic/rpl-timers.c index b89a1258d..56eda7abc 100644 --- a/os/net/rpl-classic/rpl-timers.c +++ b/os/net/rpl-classic/rpl-timers.c @@ -283,7 +283,7 @@ handle_dao_timer(void *ptr) if(uip_ds6_if.maddr_list[i].isused && uip_is_addr_mcast_global(&uip_ds6_if.maddr_list[i].ipaddr)) { dao_output_target(instance->current_dag->preferred_parent, - &uip_ds6_if.maddr_list[i].ipaddr, RPL_MCAST_LIFETIME); + &uip_ds6_if.maddr_list[i].ipaddr, instance->default_lifetime); } } @@ -293,7 +293,7 @@ handle_dao_timer(void *ptr) /* Don't send if it's also our own address, done that already */ if(uip_ds6_maddr_lookup(&mcast_route->group) == NULL) { dao_output_target(instance->current_dag->preferred_parent, - &mcast_route->group, RPL_MCAST_LIFETIME); + &mcast_route->group, instance->default_lifetime); } mcast_route = list_item_next(mcast_route); } From a79fa138052d31bbc7bc8c8fcf0a616c3e163c04 Mon Sep 17 00:00:00 2001 From: Laurent Deru Date: Thu, 7 Dec 2017 14:52:37 +0100 Subject: [PATCH 64/81] Additional cleanup when becoming DODAG Root (rpl-classic) --- os/net/rpl-classic/rpl-dag.c | 8 ++++++++ os/net/rpl-classic/rpl-icmp6.c | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/os/net/rpl-classic/rpl-dag.c b/os/net/rpl-classic/rpl-dag.c index e4f4191b1..96f086b8d 100644 --- a/os/net/rpl-classic/rpl-dag.c +++ b/os/net/rpl-classic/rpl-dag.c @@ -370,6 +370,7 @@ rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id) } if(dag == dag->instance->current_dag) { PRINTF("RPL: Dropping a joined DAG when setting this node as root"); + rpl_set_default_route(instance, NULL); dag->instance->current_dag = NULL; } else { PRINTF("RPL: Dropping a DAG when setting this node as root"); @@ -665,6 +666,10 @@ rpl_free_dag(rpl_dag_t *dag) if(RPL_IS_STORING(dag->instance)) { rpl_remove_routes(dag); } + /* Stop the DAO retransmit timer */ +#if RPL_WITH_DAO_ACK + ctimer_stop(&dag->instance->dao_retransmit_timer); +#endif /* RPL_WITH_DAO_ACK */ /* Remove autoconfigured address */ if((dag->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS)) { @@ -1323,6 +1328,9 @@ rpl_local_repair(rpl_instance_t *instance) /* no downward route anymore */ instance->has_downward_route = 0; +#if RPL_WITH_DAO_ACK + ctimer_stop(&instance->dao_retransmit_timer); +#endif /* RPL_WITH_DAO_ACK */ rpl_reset_dio_timer(instance); if(RPL_IS_STORING(instance)) { diff --git a/os/net/rpl-classic/rpl-icmp6.c b/os/net/rpl-classic/rpl-icmp6.c index 6da3c2656..c5114fd14 100644 --- a/os/net/rpl-classic/rpl-icmp6.c +++ b/os/net/rpl-classic/rpl-icmp6.c @@ -1282,6 +1282,12 @@ dao_ack_input(void) parent = NULL; } + if(instance->current_dag->rank == ROOT_RANK(instance)) { + PRINTF("RPL: DODAG root received a DAO ACK, ignoring it\n"); + uip_clear_buf(); + return; + } + 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); From 74efdf688e9cf3ae8117e4377f5fbce80b5d12f8 Mon Sep 17 00:00:00 2001 From: Laurent Deru Date: Mon, 11 Dec 2017 17:19:26 +0100 Subject: [PATCH 65/81] Always try to find the best dag --- os/net/rpl-classic/rpl-dag.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/os/net/rpl-classic/rpl-dag.c b/os/net/rpl-classic/rpl-dag.c index 96f086b8d..896b8b5e8 100644 --- a/os/net/rpl-classic/rpl-dag.c +++ b/os/net/rpl-classic/rpl-dag.c @@ -762,22 +762,17 @@ rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p) old_rank = instance->current_dag->rank; last_parent = instance->current_dag->preferred_parent; - best_dag = instance->current_dag; - if(best_dag->rank != ROOT_RANK(instance)) { - if(rpl_select_parent(p->dag) != NULL) { - if(p->dag != best_dag) { - best_dag = instance->of->best_dag(best_dag, p->dag); - } - } else if(p->dag == best_dag) { - best_dag = NULL; - for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) { - if(dag->used && dag->preferred_parent != NULL && dag->preferred_parent->rank != RPL_INFINITE_RANK) { - if(best_dag == NULL) { - best_dag = dag; - } else { - best_dag = instance->of->best_dag(best_dag, dag); - } - } + if(instance->current_dag->rank != ROOT_RANK(instance)) { + rpl_select_parent(p->dag); + } + + best_dag = NULL; + for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) { + if(dag->used && dag->preferred_parent != NULL && dag->preferred_parent->rank != RPL_INFINITE_RANK) { + if(best_dag == NULL) { + best_dag = dag; + } else { + best_dag = instance->of->best_dag(best_dag, dag); } } } From aae6276b5657f181ddce2aa629910549f27f18e0 Mon Sep 17 00:00:00 2001 From: Laurent Deru Date: Mon, 11 Dec 2017 18:28:10 +0100 Subject: [PATCH 66/81] Add missing UIP_LLH_LEN --- os/net/app-layer/coap/coap.h | 2 +- os/net/rpl-classic/rpl-ext-header.c | 4 ++-- os/net/rpl-lite/rpl-ext-header.c | 4 ++-- os/services/ip64/ip64-dhcpc.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/os/net/app-layer/coap/coap.h b/os/net/app-layer/coap/coap.h index 9d88886af..616f67d5c 100644 --- a/os/net/app-layer/coap/coap.h +++ b/os/net/app-layer/coap/coap.h @@ -46,7 +46,7 @@ /* sanity check for configured values */ #define COAP_MAX_PACKET_SIZE (COAP_MAX_HEADER_SIZE + REST_MAX_CHUNK_SIZE) -#if COAP_MAX_PACKET_SIZE > (UIP_BUFSIZE - UIP_IPH_LEN - UIP_UDPH_LEN) +#if COAP_MAX_PACKET_SIZE > (UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPH_LEN - UIP_UDPH_LEN) #error "UIP_CONF_BUFFER_SIZE too small for REST_MAX_CHUNK_SIZE" #endif diff --git a/os/net/rpl-classic/rpl-ext-header.c b/os/net/rpl-classic/rpl-ext-header.c index 0c1f8076a..a0fdb0eb4 100644 --- a/os/net/rpl-classic/rpl-ext-header.c +++ b/os/net/rpl-classic/rpl-ext-header.c @@ -408,7 +408,7 @@ insert_srh_header(void) path_len, cmpri, cmpre, ext_len, padding); /* Check if there is enough space to store the extension header */ - if(uip_len + ext_len > UIP_BUFSIZE) { + if(uip_len + ext_len > UIP_BUFSIZE - UIP_LLH_LEN) { PRINTF("RPL: Packet too long: impossible to add source routing header (%u bytes)\n", ext_len); return 0; } @@ -553,7 +553,7 @@ insert_hbh_header(const rpl_instance_t *instance) /* Insert hop-by-hop header */ PRINTF("RPL: Creating hop-by-hop option\n"); - if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE) { + if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE - UIP_LLH_LEN) { PRINTF("RPL: Packet too long: impossible to add hop-by-hop option\n"); uip_ext_len = last_uip_ext_len; return 0; diff --git a/os/net/rpl-lite/rpl-ext-header.c b/os/net/rpl-lite/rpl-ext-header.c index e71e6c1f6..96455e85c 100644 --- a/os/net/rpl-lite/rpl-ext-header.c +++ b/os/net/rpl-lite/rpl-ext-header.c @@ -302,7 +302,7 @@ insert_srh_header(void) path_len, cmpri, cmpre, ext_len, padding); /* Check if there is enough space to store the extension header */ - if(uip_len + ext_len > UIP_BUFSIZE) { + if(uip_len + ext_len > UIP_BUFSIZE - UIP_LLH_LEN) { LOG_ERR("packet too long: impossible to add source routing header (%u bytes)\n", ext_len); return 0; } @@ -464,7 +464,7 @@ insert_hbh_header(void) /* Insert hop-by-hop header */ LOG_INFO("creating hop-by-hop option\n"); - if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE) { + if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE - UIP_LLH_LEN) { LOG_ERR("packet too long: impossible to add hop-by-hop option\n"); uip_ext_len = last_uip_ext_len; return 0; diff --git a/os/services/ip64/ip64-dhcpc.c b/os/services/ip64/ip64-dhcpc.c index 81d97490d..8e8e286f8 100644 --- a/os/services/ip64/ip64-dhcpc.c +++ b/os/services/ip64/ip64-dhcpc.c @@ -61,7 +61,7 @@ struct dhcp_msg { uint8_t options[312]; }; -#if (UIP_BUFSIZE - UIP_UDPIP_HLEN) < 548 +#if (UIP_BUFSIZE - UIP_LLH_LEN - UIP_UDPIP_HLEN) < 548 #error UIP_CONF_BUFFER_SIZE may be too small to accomodate DHCPv4 packets #error Increase UIP_CONF_BUFFER_SIZE in your project-conf.h, or contiki-conf.h #error A good size is 600 bytes From 5bf06d851de9acb9b0e29811e4a4c94922ef7dc9 Mon Sep 17 00:00:00 2001 From: Laurent Deru Date: Thu, 7 Dec 2017 14:58:12 +0100 Subject: [PATCH 67/81] rpl_ext_header_remove() should only remove RPL Hop-by-Hop extention header --- os/net/rpl-classic/rpl-ext-header.c | 27 +++++++++++++++++---------- os/net/rpl-lite/rpl-ext-header.c | 27 +++++++++++++++++---------- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/os/net/rpl-classic/rpl-ext-header.c b/os/net/rpl-classic/rpl-ext-header.c index 0c1f8076a..8fab6d165 100644 --- a/os/net/rpl-classic/rpl-ext-header.c +++ b/os/net/rpl-classic/rpl-ext-header.c @@ -592,9 +592,11 @@ rpl_ext_header_remove(void) { uint8_t temp_len; uint8_t rpl_ext_hdr_len; + int uip_ext_opt_offset; uint8_t *uip_next_hdr; uip_ext_len = 0; + uip_ext_opt_offset = 2; uip_next_hdr = &UIP_IP_BUF->proto; /* Look for hop-by-hop and routing headers */ @@ -602,17 +604,22 @@ rpl_ext_header_remove(void) switch(*uip_next_hdr) { case UIP_PROTO_HBHO: case UIP_PROTO_ROUTING: - /* Remove hop-by-hop and routing headers */ - *uip_next_hdr = UIP_EXT_BUF->next; - rpl_ext_hdr_len = (UIP_EXT_BUF->len * 8) + 8; - temp_len = UIP_IP_BUF->len[1]; - uip_len -= rpl_ext_hdr_len; - UIP_IP_BUF->len[1] -= rpl_ext_hdr_len; - if(UIP_IP_BUF->len[1] > temp_len) { - UIP_IP_BUF->len[0]--; + if((*uip_next_hdr != UIP_PROTO_HBHO || UIP_EXT_HDR_OPT_RPL_BUF->opt_type == UIP_EXT_HDR_OPT_RPL)) { + /* Remove hop-by-hop and routing headers */ + *uip_next_hdr = UIP_EXT_BUF->next; + rpl_ext_hdr_len = (UIP_EXT_BUF->len * 8) + 8; + temp_len = UIP_IP_BUF->len[1]; + uip_len -= rpl_ext_hdr_len; + UIP_IP_BUF->len[1] -= rpl_ext_hdr_len; + if(UIP_IP_BUF->len[1] > temp_len) { + UIP_IP_BUF->len[0]--; + } + PRINTF("RPL: Removing RPL extension header (type %u, len %u)\n", *uip_next_hdr, rpl_ext_hdr_len); + memmove(UIP_EXT_BUF, ((uint8_t *)UIP_EXT_BUF) + rpl_ext_hdr_len, uip_len - UIP_IPH_LEN); + } else { + uip_next_hdr = &UIP_EXT_BUF->next; + uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; } - PRINTF("RPL: Removing RPL extension header (type %u, len %u)\n", *uip_next_hdr, rpl_ext_hdr_len); - memmove(UIP_EXT_BUF, ((uint8_t *)UIP_EXT_BUF) + rpl_ext_hdr_len, uip_len - UIP_IPH_LEN); break; case UIP_PROTO_DESTO: /* diff --git a/os/net/rpl-lite/rpl-ext-header.c b/os/net/rpl-lite/rpl-ext-header.c index e71e6c1f6..ee0e2a2db 100644 --- a/os/net/rpl-lite/rpl-ext-header.c +++ b/os/net/rpl-lite/rpl-ext-header.c @@ -531,9 +531,11 @@ rpl_ext_header_remove(void) { uint8_t temp_len; uint8_t rpl_ext_hdr_len; + int uip_ext_opt_offset; uint8_t *uip_next_hdr; uip_ext_len = 0; + uip_ext_opt_offset = 2; uip_next_hdr = &UIP_IP_BUF->proto; /* Look for hop-by-hop and routing headers */ @@ -541,17 +543,22 @@ rpl_ext_header_remove(void) switch(*uip_next_hdr) { case UIP_PROTO_HBHO: case UIP_PROTO_ROUTING: - /* Remove hop-by-hop and routing headers */ - *uip_next_hdr = UIP_EXT_BUF->next; - rpl_ext_hdr_len = (UIP_EXT_BUF->len * 8) + 8; - temp_len = UIP_IP_BUF->len[1]; - uip_len -= rpl_ext_hdr_len; - UIP_IP_BUF->len[1] -= rpl_ext_hdr_len; - if(UIP_IP_BUF->len[1] > temp_len) { - UIP_IP_BUF->len[0]--; + if((*uip_next_hdr != UIP_PROTO_HBHO || UIP_EXT_HDR_OPT_RPL_BUF->opt_type == UIP_EXT_HDR_OPT_RPL)) { + /* Remove hop-by-hop and routing headers */ + *uip_next_hdr = UIP_EXT_BUF->next; + rpl_ext_hdr_len = (UIP_EXT_BUF->len * 8) + 8; + temp_len = UIP_IP_BUF->len[1]; + uip_len -= rpl_ext_hdr_len; + UIP_IP_BUF->len[1] -= rpl_ext_hdr_len; + if(UIP_IP_BUF->len[1] > temp_len) { + UIP_IP_BUF->len[0]--; + } + LOG_INFO("removing RPL extension header (type %u, len %u)\n", *uip_next_hdr, rpl_ext_hdr_len); + memmove(UIP_EXT_BUF, ((uint8_t *)UIP_EXT_BUF) + rpl_ext_hdr_len, uip_len - UIP_IPH_LEN); + } else { + uip_next_hdr = &UIP_EXT_BUF->next; + uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; } - LOG_INFO("removing RPL extension header (type %u, len %u)\n", *uip_next_hdr, rpl_ext_hdr_len); - memmove(UIP_EXT_BUF, ((uint8_t *)UIP_EXT_BUF) + rpl_ext_hdr_len, uip_len - UIP_IPH_LEN); break; case UIP_PROTO_DESTO: /* From 3b24a57ad2a04a44034ea54e7f179433940abb5b Mon Sep 17 00:00:00 2001 From: Laurent Deru Date: Tue, 12 Dec 2017 16:14:49 +0100 Subject: [PATCH 68/81] Move to next header when encountering DESTO instead of aborting the loop in rpl_ext_header_remove() --- os/net/rpl-classic/rpl-ext-header.c | 1 + os/net/rpl-lite/rpl-ext-header.c | 1 + 2 files changed, 2 insertions(+) diff --git a/os/net/rpl-classic/rpl-ext-header.c b/os/net/rpl-classic/rpl-ext-header.c index 8fab6d165..3500356dc 100644 --- a/os/net/rpl-classic/rpl-ext-header.c +++ b/os/net/rpl-classic/rpl-ext-header.c @@ -633,6 +633,7 @@ rpl_ext_header_remove(void) /* Move to next header */ uip_next_hdr = &UIP_EXT_BUF->next; uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; + break; default: return; } diff --git a/os/net/rpl-lite/rpl-ext-header.c b/os/net/rpl-lite/rpl-ext-header.c index ee0e2a2db..d001948b5 100644 --- a/os/net/rpl-lite/rpl-ext-header.c +++ b/os/net/rpl-lite/rpl-ext-header.c @@ -572,6 +572,7 @@ rpl_ext_header_remove(void) /* Move to next header */ uip_next_hdr = &UIP_EXT_BUF->next; uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; + break; default: return; } From ccb705ed315e64cb8dc6bb04780e9fcbfd70da21 Mon Sep 17 00:00:00 2001 From: Laurent Deru Date: Thu, 7 Dec 2017 14:09:09 +0100 Subject: [PATCH 69/81] Use clock_gettime() instead of gettimeofday() to have a monotonic clock and use CLOCK_CONF_SECOND explicitly --- arch/cpu/native/rtimer-arch.c | 8 +++--- arch/platform/native/Makefile.native | 4 +++ arch/platform/native/clock.c | 37 +++++++++++++++++++++++----- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/arch/cpu/native/rtimer-arch.c b/arch/cpu/native/rtimer-arch.c index 2dab7efb6..ad081c9f5 100644 --- a/arch/cpu/native/rtimer-arch.c +++ b/arch/cpu/native/rtimer-arch.c @@ -79,11 +79,11 @@ rtimer_arch_schedule(rtimer_clock_t t) c = t - (unsigned short)clock_time(); - val.it_value.tv_sec = c / 1000; - val.it_value.tv_usec = (c % 1000) * 1000; + val.it_value.tv_sec = c / CLOCK_SECOND; + val.it_value.tv_usec = (c % CLOCK_SECOND) * CLOCK_SECOND; - PRINTF("rtimer_arch_schedule time %u %u in %d.%d seconds\n", t, c, c / 1000, - (c % 1000) * 1000); + PRINTF("rtimer_arch_schedule time %u %u in %d.%d seconds\n", t, c, val.it_value.tv_sec, + val.it_value.tv_usec); val.it_interval.tv_sec = val.it_interval.tv_usec = 0; setitimer(ITIMER_REAL, &val, NULL); diff --git a/arch/platform/native/Makefile.native b/arch/platform/native/Makefile.native index 4ed8e318b..2d1ee4fbc 100644 --- a/arch/platform/native/Makefile.native +++ b/arch/platform/native/Makefile.native @@ -19,6 +19,10 @@ else CONTIKI_TARGET_SOURCEFILES += tun6-net.c endif +ifeq ($(HOST_OS),Linux) +TARGET_LIBFILES += -lrt +endif + CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) .SUFFIXES: diff --git a/arch/platform/native/clock.c b/arch/platform/native/clock.c index 67d9ee317..3b94f3d4f 100644 --- a/arch/platform/native/clock.c +++ b/arch/platform/native/clock.c @@ -42,24 +42,49 @@ #include /*---------------------------------------------------------------------------*/ -clock_time_t -clock_time(void) +typedef struct clock_timespec_s { + time_t tv_sec; + long tv_nsec; +} clock_timespec_t; +/*---------------------------------------------------------------------------*/ +static void +get_time(clock_timespec_t *spec) { +#if defined(__linux__) || (defined(__MACH__) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) + struct timespec ts; + + clock_gettime(CLOCK_MONOTONIC, &ts); + + spec->tv_sec = ts.tv_sec; + spec->tv_nsec = ts.tv_nsec; +#else struct timeval tv; gettimeofday(&tv, NULL); - return tv.tv_sec * 1000 + tv.tv_usec / 1000; + spec->tv_sec = tv.tv_sec; + spec->tv_nsec = tv.tv_usec * 1000; +#endif +} +/*---------------------------------------------------------------------------*/ +clock_time_t +clock_time(void) +{ + clock_timespec_t ts; + + get_time(&ts); + + return ts.tv_sec * CLOCK_SECOND + ts.tv_nsec / (1000000000 / CLOCK_SECOND); } /*---------------------------------------------------------------------------*/ unsigned long clock_seconds(void) { - struct timeval tv; + clock_timespec_t ts; - gettimeofday(&tv, NULL); + get_time(&ts); - return tv.tv_sec; + return ts.tv_sec; } /*---------------------------------------------------------------------------*/ void From d780719530bee21b544b8f823c6cf34abca0c2cd Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Wed, 13 Dec 2017 09:39:24 +0000 Subject: [PATCH 70/81] Compile platform native with NULLNET --- arch/platform/native/platform.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/platform/native/platform.c b/arch/platform/native/platform.c index 83a7ac5fd..02fad921c 100644 --- a/arch/platform/native/platform.c +++ b/arch/platform/native/platform.c @@ -158,6 +158,7 @@ set_lladdr(void) linkaddr_set_node_addr(&addr); } /*---------------------------------------------------------------------------*/ +#if NETSTACK_CONF_WITH_IPV6 static void set_global_address(void) { @@ -183,6 +184,7 @@ set_global_address(void) uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 1); uip_ds6_defrt_add(&ipaddr, 0); } +#endif /*---------------------------------------------------------------------------*/ int contiki_argc = 0; char **contiki_argv; From 1b0bc03036dc68b359b28fe1c284250510269c4e Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 13 Dec 2017 11:23:45 +0100 Subject: [PATCH 71/81] Added compile test for NullNet on Native --- tests/01-compile-base/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/01-compile-base/Makefile b/tests/01-compile-base/Makefile index b02e202cd..45c3fd727 100644 --- a/tests/01-compile-base/Makefile +++ b/tests/01-compile-base/Makefile @@ -3,6 +3,7 @@ TOOLSDIR=../../tools EXAMPLES = \ hello-world/native \ +hello-world/native:MAKE_NET=MAKE_NET_NULLNET \ hello-world/sky \ storage/eeprom-test/native \ multicast/sky \ From 32ec93842e87a4f7b509750e6bcd8b43689b1980 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Wed, 13 Dec 2017 13:30:06 +0000 Subject: [PATCH 72/81] Compile-test the nullnet example for platform native --- tests/01-compile-base/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/01-compile-base/Makefile b/tests/01-compile-base/Makefile index 45c3fd727..dee315dfd 100644 --- a/tests/01-compile-base/Makefile +++ b/tests/01-compile-base/Makefile @@ -14,6 +14,7 @@ rpl-udp/sky \ rpl-border-router/native \ rpl-border-router/sky \ slip-radio/sky \ +nullnet/native \ TOOLS= From 83561839071c7e4015170459f9c542d262a08743 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Mon, 4 Dec 2017 17:13:28 +0000 Subject: [PATCH 73/81] Add stack library This commit adds a stack library as a wrapper around the list library --- os/lib/stack.h | 143 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 os/lib/stack.h diff --git a/os/lib/stack.h b/os/lib/stack.h new file mode 100644 index 000000000..8d56e46ef --- /dev/null +++ b/os/lib/stack.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * Copyright (c) 2017, James Pope + * 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 data + * @{ + * + * \defgroup stack-data-structure Stack library + * + * This library provides functions for the creation and manipulation of + * stacks. The library is implemented as a wrapper around the list library. + * + * A stack is declared using the STACK macro. Stack elements must be + * allocated by the calling code and must be of a C struct datatype. In this + * struct, the first field must be a pointer called \e next. This field will + * be used by the library to maintain the stack. Application code must not + * modify this field directly. + * @{ + */ +/*---------------------------------------------------------------------------*/ +#ifndef STACK_H_ +#define STACK_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "lib/list.h" + +#include +/*---------------------------------------------------------------------------*/ +/** + * \brief The stack data type + */ +typedef list_t stack_t; +/*---------------------------------------------------------------------------*/ +/** + * \brief Define a stack. + * + * This macro defines a stack. + * + * The datatype for elements must be a C struct. The struct's first member must + * be a pointer called \e next. This is used internally by the library to + * maintain data structure integrity and must not be modified directly by + * application code. + * + * \param name The name of the stack. + */ +#define STACK(name) LIST(name) +/*---------------------------------------------------------------------------*/ +struct stack { + struct stack *next; +}; +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialise a stack + * \param stack The stack + */ +static inline void +stack_init(stack_t stack) +{ + list_init(stack); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Adds an element to the top of the stack + * \param stack The stack + * \param element A pointer to the element to be added + */ +static inline void +stack_push(stack_t stack, void *element) +{ + list_push(stack, element); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Removes the top element from the stack + * \param stack The stack + * \return A pointer to the element popped + * + * If this function returns NULL if the stack was empty (stack underflow) + */ +static inline void * +stack_pop(stack_t stack) +{ + return list_pop(stack); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns the top element of the stack, without popping it + * \param stack The stack + * \return A pointer to the element at the top of the stack + */ +static inline void * +stack_peek(stack_t stack) +{ + return list_head(stack); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Check if a stack is empty + * \param stack The stack + * \retval true The stack is empty + * \retval false The stack has at least one element + */ +static inline bool +stack_is_empty(stack_t stack) +{ + return *stack == NULL ? true : false; +} +/*---------------------------------------------------------------------------*/ +#endif /* STACK_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ From 9dab37eae4a8a6585e64cdd7ebb131561ca11a25 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Mon, 4 Dec 2017 17:25:33 +0000 Subject: [PATCH 74/81] Add queue library This commit adds a queue library as a wrapper around the list library --- os/lib/queue.h | 143 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 os/lib/queue.h diff --git a/os/lib/queue.h b/os/lib/queue.h new file mode 100644 index 000000000..9d65fec9e --- /dev/null +++ b/os/lib/queue.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * Copyright (c) 2017, James Pope + * 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 data + * @{ + * + * \defgroup queue Queue library + * + * This library provides functions for the creation and manipulation of + * queues. The library is implemented as a wrapper around the list library. + * + * A queue is declared using the QUEUE macro. Queue elements must be + * allocated by the calling code and must be of a C struct datatype. In this + * struct, the first field must be a pointer called \e next. This field will + * be used by the library to maintain the queue. Application code must not + * modify this field directly. + * @{ + */ +/*---------------------------------------------------------------------------*/ +#ifndef QUEUE_H_ +#define QUEUE_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "lib/list.h" + +#include +/*---------------------------------------------------------------------------*/ +/** + * \brief The queue data type + */ +typedef list_t queue_t; +/*---------------------------------------------------------------------------*/ +/** + * \brief Define a queue. + * + * This macro defines a queue. + * + * The datatype for elements must be a C struct. The struct's first member must + * be a pointer called \e next. This is used internally by the library to + * maintain data structure integrity and must not be modified directly by + * application code. + * + * \param name The name of the queue. + */ +#define QUEUE(name) LIST(name) +/*---------------------------------------------------------------------------*/ +struct queue { + struct queue *next; +}; +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialise a queue + * \param queue The queue + */ +static inline void +queue_init(queue_t queue) +{ + list_init(queue); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Adds an element to the tail of the queue + * \param queue The queue + * \param element A pointer to the element to be added + */ +static inline void +queue_enqueue(queue_t queue, void *element) +{ + list_add(queue, element); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Removes the element at the front of the queue + * \param queue The queue + * \return A pointer to the element removed + * + * If this function returns NULL if the queue was empty (queue underflow) + */ +static inline void * +queue_dequeue(queue_t queue) +{ + return list_pop(queue); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns the front element of the queue, without removing it + * \param queue The queue + * \return A pointer to the element at the front of the queue + */ +static inline void * +queue_peek(queue_t queue) +{ + return list_head(queue); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Check if a queue is empty + * \param queue The queue + * \retval true The queue is empty + * \retval false The queue has at least one element + */ +static inline bool +queue_is_empty(queue_t queue) +{ + return *queue == NULL ? true : false; +} +/*---------------------------------------------------------------------------*/ +#endif /* QUEUE_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ From b82ca1a5ef4169d633d0a39d34d9602adc0310b5 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Mon, 4 Dec 2017 18:13:22 +0000 Subject: [PATCH 75/81] Add circular, singly-linked list library --- os/lib/circular-list.c | 157 +++++++++++++++++++++++++++++++++++++++++ os/lib/circular-list.h | 155 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 312 insertions(+) create mode 100644 os/lib/circular-list.c create mode 100644 os/lib/circular-list.h diff --git a/os/lib/circular-list.c b/os/lib/circular-list.c new file mode 100644 index 000000000..2c04d8418 --- /dev/null +++ b/os/lib/circular-list.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * Copyright (c) 2017, James Pope + * 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 circular-singly-linked-list + * @{ + * + * \file + * Implementation of circular singly linked lists + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "lib/circular-list.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +struct cl { + struct cl *next; +}; +/*---------------------------------------------------------------------------*/ +void +circular_list_init(circular_list_t cl) +{ + *cl = NULL; +} +/*---------------------------------------------------------------------------*/ +void * +circular_list_head(circular_list_t cl) +{ + return *cl; +} +/*---------------------------------------------------------------------------*/ +void * +circular_list_tail(circular_list_t cl) +{ + struct cl *this; + + if(*cl == NULL) { + return NULL; + } + + for(this = *cl; this->next != *cl; this = this->next); + + return this; +} +/*---------------------------------------------------------------------------*/ +void +circular_list_remove(circular_list_t cl, void *element) +{ + struct cl *this, *previous; + + if(*cl == NULL) { + return; + } + + /* + * We start traversing from the second element. + * The head will be visited last. We always update the list's head after + * removal, just in case we have just removed the head. + */ + previous = *cl; + this = previous->next; + + do { + if(this == element) { + previous->next = this->next; + *cl = this->next == this ? NULL : previous; + return; + } + previous = this; + this = this->next; + } while(this != ((struct cl *)*cl)->next); +} +/*---------------------------------------------------------------------------*/ +void +circular_list_add(circular_list_t cl, void *element) +{ + struct cl *head; + + if(element == NULL) { + return; + } + + /* Don't add twice */ + circular_list_remove(cl, element); + + head = *cl; + + if(head == NULL) { + /* If the list was empty, we update the new element to point to itself */ + ((struct cl *)element)->next = element; + } else { + /* If the list exists, we add the new element between the current head and + * the previously second element. */ + ((struct cl *)element)->next = head->next; + head->next = element; + } + + /* In all cases, the new element becomes the list's new head */ + *cl = element; +} +/*---------------------------------------------------------------------------*/ +unsigned long +circular_list_length(circular_list_t cl) +{ + unsigned long len = 1; + struct cl *this; + + if(circular_list_is_empty(cl)) { + return 0; + } + + for(this = *cl; this->next != *cl; this = this->next) { + len++; + } + + return len; +} +/*---------------------------------------------------------------------------*/ +bool +circular_list_is_empty(circular_list_t cl) +{ + return *cl == NULL ? true : false; +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/os/lib/circular-list.h b/os/lib/circular-list.h new file mode 100644 index 000000000..2edcaf808 --- /dev/null +++ b/os/lib/circular-list.h @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * Copyright (c) 2017, James Pope + * 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 data + * @{ + * + * \defgroup circular-singly-linked-list Circular, singly-linked list + * + * This library provides functions for the creation and manipulation of + * circular, singly-linked lists. + * + * A circular, singly-linked list is declared using the CIRCULAR_LIST macro. + * Elements must be allocated by the calling code and must be of a C struct + * datatype. In this struct, the first field must be a pointer called \e next. + * This field will be used by the library to maintain the list. Application + * code must not modify this field directly. + * + * Functions that modify the list (add / remove) will, in the general case, + * update the list's head and item order. If you call one of these functions + * as part of a list traversal, it is advised to stop / restart traversing + * after the respective function returns. + * @{ + */ +/*---------------------------------------------------------------------------*/ +#ifndef CIRCULAR_LIST_H_ +#define CIRCULAR_LIST_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +/** + * \brief Define a circular, singly-linked list. + * + * This macro defines a circular, singly-linked list. + * + * The datatype for elements must be a C struct. The struct's first member must + * be a pointer called \e next. This is used internally by the library to + * maintain data structure integrity and must not be modified directly by + * application code. + * + * \param name The name of the circular, singly-linked list. + */ +#define CIRCULAR_LIST(name) \ + static void *name##_circular_list = NULL; \ + static circular_list_t name = (circular_list_t)&name##_circular_list +/*---------------------------------------------------------------------------*/ +/** + * \brief The circular, singly-linked list datatype + */ +typedef void **circular_list_t; +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialise a circular, singly-linked list. + * \param cl The circular, singly-linked list. + */ +void circular_list_init(circular_list_t cl); + +/** + * \brief Return the tail of a circular, singly-linked list. + * \param cl The circular, singly-linked list. + * \return A pointer to the list's head, or NULL if the list is empty + */ +void *circular_list_head(circular_list_t cl); + +/** + * \brief Return the tail of a circular, singly-linked list. + * \param cl The circular, singly-linked list. + * \return A pointer to the list's tail, or NULL if the list is empty + */ +void *circular_list_tail(circular_list_t cl); + +/** + * \brief Add an element to a circular, singly-linked list. + * \param cl The circular, singly-linked list. + * \param element A pointer to the element to be added. + * + * The caller should make no assumptions as to the position in the list of the + * new element. + * + * After this function returns, the list's head is not guaranteed to be the + * same as it was before the addition. + * + * Calling this function will update the list's head and item order. If you + * call this function as part of a list traversal, it is advised to stop + * traversing after this function returns. + */ +void circular_list_add(circular_list_t cl, void *element); + +/** + * \brief Remove an element from a circular, singly-linked list. + * \param cl The circular, singly-linked list. + * \param element A pointer to the element to be removed. + * + * After this function returns, the list's head is not guaranteed to be the + * same as it was before the addition. + * + * Calling this function will update the list's head and item order. If you + * call this function as part of a list traversal, it is advised to stop + * traversing after this function returns. + */ +void circular_list_remove(circular_list_t cl, void *element); + +/** + * \brief Get the length of a circular, singly-linked list. + * \param cl The circular, singly-linked list. + * \return The number of elements in the list + */ +unsigned long circular_list_length(circular_list_t cl); + +/** + * \brief Determine whether a circular, singly-linked list is empty. + * \param cl The circular, singly-linked list. + * \retval true The list is empty + * \retval false The list is not empty + */ +bool circular_list_is_empty(circular_list_t cl); +/*---------------------------------------------------------------------------*/ +#endif /* CIRCULAR_LIST_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ From 09d6b123abefd2508beb24acbd59fd9a9aa4de0a Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 10 Dec 2017 20:41:09 +0000 Subject: [PATCH 76/81] Add doubly-linked list library --- os/lib/dbl-list.c | 226 ++++++++++++++++++++++++++++++++++++++++++++++ os/lib/dbl-list.h | 191 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 417 insertions(+) create mode 100644 os/lib/dbl-list.c create mode 100644 os/lib/dbl-list.h diff --git a/os/lib/dbl-list.c b/os/lib/dbl-list.c new file mode 100644 index 000000000..7f2f4b587 --- /dev/null +++ b/os/lib/dbl-list.c @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * Copyright (c) 2017, James Pope + * 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 doubly-linked-list + * @{ + * + * \file + * Implementation of doubly-linked lists + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "lib/dbl-list.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +struct dll { + struct dll *next; + struct dll *previous; +}; +/*---------------------------------------------------------------------------*/ +void +dbl_list_init(dbl_list_t dll) +{ + *dll = NULL; +} +/*---------------------------------------------------------------------------*/ +void * +dbl_list_head(dbl_list_t dll) +{ + return *dll; +} +/*---------------------------------------------------------------------------*/ +void * +dbl_list_tail(dbl_list_t dll) +{ + struct dll *this; + + if(*dll == NULL) { + return NULL; + } + + for(this = *dll; this->next != NULL; this = this->next); + + return this; +} +/*---------------------------------------------------------------------------*/ +void +dbl_list_remove(dbl_list_t dll, void *element) +{ + struct dll *this, *previous, *next; + + if(*dll == NULL || element == NULL) { + return; + } + + for(this = *dll; this != NULL; this = this->next) { + if(this == element) { + previous = this->previous; + next = this->next; + + if(previous) { + previous->next = this->next; + } + + if(next) { + next->previous = this->previous; + } + + if(*dll == this) { + *dll = next; + } + + return; + } + } +} +/*---------------------------------------------------------------------------*/ +void +dbl_list_add_head(dbl_list_t dll, void *element) +{ + struct dll *head; + + if(element == NULL) { + return; + } + + /* Don't add twice */ + dbl_list_remove(dll, element); + + head = dbl_list_head(dll); + + ((struct dll *)element)->previous = NULL; + ((struct dll *)element)->next = head; + + if(head) { + /* If the list was not empty, update ->previous on the old head */ + head->previous = element; + } + + *dll = element; +} +/*---------------------------------------------------------------------------*/ +void +dbl_list_add_tail(dbl_list_t dll, void *element) +{ + struct dll *tail; + + if(element == NULL) { + return; + } + + /* Don't add twice */ + dbl_list_remove(dll, element); + + tail = dbl_list_tail(dll); + + if(tail == NULL) { + /* The list was empty */ + *dll = element; + } else { + tail->next = element; + } + + ((struct dll *)element)->previous = tail; + ((struct dll *)element)->next = NULL; +} +/*---------------------------------------------------------------------------*/ +void +dbl_list_add_after(dbl_list_t dll, void *existing, void *element) +{ + if(element == NULL || existing == NULL) { + return; + } + + /* Don't add twice */ + dbl_list_remove(dll, element); + + ((struct dll *)element)->next = ((struct dll *)existing)->next; + ((struct dll *)element)->previous = existing; + + if(((struct dll *)existing)->next) { + ((struct dll *)existing)->next->previous = element; + } + ((struct dll *)existing)->next = element; +} +/*---------------------------------------------------------------------------*/ +void +dbl_list_add_before(dbl_list_t dll, void *existing, void *element) +{ + if(element == NULL || existing == NULL) { + return; + } + + /* Don't add twice */ + dbl_list_remove(dll, element); + + ((struct dll *)element)->next = existing; + ((struct dll *)element)->previous = ((struct dll *)existing)->previous; + + if(((struct dll *)existing)->previous) { + ((struct dll *)existing)->previous->next = element; + } + ((struct dll *)existing)->previous = element; + + /* If we added before the list's head, we must update the head */ + if(*dll == existing) { + *dll = element; + } +} +/*---------------------------------------------------------------------------*/ +unsigned long +dbl_list_length(dbl_list_t dll) +{ + unsigned long len = 0; + struct dll *this; + + if(*dll == NULL) { + return 0; + } + + for(this = *dll; this != NULL; this = this->next) { + len++; + } + + return len; +} +/*---------------------------------------------------------------------------*/ +bool +dbl_list_is_empty(dbl_list_t dll) +{ + return *dll == NULL ? true : false; +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/os/lib/dbl-list.h b/os/lib/dbl-list.h new file mode 100644 index 000000000..88caf30ce --- /dev/null +++ b/os/lib/dbl-list.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * Copyright (c) 2017, James Pope + * 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 data + * @{ + * + * \defgroup doubly-linked-list Doubly-linked list + * + * This library provides functions for the creation and manipulation of + * doubly-linked lists. + * + * A doubly-linked list is declared using the DBL_LIST macro. + * Elements must be allocated by the calling code and must be of a C struct + * datatype. In this struct, the first field must be a pointer called \e next. + * The second field must be a pointer called \e previous. + * These fields will be used by the library to maintain the list. Application + * code must not modify these fields directly. + * + * Functions that modify the list (add / remove) will, in the general case, + * update the list's head and item order. If you call one of these functions + * as part of a list traversal, it is advised to stop / restart traversing + * after the respective function returns. + * @{ + */ +/*---------------------------------------------------------------------------*/ +#ifndef DBL_LIST_H_ +#define DBL_LIST_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +/** + * \brief Define a doubly-linked list. + * + * This macro defines a doubly-linked list. + * + * The datatype for elements must be a C struct. + * The struct's first member must be a pointer called \e next. + * The second field must be a pointer called \e previous. + * These fields will be used by the library to maintain the list. Application + * code must not modify these fields directly. + * + * \param name The name of the doubly-linked list. + */ +#define DBL_LIST(name) \ + static void *name##_dbl_list = NULL; \ + static dbl_list_t name = (dbl_list_t)&name##_dbl_list +/*---------------------------------------------------------------------------*/ +/** + * \brief The doubly-linked list datatype + */ +typedef void **dbl_list_t; +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialise a doubly-linked list. + * \param dll The doubly-linked list. + */ +void dbl_list_init(dbl_list_t dll); + +/** + * \brief Return the tail of a doubly-linked list. + * \param dll The doubly-linked list. + * \return A pointer to the list's head, or NULL if the list is empty + */ +void *dbl_list_head(dbl_list_t dll); + +/** + * \brief Return the tail of a doubly-linked list. + * \param dll The doubly-linked list. + * \return A pointer to the list's tail, or NULL if the list is empty + */ +void *dbl_list_tail(dbl_list_t dll); + +/** + * \brief Add an element to the head of a doubly-linked list. + * \param dll The doubly-linked list. + * \param element A pointer to the element to be added. + * + * Calling this function will update the list's head and item order. If you + * call this function as part of a list traversal, it is advised to stop + * traversing after this function returns. + */ +void dbl_list_add_head(dbl_list_t dll, void *element); + +/** + * \brief Add an element to the tail of a doubly-linked list. + * \param dll The doubly-linked list. + * \param element A pointer to the element to be added. + * + * Calling this function will update the list's head and item order. If you + * call this function as part of a list traversal, it is advised to stop + * traversing after this function returns. + */ +void dbl_list_add_tail(dbl_list_t dll, void *element); + +/** + * \brief Add an element to a doubly linked list after an existing element. + * \param dll The doubly-linked list. + * \param existing A pointer to the existing element. + * \param element A pointer to the element to be added. + * + * This function will add \e element after \e existing + * + * The function will not verify that \e existing is already part of the list. + * + * Calling this function will update the list's head and item order. If you + * call this function as part of a list traversal, it is advised to stop + * traversing after this function returns. + */ +void dbl_list_add_after(dbl_list_t dll, void *existing, void *element); + +/** + * \brief Add an element to a doubly linked list before an existing element. + * \param dll The doubly-linked list. + * \param existing A pointer to the existing element. + * \param element A pointer to the element to be added. + * + * This function will add \e element before \e existing + * + * The function will not verify that \e existing is already part of the list. + * + * Calling this function will update the list's head and item order. If you + * call this function as part of a list traversal, it is advised to stop + * traversing after this function returns. + */ +void dbl_list_add_before(dbl_list_t dll, void *existing, void *element); + +/** + * \brief Remove an element from a doubly-linked list. + * \param dll The doubly-linked list. + * \param element A pointer to the element to be removed. + * + * Calling this function will update the list's head and item order. If you + * call this function as part of a list traversal, it is advised to stop + * traversing after this function returns. + */ +void dbl_list_remove(dbl_list_t dll, void *element); + +/** + * \brief Get the length of a doubly-linked list. + * \param dll The doubly-linked list. + * \return The number of elements in the list + */ +unsigned long dbl_list_length(dbl_list_t dll); + +/** + * \brief Determine whether a doubly-linked list is empty. + * \param dll The doubly-linked list. + * \retval true The list is empty + * \retval false The list is not empty + */ +bool dbl_list_is_empty(dbl_list_t dll); +/*---------------------------------------------------------------------------*/ +#endif /* DBL_LIST_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ From e87e3850c453d57c62e708f1f2bf1aff7cc4aee4 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 10 Dec 2017 23:12:07 +0000 Subject: [PATCH 77/81] Add circular, doubly-linked list library --- os/lib/dbl-circ-list.c | 227 +++++++++++++++++++++++++++++++++++++++++ os/lib/dbl-circ-list.h | 193 +++++++++++++++++++++++++++++++++++ 2 files changed, 420 insertions(+) create mode 100644 os/lib/dbl-circ-list.c create mode 100644 os/lib/dbl-circ-list.h diff --git a/os/lib/dbl-circ-list.c b/os/lib/dbl-circ-list.c new file mode 100644 index 000000000..35b33a801 --- /dev/null +++ b/os/lib/dbl-circ-list.c @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * Copyright (c) 2017, James Pope + * 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 doubly-linked-circular-list + * @{ + * + * \file + * Implementation of circular, doubly-linked lists + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "lib/dbl-circ-list.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +struct dblcl { + struct dblcl *next; + struct dblcl *previous; +}; +/*---------------------------------------------------------------------------*/ +void +dbl_circ_list_init(dbl_circ_list_t dblcl) +{ + *dblcl = NULL; +} +/*---------------------------------------------------------------------------*/ +void * +dbl_circ_list_head(dbl_circ_list_t dblcl) +{ + return *dblcl; +} +/*---------------------------------------------------------------------------*/ +void * +dbl_circ_list_tail(dbl_circ_list_t dblcl) +{ + struct dblcl *this; + + if(*dblcl == NULL) { + return NULL; + } + + for(this = *dblcl; this->next != *dblcl; this = this->next); + + return this; +} +/*---------------------------------------------------------------------------*/ +void +dbl_circ_list_remove(dbl_circ_list_t dblcl, void *element) +{ + struct dblcl *this; + + if(*dblcl == NULL || element == NULL) { + return; + } + + this = *dblcl; + + do { + if(this == element) { + this->previous->next = this->next; + this->next->previous = this->previous; + + /* We need to update the head of the list if we removed the head */ + if(*dblcl == element) { + *dblcl = this->next == this ? NULL : this->next; + } + + this->next = NULL; + this->previous = NULL; + + return; + } + + this = this->next; + } while(this != *dblcl); +} +/*---------------------------------------------------------------------------*/ +void +dbl_circ_list_add_head(dbl_circ_list_t dblcl, void *element) +{ + struct dblcl *head; + + if(element == NULL) { + return; + } + + /* Don't add twice */ + dbl_circ_list_remove(dblcl, element); + + head = dbl_circ_list_head(dblcl); + + if(head == NULL) { + /* If the list was empty */ + ((struct dblcl *)element)->next = element; + ((struct dblcl *)element)->previous = element; + } else { + /* If the list was not empty */ + ((struct dblcl *)element)->next = head; + ((struct dblcl *)element)->previous = head->previous; + head->previous->next = element; + head->previous = element; + } + + *dblcl = element; +} +/*---------------------------------------------------------------------------*/ +void +dbl_circ_list_add_tail(dbl_circ_list_t dblcl, void *element) +{ + struct dblcl *tail; + + if(element == NULL) { + return; + } + + /* Don't add twice */ + dbl_circ_list_remove(dblcl, element); + + tail = dbl_circ_list_tail(dblcl); + + if(tail == NULL) { + /* If the list was empty */ + ((struct dblcl *)element)->next = element; + ((struct dblcl *)element)->previous = element; + *dblcl = element; + } else { + /* If the list was not empty */ + ((struct dblcl *)element)->next = *dblcl; + ((struct dblcl *)element)->previous = tail; + tail->next->previous = element; + tail->next = element; + } +} +/*---------------------------------------------------------------------------*/ +void +dbl_circ_list_add_after(dbl_circ_list_t dblcl, void *existing, void *element) +{ + if(element == NULL || existing == NULL) { + return; + } + + /* Don't add twice */ + dbl_circ_list_remove(dblcl, element); + + ((struct dblcl *)element)->next = ((struct dblcl *)existing)->next; + ((struct dblcl *)element)->previous = existing; + ((struct dblcl *)existing)->next->previous = element; + ((struct dblcl *)existing)->next = element; +} +/*---------------------------------------------------------------------------*/ +void +dbl_circ_list_add_before(dbl_circ_list_t dblcl, void *existing, void *element) +{ + if(element == NULL || existing == NULL) { + return; + } + + /* Don't add twice */ + dbl_circ_list_remove(dblcl, element); + + ((struct dblcl *)element)->next = existing; + ((struct dblcl *)element)->previous = ((struct dblcl *)existing)->previous; + ((struct dblcl *)existing)->previous->next = element; + ((struct dblcl *)existing)->previous = element; + + /* If we added before the list's head, we must update the head */ + if(*dblcl == existing) { + *dblcl = element; + } +} +/*---------------------------------------------------------------------------*/ +unsigned long +dbl_circ_list_length(dbl_circ_list_t dblcl) +{ + unsigned long len = 1; + struct dblcl *this; + + if(*dblcl == NULL) { + return 0; + } + + for(this = *dblcl; this->next != *dblcl; this = this->next) { + len++; + } + + return len; +} +/*---------------------------------------------------------------------------*/ +bool +dbl_circ_list_is_empty(dbl_circ_list_t dblcl) +{ + return *dblcl == NULL ? true : false; +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/os/lib/dbl-circ-list.h b/os/lib/dbl-circ-list.h new file mode 100644 index 000000000..08eba8188 --- /dev/null +++ b/os/lib/dbl-circ-list.h @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * Copyright (c) 2017, James Pope + * 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 data + * @{ + * + * \defgroup doubly-linked-circular-list Circular, doubly-linked list + * + * This library provides functions for the creation and manipulation of + * circular, doubly-linked lists. + * + * A circular, doubly-linked list is declared using the DBL_CIRC_LIST macro. + * Elements must be allocated by the calling code and must be of a C struct + * datatype. In this struct, the first field must be a pointer called \e next. + * The second field must be a pointer called \e previous. + * These fields will be used by the library to maintain the list. Application + * code must not modify these fields directly. + * + * Functions that modify the list (add / remove) will, in the general case, + * update the list's head and item order. If you call one of these functions + * as part of a list traversal, it is advised to stop / restart traversing + * after the respective function returns. + * @{ + */ +/*---------------------------------------------------------------------------*/ +#ifndef DBL_CIRC_LIST_H_ +#define DBL_CIRC_LIST_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +/** + * \brief Define a circular, doubly-linked list. + * + * This macro defines a circular, doubly-linked list. + * + * The datatype for elements must be a C struct. + * The struct's first member must be a pointer called \e next. + * The second field must be a pointer called \e previous. + * These fields will be used by the library to maintain the list. Application + * code must not modify these fields directly. + * + * \param name The name of the circular, doubly-linked list. + */ +#define DBL_CIRC_LIST(name) \ + static void *name##_dbl_circ_list = NULL; \ + static dbl_list_t name = (dbl_circ_list_t)&name##_dbl_circ_list +/*---------------------------------------------------------------------------*/ +/** + * \brief The doubly-linked list datatype + */ +typedef void **dbl_circ_list_t; +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialise a circular, doubly-linked list. + * \param dblcl The circular, doubly-linked list. + */ +void dbl_circ_list_init(dbl_circ_list_t dblcl); + +/** + * \brief Return the tail of a circular, doubly-linked list. + * \param dblcl The circular, doubly-linked list. + * \return A pointer to the list's head, or NULL if the list is empty + */ +void *dbl_circ_list_head(dbl_circ_list_t dblcl); + +/** + * \brief Return the tail of a circular, doubly-linked list. + * \param dblcl The circular, doubly-linked list. + * \return A pointer to the list's tail, or NULL if the list is empty + */ +void *dbl_circ_list_tail(dbl_circ_list_t dblcl); + +/** + * \brief Add an element to the head of a circular, doubly-linked list. + * \param dblcl The circular, doubly-linked list. + * \param element A pointer to the element to be added. + * + * Calling this function will update the list's head and item order. If you + * call this function as part of a list traversal, it is advised to stop + * traversing after this function returns. + */ +void dbl_circ_list_add_head(dbl_circ_list_t dblcl, void *element); + +/** + * \brief Add an element to the tail of a circular, doubly-linked list. + * \param dblcl The circular, doubly-linked list. + * \param element A pointer to the element to be added. + * + * Calling this function will update the list's head and item order. If you + * call this function as part of a list traversal, it is advised to stop + * traversing after this function returns. + */ +void dbl_circ_list_add_tail(dbl_circ_list_t dblcl, void *element); + +/** + * \brief Add an element to a circular, doubly linked list after an existing element. + * \param dblcl The circular, doubly-linked list. + * \param existing A pointer to the existing element. + * \param element A pointer to the element to be added. + * + * This function will add \e element after \e existing + * + * The function will not verify that \e existing is already part of the list. + * + * Calling this function will update the list's head and item order. If you + * call this function as part of a list traversal, it is advised to stop + * traversing after this function returns. + */ +void dbl_circ_list_add_after(dbl_circ_list_t dblcl, void *existing, + void *element); + +/** + * \brief Add an element to a circular, doubly linked list before an existing element. + * \param dblcl The circular, doubly-linked list. + * \param existing A pointer to the existing element. + * \param element A pointer to the element to be added. + * + * This function will add \e element before \e existing + * + * The function will not verify that \e existing is already part of the list. + * + * Calling this function will update the list's head and item order. If you + * call this function as part of a list traversal, it is advised to stop + * traversing after this function returns. + */ +void dbl_circ_list_add_before(dbl_circ_list_t dblcl, void *existing, + void *element); + +/** + * \brief Remove an element from a circular, doubly-linked list. + * \param dblcl The circular, doubly-linked list. + * \param element A pointer to the element to be removed. + * + * Calling this function will update the list's head and item order. If you + * call this function as part of a list traversal, it is advised to stop + * traversing after this function returns. + */ +void dbl_circ_list_remove(dbl_circ_list_t dblcl, void *element); + +/** + * \brief Get the length of a circular, doubly-linked list. + * \param dblcl The circular, doubly-linked list. + * \return The number of elements in the list + */ +unsigned long dbl_circ_list_length(dbl_circ_list_t dblcl); + +/** + * \brief Determine whether a circular, doubly-linked list is empty. + * \param dblcl The circular, doubly-linked list. + * \retval true The list is empty + * \retval false The list is not empty + */ +bool dbl_circ_list_is_empty(dbl_circ_list_t dblcl); +/*---------------------------------------------------------------------------*/ +#endif /* DBL_CIRC_LIST_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ From c3d2b095b6f6775bab3d70248c66c6419ebba06a Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 10 Dec 2017 19:04:05 +0000 Subject: [PATCH 78/81] Add example demonstrating the data structure libraries --- examples/libs/data-structures/Makefile | 7 + .../libs/data-structures/data-structures.c | 383 ++++++++++++++++++ 2 files changed, 390 insertions(+) create mode 100644 examples/libs/data-structures/Makefile create mode 100644 examples/libs/data-structures/data-structures.c diff --git a/examples/libs/data-structures/Makefile b/examples/libs/data-structures/Makefile new file mode 100644 index 000000000..1f4d6b765 --- /dev/null +++ b/examples/libs/data-structures/Makefile @@ -0,0 +1,7 @@ +CONTIKI_PROJECT = data-structures + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../.. + +include $(CONTIKI)/Makefile.include diff --git a/examples/libs/data-structures/data-structures.c b/examples/libs/data-structures/data-structures.c new file mode 100644 index 000000000..21752762a --- /dev/null +++ b/examples/libs/data-structures/data-structures.c @@ -0,0 +1,383 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * Copyright (c) 2017, James Pope + * 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 "lib/stack.h" +#include "lib/queue.h" +#include "lib/circular-list.h" +#include "lib/dbl-list.h" +#include "lib/dbl-circ-list.h" +#include "lib/random.h" + +#include +#include +#include +#include +/*---------------------------------------------------------------------------*/ +PROCESS(data_structure_process, "Data structure process"); +AUTOSTART_PROCESSES(&data_structure_process); +/*---------------------------------------------------------------------------*/ +STACK(demo_stack); +QUEUE(demo_queue); +CIRCULAR_LIST(demo_cll); +DBL_LIST(demo_dbl); +DBL_CIRC_LIST(demo_dblcl); +/*---------------------------------------------------------------------------*/ +typedef struct demo_struct_s { + struct demo_struct_s *next; + struct demo_struct_s *previous; + unsigned short value; +} demo_struct_t; +/*---------------------------------------------------------------------------*/ +#define DATA_STRUCTURE_DEMO_ELEMENT_COUNT 4 +static demo_struct_t elements[DATA_STRUCTURE_DEMO_ELEMENT_COUNT]; +/*---------------------------------------------------------------------------*/ +static void +dbl_circ_list_print(dbl_circ_list_t dblcl) +{ + demo_struct_t *this = *dblcl; + + if(*dblcl == NULL) { + printf("Length=0\n"); + return; + } + + do { + printf("<--(0x%04x)--0x%04x--(0x%04x)-->", this->previous->value, + this->value, this->next->value); + this = this->next; + } while(this != *dblcl); + + printf(" (Length=%lu)\n", dbl_circ_list_length(dblcl)); +} +/*---------------------------------------------------------------------------*/ +static void +demonstrate_dbl_circ_list(void) +{ + int i; + demo_struct_t *this; + + dbl_circ_list_init(demo_dblcl); + printf("============================\n"); + printf("Circular, doubly-linked list\n"); + + for(i = 0; i < DATA_STRUCTURE_DEMO_ELEMENT_COUNT; i++) { + elements[i].next = NULL; + elements[i].previous = NULL; + } + + /* Add elements */ + dbl_circ_list_add_tail(demo_dblcl, &elements[0]); + printf("Add tail : 0x%04x | ", elements[0].value); + dbl_circ_list_print(demo_dblcl); + + dbl_circ_list_add_after(demo_dblcl, &elements[0], &elements[1]); + printf("Add after : 0x%04x | ", elements[1].value); + dbl_circ_list_print(demo_dblcl); + + dbl_circ_list_add_head(demo_dblcl, &elements[2]); + printf("Add head : 0x%04x | ", elements[2].value); + dbl_circ_list_print(demo_dblcl); + + dbl_circ_list_add_before(demo_dblcl, &elements[2], &elements[3]); + printf("Add before: 0x%04x | ", elements[3].value); + dbl_circ_list_print(demo_dblcl); + + /* Remove head */ + this = dbl_circ_list_head(demo_dblcl); + printf("Rm head: (0x%04x) | ", this->value); + dbl_circ_list_remove(demo_dblcl, this); + dbl_circ_list_print(demo_dblcl); + + /* Remove currently second element */ + this = ((demo_struct_t *)dbl_circ_list_head(demo_dblcl))->next; + printf("Rm 2nd : (0x%04x) | ", this->value); + dbl_circ_list_remove(demo_dblcl, this); + dbl_circ_list_print(demo_dblcl); + + /* Remove tail */ + this = dbl_circ_list_tail(demo_dblcl); + printf("Rm tail: (0x%04x) | ", this->value); + dbl_circ_list_remove(demo_dblcl, this); + dbl_circ_list_print(demo_dblcl); + + /* Remove last remaining element */ + this = dbl_circ_list_tail(demo_dblcl); + printf("Rm last: (0x%04x) | ", this->value); + dbl_circ_list_remove(demo_dblcl, this); + dbl_circ_list_print(demo_dblcl); + + printf("Circular, doubly-linked list is%s empty\n", + dbl_circ_list_is_empty(demo_dblcl) ? "" : " not"); +} +/*---------------------------------------------------------------------------*/ +static void +dbl_list_print(dbl_list_t dll) +{ + demo_struct_t *this; + + for(this = *dll; this != NULL; this = this->next) { + printf("<--("); + if(this->previous == NULL) { + printf(" null "); + } else { + printf("0x%04x", this->previous->value); + } + + printf(")--0x%04x--(", this->value); + + if(this->next == NULL) { + printf(" null "); + } else { + printf("0x%04x", this->next->value); + } + printf(")-->"); + } + + printf(" (Length=%lu)\n", dbl_list_length(dll)); +} +/*---------------------------------------------------------------------------*/ +static void +demonstrate_dbl_list(void) +{ + int i; + demo_struct_t *this; + + dbl_list_init(demo_dbl); + printf("==================\n"); + printf("Doubly-linked list\n"); + + for(i = 0; i < DATA_STRUCTURE_DEMO_ELEMENT_COUNT; i++) { + elements[i].next = NULL; + elements[i].previous = NULL; + } + + /* Add elements */ + dbl_list_add_tail(demo_dbl, &elements[0]); + printf("Add tail : 0x%04x | ", elements[0].value); + dbl_list_print(demo_dbl); + + dbl_list_add_after(demo_dbl, &elements[0], &elements[1]); + printf("Add after : 0x%04x | ", elements[1].value); + dbl_list_print(demo_dbl); + + dbl_list_add_head(demo_dbl, &elements[2]); + printf("Add head : 0x%04x | ", elements[2].value); + dbl_list_print(demo_dbl); + + dbl_list_add_before(demo_dbl, &elements[2], &elements[3]); + printf("Add before: 0x%04x | ", elements[3].value); + dbl_list_print(demo_dbl); + + /* Remove head */ + this = dbl_list_head(demo_dbl); + printf("Rm head: (0x%04x) | ", this->value); + dbl_list_remove(demo_dbl, this); + dbl_list_print(demo_dbl); + + /* Remove currently second element */ + this = ((demo_struct_t *)dbl_list_head(demo_dbl))->next; + printf("Rm 2nd : (0x%04x) | ", this->value); + dbl_list_remove(demo_dbl, this); + dbl_list_print(demo_dbl); + + /* Remove tail */ + this = dbl_list_tail(demo_dbl); + printf("Rm tail: (0x%04x) | ", this->value); + dbl_list_remove(demo_dbl, this); + dbl_list_print(demo_dbl); + + /* Remove last remaining element */ + this = dbl_list_tail(demo_dbl); + printf("Rm last: (0x%04x) | ", this->value); + dbl_list_remove(demo_dbl, this); + dbl_list_print(demo_dbl); + + printf("Doubly-linked list is%s empty\n", + dbl_list_is_empty(demo_dbl) ? "" : " not"); +} +/*---------------------------------------------------------------------------*/ +static void +circular_list_print(circular_list_t cl) +{ + demo_struct_t *this = *cl; + + if(*cl == NULL) { + printf("Length=0\n"); + return; + } + + do { + printf("0x%04x-->", this->value); + this = this->next; + } while(this != *cl); + + printf("0x%04x (Length=%lu)\n", this->value, circular_list_length(cl)); +} +/*---------------------------------------------------------------------------*/ +static void +demonstrate_circular_list(void) +{ + int i; + + circular_list_init(demo_cll); + printf("============================\n"); + printf("Circular, singly-linked list\n"); + + /* Add elements */ + for(i = 0; i < DATA_STRUCTURE_DEMO_ELEMENT_COUNT; i++) { + elements[i].next = NULL; + circular_list_add(demo_cll, &elements[i]); + + printf("Add: 0x%04x | ", elements[i].value); + circular_list_print(demo_cll); + } + + /* Remove head */ + circular_list_remove(demo_cll, circular_list_head(demo_cll)); + printf("Remove head | "); + circular_list_print(demo_cll); + + /* Remove currently second element */ + circular_list_remove(demo_cll, + ((demo_struct_t *)circular_list_head(demo_cll))->next); + printf("Remove 2nd | "); + circular_list_print(demo_cll); + + /* Remove tail */ + circular_list_remove(demo_cll, circular_list_tail(demo_cll)); + printf("Remove tail | "); + circular_list_print(demo_cll); + + /* Remove last remaining element */ + circular_list_remove(demo_cll, circular_list_tail(demo_cll)); + printf("Remove last | "); + circular_list_print(demo_cll); + + printf("Circular list is%s empty\n", + circular_list_is_empty(demo_cll) ? "" : " not"); +} +/*---------------------------------------------------------------------------*/ +static void +demonstrate_stack(void) +{ + int i; + demo_struct_t *this; + + printf("=====\n"); + printf("Stack\n"); + + stack_init(demo_stack); + + /* Add elements */ + for(i = 0; i < DATA_STRUCTURE_DEMO_ELEMENT_COUNT; i++) { + elements[i].next = NULL; + stack_push(demo_stack, &elements[i]); + printf("Push: 0x%04x\n", elements[i].value); + } + + printf("Peek: 0x%04x\n", + ((demo_struct_t *)stack_peek(demo_stack))->value); + + for(i = 0; i <= DATA_STRUCTURE_DEMO_ELEMENT_COUNT; i++) { + this = stack_pop(demo_stack); + printf("Pop: "); + if(this == NULL) { + printf("(stack underflow)\n"); + } else { + printf("0x%04x\n", this->value); + } + } + printf("Stack is%s empty\n", + stack_is_empty(demo_stack) ? "" : " not"); +} +/*---------------------------------------------------------------------------*/ +static void +demonstrate_queue(void) +{ + int i; + demo_struct_t *this; + + printf("=====\n"); + printf("Queue\n"); + + queue_init(demo_queue); + + /* Add elements */ + for(i = 0; i < DATA_STRUCTURE_DEMO_ELEMENT_COUNT; i++) { + elements[i].next = NULL; + queue_enqueue(demo_queue, &elements[i]); + printf("Enqueue: 0x%04x\n", elements[i].value); + } + + printf("Peek: 0x%04x\n", + ((demo_struct_t *)queue_peek(demo_queue))->value); + + for(i = 0; i <= DATA_STRUCTURE_DEMO_ELEMENT_COUNT; i++) { + this = queue_dequeue(demo_queue); + printf("Dequeue: "); + if(this == NULL) { + printf("(queue underflow)\n"); + } else { + printf("0x%04lx\n", (unsigned long)this->value); + } + } + + printf("Queue is%s empty\n", + queue_is_empty(demo_queue) ? "" : " not"); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(data_structure_process, ev, data) +{ + int i; + + PROCESS_BEGIN(); + + /* Generate some elements */ + printf("Elements: ["); + + for(i = 0; i < DATA_STRUCTURE_DEMO_ELEMENT_COUNT; i++) { + elements[i].next = NULL; + elements[i].value = random_rand(); + printf(" 0x%04x", elements[i].value); + } + printf(" ]\n"); + + demonstrate_stack(); + demonstrate_queue(); + demonstrate_circular_list(); + demonstrate_dbl_list(); + demonstrate_dbl_circ_list(); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ From bf44dbe62e8ecccf7d45183ff1c7387e3239b67c Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Tue, 12 Dec 2017 17:16:05 +0000 Subject: [PATCH 79/81] Add unit tests for the data structure libraries --- .../31-data-structures-sky.csc | 98 ++ .../code-data-structures/Makefile | 9 + .../code-data-structures/project-conf.h | 37 + .../test-data-structures.c | 897 ++++++++++++++++++ .../07-simulation-base/js/data-structures.js | 25 + 5 files changed, 1066 insertions(+) create mode 100644 tests/07-simulation-base/31-data-structures-sky.csc create mode 100644 tests/07-simulation-base/code-data-structures/Makefile create mode 100644 tests/07-simulation-base/code-data-structures/project-conf.h create mode 100644 tests/07-simulation-base/code-data-structures/test-data-structures.c create mode 100644 tests/07-simulation-base/js/data-structures.js diff --git a/tests/07-simulation-base/31-data-structures-sky.csc b/tests/07-simulation-base/31-data-structures-sky.csc new file mode 100644 index 000000000..cd0e35ee3 --- /dev/null +++ b/tests/07-simulation-base/31-data-structures-sky.csc @@ -0,0 +1,98 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + data-structures-sky + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + Sky Mote Type #sky1 + [CONTIKI_DIR]/tests/07-simulation-base/code-data-structures/test-data-structures.c + make test-data-structures.sky TARGET=sky + [CONTIKI_DIR]/tests/07-simulation-base/code-data-structures/test-data-structures.sky + 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.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 3.086692968239446 + 5.726233183606267 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + org.contikios.cooja.plugins.SimControl + 280 + 2 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.LogListener + + + + + + 586 + 1 + 666 + 400 + 160 + + + org.contikios.cooja.plugins.ScriptRunner + + [CONFIG_DIR]/js/data-structures.js + true + + 600 + 0 + 700 + 5 + 1 + + diff --git a/tests/07-simulation-base/code-data-structures/Makefile b/tests/07-simulation-base/code-data-structures/Makefile new file mode 100644 index 000000000..d88177bbe --- /dev/null +++ b/tests/07-simulation-base/code-data-structures/Makefile @@ -0,0 +1,9 @@ +all: test-data-structures + +MODULES += os/services/unit-test + +MAKE_MAC = MAKE_MAC_NULLMAC +MAKE_NET = MAKE_NET_NULLNET + +CONTIKI = ../../.. +include $(CONTIKI)/Makefile.include diff --git a/tests/07-simulation-base/code-data-structures/project-conf.h b/tests/07-simulation-base/code-data-structures/project-conf.h new file mode 100644 index 000000000..1e6d48809 --- /dev/null +++ b/tests/07-simulation-base/code-data-structures/project-conf.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2017, Yasuyuki Tanaka + * 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_ + +#define UNIT_TEST_PRINT_FUNCTION print_test_report + +#endif /* PROJECT_CONF_H_ */ diff --git a/tests/07-simulation-base/code-data-structures/test-data-structures.c b/tests/07-simulation-base/code-data-structures/test-data-structures.c new file mode 100644 index 000000000..e682e43da --- /dev/null +++ b/tests/07-simulation-base/code-data-structures/test-data-structures.c @@ -0,0 +1,897 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * 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 "lib/stack.h" +#include "lib/queue.h" +#include "lib/circular-list.h" +#include "lib/dbl-list.h" +#include "lib/dbl-circ-list.h" +#include "lib/random.h" +#include "services/unit-test/unit-test.h" + +#include +#include +#include +#include +/*---------------------------------------------------------------------------*/ +PROCESS(data_structure_test_process, "Data structure process"); +AUTOSTART_PROCESSES(&data_structure_test_process); +/*---------------------------------------------------------------------------*/ +typedef struct demo_struct_s { + struct demo_struct_s *next; + struct demo_struct_s *previous; +} demo_struct_t; +/*---------------------------------------------------------------------------*/ +#define ELEMENT_COUNT 10 +static demo_struct_t elements[ELEMENT_COUNT]; +/*---------------------------------------------------------------------------*/ +void +print_test_report(const unit_test_t *utp) +{ + printf("=check-me= "); + if(utp->result == unit_test_failure) { + printf("FAILED - %s: exit at L%u\n", utp->descr, utp->exit_line); + } else { + printf("SUCCEEDED - %s\n", utp->descr); + } +} +/*---------------------------------------------------------------------------*/ +UNIT_TEST_REGISTER(test_stack, "Stack Push/Pop"); +UNIT_TEST(test_stack) +{ + STACK(stack); + + UNIT_TEST_BEGIN(); + + memset(elements, 0, sizeof(elements)); + stack_init(stack); + + /* Starts from empty */ + UNIT_TEST_ASSERT(stack_is_empty(stack) == true); + UNIT_TEST_ASSERT(stack_peek(stack) == NULL); + UNIT_TEST_ASSERT(stack_pop(stack) == NULL); + + /* + * Push two elements. Peek and pop should be the last one. Stack should be + * non-empty after the pop + */ + stack_push(stack, &elements[0]); + stack_push(stack, &elements[1]); + + UNIT_TEST_ASSERT(stack_peek(stack) == &elements[1]); + UNIT_TEST_ASSERT(stack_pop(stack) == &elements[1]); + UNIT_TEST_ASSERT(stack_peek(stack) == &elements[0]); + UNIT_TEST_ASSERT(stack_is_empty(stack) == false); + UNIT_TEST_ASSERT(stack_pop(stack) == &elements[0]); + + /* Ends empty */ + UNIT_TEST_ASSERT(stack_is_empty(stack) == true); + UNIT_TEST_ASSERT(stack_peek(stack) == NULL); + UNIT_TEST_ASSERT(stack_pop(stack) == NULL); + + UNIT_TEST_END(); +} +/*---------------------------------------------------------------------------*/ +UNIT_TEST_REGISTER(test_queue, "Queue Enqueue/Dequeue"); +UNIT_TEST(test_queue) +{ + QUEUE(queue); + + UNIT_TEST_BEGIN(); + + memset(elements, 0, sizeof(elements)); + queue_init(queue); + + /* Starts from empty */ + UNIT_TEST_ASSERT(queue_is_empty(queue) == true); + UNIT_TEST_ASSERT(queue_peek(queue) == NULL); + UNIT_TEST_ASSERT(queue_dequeue(queue) == NULL); + + /* Enqueue three elements. They should come out in the same order */ + queue_enqueue(queue, &elements[0]); + queue_enqueue(queue, &elements[1]); + queue_enqueue(queue, &elements[2]); + + UNIT_TEST_ASSERT(queue_dequeue(queue) == &elements[0]); + UNIT_TEST_ASSERT(queue_dequeue(queue) == &elements[1]); + UNIT_TEST_ASSERT(queue_dequeue(queue) == &elements[2]); + + /* Should be empty */ + UNIT_TEST_ASSERT(queue_is_empty(queue) == true); + UNIT_TEST_ASSERT(queue_peek(queue) == NULL); + UNIT_TEST_ASSERT(queue_dequeue(queue) == NULL); + + UNIT_TEST_END(); +} +/*---------------------------------------------------------------------------*/ +UNIT_TEST_REGISTER(test_csll, "Circular, singly-linked list"); +UNIT_TEST(test_csll) +{ + demo_struct_t *head, *tail; + + CIRCULAR_LIST(csll); + + UNIT_TEST_BEGIN(); + + memset(elements, 0, sizeof(elements)); + circular_list_init(csll); + + /* Starts from empty */ + UNIT_TEST_ASSERT(circular_list_is_empty(csll) == true); + UNIT_TEST_ASSERT(circular_list_length(csll) == 0); + UNIT_TEST_ASSERT(circular_list_head(csll) == NULL); + UNIT_TEST_ASSERT(circular_list_tail(csll) == NULL); + + /* Add one element. Should point to itself and act as head and tail */ + circular_list_add(csll, &elements[0]); + + UNIT_TEST_ASSERT(circular_list_is_empty(csll) == false); + UNIT_TEST_ASSERT(circular_list_length(csll) == 1); + UNIT_TEST_ASSERT(circular_list_head(csll) == &elements[0]); + UNIT_TEST_ASSERT(circular_list_tail(csll) == &elements[0]); + UNIT_TEST_ASSERT(elements[0].next == &elements[0]); + + /* Add a second element. The two should point to each-other */ + circular_list_add(csll, &elements[1]); + UNIT_TEST_ASSERT(elements[0].next == &elements[1]); + UNIT_TEST_ASSERT(elements[1].next == &elements[0]); + + /* + * Add a third element and check that head->next->next points to tail. + * Check that tail->next points to the head + */ + circular_list_add(csll, &elements[2]); + head = circular_list_head(csll); + tail = circular_list_tail(csll); + + UNIT_TEST_ASSERT(head->next->next == circular_list_tail(csll)); + UNIT_TEST_ASSERT(tail->next == circular_list_head(csll)); + + /* Re-add an existing element. Check the list's integrity */ + circular_list_add(csll, &elements[1]); + head = circular_list_head(csll); + tail = circular_list_tail(csll); + + UNIT_TEST_ASSERT(circular_list_is_empty(csll) == false); + UNIT_TEST_ASSERT(circular_list_length(csll) == 3); + UNIT_TEST_ASSERT(head->next->next->next == circular_list_head(csll)); + UNIT_TEST_ASSERT(head->next->next == circular_list_tail(csll)); + UNIT_TEST_ASSERT(tail->next == circular_list_head(csll)); + + /* Add another two elements, then start testing removal */ + circular_list_add(csll, &elements[3]); + circular_list_add(csll, &elements[4]); + + /* Remove an item in the middle and test list integrity */ + head = circular_list_head(csll); + circular_list_remove(csll, head->next->next); + head = circular_list_head(csll); + tail = circular_list_tail(csll); + + UNIT_TEST_ASSERT(circular_list_length(csll) == 4); + UNIT_TEST_ASSERT(head->next->next->next->next == circular_list_head(csll)); + UNIT_TEST_ASSERT(head->next->next->next == circular_list_tail(csll)); + UNIT_TEST_ASSERT(tail->next == circular_list_head(csll)); + + /* Remove the head and test list integrity */ + circular_list_remove(csll, circular_list_head(csll)); + head = circular_list_head(csll); + tail = circular_list_tail(csll); + + UNIT_TEST_ASSERT(circular_list_length(csll) == 3); + UNIT_TEST_ASSERT(head->next->next->next == circular_list_head(csll)); + UNIT_TEST_ASSERT(head->next->next == circular_list_tail(csll)); + UNIT_TEST_ASSERT(tail->next == circular_list_head(csll)); + + /* Remove the tail and test list integrity */ + circular_list_remove(csll, circular_list_tail(csll)); + head = circular_list_head(csll); + tail = circular_list_tail(csll); + + UNIT_TEST_ASSERT(circular_list_length(csll) == 2); + UNIT_TEST_ASSERT(head->next->next == circular_list_head(csll)); + UNIT_TEST_ASSERT(head->next == circular_list_tail(csll)); + UNIT_TEST_ASSERT(tail->next == circular_list_head(csll)); + + /* + * Remove the tail + * Only one item left: Make sure the head and tail are the same and point to + * each other + */ + circular_list_remove(csll, circular_list_tail(csll)); + head = circular_list_head(csll); + tail = circular_list_tail(csll); + + UNIT_TEST_ASSERT(circular_list_length(csll) == 1); + UNIT_TEST_ASSERT(head == tail); + UNIT_TEST_ASSERT(head->next->next == circular_list_head(csll)); + UNIT_TEST_ASSERT(head->next == circular_list_head(csll)); + UNIT_TEST_ASSERT(head->next == circular_list_tail(csll)); + UNIT_TEST_ASSERT(tail->next == circular_list_head(csll)); + UNIT_TEST_ASSERT(tail->next == circular_list_tail(csll)); + + /* Remove the last element by removing the head */ + circular_list_remove(csll, circular_list_head(csll)); + UNIT_TEST_ASSERT(circular_list_is_empty(csll) == true); + UNIT_TEST_ASSERT(circular_list_length(csll) == 0); + UNIT_TEST_ASSERT(circular_list_head(csll) == NULL); + UNIT_TEST_ASSERT(circular_list_tail(csll) == NULL); + + /* Remove the last element by removing the tail */ + circular_list_add(csll, &elements[0]); + circular_list_remove(csll, circular_list_tail(csll)); + UNIT_TEST_ASSERT(circular_list_is_empty(csll) == true); + UNIT_TEST_ASSERT(circular_list_length(csll) == 0); + UNIT_TEST_ASSERT(circular_list_head(csll) == NULL); + UNIT_TEST_ASSERT(circular_list_tail(csll) == NULL); + + UNIT_TEST_END(); +} +/*---------------------------------------------------------------------------*/ +UNIT_TEST_REGISTER(test_dll, "Doubly-linked list"); +UNIT_TEST(test_dll) +{ + demo_struct_t *head, *tail; + + CIRCULAR_LIST(dll); + + UNIT_TEST_BEGIN(); + + memset(elements, 0, sizeof(elements)); + + /* Starts from empty */ + dbl_list_init(dll); + UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == true); + UNIT_TEST_ASSERT(dbl_list_length(dll) == 0); + UNIT_TEST_ASSERT(dbl_list_head(dll) == NULL); + UNIT_TEST_ASSERT(dbl_list_tail(dll) == NULL); + + /* + * Add an item by adding to the head. + * Head and tail should point to NULL in both directions + */ + dbl_list_add_head(dll, &elements[0]); + head = dbl_list_head(dll); + tail = dbl_list_tail(dll); + + UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false); + UNIT_TEST_ASSERT(dbl_list_length(dll) == 1); + UNIT_TEST_ASSERT(head == &elements[0]); + UNIT_TEST_ASSERT(tail == &elements[0]); + UNIT_TEST_ASSERT(head->previous == NULL); + UNIT_TEST_ASSERT(head->next == NULL); + UNIT_TEST_ASSERT(tail->previous == NULL); + UNIT_TEST_ASSERT(tail->next == NULL); + + /* + * Add an item by adding to the tail. + * Head and tail should point to NULL in both directions + */ + dbl_list_remove(dll, dbl_list_head(dll)); + dbl_list_add_tail(dll, &elements[1]); + head = dbl_list_head(dll); + tail = dbl_list_tail(dll); + + UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false); + UNIT_TEST_ASSERT(dbl_list_length(dll) == 1); + UNIT_TEST_ASSERT(head == &elements[1]); + UNIT_TEST_ASSERT(tail == &elements[1]); + UNIT_TEST_ASSERT(head->previous == NULL); + UNIT_TEST_ASSERT(head->next == NULL); + UNIT_TEST_ASSERT(tail->previous == NULL); + UNIT_TEST_ASSERT(tail->next == NULL); + + /* + * Add a second item to head. Head points forward to tail. + * Tail points backwards to head. + */ + dbl_list_add_head(dll, &elements[2]); + head = dbl_list_head(dll); + tail = dbl_list_tail(dll); + + UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false); + UNIT_TEST_ASSERT(dbl_list_length(dll) == 2); + UNIT_TEST_ASSERT(head == &elements[2]); + UNIT_TEST_ASSERT(tail == &elements[1]); + UNIT_TEST_ASSERT(head->previous == NULL); + UNIT_TEST_ASSERT(head->next == tail); + UNIT_TEST_ASSERT(tail->previous == head); + UNIT_TEST_ASSERT(tail->next == NULL); + + /* + * Add before head. + * NULL <-- 3 --> 2 --> 1 --> NULL + */ + dbl_list_add_before(dll, dbl_list_head(dll), &elements[3]); + head = dbl_list_head(dll); + tail = dbl_list_tail(dll); + + UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false); + UNIT_TEST_ASSERT(dbl_list_length(dll) == 3); + UNIT_TEST_ASSERT(head == &elements[3]); + UNIT_TEST_ASSERT(tail == &elements[1]); + UNIT_TEST_ASSERT(head->previous == NULL); + UNIT_TEST_ASSERT(head->next == &elements[2]); + UNIT_TEST_ASSERT(head->next->next == tail); + UNIT_TEST_ASSERT(head->next->next->next == NULL); + UNIT_TEST_ASSERT(tail->previous == &elements[2]); + UNIT_TEST_ASSERT(tail->previous->previous == &elements[3]); + UNIT_TEST_ASSERT(tail->previous->previous->previous == NULL); + UNIT_TEST_ASSERT(tail->next == NULL); + + /* + * Add after head. + * NULL <-- 3 --> 4 --> 2 --> 1 --> NULL + */ + dbl_list_add_after(dll, dbl_list_head(dll), &elements[4]); + head = dbl_list_head(dll); + tail = dbl_list_tail(dll); + + UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false); + UNIT_TEST_ASSERT(dbl_list_length(dll) == 4); + UNIT_TEST_ASSERT(head == &elements[3]); + UNIT_TEST_ASSERT(tail == &elements[1]); + UNIT_TEST_ASSERT(head->previous == NULL); + UNIT_TEST_ASSERT(head->next == &elements[4]); + UNIT_TEST_ASSERT(head->next->next == &elements[2]); + UNIT_TEST_ASSERT(head->next->next->next == tail); + UNIT_TEST_ASSERT(head->next->next->next->next == NULL); + UNIT_TEST_ASSERT(tail->previous == &elements[2]); + UNIT_TEST_ASSERT(tail->previous->previous == &elements[4]); + UNIT_TEST_ASSERT(tail->previous->previous->previous == &elements[3]); + UNIT_TEST_ASSERT(tail->previous->previous->previous->previous == NULL); + UNIT_TEST_ASSERT(tail->next == NULL); + + /* + * Add at 3rd position by adding after 2nd + * NULL <-- 3 --> 4 --> 5 --> 2 --> 1 --> NULL + */ + dbl_list_add_after(dll, &elements[4], &elements[5]); + head = dbl_list_head(dll); + tail = dbl_list_tail(dll); + + UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false); + UNIT_TEST_ASSERT(dbl_list_length(dll) == 5); + UNIT_TEST_ASSERT(head == &elements[3]); + UNIT_TEST_ASSERT(tail == &elements[1]); + UNIT_TEST_ASSERT(head->previous == NULL); + UNIT_TEST_ASSERT(head->next == &elements[4]); + UNIT_TEST_ASSERT(head->next->next == &elements[5]); + UNIT_TEST_ASSERT(tail->previous->previous == &elements[5]); + UNIT_TEST_ASSERT(tail->previous == &elements[2]); + UNIT_TEST_ASSERT(elements[5].next == &elements[2]); + UNIT_TEST_ASSERT(elements[5].previous == &elements[4]); + UNIT_TEST_ASSERT(tail->next == NULL); + + /* + * Add at 3rd position by adding before 3rd + * NULL <-- 3 --> 4 --> 6 --> 5 --> 2 --> 1 --> NULL + */ + dbl_list_add_before(dll, &elements[5], &elements[6]); + head = dbl_list_head(dll); + tail = dbl_list_tail(dll); + + UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false); + UNIT_TEST_ASSERT(dbl_list_length(dll) == 6); + UNIT_TEST_ASSERT(head == &elements[3]); + UNIT_TEST_ASSERT(tail == &elements[1]); + UNIT_TEST_ASSERT(head->previous == NULL); + UNIT_TEST_ASSERT(head->next == &elements[4]); + UNIT_TEST_ASSERT(head->next->next == &elements[6]); + UNIT_TEST_ASSERT(tail->previous->previous == &elements[5]); + UNIT_TEST_ASSERT(elements[6].next == &elements[5]); + UNIT_TEST_ASSERT(elements[6].previous == &elements[4]); + UNIT_TEST_ASSERT(tail->next == NULL); + + /* + * Add before tail + * NULL <-- 3 --> 4 --> 6 --> 5 --> 2 --> 7 --> 1 --> NULL + */ + dbl_list_add_before(dll, dbl_list_tail(dll), &elements[7]); + head = dbl_list_head(dll); + tail = dbl_list_tail(dll); + + UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false); + UNIT_TEST_ASSERT(dbl_list_length(dll) == 7); + UNIT_TEST_ASSERT(head == &elements[3]); + UNIT_TEST_ASSERT(tail == &elements[1]); + UNIT_TEST_ASSERT(head->previous == NULL); + UNIT_TEST_ASSERT(tail->previous == &elements[7]); + UNIT_TEST_ASSERT(elements[7].next == &elements[1]); + UNIT_TEST_ASSERT(elements[7].previous == &elements[2]); + UNIT_TEST_ASSERT(tail->next == NULL); + + /* + * Add after tail + * NULL <-- 3 --> 4 --> 6 --> 5 --> 2 --> 7 --> 1 --> 8 --> NULL + */ + dbl_list_add_after(dll, dbl_list_tail(dll), &elements[8]); + head = dbl_list_head(dll); + tail = dbl_list_tail(dll); + + UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false); + UNIT_TEST_ASSERT(dbl_list_length(dll) == 8); + UNIT_TEST_ASSERT(head == &elements[3]); + UNIT_TEST_ASSERT(tail == &elements[8]); + UNIT_TEST_ASSERT(head->previous == NULL); + UNIT_TEST_ASSERT(tail->previous == &elements[1]); + UNIT_TEST_ASSERT(elements[8].next == NULL); + UNIT_TEST_ASSERT(elements[8].previous == &elements[1]); + UNIT_TEST_ASSERT(tail->next == NULL); + + /* + * Find and remove element 5 + * NULL <-- 3 --> 4 --> 6 --> 2 --> 7 --> 1 --> 8 --> NULL + */ + dbl_list_remove(dll, &elements[5]); + head = dbl_list_head(dll); + tail = dbl_list_tail(dll); + + UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false); + UNIT_TEST_ASSERT(dbl_list_length(dll) == 7); + UNIT_TEST_ASSERT(head == &elements[3]); + UNIT_TEST_ASSERT(tail == &elements[8]); + UNIT_TEST_ASSERT(head->previous == NULL); + UNIT_TEST_ASSERT(elements[6].next == &elements[2]); + UNIT_TEST_ASSERT(elements[2].previous == &elements[6]); + UNIT_TEST_ASSERT(tail->next == NULL); + + /* + * Remove before tail + * NULL <-- 3 --> 4 --> 6 --> 2 --> 7 --> 8 --> NULL + */ + dbl_list_remove(dll, ((demo_struct_t *)dbl_list_tail(dll))->previous); + head = dbl_list_head(dll); + tail = dbl_list_tail(dll); + + UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false); + UNIT_TEST_ASSERT(dbl_list_length(dll) == 6); + UNIT_TEST_ASSERT(head == &elements[3]); + UNIT_TEST_ASSERT(tail == &elements[8]); + UNIT_TEST_ASSERT(head->previous == NULL); + UNIT_TEST_ASSERT(elements[7].next == tail); + UNIT_TEST_ASSERT(tail->previous == &elements[7]); + UNIT_TEST_ASSERT(tail->next == NULL); + + /* + * Remove after head + * NULL <-- 3 --> 6 --> 2 --> 7 --> 8 --> NULL + */ + dbl_list_remove(dll, ((demo_struct_t *)dbl_list_head(dll))->next); + head = dbl_list_head(dll); + tail = dbl_list_tail(dll); + + UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false); + UNIT_TEST_ASSERT(dbl_list_length(dll) == 5); + UNIT_TEST_ASSERT(head == &elements[3]); + UNIT_TEST_ASSERT(tail == &elements[8]); + UNIT_TEST_ASSERT(head->previous == NULL); + UNIT_TEST_ASSERT(head->next == &elements[6]); + UNIT_TEST_ASSERT(elements[6].previous == head); + UNIT_TEST_ASSERT(tail->next == NULL); + + /* + * Find element 2 and remove whatever is after it + * NULL <-- 3 --> 6 --> 2 --> 8 --> NULL + */ + dbl_list_remove(dll, elements[2].next); + head = dbl_list_head(dll); + tail = dbl_list_tail(dll); + + UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false); + UNIT_TEST_ASSERT(dbl_list_length(dll) == 4); + UNIT_TEST_ASSERT(head == &elements[3]); + UNIT_TEST_ASSERT(tail == &elements[8]); + UNIT_TEST_ASSERT(head->previous == NULL); + UNIT_TEST_ASSERT(elements[2].next == tail); + UNIT_TEST_ASSERT(tail->previous == &elements[2]); + UNIT_TEST_ASSERT(tail->next == NULL); + + /* + * Find element 2 and remove whatever is before it + * NULL <-- 3 --> 2 --> 8 --> NULL + */ + dbl_list_remove(dll, elements[2].previous); + head = dbl_list_head(dll); + tail = dbl_list_tail(dll); + + UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false); + UNIT_TEST_ASSERT(dbl_list_length(dll) == 3); + UNIT_TEST_ASSERT(head == &elements[3]); + UNIT_TEST_ASSERT(tail == &elements[8]); + UNIT_TEST_ASSERT(head->previous == NULL); + UNIT_TEST_ASSERT(head->next == &elements[2]); + UNIT_TEST_ASSERT(elements[2].previous == head); + UNIT_TEST_ASSERT(tail->next == NULL); + + /* + * Remove head + * NULL <-- 2 --> 8 --> NULL + */ + dbl_list_remove(dll, dbl_list_head(dll)); + head = dbl_list_head(dll); + tail = dbl_list_tail(dll); + + UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false); + UNIT_TEST_ASSERT(dbl_list_length(dll) == 2); + UNIT_TEST_ASSERT(head == &elements[2]); + UNIT_TEST_ASSERT(tail == &elements[8]); + UNIT_TEST_ASSERT(head->previous == NULL); + UNIT_TEST_ASSERT(head->next == tail); + UNIT_TEST_ASSERT(tail->previous == head); + UNIT_TEST_ASSERT(tail->next == NULL); + + /* + * Remove tail + * NULL <-- 8 --> NULL + */ + dbl_list_remove(dll, dbl_list_head(dll)); + head = dbl_list_head(dll); + tail = dbl_list_tail(dll); + + UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false); + UNIT_TEST_ASSERT(dbl_list_length(dll) == 1); + UNIT_TEST_ASSERT(head == &elements[8]); + UNIT_TEST_ASSERT(tail == &elements[8]); + UNIT_TEST_ASSERT(head->previous == NULL); + UNIT_TEST_ASSERT(head->next == NULL); + UNIT_TEST_ASSERT(tail->previous == NULL); + UNIT_TEST_ASSERT(tail->next == NULL); + + /* Remove the last element */ + dbl_list_remove(dll, dbl_list_head(dll)); + UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == true); + UNIT_TEST_ASSERT(dbl_list_length(dll) == 0); + UNIT_TEST_ASSERT(dbl_list_head(dll) == NULL); + UNIT_TEST_ASSERT(dbl_list_tail(dll) == NULL); + + UNIT_TEST_END(); +} +/*---------------------------------------------------------------------------*/ +UNIT_TEST_REGISTER(test_cdll, "Circular, doubly-linked list"); +UNIT_TEST(test_cdll) +{ + demo_struct_t *head, *tail; + + CIRCULAR_LIST(cdll); + + UNIT_TEST_BEGIN(); + + memset(elements, 0, sizeof(elements)); + + /* Starts from empty */ + dbl_circ_list_init(cdll); + UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == true); + UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 0); + UNIT_TEST_ASSERT(dbl_circ_list_head(cdll) == NULL); + UNIT_TEST_ASSERT(dbl_circ_list_tail(cdll) == NULL); + + /* + * Add an item by adding to the head. + * Head and tail should be the same element and should point to itself in + * both directions + */ + dbl_circ_list_add_head(cdll, &elements[0]); + head = dbl_circ_list_head(cdll); + tail = dbl_circ_list_tail(cdll); + + UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false); + UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 1); + UNIT_TEST_ASSERT(head == &elements[0]); + UNIT_TEST_ASSERT(tail == &elements[0]); + UNIT_TEST_ASSERT(head->previous == head); + UNIT_TEST_ASSERT(head->next == head); + UNIT_TEST_ASSERT(tail->previous == tail); + UNIT_TEST_ASSERT(tail->next == tail); + + /* + * Add an item by adding to the tail. + * (tail) <--> 0 <--> 1 <--> (head) + * Head should point to tail in both directions + */ + dbl_circ_list_add_tail(cdll, &elements[1]); + head = dbl_circ_list_head(cdll); + tail = dbl_circ_list_tail(cdll); + + UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false); + UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 2); + UNIT_TEST_ASSERT(head == &elements[0]); + UNIT_TEST_ASSERT(tail == &elements[1]); + UNIT_TEST_ASSERT(head->next == tail); + UNIT_TEST_ASSERT(tail->previous == head); + UNIT_TEST_ASSERT(head->previous == tail); + UNIT_TEST_ASSERT(tail->next == head); + + /* + * Add before head. + * (tail) <--> 2 <--> 0 <--> 1 <--> (head) + */ + dbl_circ_list_add_before(cdll, dbl_circ_list_head(cdll), &elements[2]); + head = dbl_circ_list_head(cdll); + tail = dbl_circ_list_tail(cdll); + + UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false); + UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 3); + UNIT_TEST_ASSERT(head == &elements[2]); + UNIT_TEST_ASSERT(tail == &elements[1]); + UNIT_TEST_ASSERT(head->previous == tail); + UNIT_TEST_ASSERT(tail->next == head); + UNIT_TEST_ASSERT(elements[2].previous == tail); + UNIT_TEST_ASSERT(elements[2].next == &elements[0]); + UNIT_TEST_ASSERT(elements[0].previous == head); + + /* + * Add after head. + * (tail) <--> 2 <--> 3 <--> 0 <--> 1 <--> (head) + */ + dbl_circ_list_add_after(cdll, dbl_circ_list_head(cdll), &elements[3]); + head = dbl_circ_list_head(cdll); + tail = dbl_circ_list_tail(cdll); + + UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false); + UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 4); + UNIT_TEST_ASSERT(head == &elements[2]); + UNIT_TEST_ASSERT(tail == &elements[1]); + UNIT_TEST_ASSERT(head->previous == tail); + UNIT_TEST_ASSERT(tail->next == head); + UNIT_TEST_ASSERT(elements[3].previous == head); + UNIT_TEST_ASSERT(elements[3].next == &elements[0]); + UNIT_TEST_ASSERT(elements[0].previous == &elements[3]); + + /* + * Add at 3rd position by adding after 2nd + * (tail) <--> 2 <--> 3 <--> 4 <--> 0 <--> 1 <--> (head) + */ + dbl_circ_list_add_after(cdll, &elements[3], &elements[4]); + head = dbl_circ_list_head(cdll); + tail = dbl_circ_list_tail(cdll); + + UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false); + UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 5); + UNIT_TEST_ASSERT(head == &elements[2]); + UNIT_TEST_ASSERT(tail == &elements[1]); + UNIT_TEST_ASSERT(head->previous == tail); + UNIT_TEST_ASSERT(tail->next == head); + UNIT_TEST_ASSERT(elements[3].next == &elements[4]); + UNIT_TEST_ASSERT(elements[4].previous == &elements[3]); + UNIT_TEST_ASSERT(elements[4].next == &elements[0]); + UNIT_TEST_ASSERT(elements[0].previous == &elements[4]); + + /* + * Add at 3rd position by adding before 3rd + * (tail) <--> 2 <--> 3 <--> 5 <--> 4 <--> 0 <--> 1 <--> (head) + */ + dbl_circ_list_add_before(cdll, &elements[4], &elements[5]); + head = dbl_circ_list_head(cdll); + tail = dbl_circ_list_tail(cdll); + + UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false); + UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 6); + UNIT_TEST_ASSERT(head == &elements[2]); + UNIT_TEST_ASSERT(tail == &elements[1]); + UNIT_TEST_ASSERT(head->previous == tail); + UNIT_TEST_ASSERT(tail->next == head); + UNIT_TEST_ASSERT(elements[3].next == &elements[5]); + UNIT_TEST_ASSERT(elements[5].previous == &elements[3]); + UNIT_TEST_ASSERT(elements[5].next == &elements[4]); + UNIT_TEST_ASSERT(elements[4].previous == &elements[5]); + + /* + * Add before tail + * (tail) <--> 2 <--> 3 <--> 5 <--> 4 <--> 0 <--> 6 <--> 1 <--> (head) + */ + dbl_circ_list_add_before(cdll, dbl_circ_list_tail(cdll), &elements[6]); + head = dbl_circ_list_head(cdll); + tail = dbl_circ_list_tail(cdll); + + UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false); + UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 7); + UNIT_TEST_ASSERT(head == &elements[2]); + UNIT_TEST_ASSERT(tail == &elements[1]); + UNIT_TEST_ASSERT(head->previous == tail); + UNIT_TEST_ASSERT(tail->next == head); + UNIT_TEST_ASSERT(elements[0].next == &elements[6]); + UNIT_TEST_ASSERT(elements[6].previous == &elements[0]); + UNIT_TEST_ASSERT(elements[6].next == &elements[1]); + UNIT_TEST_ASSERT(elements[1].previous == &elements[6]); + + /* + * Add after tail + * (tail) <--> 2 <--> 3 <--> 5 <--> 4 <--> 0 <--> 6 <--> 1 <--> 7 <--> (head) + */ + dbl_circ_list_add_after(cdll, dbl_circ_list_tail(cdll), &elements[7]); + head = dbl_circ_list_head(cdll); + tail = dbl_circ_list_tail(cdll); + + UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false); + UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 8); + UNIT_TEST_ASSERT(head == &elements[2]); + UNIT_TEST_ASSERT(tail == &elements[7]); + UNIT_TEST_ASSERT(head->previous == tail); + UNIT_TEST_ASSERT(tail->next == head); + UNIT_TEST_ASSERT(elements[1].next == &elements[7]); + UNIT_TEST_ASSERT(elements[7].previous == &elements[1]); + UNIT_TEST_ASSERT(elements[7].next == &elements[2]); + UNIT_TEST_ASSERT(elements[2].previous == &elements[7]); + + /* + * Find and remove element 5 + * (tail) <--> 2 <--> 3 <--> 4 <--> 0 <--> 6 <--> 1 <--> 7 <--> (head) + */ + dbl_circ_list_remove(cdll, &elements[5]); + head = dbl_circ_list_head(cdll); + tail = dbl_circ_list_tail(cdll); + + UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false); + UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 7); + UNIT_TEST_ASSERT(head == &elements[2]); + UNIT_TEST_ASSERT(tail == &elements[7]); + UNIT_TEST_ASSERT(head->previous == tail); + UNIT_TEST_ASSERT(tail->next == head); + UNIT_TEST_ASSERT(elements[3].next == &elements[4]); + UNIT_TEST_ASSERT(elements[4].previous == &elements[3]); + + /* + * Find element 4 and remove what's after it + * (tail) <--> 2 <--> 3 <--> 4 <--> 6 <--> 1 <--> 7 <--> (head) + */ + dbl_circ_list_remove(cdll, elements[4].next); + head = dbl_circ_list_head(cdll); + tail = dbl_circ_list_tail(cdll); + + UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false); + UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 6); + UNIT_TEST_ASSERT(head == &elements[2]); + UNIT_TEST_ASSERT(tail == &elements[7]); + UNIT_TEST_ASSERT(head->previous == tail); + UNIT_TEST_ASSERT(tail->next == head); + UNIT_TEST_ASSERT(elements[4].next == &elements[6]); + UNIT_TEST_ASSERT(elements[6].previous == &elements[4]); + + /* + * Find element 4 and remove what's before it + * (tail) <--> 2 <--> 4 <--> 6 <--> 1 <--> 7 <--> (head) + */ + dbl_circ_list_remove(cdll, elements[4].previous); + head = dbl_circ_list_head(cdll); + tail = dbl_circ_list_tail(cdll); + + UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false); + UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 5); + UNIT_TEST_ASSERT(head == &elements[2]); + UNIT_TEST_ASSERT(tail == &elements[7]); + UNIT_TEST_ASSERT(head->previous == tail); + UNIT_TEST_ASSERT(tail->next == head); + UNIT_TEST_ASSERT(elements[2].next == &elements[4]); + UNIT_TEST_ASSERT(elements[4].previous == &elements[2]); + + /* + * Remove before tail + * (tail) <--> 2 <--> 4 <--> 6 <--> 7 <--> (head) + */ + dbl_circ_list_remove(cdll, + ((demo_struct_t *)dbl_circ_list_tail(cdll))->previous); + head = dbl_circ_list_head(cdll); + tail = dbl_circ_list_tail(cdll); + + UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false); + UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 4); + UNIT_TEST_ASSERT(head == &elements[2]); + UNIT_TEST_ASSERT(tail == &elements[7]); + UNIT_TEST_ASSERT(head->previous == tail); + UNIT_TEST_ASSERT(tail->next == head); + UNIT_TEST_ASSERT(elements[6].next == &elements[7]); + UNIT_TEST_ASSERT(elements[7].previous == &elements[6]); + + /* + * Remove after tail + * (tail) <--> 4 <--> 6 <--> 7 <--> (head) + */ + dbl_circ_list_remove(cdll, + ((demo_struct_t *)dbl_circ_list_tail(cdll))->next); + head = dbl_circ_list_head(cdll); + tail = dbl_circ_list_tail(cdll); + + UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false); + UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 3); + UNIT_TEST_ASSERT(head == &elements[4]); + UNIT_TEST_ASSERT(tail == &elements[7]); + UNIT_TEST_ASSERT(head->previous == tail); + UNIT_TEST_ASSERT(tail->next == head); + UNIT_TEST_ASSERT(elements[7].next == &elements[4]); + UNIT_TEST_ASSERT(elements[4].previous == &elements[7]); + + /* + * Remove after head + * (tail) <--> 4 <--> 7 <--> (head) + */ + dbl_circ_list_remove(cdll, + ((demo_struct_t *)dbl_circ_list_head(cdll))->next); + head = dbl_circ_list_head(cdll); + tail = dbl_circ_list_tail(cdll); + + UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false); + UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 2); + UNIT_TEST_ASSERT(head == &elements[4]); + UNIT_TEST_ASSERT(tail == &elements[7]); + UNIT_TEST_ASSERT(head->previous == tail); + UNIT_TEST_ASSERT(head->next == tail); + UNIT_TEST_ASSERT(tail->previous == head); + UNIT_TEST_ASSERT(tail->next == head); + + /* + * Remove before head + * (tail) <--> 4 <--> (head) + */ + dbl_circ_list_remove(cdll, + ((demo_struct_t *)dbl_circ_list_head(cdll))->previous); + head = dbl_circ_list_head(cdll); + tail = dbl_circ_list_tail(cdll); + + UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false); + UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 1); + UNIT_TEST_ASSERT(head == &elements[4]); + UNIT_TEST_ASSERT(tail == &elements[4]); + UNIT_TEST_ASSERT(head->previous == tail); + UNIT_TEST_ASSERT(head->next == tail); + + /* Remove head */ + dbl_circ_list_remove(cdll, dbl_circ_list_head(cdll)); + dbl_circ_list_remove(cdll, dbl_circ_list_head(cdll)); + UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == true); + UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 0); + UNIT_TEST_ASSERT(dbl_circ_list_head(cdll) == NULL); + UNIT_TEST_ASSERT(dbl_circ_list_tail(cdll) == NULL); + + UNIT_TEST_END(); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(data_structure_test_process, ev, data) +{ + PROCESS_BEGIN(); + + printf("Run unit-test\n"); + printf("---\n"); + + memset(elements, 0, sizeof(elements)); + + UNIT_TEST_RUN(test_stack); + UNIT_TEST_RUN(test_queue); + UNIT_TEST_RUN(test_csll); + UNIT_TEST_RUN(test_dll); + UNIT_TEST_RUN(test_cdll); + + printf("=check-me= DONE\n"); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/tests/07-simulation-base/js/data-structures.js b/tests/07-simulation-base/js/data-structures.js new file mode 100644 index 000000000..5acb27f11 --- /dev/null +++ b/tests/07-simulation-base/js/data-structures.js @@ -0,0 +1,25 @@ +TIMEOUT(10000, log.testFailed()); + +var failed = false; + +while(true) { + YIELD(); + + log.log(time + " " + "node-" + id + " "+ msg + "\n"); + + if(msg.contains("=check-me=") == false) { + continue; + } + + if(msg.contains("FAILED")) { + failed = true; + } + + if(msg.contains("DONE")) { + break; + } +} +if(failed) { + log.testFailed(); +} +log.testOK(); From 5919f120a5dd3659a116973f7a7774008f4ae47b Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Tue, 12 Dec 2017 23:54:34 +0000 Subject: [PATCH 80/81] Add data structure library test on platform native --- .travis.yml | 1 + .../08-native-runs/01-test-data-structures.sh | 40 +++++++++++++++++++ tests/08-native-runs/Makefile | 1 + 3 files changed, 42 insertions(+) create mode 100755 tests/08-native-runs/01-test-data-structures.sh create mode 100644 tests/08-native-runs/Makefile diff --git a/.travis.yml b/.travis.yml index 9094189c8..7591dd772 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,3 +31,4 @@ env: - TEST_NAME='compile-nxp-ports' - TEST_NAME='doxygen' - TEST_NAME='compile-tools' + - TEST_NAME='native-runs' diff --git a/tests/08-native-runs/01-test-data-structures.sh b/tests/08-native-runs/01-test-data-structures.sh new file mode 100755 index 000000000..790235638 --- /dev/null +++ b/tests/08-native-runs/01-test-data-structures.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +# Contiki directory +CONTIKI=$1 + +# Example code directory +CODE_DIR=$CONTIKI/tests/07-simulation-base/code-data-structures/ +CODE=test-data-structures + +# Starting Contiki-NG native node +echo "Starting native node" +make -C $CODE_DIR TARGET=native > make.log 2> make.err +$CODE_DIR/$CODE.native > $CODE.log 2> $CODE.err & +CPID=$! +sleep 2 + +echo "Closing native node" +sleep 2 +pgrep $CODE | xargs kill -9 + +if grep -q "=check-me= FAILED" $CODE.log ; then + echo "==== make.log ====" ; cat make.log; + echo "==== make.err ====" ; cat make.err; + echo "==== $CODE.log ====" ; cat $CODE.log; + echo "==== $CODE.err ====" ; cat $CODE.err; + + printf "%-32s TEST FAIL\n" "$CODE" | tee $CODE.testlog; +else + cp $CODE.log $CODE.testlog + printf "%-32s TEST OK\n" "$CODE" | tee $CODE.testlog; +fi + +rm make.log +rm make.err +rm $CODE.log +rm $CODE.err + +# We do not want Make to stop -> Return 0 +# The Makefile will check if a log contains FAIL at the end +exit 0 diff --git a/tests/08-native-runs/Makefile b/tests/08-native-runs/Makefile new file mode 100644 index 000000000..c46e5271d --- /dev/null +++ b/tests/08-native-runs/Makefile @@ -0,0 +1 @@ +include ../Makefile.script-test From d56dfde0068a0e9f9a7ca7d0a9aa3d37069f003b Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Wed, 13 Dec 2017 23:18:01 +0000 Subject: [PATCH 81/81] Compile-test the data structure library example Adds compile tests for native, sky, zoul, nrf52dk --- tests/01-compile-base/Makefile | 2 ++ tests/02-compile-arm-ports-01/Makefile | 1 + tests/03-compile-arm-ports-02/Makefile | 1 + 3 files changed, 4 insertions(+) diff --git a/tests/01-compile-base/Makefile b/tests/01-compile-base/Makefile index dee315dfd..78efc6411 100644 --- a/tests/01-compile-base/Makefile +++ b/tests/01-compile-base/Makefile @@ -10,6 +10,8 @@ multicast/sky \ libs/logging/native \ libs/energest/native \ libs/energest/sky \ +libs/data-structures/native \ +libs/data-structures/sky \ rpl-udp/sky \ rpl-border-router/native \ rpl-border-router/sky \ diff --git a/tests/02-compile-arm-ports-01/Makefile b/tests/02-compile-arm-ports-01/Makefile index 7b83165cf..b54acc303 100644 --- a/tests/02-compile-arm-ports-01/Makefile +++ b/tests/02-compile-arm-ports-01/Makefile @@ -34,6 +34,7 @@ platform-specific/nrf52dk/coap-demo/nrf52dk:coap-client:SERVER_IPV6_ADDR=ffff \ platform-specific/nrf52dk/mqtt-demo/nrf52dk \ platform-specific/nrf52dk/blink-hello/nrf52dk \ platform-specific/nrf52dk/timer-test/nrf52dk \ +libs/data-structures/nrf52dk \ libs/logging/nrf52dk TOOLS= diff --git a/tests/03-compile-arm-ports-02/Makefile b/tests/03-compile-arm-ports-02/Makefile index 62b0ad084..25345e14c 100644 --- a/tests/03-compile-arm-ports-02/Makefile +++ b/tests/03-compile-arm-ports-02/Makefile @@ -26,6 +26,7 @@ http-socket/zoul \ libs/timers/zoul \ libs/energest/zoul \ libs/trickle-library/zoul \ +libs/data-structures/zoul \ nullnet/zoul \ slip-radio/zoul \ storage/cfs-coffee/openmote-cc2538 \