From c3c8f8ed312aa49417d84ec8cae6311784f7282f Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 28 Mar 2017 16:14:58 -0600 Subject: [PATCH 1/7] 6loWPAN: Simplify some logic in send() if there is only an IEEE802.15.4 MAC --- net/socket/send.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/net/socket/send.c b/net/socket/send.c index 20252fcdae..fd37860a1a 100644 --- a/net/socket/send.c +++ b/net/socket/send.c @@ -164,13 +164,22 @@ ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len, /* Try 6loWPAN TCP packet send */ ret = psock_6lowpan_tcp_send(psock, buf, len); + +#ifdef CONFIG_NETDEV_MULTINIC if (ret < 0) -#endif { - /* Try TCP/IP packet send */ + /* UDP/IP packet send */ ret = psock_tcp_send(psock, buf, len); } + +#endif /* CONFIG_NETDEV_MULTINIC */ +#else /* CONFIG_NET_6LOWPAN */ + + /* Only TCP/IP packet send */ + + ret = psock_tcp_send(psock, buf, len); +#endif /* CONFIG_NET_6LOWPAN */ } #endif /* CONFIG_NET_TCP */ } @@ -200,13 +209,22 @@ ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len, /* Try 6loWPAN UDP packet send */ ret = psock_6lowpan_udp_send(psock, buf, len); + +#ifdef CONFIG_NETDEV_MULTINIC if (ret < 0) -#endif { /* UDP/IP packet send */ ret = psock_udp_send(psock, buf, len); } + +#endif /* CONFIG_NETDEV_MULTINIC */ +#else /* CONFIG_NET_6LOWPAN */ + + /* Only UDP/IP packet send */ + + ret = psock_udp_send(psock, buf, len); +#endif /* CONFIG_NET_6LOWPAN */ } #endif /* CONFIG_NET_UDP */ } From ae5b5ae4319e3bd74ea7cb7aa9671afecac6e181 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 28 Mar 2017 17:26:53 -0600 Subject: [PATCH 2/7] Add Rime address macros --- net/sixlowpan/Kconfig | 3 +++ net/sixlowpan/sixlowpan.h | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/net/sixlowpan/Kconfig b/net/sixlowpan/Kconfig index 4505a7ee88..1a3882d1ad 100644 --- a/net/sixlowpan/Kconfig +++ b/net/sixlowpan/Kconfig @@ -124,6 +124,9 @@ endif # NET_6LOWPAN_COMPRESSION_HC06 config NET_6LOWPAN_RIMEADDR_SIZE int "Rime address size" default 2 + range 2 8 + ---help--- + Only the values 2 and 8 are supported config NET_SIXLOWPAN_MAXAGE int "Packet reassembly timeout" diff --git a/net/sixlowpan/sixlowpan.h b/net/sixlowpan/sixlowpan.h index 46a282b41d..3acd0f4804 100644 --- a/net/sixlowpan/sixlowpan.h +++ b/net/sixlowpan/sixlowpan.h @@ -45,10 +45,24 @@ #ifdef CONFIG_NET_6LOWPAN +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Rime addres macros */ + +#define rimeaddr_copy(dest,src) \ + memcpy(dest, src, CONFIG_NET_6LOWPAN_RIMEADDR_SIZE) + +#define rimeaddr_cmp(addr1,addr2) \ + (memcmp(addr1, addr2, CONFIG_NET_6LOWPAN_RIMEADDR_SIZE) == 0) + /**************************************************************************** * Public Types ****************************************************************************/ +/* Rime address representation */ + struct rimeaddr_s { uint8_t u8[CONFIG_NET_6LOWPAN_RIMEADDR_SIZE]; From 9f3b24a4a10ebd5dd5616941789bbe2ea85b6739 Mon Sep 17 00:00:00 2001 From: Juha Niskanen Date: Wed, 29 Mar 2017 07:08:10 -0600 Subject: [PATCH 3/7] STM32 F7: add stm32 RNG support. This is copied from stm32l4. Tested on STM32F746ZG board. --- arch/arm/src/stm32f7/Make.defs | 4 + arch/arm/src/stm32f7/chip/stm32_rng.h | 77 ++++++ arch/arm/src/stm32f7/stm32_rng.c | 362 ++++++++++++++++++++++++++ arch/arm/src/stm32l4/stm32l4_rng.c | 4 +- 4 files changed, 445 insertions(+), 2 deletions(-) create mode 100644 arch/arm/src/stm32f7/chip/stm32_rng.h create mode 100644 arch/arm/src/stm32f7/stm32_rng.c diff --git a/arch/arm/src/stm32f7/Make.defs b/arch/arm/src/stm32f7/Make.defs index d25b702d67..8baa4fbf13 100644 --- a/arch/arm/src/stm32f7/Make.defs +++ b/arch/arm/src/stm32f7/Make.defs @@ -194,3 +194,7 @@ endif ifeq ($(CONFIG_STM32F7_BBSRAM),y) CHIP_CSRCS += stm32_bbsram.c endif + +ifeq ($(CONFIG_STM32F7_RNG),y) +CHIP_CSRCS += stm32_rng.c +endif diff --git a/arch/arm/src/stm32f7/chip/stm32_rng.h b/arch/arm/src/stm32f7/chip/stm32_rng.h new file mode 100644 index 0000000000..3f5351a074 --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32_rng.h @@ -0,0 +1,77 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/chip/stm32_rng.h + * + * Copyright (C) 2012 Max Holtzberg. All rights reserved. + * Author: Max Holtzberg + * + * 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 NuttX 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 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_STC_STM32F7_CHIP_STM32_RNG_H +#define __ARCH_ARM_STC_STM32F7_CHIP_STM32_RNG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_RNG_CR_OFFSET 0x0000 /* RNG Control Register */ +#define STM32_RNG_SR_OFFSET 0x0004 /* RNG Status Register */ +#define STM32_RNG_DR_OFFSET 0x0008 /* RNG Data Register */ + +/* Register Addresses ***************************************************************/ + +#define STM32_RNG_CR (STM32_RNG_BASE+STM32_RNG_CR_OFFSET) +#define STM32_RNG_SR (STM32_RNG_BASE+STM32_RNG_SR_OFFSET) +#define STM32_RNG_DR (STM32_RNG_BASE+STM32_RNG_DR_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* RNG Control Register */ + +#define RNG_CR_RNGEN (1 << 2) /* Bit 2: RNG enable */ +#define RNG_CR_IE (1 << 3) /* Bit 3: Interrupt enable */ + +/* RNG Status Register */ + +#define RNG_SR_DRDY (1 << 0) /* Bit 0: Data ready */ +#define RNG_SR_CECS (1 << 1) /* Bit 1: Clock error current status */ +#define RNG_SR_SECS (1 << 2) /* Bit 2: Seed error current status */ +#define RNG_SR_CEIS (1 << 5) /* Bit 5: Clock error interrupt status */ +#define RNG_SR_SEIS (1 << 6) /* Bit 6: Seed error interrupt status */ + +#endif /* __ARCH_ARM_STC_STM32F7_CHIP_STM32_RNG_H */ diff --git a/arch/arm/src/stm32f7/stm32_rng.c b/arch/arm/src/stm32f7/stm32_rng.c new file mode 100644 index 0000000000..8fb0f46685 --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_rng.c @@ -0,0 +1,362 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32_rng.c + * + * Copyright (C) 2012 Max Holtzberg. All rights reserved. + * Author: Max Holtzberg + * mods for STL32L4 port by dev@ziggurat29.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "up_arch.h" +#include "chip/stm32_rng.h" +#include "up_internal.h" + +#if defined(CONFIG_STM32F7_RNG) +#if defined(CONFIG_DEV_RANDOM) || defined(CONFIG_DEV_URANDOM_ARCH) + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int stm32_rng_initialize(void); +static int stm32_rnginterrupt(int irq, void *context, FAR void *arg); +static void stm32_rngenable(void); +static void stm32_rngdisable(void); +static ssize_t stm32_rngread(struct file *filep, char *buffer, size_t); + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct rng_dev_s +{ + sem_t rd_devsem; /* Threads can only exclusively access the RNG */ + sem_t rd_readsem; /* To block until the buffer is filled */ + char *rd_buf; + size_t rd_buflen; + uint32_t rd_lastval; + bool rd_first; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct rng_dev_s g_rngdev; + +static const struct file_operations g_rngops = +{ + 0, /* open */ + 0, /* close */ + stm32_rngread, /* read */ + 0, /* write */ + 0, /* seek */ + 0 /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + , 0 /* poll */ +#endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + , 0 /* unlink */ +#endif +}; + +/**************************************************************************** + * Private functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_rng_initialize + ****************************************************************************/ + +static int stm32_rng_initialize(void) +{ + _info("Initializing RNG\n"); + + memset(&g_rngdev, 0, sizeof(struct rng_dev_s)); + + sem_init(&g_rngdev.rd_devsem, 0, 1); + + if (irq_attach(STM32_IRQ_RNG, stm32_rnginterrupt, NULL)) + { + /* We could not attach the ISR to the interrupt */ + + _info("Could not attach IRQ.\n"); + + return -EAGAIN; + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_rngenable + ****************************************************************************/ + +static void stm32_rngenable(void) +{ + uint32_t regval; + + g_rngdev.rd_first = true; + + /* Enable generation and interrupts */ + + regval = getreg32(STM32_RNG_CR); + regval |= RNG_CR_RNGEN; + regval |= RNG_CR_IE; + putreg32(regval, STM32_RNG_CR); + + up_enable_irq(STM32_IRQ_RNG); +} + +/**************************************************************************** + * Name: stm32_rngdisable + ****************************************************************************/ + +static void stm32_rngdisable(void) +{ + uint32_t regval; + + up_disable_irq(STM32_IRQ_RNG); + + regval = getreg32(STM32_RNG_CR); + regval &= ~RNG_CR_IE; + regval &= ~RNG_CR_RNGEN; + putreg32(regval, STM32_RNG_CR); +} + +/**************************************************************************** + * Name: stm32_rnginterrupt + ****************************************************************************/ + +static int stm32_rnginterrupt(int irq, void *context, FAR void *arg) +{ + uint32_t rngsr; + uint32_t data; + + rngsr = getreg32(STM32_RNG_SR); + if (rngsr & RNG_SR_CEIS) /* Check for clock error int stat */ + { + /* Clear it, we will try again. */ + + putreg32(rngsr & ~RNG_SR_CEIS, STM32_RNG_SR); + return OK; + } + + if (rngsr & RNG_SR_SEIS) /* Check for seed error in int stat */ + { + uint32_t crval; + + /* Clear seed error, then disable/enable the rng and try again. */ + + putreg32(rngsr & ~RNG_SR_SEIS, STM32_RNG_SR); + crval = getreg32(STM32_RNG_CR); + crval &= ~RNG_CR_RNGEN; + putreg32(crval, STM32_RNG_CR); + crval |= RNG_CR_RNGEN; + putreg32(crval, STM32_RNG_CR); + return OK; + } + + if (!(rngsr & RNG_SR_DRDY)) /* Data ready must be set */ + { + /* This random value is not valid, we will try again. */ + + return OK; + } + + data = getreg32(STM32_RNG_DR); + + /* As required by the FIPS PUB (Federal Information Processing Standard + * Publication) 140-2, the first random number generated after setting the + * RNGEN bit should not be used, but saved for comparison with the next + * generated random number. Each subsequent generated random number has to be + * compared with the previously generated number. The test fails if any two + * compared numbers are equal (continuous random number generator test). + */ + + if (g_rngdev.rd_first) + { + g_rngdev.rd_first = false; + g_rngdev.rd_lastval = data; + return OK; + } + + if (g_rngdev.rd_lastval == data) + { + /* Two subsequent same numbers, we will try again. */ + + return OK; + } + + /* If we get here, the random number is valid. */ + + g_rngdev.rd_lastval = data; + + if (g_rngdev.rd_buflen >= 4) + { + g_rngdev.rd_buflen -= 4; + *(uint32_t *)&g_rngdev.rd_buf[g_rngdev.rd_buflen] = data; + } + else + { + while (g_rngdev.rd_buflen > 0) + { + g_rngdev.rd_buf[--g_rngdev.rd_buflen] = (char)data; + data >>= 8; + } + } + + if (g_rngdev.rd_buflen == 0) + { + /* Buffer filled, stop further interrupts. */ + + stm32_rngdisable(); + sem_post(&g_rngdev.rd_readsem); + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_rngread + ****************************************************************************/ + +static ssize_t stm32_rngread(struct file *filep, char *buffer, size_t buflen) +{ + if (sem_wait(&g_rngdev.rd_devsem) != OK) + { + return -errno; + } + else + { + /* We've got the device semaphore, proceed with reading */ + + /* Initialize the operation semaphore with 0 for blocking until the + * buffer is filled from interrupts. The readsem semaphore is used + * for signaling and, hence, should not have priority inheritance + * enabled. + */ + + sem_init(&g_rngdev.rd_readsem, 0, 0); + sem_setprotocol(&g_rngdev.rd_readsem, SEM_PRIO_NONE); + + g_rngdev.rd_buflen = buflen; + g_rngdev.rd_buf = buffer; + + /* Enable RNG with interrupts */ + + stm32_rngenable(); + + /* Wait until the buffer is filled */ + + sem_wait(&g_rngdev.rd_readsem); + + /* Done with the operation semaphore */ + + sem_destroy(&g_rngdev.rd_readsem); + + /* Free RNG via the device semaphore for next use */ + + sem_post(&g_rngdev.rd_devsem); + + return buflen; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: devrandom_register + * + * Description: + * Initialize the RNG hardware and register the /dev/random driver. + * Must be called BEFORE devurandom_register. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_DEV_RANDOM +void devrandom_register(void) +{ + stm32_rng_initialize(); + (void)register_driver("/dev/random", &g_rngops, 0444, NULL); +} +#endif + +/**************************************************************************** + * Name: devurandom_register + * + * Description: + * Register /dev/urandom + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_DEV_URANDOM_ARCH +void devurandom_register(void) +{ +#ifndef CONFIG_DEV_RANDOM + stm32_rng_initialize(); +#endif + (void)register_driver("/dev/urandom", &g_rngops, 0444, NULL); +} +#endif + +#endif /* CONFIG_DEV_RANDOM || CONFIG_DEV_URANDOM_ARCH */ +#endif /* CONFIG_STM32F7_RNG */ diff --git a/arch/arm/src/stm32l4/stm32l4_rng.c b/arch/arm/src/stm32l4/stm32l4_rng.c index dd0f782f2d..3334d86ec0 100644 --- a/arch/arm/src/stm32l4/stm32l4_rng.c +++ b/arch/arm/src/stm32l4/stm32l4_rng.c @@ -145,7 +145,7 @@ static void stm32l4_rngenable(void) up_enable_irq(STM32L4_IRQ_RNG); } -static void stm32l4_rngdisable() +static void stm32l4_rngdisable(void) { uint32_t regval; @@ -261,7 +261,7 @@ static ssize_t stm32l4_rngread(struct file *filep, char *buffer, size_t buflen) /* We've got the device semaphore, proceed with reading */ /* Initialize the operation semaphore with 0 for blocking until the - * buffer is filled from interrupts. The waitsem semaphore is used + * buffer is filled from interrupts. The readsem semaphore is used * for signaling and, hence, should not have priority inheritance * enabled. */ From 5577f5845839913f22936fe2c77622a38ed8eb6d Mon Sep 17 00:00:00 2001 From: Juha Niskanen Date: Wed, 29 Mar 2017 07:12:19 -0600 Subject: [PATCH 4/7] STM32 RNG: Fix semaphore initial value and disable priority inheritance --- arch/arm/src/stm32/stm32_rng.c | 35 ++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/arch/arm/src/stm32/stm32_rng.c b/arch/arm/src/stm32/stm32_rng.c index ccbbd96dd7..6588814d6c 100644 --- a/arch/arm/src/stm32/stm32_rng.c +++ b/arch/arm/src/stm32/stm32_rng.c @@ -46,6 +46,7 @@ #include #include +#include #include #include @@ -97,13 +98,20 @@ static const struct file_operations g_rngops = #ifndef CONFIG_DISABLE_POLL , 0 /* poll */ #endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + , 0 /* unlink */ +#endif }; /**************************************************************************** * Private functions ****************************************************************************/ -static int stm32_rng_initialize() +/**************************************************************************** + * Name: stm32_rng_initialize + ****************************************************************************/ + +static int stm32_rng_initialize(void) { uint32_t regval; @@ -133,7 +141,11 @@ static int stm32_rng_initialize() return OK; } -static void stm32_enable() +/**************************************************************************** + * Name: stm32_enable + ****************************************************************************/ + +static void stm32_enable(void) { uint32_t regval; @@ -144,7 +156,11 @@ static void stm32_enable() putreg32(regval, STM32_RNG_CR); } -static void stm32_disable() +/**************************************************************************** + * Name: stm32_disable + ****************************************************************************/ + +static void stm32_disable(void) { uint32_t regval; regval = getreg32(STM32_RNG_CR); @@ -152,6 +168,10 @@ static void stm32_disable() putreg32(regval, STM32_RNG_CR); } +/**************************************************************************** + * Name: stm32_interrupt + ****************************************************************************/ + static int stm32_interrupt(int irq, void *context, FAR void *arg) { uint32_t rngsr; @@ -234,11 +254,14 @@ static ssize_t stm32_read(struct file *filep, char *buffer, size_t buflen) { /* We've got the semaphore. */ - /* Initialize semaphore with 0 for blocking until the buffer is filled from - * interrupts. + /* Initialize the operation semaphore with 0 for blocking until the + * buffer is filled from interrupts. The readsem semaphore is used + * for signaling and, hence, should not have priority inheritance + * enabled. */ - sem_init(&g_rngdev.rd_readsem, 0, 1); + sem_init(&g_rngdev.rd_readsem, 0, 0); + sem_setprotocol(&g_rngdev.rd_readsem, SEM_PRIO_NONE); g_rngdev.rd_buflen = buflen; g_rngdev.rd_buf = buffer; From 28e74ec058e07c8b49f6f253a7a3ab9cb568a365 Mon Sep 17 00:00:00 2001 From: Sebastien Lorquet Date: Wed, 29 Mar 2017 07:16:27 -0600 Subject: [PATCH 5/7] Nucleo L476RG: More naming fixes. --- configs/nucleo-l476rg/src/nucleo-l476rg.h | 22 +++++++++++----------- configs/nucleo-l476rg/src/stm32_appinit.c | 10 +++++----- configs/nucleo-l476rg/src/stm32_boot.c | 10 +++++----- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/configs/nucleo-l476rg/src/nucleo-l476rg.h b/configs/nucleo-l476rg/src/nucleo-l476rg.h index e82283b177..a6f676da54 100644 --- a/configs/nucleo-l476rg/src/nucleo-l476rg.h +++ b/configs/nucleo-l476rg/src/nucleo-l476rg.h @@ -71,7 +71,7 @@ # undef HAVE_RTC_DRIVER #endif -#if !defined(CONFIG_STM32_SDIO) || !defined(CONFIG_MMCSD) || \ +#if !defined(CONFIG_STM32L4_SDIO) || !defined(CONFIG_MMCSD) || \ !defined(CONFIG_MMCSD_SDIO) # undef HAVE_MMCSD #endif @@ -293,10 +293,10 @@ /* Global driver instances */ -#ifdef CONFIG_STM32_SPI1 +#ifdef CONFIG_STM32L4_SPI1 extern struct spi_dev_s *g_spi1; #endif -#ifdef CONFIG_STM32_SPI2 +#ifdef CONFIG_STM32L4_SPI2 extern struct spi_dev_s *g_spi2; #endif #ifdef HAVE_MMCSD @@ -308,27 +308,27 @@ extern struct sdio_dev_s *g_sdio; ************************************************************************************/ /************************************************************************************ - * Name: stm32_spiinitialize + * Name: stm32l4_spiinitialize * * Description: * Called to configure SPI chip select GPIO pins. * ************************************************************************************/ -void stm32_spiinitialize(void); +void stm32l4_spiinitialize(void); /************************************************************************************ - * Name: stm32_usbinitialize + * Name: stm32l4_usbinitialize * * Description: * Called to setup USB-related GPIO pins. * ************************************************************************************/ -void stm32_usbinitialize(void); +void stm32l4_usbinitialize(void); /************************************************************************************ - * Name: stm32_pwm_setup + * Name: stm32l4_pwm_setup * * Description: * Initialize PWM and register the PWM device. @@ -336,11 +336,11 @@ void stm32_usbinitialize(void); ************************************************************************************/ #ifdef CONFIG_PWM -int stm32_pwm_setup(void); +int stm32l4_pwm_setup(void); #endif /************************************************************************************ - * Name: stm32_adc_setup + * Name: stm32l4_adc_setup * * Description: * Initialize ADC and register the ADC driver. @@ -348,7 +348,7 @@ int stm32_pwm_setup(void); ************************************************************************************/ #ifdef CONFIG_ADC -int stm32_adc_setup(void); +int stm32l4_adc_setup(void); #endif /**************************************************************************** diff --git a/configs/nucleo-l476rg/src/stm32_appinit.c b/configs/nucleo-l476rg/src/stm32_appinit.c index 41b54976ae..ceaa3a76f5 100644 --- a/configs/nucleo-l476rg/src/stm32_appinit.c +++ b/configs/nucleo-l476rg/src/stm32_appinit.c @@ -1,5 +1,5 @@ /**************************************************************************** - * configs/nucleo-l476rg/src/stm32_appinit.c + * configs/nucleo-l476rg/src/stm32l4_appinit.c * * Copyright (C) 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -199,20 +199,20 @@ int board_app_initialize(uintptr_t arg) #ifdef CONFIG_PWM /* Initialize PWM and register the PWM device. */ - ret = stm32_pwm_setup(); + ret = stm32l4_pwm_setup(); if (ret < 0) { - syslog(LOG_ERR, "ERROR: stm32_pwm_setup() failed: %d\n", ret); + syslog(LOG_ERR, "ERROR: stm32l4_pwm_setup() failed: %d\n", ret); } #endif #ifdef CONFIG_ADC /* Initialize ADC and register the ADC driver. */ - ret = stm32_adc_setup(); + ret = stm32l4_adc_setup(); if (ret < 0) { - syslog(LOG_ERR, "ERROR: stm32_adc_setup failed: %d\n", ret); + syslog(LOG_ERR, "ERROR: stm32l4_adc_setup failed: %d\n", ret); } #endif diff --git a/configs/nucleo-l476rg/src/stm32_boot.c b/configs/nucleo-l476rg/src/stm32_boot.c index 0389d18cf1..2acb52ee62 100644 --- a/configs/nucleo-l476rg/src/stm32_boot.c +++ b/configs/nucleo-l476rg/src/stm32_boot.c @@ -1,5 +1,5 @@ /************************************************************************************ - * configs/nucleo-l476rg/src/stm32_boot.c + * configs/nucleo-l476rg/src/stm32l4_boot.c * * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -82,19 +82,19 @@ void stm32l4_boardinitialize(void) #endif /* Configure SPI chip selects if 1) SP2 is not disabled, and 2) the weak function - * stm32_spiinitialize() has been brought into the link. + * stm32l4_spiinitialize() has been brought into the link. */ -#if defined(CONFIG_STM32_SPI1) || defined(CONFIG_STM32_SPI2) || defined(CONFIG_STM32_SPI3) +#if defined(CONFIG_STM32L4_SPI1) || defined(CONFIG_STM32L4_SPI2) || defined(CONFIG_STM32L4_SPI3) stm32l4_spiinitialize(); #endif /* Initialize USB is 1) USBDEV is selected, 2) the USB controller is not - * disabled, and 3) the weak function stm32_usbinitialize() has been brought + * disabled, and 3) the weak function stm32l4_usbinitialize() has been brought * into the build. */ -#if defined(CONFIG_USBDEV) && defined(CONFIG_STM32_USB) +#if defined(CONFIG_USBDEV) && defined(CONFIG_STM32L4_USB) stm32l4_usbinitialize(); #endif } From eb344d7260731d850b64a201ed085496c4dce0cf Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 29 Mar 2017 07:50:40 -0600 Subject: [PATCH 6/7] Fix an assertion noted by Jussi Kivilinna. This was a consequence of the recent robust mutex changes. If robust mutexes are selected, then each mutex that a thread takes is retained in a list in threads TCB. If the thread exits and that list is not empty, then we know that the thread exitted while holding mutexes. And, in that case, each will be marked as inconsistent and the any waiter for the thread is awakened. For the case of pthread_mutex_trywait(), the mutex was not being added to the list! while not usually a fatal error, this was caught by an assertion when pthread_mutex_unlock() was called: It tried to remove the mutex from the TCB list and it was not there when, of course, it shoule be. The fix was to add pthread_mutex_trytake() which does sem_trywait() and if successful, does correctly add the mutext to the TCB list. This should eliminated the assertion. --- sched/pthread/pthread.h | 6 +- sched/pthread/pthread_mutex.c | 145 ++++++++++++++++++++++----- sched/pthread/pthread_mutextrylock.c | 113 ++++++++++----------- 3 files changed, 180 insertions(+), 84 deletions(-) diff --git a/sched/pthread/pthread.h b/sched/pthread/pthread.h index bc0238c903..b4e87d9533 100644 --- a/sched/pthread/pthread.h +++ b/sched/pthread/pthread.h @@ -112,11 +112,13 @@ int pthread_givesemaphore(sem_t *sem); #ifndef CONFIG_PTHREAD_MUTEX_UNSAFE int pthread_mutex_take(FAR struct pthread_mutex_s *mutex, bool intr); +int pthread_mutex_trytake(FAR struct pthread_mutex_s *mutex); int pthread_mutex_give(FAR struct pthread_mutex_s *mutex); void pthread_mutex_inconsistent(FAR struct pthread_tcb_s *tcb); #else -# define pthread_mutex_take(m,i) pthread_takesemaphore(&(m)->sem,(i)) -# define pthread_mutex_give(m) pthread_givesemaphore(&(m)->sem) +# define pthread_mutex_take(m,i) pthread_takesemaphore(&(m)->sem,(i)) +# define pthread_mutex_trytake(m) sem_trywait(&(m)->sem) +# define pthread_mutex_give(m) pthread_givesemaphore(&(m)->sem) #endif #ifdef CONFIG_PTHREAD_MUTEX_TYPES diff --git a/sched/pthread/pthread_mutex.c b/sched/pthread/pthread_mutex.c index 03bf35ea49..f11a5b01f6 100644 --- a/sched/pthread/pthread_mutex.c +++ b/sched/pthread/pthread_mutex.c @@ -50,6 +50,39 @@ #include "sched/sched.h" #include "pthread/pthread.h" +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pthread_mutex_add + * + * Description: + * Add the mutex to the list of mutexes held by this thread. + * + * Parameters: + * mutex - The mux to be locked + * + * Return Value: + * None + * + ****************************************************************************/ + +static void pthread_mutex_add(FAR struct pthread_mutex_s *mutex) +{ + FAR struct pthread_tcb_s *rtcb = (FAR struct pthread_tcb_s *)this_task(); + irqstate_t flags; + + DEBUGASSERT(mutex->flink == NULL); + + /* Add the mutex to the list of mutexes held by this task */ + + flags = enter_critical_section(); + mutex->flink = rtcb->mhead; + rtcb->mhead = mutex; + leave_critical_section(flags); +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -58,8 +91,8 @@ * Name: pthread_mutex_take * * Description: - * Take the pthread_mutex and, if successful, add the mutex to the ist of - * mutexes held by this thread. + * Take the pthread_mutex, waiting if necessary. If successful, add the + * mutex to the list of mutexes held by this thread. * * Parameters: * mutex - The mux to be locked @@ -84,38 +117,104 @@ int pthread_mutex_take(FAR struct pthread_mutex_s *mutex, bool intr) sched_lock(); - /* Take semaphore underlying the mutex */ + /* Error out if the mutex is already in an inconsistent state. */ - ret = pthread_takesemaphore(&mutex->sem, intr); - if (ret == OK) + if ((mutex->flags & _PTHREAD_MFLAGS_INCONSISTENT) != 0) { - DEBUGASSERT(mutex->flink == NULL); + ret = EOWNERDEAD; + } + else + { + /* Take semaphore underlying the mutex */ - /* Check if the holder of the mutex has terminated. In that case, - * the state of the mutex is inconsistent and we return EOWNERDEAD. - */ - - if ((mutex->flags & _PTHREAD_MFLAGS_INCONSISTENT) != 0) + ret = pthread_takesemaphore(&mutex->sem, intr); + if (ret < OK) { - ret = EOWNERDEAD; + ret = get_errno(); } - - /* Add the mutex to the list of mutexes held by this task */ - else { - FAR struct pthread_tcb_s *rtcb = (FAR struct pthread_tcb_s *)this_task(); - irqstate_t flags; + /* Check if the holder of the mutex has terminated without + * releasing. In that case, the state of the mutex is + * inconsistent and we return EOWNERDEAD. + */ - flags = enter_critical_section(); - mutex->flink = rtcb->mhead; - rtcb->mhead = mutex; - leave_critical_section(flags); + if ((mutex->flags & _PTHREAD_MFLAGS_INCONSISTENT) != 0) + { + ret = EOWNERDEAD; + } + + /* Add the mutex to the list of mutexes held by this task */ + + else + { + pthread_mutex_add(mutex); + } } } + + sched_unlock(); + } + + return ret; +} + +/**************************************************************************** + * Name: pthread_mutex_trytake + * + * Description: + * Try to take the pthread_mutex without waiting. If successful, add the + * mutex to the list of mutexes held by this thread. + * + * Parameters: + * mutex - The mux to be locked + * intr - false: ignore EINTR errors when locking; true tread EINTR as + * other errors by returning the errno value + * + * Return Value: + * 0 on success or an errno value on failure. + * + ****************************************************************************/ + +int pthread_mutex_trytake(FAR struct pthread_mutex_s *mutex) +{ + int ret = EINVAL; + + /* Verify input parameters */ + + DEBUGASSERT(mutex != NULL); + if (mutex != NULL) + { + /* Make sure that no unexpected context switches occur */ + + sched_lock(); + + /* Error out if the mutex is already in an inconsistent state. */ + + if ((mutex->flags & _PTHREAD_MFLAGS_INCONSISTENT) != 0) + { + ret = EOWNERDEAD; + } + else + { + /* Try to take the semaphore underlying the mutex */ + + ret = sem_trywait(&mutex->sem); + if (ret < OK) + { + ret = get_errno(); + } + else + { + /* Add the mutex to the list of mutexes held by this task */ + + pthread_mutex_add(mutex); + } + } + + sched_unlock(); } - sched_unlock(); return ret; } @@ -173,7 +272,7 @@ int pthread_mutex_give(FAR struct pthread_mutex_s *mutex) mutex->flink = NULL; leave_critical_section(flags); - + /* Now release the underlying semaphore */ ret = pthread_givesemaphore(&mutex->sem); diff --git a/sched/pthread/pthread_mutextrylock.c b/sched/pthread/pthread_mutextrylock.c index 9083fd465a..f4cda697b7 100644 --- a/sched/pthread/pthread_mutextrylock.c +++ b/sched/pthread/pthread_mutextrylock.c @@ -102,7 +102,7 @@ int pthread_mutex_trylock(FAR pthread_mutex_t *mutex) /* Try to get the semaphore. */ - status = sem_trywait((FAR sem_t *)&mutex->sem); + status = pthread_mutex_trytake(mutex); if (status == OK) { /* If we successfully obtained the semaphore, then indicate @@ -120,96 +120,91 @@ int pthread_mutex_trylock(FAR pthread_mutex_t *mutex) ret = OK; } - /* sem_trywait failed */ + /* pthread_mutex_trytake failed. Did it fail because the semaphore + * was not avaialable? + */ - else + else if (status == EAGAIN) { - /* Did it fail because the semaphore was not avaialable? */ - - int errcode = get_errno(); - if (errcode == EAGAIN) - { #ifdef CONFIG_PTHREAD_MUTEX_TYPES - /* Check if recursive mutex was locked by the calling thread. */ + /* Check if recursive mutex was locked by the calling thread. */ - if (mutex->type == PTHREAD_MUTEX_RECURSIVE && mutex->pid == mypid) + if (mutex->type == PTHREAD_MUTEX_RECURSIVE && mutex->pid == mypid) + { + /* Increment the number of locks held and return successfully. */ + + if (mutex->nlocks < INT16_MAX) { - /* Increment the number of locks held and return successfully. */ - - if (mutex->nlocks < INT16_MAX) - { - mutex->nlocks++; - ret = OK; - } - else - { - ret = EOVERFLOW; - } + mutex->nlocks++; + ret = OK; } else + { + ret = EOVERFLOW; + } + } + else #endif #ifndef CONFIG_PTHREAD_MUTEX_UNSAFE - /* The calling thread does not hold the semaphore. The correct - * behavior for the 'robust' mutex is to verify that the holder of - * the mutex is still valid. This is protection from the case - * where the holder of the mutex has exitted without unlocking it. - */ + /* The calling thread does not hold the semaphore. The correct + * behavior for the 'robust' mutex is to verify that the holder of + * the mutex is still valid. This is protection from the case + * where the holder of the mutex has exitted without unlocking it. + */ #ifdef CONFIG_PTHREAD_MUTEX_BOTH #ifdef CONFIG_PTHREAD_MUTEX_TYPES - /* Check if this NORMAL mutex is robust */ + /* Check if this NORMAL mutex is robust */ - if (mutex->pid > 0 && - ((mutex->flags & _PTHREAD_MFLAGS_ROBUST) != 0 || - mutex->type != PTHREAD_MUTEX_NORMAL) && - sched_gettcb(mutex->pid) == NULL) + if (mutex->pid > 0 && + ((mutex->flags & _PTHREAD_MFLAGS_ROBUST) != 0 || + mutex->type != PTHREAD_MUTEX_NORMAL) && + sched_gettcb(mutex->pid) == NULL) #else /* CONFIG_PTHREAD_MUTEX_TYPES */ - /* Check if this NORMAL mutex is robust */ + /* Check if this NORMAL mutex is robust */ - if (mutex->pid > 0 && - (mutex->flags & _PTHREAD_MFLAGS_ROBUST) != 0 && - sched_gettcb(mutex->pid) == NULL) + if (mutex->pid > 0 && + (mutex->flags & _PTHREAD_MFLAGS_ROBUST) != 0 && + sched_gettcb(mutex->pid) == NULL) #endif /* CONFIG_PTHREAD_MUTEX_TYPES */ #else /* CONFIG_PTHREAD_MUTEX_ROBUST */ - /* This mutex is always robust, whatever type it is. */ + /* This mutex is always robust, whatever type it is. */ - if (mutex->pid > 0 && sched_gettcb(mutex->pid) == NULL) + if (mutex->pid > 0 && sched_gettcb(mutex->pid) == NULL) #endif - { - DEBUGASSERT(mutex->pid != 0); /* < 0: available, >0 owned, ==0 error */ - DEBUGASSERT((mutex->flags & _PTHREAD_MFLAGS_INCONSISTENT) != 0); + { + DEBUGASSERT(mutex->pid != 0); /* < 0: available, >0 owned, ==0 error */ + DEBUGASSERT((mutex->flags & _PTHREAD_MFLAGS_INCONSISTENT) != 0); - /* A thread holds the mutex, but there is no such thread. - * POSIX requires that the 'robust' mutex return EOWNERDEAD - * in this case. It is then the caller's responsibility to - * call pthread_mutx_consistent() fo fix the mutex. - */ + /* A thread holds the mutex, but there is no such thread. + * POSIX requires that the 'robust' mutex return EOWNERDEAD + * in this case. It is then the caller's responsibility to + * call pthread_mutx_consistent() fo fix the mutex. + */ - mutex->flags |= _PTHREAD_MFLAGS_INCONSISTENT; - ret = EOWNERDEAD; - } - - /* The mutex is locked by another, active thread */ - - else -#endif /* CONFIG_PTHREAD_MUTEX_UNSAFE */ - - { - ret = EBUSY; - } + mutex->flags |= _PTHREAD_MFLAGS_INCONSISTENT; + ret = EOWNERDEAD; } - /* Some other, unhandled error occurred */ + /* The mutex is locked by another, active thread */ else +#endif /* CONFIG_PTHREAD_MUTEX_UNSAFE */ { - ret = errcode; + ret = EBUSY; } } + /* Some other, unhandled error occurred */ + + else + { + ret = status; + } + sched_unlock(); } From 5fb222180c861aa78be465967fdc4ae956dffbd8 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 29 Mar 2017 10:17:34 -0600 Subject: [PATCH 7/7] 6loWPAN: IEEE802.15.4 MAC driver will need a special form of the network device structure to manage fragmentation of the large packet into frames. --- configs/samv71-xult/netnsh/defconfig | 6 ++- include/nuttx/net/sixlowpan.h | 80 +++++++++++++++++----------- net/netdev/netdev_register.c | 2 +- net/sixlowpan/Kconfig | 8 +++ net/sixlowpan/sixlowpan_send.c | 28 +++++++--- 5 files changed, 85 insertions(+), 39 deletions(-) diff --git a/configs/samv71-xult/netnsh/defconfig b/configs/samv71-xult/netnsh/defconfig index b651274195..395fe4df82 100644 --- a/configs/samv71-xult/netnsh/defconfig +++ b/configs/samv71-xult/netnsh/defconfig @@ -96,6 +96,7 @@ CONFIG_ARCH="arm" # CONFIG_ARCH_CHIP_LPC2378 is not set # CONFIG_ARCH_CHIP_LPC31XX is not set # CONFIG_ARCH_CHIP_LPC43XX is not set +# CONFIG_ARCH_CHIP_MOXART is not set # CONFIG_ARCH_CHIP_NUC1XX is not set # CONFIG_ARCH_CHIP_SAMA5 is not set # CONFIG_ARCH_CHIP_SAMD is not set @@ -107,7 +108,7 @@ CONFIG_ARCH_CHIP_SAMV7=y # CONFIG_ARCH_CHIP_STM32L4 is not set # CONFIG_ARCH_CHIP_STR71X is not set # CONFIG_ARCH_CHIP_TMS570 is not set -# CONFIG_ARCH_CHIP_MOXART is not set +# CONFIG_ARCH_CHIP_XMC4 is not set # CONFIG_ARCH_ARM7TDMI is not set # CONFIG_ARCH_ARM926EJS is not set # CONFIG_ARCH_ARM920T is not set @@ -457,6 +458,8 @@ CONFIG_SCHED_WAITPID=y # # CONFIG_PTHREAD_MUTEX_TYPES is not set CONFIG_PTHREAD_MUTEX_ROBUST=y +# CONFIG_PTHREAD_MUTEX_UNSAFE is not set +# CONFIG_PTHREAD_MUTEX_BOTH is not set CONFIG_NPTHREAD_KEYS=4 # CONFIG_PTHREAD_CLEANUP is not set # CONFIG_CANCELLATION_POINTS is not set @@ -1160,6 +1163,7 @@ CONFIG_EXAMPLES_NSH=y # CONFIG_EXAMPLES_USBSERIAL is not set # CONFIG_EXAMPLES_WATCHDOG is not set # CONFIG_EXAMPLES_WEBSERVER is not set +# CONFIG_EXAMPLES_XBC_TEST is not set # # File System Utilities diff --git a/include/nuttx/net/sixlowpan.h b/include/nuttx/net/sixlowpan.h index 4887d255f0..be7f9f1e36 100644 --- a/include/nuttx/net/sixlowpan.h +++ b/include/nuttx/net/sixlowpan.h @@ -50,8 +50,11 @@ ****************************************************************************/ #include + #include +#include + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -223,51 +226,66 @@ (((a)->u16[6]) == 0) && \ (((a)->u8[14]) == 0)) -/* Maximum size of an IEEE802.15.4 frame */ +/* This maximum size of an IEEE802.15.4 frame. Certain, non-standard + * devices may exceed this value, however. + */ -#define SIXLOWPAN_MAC_MAXFRAME 127 +#define SIXLOWPAN_MAC_STDFRAME 127 /**************************************************************************** * Public Types ****************************************************************************/ -/* The header for fragments +/* The device structure for IEEE802.15.4 MAC network device differs from the + * standard Ethernet MAC device structure. The main reason for this + * difference is that fragmentation must be supported. * - * NOTE: We do not define different structures for FRAG1 and FRAGN headers, - * which are different. For FRAG1, the offset field is just not used + * The IEEE802.15.4 MAC does not use the d_buf packet buffer directly. + * Rather, it uses a smaller frame buffer. The packet data is provided to + * the frame buffer each time that the IEEE802.15.4 MAC needs to send + * more data. + * + * This is accomplished by "inheriting" the standard 'struct net_driver_s' + * and appending the frame buffer as well as other metadata needed to + * manage the fragmentation. 'struct ieee802154_driver_s' is cast + * compatible with 'struct net_driver_s' when CONFIG_NET_MULTINIC is not + * defined or when dev->d_lltype == NET_LL_IEEE802154. */ -struct sixlowpan_frag_hdr +struct ieee802154_driver_s { - uint16_t dispatch_size; - uint16_t tag; - uint8_t offset; -}; + /* This definitiona must appear first in the structure definition to + * assure cast compatibility. + */ -/* The HC1 header when HC_UDP is not used - * - * When all fields are compressed and HC_UDP is not used, we use this - * structure. If HC_UDP is used, the ttl is in another spot, and we use the - * sixlowpan_hc1_hc_udp structure - */ + struct net_driver_s i_dev; -struct sixlowpan_hc1hdr_s -{ - uint8_t dispatch; - uint8_t encoding; - uint8_t ttl; -}; + /* IEEE802.15.4 MAC-specific definitions follow. */ -/* HC1 followed by HC_UDP */ + /* The i_frame array is used to hold outgoing frame. When the + * IEEE802.15.4 device polls for new data, the outgoing frame containing + * the next fragment is placed in i_frame. + * + * The network will handle only a single outgong frame at a time. The + * IEEE802.15.4 MAC driver design may be concurrently sending and + * requesting new framesusing break-off fram buffers. That frame buffer + * management must be controlled by the IEEE802.15.4 MAC driver. + * + * Driver provied frame buffers should be 16-bit aligned. + */ -struct sixlowpan_hc1_hcudp_hdr_s -{ - uint8_t dispatch; - uint8_t hc1_encoding; - uint8_t hc_udp_encoding; - uint8_t ttl; - uint8_t ports; - uint16_t udpchksum; + FAR uint8_t *i_frame; + + /* The length of valid data in the i_frame buffer. + * + * When the network device driver calls the network input function, + * i_framelen should be set to zero. If there is frame to be sent + * by the network, i_framelen will be set to indicate the size of + * frame to be sent. The value zero means that there is no frame + * to be sent. + */ + + uint16_t i_framelen; }; /* The structure of a next header compressor. This compressor is provided diff --git a/net/netdev/netdev_register.c b/net/netdev/netdev_register.c index 9a3a01c66d..4dda608c1a 100644 --- a/net/netdev/netdev_register.c +++ b/net/netdev/netdev_register.c @@ -230,7 +230,7 @@ int netdev_register(FAR struct net_driver_s *dev, enum net_lltype_e lltype) #ifdef CONFIG_NET_6LOWPAN case NET_LL_IEEE802154: /* IEEE 802.15.4 MAC */ dev->d_llhdrlen = 0; /* REVISIT */ - dev->d_mtu = SIXLOWPAN_MAC_MAXFRAME; + dev->d_mtu = CONFIG_NET_6LOWPAN_FRAMELEN; #ifdef CONFIG_NET_TCP dev->d_recvwndo = CONFIG_NET_6LOWPAN_TCP_RECVWNDO; #endif diff --git a/net/sixlowpan/Kconfig b/net/sixlowpan/Kconfig index 1a3882d1ad..84cb1c6652 100644 --- a/net/sixlowpan/Kconfig +++ b/net/sixlowpan/Kconfig @@ -20,6 +20,14 @@ config NET_6LOWPAN_FRAG CONFIG_NET_6LOWPAN_FRAG specifies if 6lowpan fragmentation should be used or not. Fragmentation is on by default. +config NET_6LOWPAN_FRAMELEN + int "IEEE802.15.4 MAC Frame Length" + default 127 + range 127 999999 + ---help--- + Some wireless devices may use non-standard frame lengths. This + setting should never be smaller than 127. + choice prompt "6loWPAN Compression" default NET_6LOWPAN_COMPRESSION_HC06 diff --git a/net/sixlowpan/sixlowpan_send.c b/net/sixlowpan/sixlowpan_send.c index de33894597..b85c685f42 100644 --- a/net/sixlowpan/sixlowpan_send.c +++ b/net/sixlowpan/sixlowpan_send.c @@ -54,6 +54,7 @@ #ifdef CONFIG_NET_6LOWPAN + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -62,11 +63,20 @@ * Name: sixlowpan_send * * Description: - * Process an outgoing UDP or TCP packet. Called from UDP/TCP logic to - * determine if the the packet should be formatted for 6loWPAN output. + * Process an outgoing UDP or TCP packet. Takes an IP packet and formats + * it to be sent on an 802.15.4 network using 6lowpan. Called from common + * UDP/TCP send logic. + * + * The payload data is in the caller 'buf' and is of length 'len'. + * Compressed headers will be added and if necessary the packet is + * fragmented. The resulting packet/fragments are put in dev->d_buf and + * the first frame will be delivered to the 802.15.4 MAC. via ieee->i_frame. + * + * Input Parmeters: * * Input Parameters: - * dev - The IEEE802.15.4 MAC network driver interface. + * dev - The IEEE802.15.4 MAC network driver interface. + * raddr - The MAC address of the destination * * Returned Value: * Ok is returned on success; Othewise a negated errno value is returned. @@ -79,8 +89,10 @@ * ****************************************************************************/ -int sixlowpan_send(FAR struct net_driver_s *dev) +int sixlowpan_send(FAR struct net_driver_s *dev, net_ipv6addr_t raddr) { + FAR struct ieee802154_driver_s *ieee = (FAR struct ieee802154_driver_s *)dev; + net_lock(); /* REVISIT: To be provided */ net_unlock(); @@ -143,6 +155,7 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf, conn = (FAR struct tcp_conn_s *)psock->s_conn; DEBUGASSERT(conn != NULL); +#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6) /* Ignore if not IPv6 domain */ if (conn->domain != PF_INET6) @@ -150,6 +163,7 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf, nwarn("WARNING: Not IPv6\n"); return (ssize_t)-EPROTOTYPE; } +#endif /* Route outgoing message to the correct device */ @@ -188,7 +202,7 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf, * packet. */ - ret = sixlowpan_send(dev); + ret = sixlowpan_send(dev, conn->u.ipv6.raddr); if (ret < 0) { nerr("ERROR: sixlowpan_send() failed: %d\n", ret); @@ -251,6 +265,7 @@ ssize_t psock_6lowpan_udp_send(FAR struct socket *psock, FAR const void *buf, conn = (FAR struct udp_conn_s *)psock->s_conn; DEBUGASSERT(conn != NULL); +#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6) /* Ignore if not IPv6 domain */ if (conn->domain != PF_INET6) @@ -258,6 +273,7 @@ ssize_t psock_6lowpan_udp_send(FAR struct socket *psock, FAR const void *buf, nwarn("WARNING: Not IPv6\n"); return (ssize_t)-EPROTOTYPE; } +#endif /* Route outgoing message to the correct device */ @@ -296,7 +312,7 @@ ssize_t psock_6lowpan_udp_send(FAR struct socket *psock, FAR const void *buf, * packet. */ - ret = sixlowpan_send(dev); + ret = sixlowpan_send(dev, conn->u.ipv6.raddr); if (ret < 0) { nerr("ERROR: sixlowpan_send() failed: %d\n", ret);