mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 00:14:22 +08:00
Merge remote-tracking branch 'origin/master' into ieee802154
This commit is contained in:
@@ -46,6 +46,7 @@
|
|||||||
|
|
||||||
#include <nuttx/irq.h>
|
#include <nuttx/irq.h>
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
|
#include <nuttx/semaphore.h>
|
||||||
#include <nuttx/fs/fs.h>
|
#include <nuttx/fs/fs.h>
|
||||||
#include <nuttx/drivers/drivers.h>
|
#include <nuttx/drivers/drivers.h>
|
||||||
|
|
||||||
@@ -97,13 +98,20 @@ static const struct file_operations g_rngops =
|
|||||||
#ifndef CONFIG_DISABLE_POLL
|
#ifndef CONFIG_DISABLE_POLL
|
||||||
, 0 /* poll */
|
, 0 /* poll */
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||||
|
, 0 /* unlink */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private functions
|
* Private functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int stm32_rng_initialize()
|
/****************************************************************************
|
||||||
|
* Name: stm32_rng_initialize
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int stm32_rng_initialize(void)
|
||||||
{
|
{
|
||||||
uint32_t regval;
|
uint32_t regval;
|
||||||
|
|
||||||
@@ -133,7 +141,11 @@ static int stm32_rng_initialize()
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stm32_enable()
|
/****************************************************************************
|
||||||
|
* Name: stm32_enable
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void stm32_enable(void)
|
||||||
{
|
{
|
||||||
uint32_t regval;
|
uint32_t regval;
|
||||||
|
|
||||||
@@ -144,7 +156,11 @@ static void stm32_enable()
|
|||||||
putreg32(regval, STM32_RNG_CR);
|
putreg32(regval, STM32_RNG_CR);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stm32_disable()
|
/****************************************************************************
|
||||||
|
* Name: stm32_disable
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void stm32_disable(void)
|
||||||
{
|
{
|
||||||
uint32_t regval;
|
uint32_t regval;
|
||||||
regval = getreg32(STM32_RNG_CR);
|
regval = getreg32(STM32_RNG_CR);
|
||||||
@@ -152,6 +168,10 @@ static void stm32_disable()
|
|||||||
putreg32(regval, STM32_RNG_CR);
|
putreg32(regval, STM32_RNG_CR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: stm32_interrupt
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
static int stm32_interrupt(int irq, void *context, FAR void *arg)
|
static int stm32_interrupt(int irq, void *context, FAR void *arg)
|
||||||
{
|
{
|
||||||
uint32_t rngsr;
|
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. */
|
/* We've got the semaphore. */
|
||||||
|
|
||||||
/* Initialize semaphore with 0 for blocking until the buffer is filled from
|
/* Initialize the operation semaphore with 0 for blocking until the
|
||||||
* interrupts.
|
* 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_buflen = buflen;
|
||||||
g_rngdev.rd_buf = buffer;
|
g_rngdev.rd_buf = buffer;
|
||||||
|
|||||||
@@ -194,3 +194,7 @@ endif
|
|||||||
ifeq ($(CONFIG_STM32F7_BBSRAM),y)
|
ifeq ($(CONFIG_STM32F7_BBSRAM),y)
|
||||||
CHIP_CSRCS += stm32_bbsram.c
|
CHIP_CSRCS += stm32_bbsram.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_STM32F7_RNG),y)
|
||||||
|
CHIP_CSRCS += stm32_rng.c
|
||||||
|
endif
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
/************************************************************************************
|
||||||
|
* arch/arm/src/stm32f7/chip/stm32_rng.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Max Holtzberg. All rights reserved.
|
||||||
|
* Author: Max Holtzberg <mh@uvc.de>
|
||||||
|
*
|
||||||
|
* 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 <nuttx/config.h>
|
||||||
|
#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 */
|
||||||
@@ -0,0 +1,362 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* arch/arm/src/stm32f7/stm32_rng.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Max Holtzberg. All rights reserved.
|
||||||
|
* Author: Max Holtzberg <mh@uvc.de>
|
||||||
|
* 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 <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <debug.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <nuttx/irq.h>
|
||||||
|
#include <nuttx/arch.h>
|
||||||
|
#include <nuttx/semaphore.h>
|
||||||
|
#include <nuttx/fs/fs.h>
|
||||||
|
#include <nuttx/drivers/drivers.h>
|
||||||
|
|
||||||
|
#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 */
|
||||||
@@ -145,7 +145,7 @@ static void stm32l4_rngenable(void)
|
|||||||
up_enable_irq(STM32L4_IRQ_RNG);
|
up_enable_irq(STM32L4_IRQ_RNG);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stm32l4_rngdisable()
|
static void stm32l4_rngdisable(void)
|
||||||
{
|
{
|
||||||
uint32_t regval;
|
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 */
|
/* We've got the device semaphore, proceed with reading */
|
||||||
|
|
||||||
/* Initialize the operation semaphore with 0 for blocking until the
|
/* 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
|
* for signaling and, hence, should not have priority inheritance
|
||||||
* enabled.
|
* enabled.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -71,7 +71,7 @@
|
|||||||
# undef HAVE_RTC_DRIVER
|
# undef HAVE_RTC_DRIVER
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(CONFIG_STM32_SDIO) || !defined(CONFIG_MMCSD) || \
|
#if !defined(CONFIG_STM32L4_SDIO) || !defined(CONFIG_MMCSD) || \
|
||||||
!defined(CONFIG_MMCSD_SDIO)
|
!defined(CONFIG_MMCSD_SDIO)
|
||||||
# undef HAVE_MMCSD
|
# undef HAVE_MMCSD
|
||||||
#endif
|
#endif
|
||||||
@@ -293,10 +293,10 @@
|
|||||||
|
|
||||||
/* Global driver instances */
|
/* Global driver instances */
|
||||||
|
|
||||||
#ifdef CONFIG_STM32_SPI1
|
#ifdef CONFIG_STM32L4_SPI1
|
||||||
extern struct spi_dev_s *g_spi1;
|
extern struct spi_dev_s *g_spi1;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_STM32_SPI2
|
#ifdef CONFIG_STM32L4_SPI2
|
||||||
extern struct spi_dev_s *g_spi2;
|
extern struct spi_dev_s *g_spi2;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_MMCSD
|
#ifdef HAVE_MMCSD
|
||||||
@@ -308,27 +308,27 @@ extern struct sdio_dev_s *g_sdio;
|
|||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Name: stm32_spiinitialize
|
* Name: stm32l4_spiinitialize
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Called to configure SPI chip select GPIO pins.
|
* Called to configure SPI chip select GPIO pins.
|
||||||
*
|
*
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
void stm32_spiinitialize(void);
|
void stm32l4_spiinitialize(void);
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Name: stm32_usbinitialize
|
* Name: stm32l4_usbinitialize
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Called to setup USB-related GPIO pins.
|
* Called to setup USB-related GPIO pins.
|
||||||
*
|
*
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
void stm32_usbinitialize(void);
|
void stm32l4_usbinitialize(void);
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Name: stm32_pwm_setup
|
* Name: stm32l4_pwm_setup
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Initialize PWM and register the PWM device.
|
* Initialize PWM and register the PWM device.
|
||||||
@@ -336,11 +336,11 @@ void stm32_usbinitialize(void);
|
|||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_PWM
|
#ifdef CONFIG_PWM
|
||||||
int stm32_pwm_setup(void);
|
int stm32l4_pwm_setup(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Name: stm32_adc_setup
|
* Name: stm32l4_adc_setup
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Initialize ADC and register the ADC driver.
|
* Initialize ADC and register the ADC driver.
|
||||||
@@ -348,7 +348,7 @@ int stm32_pwm_setup(void);
|
|||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_ADC
|
#ifdef CONFIG_ADC
|
||||||
int stm32_adc_setup(void);
|
int stm32l4_adc_setup(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|||||||
@@ -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.
|
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
@@ -199,20 +199,20 @@ int board_app_initialize(uintptr_t arg)
|
|||||||
#ifdef CONFIG_PWM
|
#ifdef CONFIG_PWM
|
||||||
/* Initialize PWM and register the PWM device. */
|
/* Initialize PWM and register the PWM device. */
|
||||||
|
|
||||||
ret = stm32_pwm_setup();
|
ret = stm32l4_pwm_setup();
|
||||||
if (ret < 0)
|
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
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_ADC
|
#ifdef CONFIG_ADC
|
||||||
/* Initialize ADC and register the ADC driver. */
|
/* Initialize ADC and register the ADC driver. */
|
||||||
|
|
||||||
ret = stm32_adc_setup();
|
ret = stm32l4_adc_setup();
|
||||||
if (ret < 0)
|
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
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
* Copyright (C) 2014-2015 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
@@ -82,19 +82,19 @@ void stm32l4_boardinitialize(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Configure SPI chip selects if 1) SP2 is not disabled, and 2) the weak function
|
/* 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();
|
stm32l4_spiinitialize();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Initialize USB is 1) USBDEV is selected, 2) the USB controller is not
|
/* 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.
|
* into the build.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(CONFIG_USBDEV) && defined(CONFIG_STM32_USB)
|
#if defined(CONFIG_USBDEV) && defined(CONFIG_STM32L4_USB)
|
||||||
stm32l4_usbinitialize();
|
stm32l4_usbinitialize();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ CONFIG_ARCH="arm"
|
|||||||
# CONFIG_ARCH_CHIP_LPC2378 is not set
|
# CONFIG_ARCH_CHIP_LPC2378 is not set
|
||||||
# CONFIG_ARCH_CHIP_LPC31XX is not set
|
# CONFIG_ARCH_CHIP_LPC31XX is not set
|
||||||
# CONFIG_ARCH_CHIP_LPC43XX 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_NUC1XX is not set
|
||||||
# CONFIG_ARCH_CHIP_SAMA5 is not set
|
# CONFIG_ARCH_CHIP_SAMA5 is not set
|
||||||
# CONFIG_ARCH_CHIP_SAMD 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_STM32L4 is not set
|
||||||
# CONFIG_ARCH_CHIP_STR71X is not set
|
# CONFIG_ARCH_CHIP_STR71X is not set
|
||||||
# CONFIG_ARCH_CHIP_TMS570 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_ARM7TDMI is not set
|
||||||
# CONFIG_ARCH_ARM926EJS is not set
|
# CONFIG_ARCH_ARM926EJS is not set
|
||||||
# CONFIG_ARCH_ARM920T 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_TYPES is not set
|
||||||
CONFIG_PTHREAD_MUTEX_ROBUST=y
|
CONFIG_PTHREAD_MUTEX_ROBUST=y
|
||||||
|
# CONFIG_PTHREAD_MUTEX_UNSAFE is not set
|
||||||
|
# CONFIG_PTHREAD_MUTEX_BOTH is not set
|
||||||
CONFIG_NPTHREAD_KEYS=4
|
CONFIG_NPTHREAD_KEYS=4
|
||||||
# CONFIG_PTHREAD_CLEANUP is not set
|
# CONFIG_PTHREAD_CLEANUP is not set
|
||||||
# CONFIG_CANCELLATION_POINTS 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_USBSERIAL is not set
|
||||||
# CONFIG_EXAMPLES_WATCHDOG is not set
|
# CONFIG_EXAMPLES_WATCHDOG is not set
|
||||||
# CONFIG_EXAMPLES_WEBSERVER is not set
|
# CONFIG_EXAMPLES_WEBSERVER is not set
|
||||||
|
# CONFIG_EXAMPLES_XBC_TEST is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# File System Utilities
|
# File System Utilities
|
||||||
|
|||||||
@@ -50,8 +50,11 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <nuttx/net/netdev.h>
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -223,51 +226,66 @@
|
|||||||
(((a)->u16[6]) == 0) && \
|
(((a)->u16[6]) == 0) && \
|
||||||
(((a)->u8[14]) == 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
|
* 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,
|
* The IEEE802.15.4 MAC does not use the d_buf packet buffer directly.
|
||||||
* which are different. For FRAG1, the offset field is just not used
|
* 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;
|
/* This definitiona must appear first in the structure definition to
|
||||||
uint16_t tag;
|
* assure cast compatibility.
|
||||||
uint8_t offset;
|
*/
|
||||||
};
|
|
||||||
|
|
||||||
/* The HC1 header when HC_UDP is not used
|
struct net_driver_s i_dev;
|
||||||
*
|
|
||||||
* 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 sixlowpan_hc1hdr_s
|
/* IEEE802.15.4 MAC-specific definitions follow. */
|
||||||
{
|
|
||||||
uint8_t dispatch;
|
|
||||||
uint8_t encoding;
|
|
||||||
uint8_t ttl;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* 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
|
FAR uint8_t *i_frame;
|
||||||
{
|
|
||||||
uint8_t dispatch;
|
/* The length of valid data in the i_frame buffer.
|
||||||
uint8_t hc1_encoding;
|
*
|
||||||
uint8_t hc_udp_encoding;
|
* When the network device driver calls the network input function,
|
||||||
uint8_t ttl;
|
* i_framelen should be set to zero. If there is frame to be sent
|
||||||
uint8_t ports;
|
* by the network, i_framelen will be set to indicate the size of
|
||||||
uint16_t udpchksum;
|
* 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
|
/* The structure of a next header compressor. This compressor is provided
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ int netdev_register(FAR struct net_driver_s *dev, enum net_lltype_e lltype)
|
|||||||
#ifdef CONFIG_NET_6LOWPAN
|
#ifdef CONFIG_NET_6LOWPAN
|
||||||
case NET_LL_IEEE802154: /* IEEE 802.15.4 MAC */
|
case NET_LL_IEEE802154: /* IEEE 802.15.4 MAC */
|
||||||
dev->d_llhdrlen = 0; /* REVISIT */
|
dev->d_llhdrlen = 0; /* REVISIT */
|
||||||
dev->d_mtu = SIXLOWPAN_MAC_MAXFRAME;
|
dev->d_mtu = CONFIG_NET_6LOWPAN_FRAMELEN;
|
||||||
#ifdef CONFIG_NET_TCP
|
#ifdef CONFIG_NET_TCP
|
||||||
dev->d_recvwndo = CONFIG_NET_6LOWPAN_TCP_RECVWNDO;
|
dev->d_recvwndo = CONFIG_NET_6LOWPAN_TCP_RECVWNDO;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,6 +20,14 @@ config NET_6LOWPAN_FRAG
|
|||||||
CONFIG_NET_6LOWPAN_FRAG specifies if 6lowpan fragmentation should be
|
CONFIG_NET_6LOWPAN_FRAG specifies if 6lowpan fragmentation should be
|
||||||
used or not. Fragmentation is on by default.
|
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
|
choice
|
||||||
prompt "6loWPAN Compression"
|
prompt "6loWPAN Compression"
|
||||||
default NET_6LOWPAN_COMPRESSION_HC06
|
default NET_6LOWPAN_COMPRESSION_HC06
|
||||||
@@ -124,6 +132,9 @@ endif # NET_6LOWPAN_COMPRESSION_HC06
|
|||||||
config NET_6LOWPAN_RIMEADDR_SIZE
|
config NET_6LOWPAN_RIMEADDR_SIZE
|
||||||
int "Rime address size"
|
int "Rime address size"
|
||||||
default 2
|
default 2
|
||||||
|
range 2 8
|
||||||
|
---help---
|
||||||
|
Only the values 2 and 8 are supported
|
||||||
|
|
||||||
config NET_SIXLOWPAN_MAXAGE
|
config NET_SIXLOWPAN_MAXAGE
|
||||||
int "Packet reassembly timeout"
|
int "Packet reassembly timeout"
|
||||||
|
|||||||
@@ -45,10 +45,24 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_NET_6LOWPAN
|
#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
|
* Public Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* Rime address representation */
|
||||||
|
|
||||||
struct rimeaddr_s
|
struct rimeaddr_s
|
||||||
{
|
{
|
||||||
uint8_t u8[CONFIG_NET_6LOWPAN_RIMEADDR_SIZE];
|
uint8_t u8[CONFIG_NET_6LOWPAN_RIMEADDR_SIZE];
|
||||||
|
|||||||
@@ -54,6 +54,7 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_NET_6LOWPAN
|
#ifdef CONFIG_NET_6LOWPAN
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -62,11 +63,20 @@
|
|||||||
* Name: sixlowpan_send
|
* Name: sixlowpan_send
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Process an outgoing UDP or TCP packet. Called from UDP/TCP logic to
|
* Process an outgoing UDP or TCP packet. Takes an IP packet and formats
|
||||||
* determine if the the packet should be formatted for 6loWPAN output.
|
* 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:
|
* 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:
|
* Returned Value:
|
||||||
* Ok is returned on success; Othewise a negated errno value is returned.
|
* 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();
|
net_lock();
|
||||||
/* REVISIT: To be provided */
|
/* REVISIT: To be provided */
|
||||||
net_unlock();
|
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;
|
conn = (FAR struct tcp_conn_s *)psock->s_conn;
|
||||||
DEBUGASSERT(conn != NULL);
|
DEBUGASSERT(conn != NULL);
|
||||||
|
|
||||||
|
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
||||||
/* Ignore if not IPv6 domain */
|
/* Ignore if not IPv6 domain */
|
||||||
|
|
||||||
if (conn->domain != PF_INET6)
|
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");
|
nwarn("WARNING: Not IPv6\n");
|
||||||
return (ssize_t)-EPROTOTYPE;
|
return (ssize_t)-EPROTOTYPE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Route outgoing message to the correct device */
|
/* 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.
|
* packet.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret = sixlowpan_send(dev);
|
ret = sixlowpan_send(dev, conn->u.ipv6.raddr);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
nerr("ERROR: sixlowpan_send() failed: %d\n", ret);
|
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;
|
conn = (FAR struct udp_conn_s *)psock->s_conn;
|
||||||
DEBUGASSERT(conn != NULL);
|
DEBUGASSERT(conn != NULL);
|
||||||
|
|
||||||
|
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
||||||
/* Ignore if not IPv6 domain */
|
/* Ignore if not IPv6 domain */
|
||||||
|
|
||||||
if (conn->domain != PF_INET6)
|
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");
|
nwarn("WARNING: Not IPv6\n");
|
||||||
return (ssize_t)-EPROTOTYPE;
|
return (ssize_t)-EPROTOTYPE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Route outgoing message to the correct device */
|
/* 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.
|
* packet.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret = sixlowpan_send(dev);
|
ret = sixlowpan_send(dev, conn->u.ipv6.raddr);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
nerr("ERROR: sixlowpan_send() failed: %d\n", ret);
|
nerr("ERROR: sixlowpan_send() failed: %d\n", ret);
|
||||||
|
|||||||
+21
-3
@@ -164,13 +164,22 @@ ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len,
|
|||||||
/* Try 6loWPAN TCP packet send */
|
/* Try 6loWPAN TCP packet send */
|
||||||
|
|
||||||
ret = psock_6lowpan_tcp_send(psock, buf, len);
|
ret = psock_6lowpan_tcp_send(psock, buf, len);
|
||||||
|
|
||||||
|
#ifdef CONFIG_NETDEV_MULTINIC
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
/* Try TCP/IP packet send */
|
/* UDP/IP packet send */
|
||||||
|
|
||||||
ret = psock_tcp_send(psock, buf, len);
|
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 */
|
#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 */
|
/* Try 6loWPAN UDP packet send */
|
||||||
|
|
||||||
ret = psock_6lowpan_udp_send(psock, buf, len);
|
ret = psock_6lowpan_udp_send(psock, buf, len);
|
||||||
|
|
||||||
|
#ifdef CONFIG_NETDEV_MULTINIC
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
/* UDP/IP packet send */
|
/* UDP/IP packet send */
|
||||||
|
|
||||||
ret = psock_udp_send(psock, buf, len);
|
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 */
|
#endif /* CONFIG_NET_UDP */
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,11 +112,13 @@ int pthread_givesemaphore(sem_t *sem);
|
|||||||
|
|
||||||
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
|
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
|
||||||
int pthread_mutex_take(FAR struct pthread_mutex_s *mutex, bool intr);
|
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);
|
int pthread_mutex_give(FAR struct pthread_mutex_s *mutex);
|
||||||
void pthread_mutex_inconsistent(FAR struct pthread_tcb_s *tcb);
|
void pthread_mutex_inconsistent(FAR struct pthread_tcb_s *tcb);
|
||||||
#else
|
#else
|
||||||
# define pthread_mutex_take(m,i) pthread_takesemaphore(&(m)->sem,(i))
|
# define pthread_mutex_take(m,i) pthread_takesemaphore(&(m)->sem,(i))
|
||||||
# define pthread_mutex_give(m) pthread_givesemaphore(&(m)->sem)
|
# define pthread_mutex_trytake(m) sem_trywait(&(m)->sem)
|
||||||
|
# define pthread_mutex_give(m) pthread_givesemaphore(&(m)->sem)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PTHREAD_MUTEX_TYPES
|
#ifdef CONFIG_PTHREAD_MUTEX_TYPES
|
||||||
|
|||||||
+122
-23
@@ -50,6 +50,39 @@
|
|||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
#include "pthread/pthread.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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -58,8 +91,8 @@
|
|||||||
* Name: pthread_mutex_take
|
* Name: pthread_mutex_take
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Take the pthread_mutex and, if successful, add the mutex to the ist of
|
* Take the pthread_mutex, waiting if necessary. If successful, add the
|
||||||
* mutexes held by this thread.
|
* mutex to the list of mutexes held by this thread.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* mutex - The mux to be locked
|
* mutex - The mux to be locked
|
||||||
@@ -84,38 +117,104 @@ int pthread_mutex_take(FAR struct pthread_mutex_s *mutex, bool intr)
|
|||||||
|
|
||||||
sched_lock();
|
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 ((mutex->flags & _PTHREAD_MFLAGS_INCONSISTENT) != 0)
|
||||||
if (ret == OK)
|
|
||||||
{
|
{
|
||||||
DEBUGASSERT(mutex->flink == NULL);
|
ret = EOWNERDEAD;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Take semaphore underlying the mutex */
|
||||||
|
|
||||||
/* Check if the holder of the mutex has terminated. In that case,
|
ret = pthread_takesemaphore(&mutex->sem, intr);
|
||||||
* the state of the mutex is inconsistent and we return EOWNERDEAD.
|
if (ret < OK)
|
||||||
*/
|
|
||||||
|
|
||||||
if ((mutex->flags & _PTHREAD_MFLAGS_INCONSISTENT) != 0)
|
|
||||||
{
|
{
|
||||||
ret = EOWNERDEAD;
|
ret = get_errno();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the mutex to the list of mutexes held by this task */
|
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FAR struct pthread_tcb_s *rtcb = (FAR struct pthread_tcb_s *)this_task();
|
/* Check if the holder of the mutex has terminated without
|
||||||
irqstate_t flags;
|
* releasing. In that case, the state of the mutex is
|
||||||
|
* inconsistent and we return EOWNERDEAD.
|
||||||
|
*/
|
||||||
|
|
||||||
flags = enter_critical_section();
|
if ((mutex->flags & _PTHREAD_MFLAGS_INCONSISTENT) != 0)
|
||||||
mutex->flink = rtcb->mhead;
|
{
|
||||||
rtcb->mhead = mutex;
|
ret = EOWNERDEAD;
|
||||||
leave_critical_section(flags);
|
}
|
||||||
|
|
||||||
|
/* 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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,7 +272,7 @@ int pthread_mutex_give(FAR struct pthread_mutex_s *mutex)
|
|||||||
|
|
||||||
mutex->flink = NULL;
|
mutex->flink = NULL;
|
||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
|
|
||||||
/* Now release the underlying semaphore */
|
/* Now release the underlying semaphore */
|
||||||
|
|
||||||
ret = pthread_givesemaphore(&mutex->sem);
|
ret = pthread_givesemaphore(&mutex->sem);
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ int pthread_mutex_trylock(FAR pthread_mutex_t *mutex)
|
|||||||
|
|
||||||
/* Try to get the semaphore. */
|
/* Try to get the semaphore. */
|
||||||
|
|
||||||
status = sem_trywait((FAR sem_t *)&mutex->sem);
|
status = pthread_mutex_trytake(mutex);
|
||||||
if (status == OK)
|
if (status == OK)
|
||||||
{
|
{
|
||||||
/* If we successfully obtained the semaphore, then indicate
|
/* If we successfully obtained the semaphore, then indicate
|
||||||
@@ -120,96 +120,91 @@ int pthread_mutex_trylock(FAR pthread_mutex_t *mutex)
|
|||||||
ret = OK;
|
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
|
#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. */
|
mutex->nlocks++;
|
||||||
|
ret = OK;
|
||||||
if (mutex->nlocks < INT16_MAX)
|
|
||||||
{
|
|
||||||
mutex->nlocks++;
|
|
||||||
ret = OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ret = EOVERFLOW;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
ret = EOVERFLOW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
|
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
|
||||||
/* The calling thread does not hold the semaphore. The correct
|
/* The calling thread does not hold the semaphore. The correct
|
||||||
* behavior for the 'robust' mutex is to verify that the holder of
|
* behavior for the 'robust' mutex is to verify that the holder of
|
||||||
* the mutex is still valid. This is protection from the case
|
* the mutex is still valid. This is protection from the case
|
||||||
* where the holder of the mutex has exitted without unlocking it.
|
* where the holder of the mutex has exitted without unlocking it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_PTHREAD_MUTEX_BOTH
|
#ifdef CONFIG_PTHREAD_MUTEX_BOTH
|
||||||
#ifdef CONFIG_PTHREAD_MUTEX_TYPES
|
#ifdef CONFIG_PTHREAD_MUTEX_TYPES
|
||||||
/* Check if this NORMAL mutex is robust */
|
/* Check if this NORMAL mutex is robust */
|
||||||
|
|
||||||
if (mutex->pid > 0 &&
|
if (mutex->pid > 0 &&
|
||||||
((mutex->flags & _PTHREAD_MFLAGS_ROBUST) != 0 ||
|
((mutex->flags & _PTHREAD_MFLAGS_ROBUST) != 0 ||
|
||||||
mutex->type != PTHREAD_MUTEX_NORMAL) &&
|
mutex->type != PTHREAD_MUTEX_NORMAL) &&
|
||||||
sched_gettcb(mutex->pid) == NULL)
|
sched_gettcb(mutex->pid) == NULL)
|
||||||
|
|
||||||
#else /* CONFIG_PTHREAD_MUTEX_TYPES */
|
#else /* CONFIG_PTHREAD_MUTEX_TYPES */
|
||||||
/* Check if this NORMAL mutex is robust */
|
/* Check if this NORMAL mutex is robust */
|
||||||
|
|
||||||
if (mutex->pid > 0 &&
|
if (mutex->pid > 0 &&
|
||||||
(mutex->flags & _PTHREAD_MFLAGS_ROBUST) != 0 &&
|
(mutex->flags & _PTHREAD_MFLAGS_ROBUST) != 0 &&
|
||||||
sched_gettcb(mutex->pid) == NULL)
|
sched_gettcb(mutex->pid) == NULL)
|
||||||
|
|
||||||
#endif /* CONFIG_PTHREAD_MUTEX_TYPES */
|
#endif /* CONFIG_PTHREAD_MUTEX_TYPES */
|
||||||
#else /* CONFIG_PTHREAD_MUTEX_ROBUST */
|
#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
|
#endif
|
||||||
{
|
{
|
||||||
DEBUGASSERT(mutex->pid != 0); /* < 0: available, >0 owned, ==0 error */
|
DEBUGASSERT(mutex->pid != 0); /* < 0: available, >0 owned, ==0 error */
|
||||||
DEBUGASSERT((mutex->flags & _PTHREAD_MFLAGS_INCONSISTENT) != 0);
|
DEBUGASSERT((mutex->flags & _PTHREAD_MFLAGS_INCONSISTENT) != 0);
|
||||||
|
|
||||||
/* A thread holds the mutex, but there is no such thread.
|
/* A thread holds the mutex, but there is no such thread.
|
||||||
* POSIX requires that the 'robust' mutex return EOWNERDEAD
|
* POSIX requires that the 'robust' mutex return EOWNERDEAD
|
||||||
* in this case. It is then the caller's responsibility to
|
* in this case. It is then the caller's responsibility to
|
||||||
* call pthread_mutx_consistent() fo fix the mutex.
|
* call pthread_mutx_consistent() fo fix the mutex.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mutex->flags |= _PTHREAD_MFLAGS_INCONSISTENT;
|
mutex->flags |= _PTHREAD_MFLAGS_INCONSISTENT;
|
||||||
ret = EOWNERDEAD;
|
ret = EOWNERDEAD;
|
||||||
}
|
|
||||||
|
|
||||||
/* The mutex is locked by another, active thread */
|
|
||||||
|
|
||||||
else
|
|
||||||
#endif /* CONFIG_PTHREAD_MUTEX_UNSAFE */
|
|
||||||
|
|
||||||
{
|
|
||||||
ret = EBUSY;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Some other, unhandled error occurred */
|
/* The mutex is locked by another, active thread */
|
||||||
|
|
||||||
else
|
else
|
||||||
|
#endif /* CONFIG_PTHREAD_MUTEX_UNSAFE */
|
||||||
{
|
{
|
||||||
ret = errcode;
|
ret = EBUSY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Some other, unhandled error occurred */
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = status;
|
||||||
|
}
|
||||||
|
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user