Merge remote-tracking branch 'origin/master' into composite

This commit is contained in:
Gregory Nutt 2017-07-05 11:12:52 -06:00
commit a4cd90d4ef
72 changed files with 7190 additions and 297 deletions

View file

@ -8,7 +8,7 @@
<tr align="center" bgcolor="#e4e4e4">
<td>
<h1><big><font color="#3c34ec"><i>NuttShell (NSH)</i></font></big></h1>
<p>Last Updated: June 26, 2017</p>
<p>Last Updated: July 2, 2017</p>
</td>
</tr>
</table>
@ -1810,11 +1810,11 @@ nsh&gt; mount -t procfs /proc
<p><b>Command Syntax:</b></p>
<ul><pre>
ifdown &lt;nic-name&gt;
ifdown &lt;interface&gt;
</pre></ul>
<p>
<b>Synopsis</b>.
Take down the interface identified by the name &lt;nic-name&gt;.
Take down the interface identified by the name &lt;interface&gt;.
</p>
<p>
<b>Example:</b>
@ -1833,11 +1833,11 @@ ifdown eth0
<p><b>Command Syntax:</b></p>
<ul><pre>
ifup &lt;nic-name&gt;
ifup &lt;interface&gt;
</pre></ul>
<p>
<b>Synopsis</b>.
Bring up down the interface identified by the name &lt;nic-name&gt;.
Bring up down the interface identified by the name &lt;interface&gt;.
</p>
<p>
<b>Example:</b>

View file

@ -108,6 +108,16 @@ config ARMV7M_TOOLCHAIN_GNU_EABIW
bool "Generic GNU EABI toolchain under Windows"
depends on TOOLCHAIN_WINDOWS
select ARCH_TOOLCHAIN_GNU
config ARMV7M_TOOLCHAIN_CLANGL
bool "Generic Clang toolchain under Linux (or other POSIX environment)"
depends on !WINDOWS_NATIVE
select ARCH_TOOLCHAIN_GNU
config ARMV7M_TOOLCHAIN_CLANGW
bool "Generic Clang toolchain under Windows"
depends on TOOLCHAIN_WINDOWS
select ARCH_TOOLCHAIN_GNU
---help---
This option should work for any modern GNU toolchain (GCC 4.5 or newer)
configured for arm-none-eabi.

View file

@ -102,6 +102,18 @@ ifeq ($(filter y, \
CONFIG_ARMV7M_TOOLCHAIN ?= GNU_EABIW
endif
ifeq ($(filter y, \
$(CONFIG_ARMV7M_TOOLCHAIN_CLANGL) \
),y)
CONFIG_ARMV7M_TOOLCHAIN ?= CLANGL
endif
ifeq ($(filter y, \
$(CONFIG_ARMV7M_TOOLCHAIN_CLANGW) \
),y)
CONFIG_ARMV7M_TOOLCHAIN ?= CLANGW
endif
#
# Supported toolchains
#
@ -255,6 +267,27 @@ ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),GNU_EABIW)
endif
endif
# Clang toolchain on OS X, Linux or any typical Posix system
ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),CLANGL)
CROSSDEV ?= arm-none-eabi-
ARCROSSDEV ?= arm-none-eabi-
MAXOPTIMIZATION ?= -Os
ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT)
endif
# Clang toolchain under Windows
ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),CLANGW)
CROSSDEV ?= arm-none-eabi-
ARCROSSDEV ?= arm-none-eabi-
MAXOPTIMIZATION ?= -Os
ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT)
ifeq ($(CONFIG_WINDOWS_CYGWIN),y)
WINTOOL = y
endif
endif
# Raisonance RIDE7 under Windows
ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),RAISONANCE)

View file

@ -364,9 +364,9 @@ void sam_lowsetup(void)
# warning The SYSIO Pin4 must be bound to PB4 to use USART1
# endif
uint32_t sysioreg = getreg32(SAM_MATRIX_CCFG_SYSIO);
sysioreg |= MATRIX_CCFG_SYSIO_SYSIO4;
putreg32(sysioreg, SAM_MATRIX_CCFG_SYSIO);
regval = getreg32(SAM_MATRIX_CCFG_SYSIO);
regval |= MATRIX_CCFG_SYSIO_SYSIO4;
putreg32(regval, SAM_MATRIX_CCFG_SYSIO);
#endif

View file

@ -600,6 +600,10 @@ static int stm32_rtc_alarm_handler(int irq, void *context, void *arg)
uint32_t cr;
int ret = OK;
/* Disable the write protection for RTC registers */
rtc_wprunlock();
isr = getreg32(STM32_RTC_ISR);
/* Check for EXTI from Alarm A or B and handle according */
@ -624,7 +628,7 @@ static int stm32_rtc_alarm_handler(int irq, void *context, void *arg)
}
isr = getreg32(STM32_RTC_ISR) & ~RTC_ISR_ALRAF;
putreg32(isr, STM32_RTC_CR);
putreg32(isr, STM32_RTC_ISR);
}
}
@ -649,11 +653,14 @@ static int stm32_rtc_alarm_handler(int irq, void *context, void *arg)
}
isr = getreg32(STM32_RTC_ISR) & ~RTC_ISR_ALRBF;
putreg32(isr, STM32_RTC_CR);
putreg32(isr, STM32_RTC_ISR);
}
}
#endif
/* Re-enable the write protection for RTC registers */
rtc_wprlock();
return ret;
}
#endif

View file

@ -135,6 +135,7 @@ static struct stm32_priv_s g_mrf24j40_mb1_priv =
.dev.attach = stm32_attach_irq,
.dev.enable = stm32_enable_irq,
.handler = NULL,
.arg = NULL,
.intcfg = GPIO_MB1_INT,
.spidev = 3,
};
@ -145,7 +146,9 @@ static struct stm32_priv_s g_mrf24j40_mb2_priv =
{
.dev.attach = stm32_attach_irq,
.dev.enable = stm32_enable_irq,
.uint32_t = GPIO_MB2_INT,
.handler = NULL,
.arg = NULL,
.intcfg = GPIO_MB2_INT,
.spidev = 2,
};
#endif

View file

@ -136,17 +136,18 @@ void stm32_spi3select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected)
{
spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert");
switch(devid)
{
switch (devid)
{
#ifdef CONFIG_IEEE802154_MRF24J40
case SPIDEV_IEEE802154(0):
/* Set the GPIO low to select and high to de-select */
stm32_gpiowrite(GPIO_MB1_CS, !selected);
break;
case SPIDEV_IEEE802154(0):
/* Set the GPIO low to select and high to de-select */
stm32_gpiowrite(GPIO_MB1_CS, !selected);
break;
#endif
default:
break;
}
default:
break;
}
}
uint8_t stm32_spi3status(FAR struct spi_dev_s *dev, uint32_t devid)

View file

@ -0,0 +1,117 @@
############################################################################
# configs/nucleo-f4x1re/f401-nsh-clang/Make.defs
#
# Copyright (C) 2017 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# 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.
#
############################################################################
include ${TOPDIR}/.config
include ${TOPDIR}/tools/Config.mk
include ${TOPDIR}/arch/arm/src/armv7-m/Toolchain.defs
ifeq ($(CONFIG_ARCH_CHIP_STM32F401RE),y)
LDSCRIPT = f401re.ld
else
ifeq ($(CONFIG_ARCH_CHIP_STM32F411RE),y)
LDSCRIPT = f411re.ld
endif
endif
ifeq ($(WINTOOL),y)
# Windows-native toolchains
DIRLINK = $(TOPDIR)/tools/copydir.sh
DIRUNLINK = $(TOPDIR)/tools/unlink.sh
MKDEP = $(TOPDIR)/tools/mkwindeps.sh
ARCHINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}"
ARCHXXINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" -isystem "${shell cygpath -w $(TOPDIR)/include/cxx}"
ARCHSCRIPT = -T "${shell cygpath -w $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)}"
else
# Linux/Cygwin-native toolchain
MKDEP = $(TOPDIR)/tools/mkdeps$(HOSTEXEEXT)
ARCHINCLUDES = -I. -isystem $(TOPDIR)/include
ARCHXXINCLUDES = -I. -isystem $(TOPDIR)/include -isystem $(TOPDIR)/include/cxx
ARCHSCRIPT = -T$(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)
endif
CC = clang
CXX = clang++
CPP = clang -E
LD = $(CROSSDEV)ld
AR = $(ARCROSSDEV)ar rcs
NM = $(ARCROSSDEV)nm
OBJCOPY = $(CROSSDEV)objcopy
OBJDUMP = $(CROSSDEV)objdump
ARCHCCVERSION = {shell $(CC) -v 2>&1 | sed -n '/clang version/p' | sed -e 's/.* clang version \([0-9\.]\)/\1/g' -e 's/[-\ ].*//g'}
ARCHCCMAJOR = ${shell echo $(ARCHCCVERSION) | cut -d'.' -f1}
ifeq ($(CONFIG_DEBUG_SYMBOLS),y)
ARCHOPTIMIZATION = -g
endif
ifneq ($(CONFIG_DEBUG_NOOPT),y)
ARCHOPTIMIZATION += $(MAXOPTIMIZATION) -fno-strict-aliasing -fomit-frame-pointer
endif
ARCHCFLAGS = -fno-builtin -nostdlib -ffreestanding -target arm-none-eabi -march=armv7-m -mcpu=cortex-m4
ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fcheck-new -nostdlib -ffreestanding -target arm-none-eabi -march=armv7-m -mcpu=cortex-m4 -DCONFIG_WCHAR_BUILTIN
ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef
ARCHWARNINGSXX = -Wall -Wshadow -Wundef
ARCHDEFINES =
ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10
CFLAGS = $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS)
CXXFLAGS = $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
CPPFLAGS = $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES)
AFLAGS = $(CFLAGS) -D__ASSEMBLY__
NXFLATLDFLAGS1 = -r -d -warn-common
NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -no-check-sections
LDNXFLATFLAGS = -e main -s 2048
ASMEXT = .S
OBJEXT = .o
LIBEXT = .a
EXEEXT =
ifneq ($(CROSSDEV),arm-nuttx-elf-)
LDFLAGS += -nostartfiles -nodefaultlibs
endif
ifeq ($(CONFIG_DEBUG_SYMBOLS),y)
LDFLAGS += -g
endif
HOSTCC = clang
HOSTINCLUDES = -I.
HOSTCFLAGS = -Wall -Wstrict-prototypes -Wshadow -Wundef -g -pipe
HOSTLDFLAGS =

File diff suppressed because it is too large Load diff

View file

@ -5,6 +5,37 @@
if ARCH_BOARD_SAME70_XPLAINED
config SAME70XPLAINED_CLICKSHIELD
bool "Mikroe Click Shield"
default n
---help---
In the mrf24j40-starhub configuration, a click shield from
MikroElectronika was used along with a Click "Bee" module. The
click shield supports two click shields.
config SAME70XPLAINED_MB1_SPI
bool
default n
config SAME70XPLAINED_MB2_SPI
bool
default n
choice
prompt "Bee mikroBUS"
depends on SAME70XPLAINED_CLICKSHIELD && IEEE802154_MRF24J40
default SAME70XPLAINED_MB1_BEE
config SAME70XPLAINED_MB1_BEE
bool "MRF24J40 Bee in mikroBUS1"
select SAME70XPLAINED_MB1_SPI
config SAME70XPLAINED_MB2_BEE
bool "MRF24J40 Bee in mikroBUS2"
select SAME70XPLAINED_MB2_SPI
endchoice # Bee mikroBUS
config SAME70XPLAINED_HSMCI0_AUTOMOUNT
bool "HSMCI0 automounter"
default n

View file

@ -19,6 +19,7 @@ Contents
- USBHS Device Controller Driver
- MCAN1 Loopback Test
- SPI Slave
- Click Shield
- Tickless OS
- Debugging
- Using OpenOCD and GDB to flash via the EDBG chip
@ -834,6 +835,64 @@ SPI Slave
b) It will hog all of the CPU for the duration of the transfer).
Click Shield
============
In the mrf24j40-starhub configuration, a click shield from
MikroElectronika was used along with a Click "Bee" module. The click
shield supports two click shields and the following tables describe the
relationship between the pins on each click shield, the Arduino
connector and the SAME70 pins.
--------- ---------------------- -------- --------- ------------------ ----------
mikroBUS1 Arduino SAME70 mikroBUS2 Arduino SAME70
--------- ---------------------- -------- --------- ------------------ ----------
AN HD1 A0 AN0 Pin 1 AD0 PD26 AN HD1 A1 AN1 Pin 2 AD1 PC31
RST HD1 A3 Pin 4 AD3 PA19 RST HD1 A2 Pin 3 AD2 PD30
CS HD4 D10 SPI-SS Pin 8 D10 PD25 CS HD4 D9 Pin 9 D9 PC9
SCK HD4 D13 SPI-SCK Pin 5 D13 PD22 SCK Same
MISO HD4 D12 SPI-MISO Pin 6 D12 PD20 MISO Same
MOSI HD4 D11 SPI-MOSI Pin 7 D11 PD21 MOSI Same
3.3V N/A 3.3V N/A
GND N/A GND N/A
PWM HD3 D6 PWMA Pin 2 D6 PC19 PWM HD3 D5 PWMB Pin 5 D5 PD11
INT HD3 D2 INT0 Pin 6 D2 PA5 INT HD3 D3 INT1 Pin 5 D3 PA6
RX HD3 D0 HDR-RX* Pin 8 D0 PD28 RX Same
TX HD3 D1 HDR-TX* Pin 7 D1 PD30 TX Same
SCL HD1 A5 I2C-SCL Pin 5 AD5 PC30 SDA Same
SDA HD1 A4 I2C-SDA Pin 6 AD4 PC13 SCL Same
5V N/A 5V N/A
GND N/A GND N/A
--------- ---------------------- -------- --------- ------------------ ----------
* Depends upon setting of SW1, UART vs PROG.
--- ----- ------------------------------ ---------------------------------
PIN PORT SHIELD FUNCTION SAME70PIN CONFIGURATION
--- ----- ------------------------------ ---------------------------------
AD0 PD26 microBUS2 Analog TD PD26 *** Not an AFE pin ***
AD1 PC31 microBUS2 Analog PC31 AFE1_AD6 GPIO_AFE1_AD6
AD2 PD30 microBUS2 GPIO reset output PD30
AD3 PA19 microBUS1 GPIO reset output PA19
AD4 PC13 (both) I2C-SDA PC13 *** Does not support I2C SDA ***
AD5 PC30 (both) I2C-SCL PC30 *** Does not support I2C SCL ***
AD6 PA17 *** Not used ***
AD7 PC12 *** Not used ***
D0 PD28 (both) HDR_RX PD28 URXD3 GPIO_UART3_RXD
D1 PD30 (both) HDR_TX PD30 UTXD3 GPIO_UART3_TXD_1
D2 PA5 microBUS1 GPIO interrupt input PA5
D3 PA6 microBUS2 GPIO interrupt input PA6
D4 PD27 *** Not used ***
D5 PD11 microBUS2 PWMB PD11 PWMC0_H0
D6 PC19 microBUS1 PWMA PC19 PWMC0_H2
D7 PA2 *** Not used ***
D8 PA17 *** Not used ***
D9 PC9 microBUS2 CS GPIO output PC9
D10 PD25 microBUS1 CS GPIO output PD25 SPI0_NPCS1
D11 PD21 (both) SPI-MOSI PD21 SPI0_MOSI GPIO_SPI0_MOSI
D12 PD20 (both) SPI-MISO PD20 SPI0_MISO GPIO_SPI0_MISO
D13 PD22 (both) SPI-SCK PD22 SPI0_SPCK GPIO_SPI0_SPCK
Tickless OS
===========

View file

@ -34,6 +34,7 @@ CONFIG_BUILD_FLAT=y
# CONFIG_MOTOROLA_SREC is not set
CONFIG_RAW_BINARY=y
# CONFIG_UBOOT_UIMAGE is not set
# CONFIG_DFU_BINARY is not set
#
# Customize Header Files
@ -129,8 +130,6 @@ CONFIG_ARCH_CORTEXM7=y
# CONFIG_ARCH_CORTEXR7F is not set
CONFIG_ARCH_FAMILY="armv7-m"
CONFIG_ARCH_CHIP="samv7"
# CONFIG_ARCH_TOOLCHAIN_IAR is not set
CONFIG_ARCH_TOOLCHAIN_GNU=y
# CONFIG_ARMV7M_USEBASEPRI is not set
CONFIG_ARCH_HAVE_CMNVECTOR=y
CONFIG_ARMV7M_CMNVECTOR=y
@ -319,6 +318,8 @@ CONFIG_SAMV7_EMAC0_ISETH0=y
# CONFIG_SAMV7_EMAC_PREALLOCATE is not set
# CONFIG_SAMV7_EMAC_NBC is not set
CONFIG_SAMV7_EMAC_HPWORK=y
# CONFIG_ARCH_TOOLCHAIN_IAR is not set
CONFIG_ARCH_TOOLCHAIN_GNU=y
#
# Architecture Options
@ -339,6 +340,7 @@ CONFIG_ARCH_HAVE_MPU=y
# CONFIG_ARCH_HAVE_EXTCLK is not set
# CONFIG_ARCH_HAVE_POWEROFF is not set
CONFIG_ARCH_HAVE_RESET=y
# CONFIG_ARCH_HAVE_RTC_SUBSECONDS is not set
# CONFIG_ARCH_USE_MPU is not set
# CONFIG_ARCH_IRQPRIO is not set
CONFIG_ARCH_STACKDUMP=y
@ -536,15 +538,6 @@ CONFIG_DEV_NULL=y
#
# Buffering
#
#
# Common I/O Buffer Support
#
CONFIG_MM_IOB=y
CONFIG_IOB_NBUFFERS=24
CONFIG_IOB_BUFSIZE=196
CONFIG_IOB_NCHAINS=8
CONFIG_IOB_THROTTLE=8
# CONFIG_DRVR_WRITEBUFFER is not set
# CONFIG_DRVR_READAHEAD is not set
# CONFIG_RAMDISK is not set
@ -772,7 +765,9 @@ CONFIG_USART1_2STOP=0
# System Logging
#
# CONFIG_ARCH_SYSLOG is not set
CONFIG_SYSLOG_WRITE=y
# CONFIG_RAMLOG is not set
# CONFIG_SYSLOG_BUFFER is not set
# CONFIG_SYSLOG_INTBUFFER is not set
# CONFIG_SYSLOG_TIMESTAMP is not set
CONFIG_SYSLOG_SERIAL_CONSOLE=y
@ -890,6 +885,11 @@ CONFIG_ARP_SEND_DELAYMSEC=20
# CONFIG_NET_ARCH_INCR32 is not set
# CONFIG_NET_ARCH_CHKSUM is not set
CONFIG_NET_STATISTICS=y
# CONFIG_NET_HAVE_STAR is not set
#
# Network Topologies
#
#
# Routing Table Configuration
@ -958,6 +958,15 @@ CONFIG_MM_REGIONS=1
# CONFIG_ARCH_HAVE_HEAP2 is not set
# CONFIG_GRAN is not set
#
# Common I/O Buffer Support
#
CONFIG_MM_IOB=y
CONFIG_IOB_NBUFFERS=24
CONFIG_IOB_BUFSIZE=196
CONFIG_IOB_NCHAINS=8
CONFIG_IOB_THROTTLE=8
#
# Audio Support
#
@ -966,6 +975,7 @@ CONFIG_MM_REGIONS=1
#
# Wireless Support
#
# CONFIG_WIRELESS is not set
#
# Binary Loader
@ -1216,6 +1226,7 @@ CONFIG_NETUTILS_NETLIB=y
# CONFIG_NETUTILS_NTPCLIENT is not set
# CONFIG_NETUTILS_PPPD is not set
# CONFIG_NETUTILS_SMTP is not set
# CONFIG_NETUTILS_TELNETC is not set
CONFIG_NETUTILS_TELNETD=y
CONFIG_NETUTILS_TFTPC=y
CONFIG_NETUTILS_WEBCLIENT=y
@ -1293,6 +1304,7 @@ CONFIG_NSH_DISABLE_PRINTF=y
# CONFIG_NSH_DISABLE_SLEEP is not set
# CONFIG_NSH_DISABLE_TIME is not set
# CONFIG_NSH_DISABLE_TEST is not set
# CONFIG_NSH_DISABLE_TELNETD is not set
# CONFIG_NSH_DISABLE_UMOUNT is not set
# CONFIG_NSH_DISABLE_UNAME is not set
# CONFIG_NSH_DISABLE_UNSET is not set
@ -1329,6 +1341,7 @@ CONFIG_NSH_ARCHINIT=y
# Networking Configuration
#
CONFIG_NSH_NETINIT=y
# CONFIG_NSH_NETLOCAL is not set
CONFIG_NSH_NETINIT_THREAD=y
CONFIG_NSH_NETINIT_MONITOR=y
CONFIG_NSH_NETINIT_SIGNO=18
@ -1378,6 +1391,7 @@ CONFIG_NSH_IOBUFFER_SIZE=512
#
# CONFIG_SYSTEM_CLE is not set
# CONFIG_SYSTEM_CUTERM is not set
# CONFIG_SYSTEM_DHCPC_RENEW is not set
# CONFIG_SYSTEM_FLASH_ERASEALL is not set
# CONFIG_SYSTEM_FREE is not set
# CONFIG_SYSTEM_HEX2BIN is not set
@ -1392,6 +1406,7 @@ CONFIG_I2CTOOL_DEFFREQ=400000
# CONFIG_SYSTEM_INSTALL is not set
# CONFIG_SYSTEM_MDIO is not set
# CONFIG_SYSTEM_NETDB is not set
# CONFIG_SYSTEM_NTPC is not set
# CONFIG_SYSTEM_RAMTEST is not set
CONFIG_READLINE_HAVE_EXTMATCH=y
CONFIG_SYSTEM_READLINE=y
@ -1408,3 +1423,10 @@ CONFIG_READLINE_ECHO=y
#
# Wireless Libraries and NSH Add-Ons
#
#
# IEEE 802.15.4 applications
#
# CONFIG_IEEE802154_LIBMAC is not set
# CONFIG_IEEE802154_LIBUTILS is not set
# CONFIG_IEEE802154_I8SAK is not set

View file

@ -34,6 +34,7 @@ CONFIG_BUILD_FLAT=y
# CONFIG_MOTOROLA_SREC is not set
CONFIG_RAW_BINARY=y
# CONFIG_UBOOT_UIMAGE is not set
# CONFIG_DFU_BINARY is not set
#
# Customize Header Files
@ -95,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
@ -102,11 +104,12 @@ CONFIG_ARCH="arm"
# CONFIG_ARCH_CHIP_SAM34 is not set
CONFIG_ARCH_CHIP_SAMV7=y
# CONFIG_ARCH_CHIP_STM32 is not set
# CONFIG_ARCH_CHIP_STM32F0 is not set
# CONFIG_ARCH_CHIP_STM32F7 is not set
# 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
@ -127,8 +130,6 @@ CONFIG_ARCH_CORTEXM7=y
# CONFIG_ARCH_CORTEXR7F is not set
CONFIG_ARCH_FAMILY="armv7-m"
CONFIG_ARCH_CHIP="samv7"
# CONFIG_ARCH_TOOLCHAIN_IAR is not set
CONFIG_ARCH_TOOLCHAIN_GNU=y
# CONFIG_ARMV7M_USEBASEPRI is not set
CONFIG_ARCH_HAVE_CMNVECTOR=y
CONFIG_ARMV7M_CMNVECTOR=y
@ -302,6 +303,8 @@ CONFIG_SAMV7_HSMCI_DMA=y
# CONFIG_SAMV7_HSMCI_RDPROOF is not set
# CONFIG_SAMV7_HSMCI_WRPROOF is not set
# CONFIG_SAMV7_HSMCI_UNALIGNED is not set
# CONFIG_ARCH_TOOLCHAIN_IAR is not set
CONFIG_ARCH_TOOLCHAIN_GNU=y
#
# Architecture Options
@ -322,6 +325,7 @@ CONFIG_ARCH_HAVE_MPU=y
# CONFIG_ARCH_HAVE_EXTCLK is not set
# CONFIG_ARCH_HAVE_POWEROFF is not set
CONFIG_ARCH_HAVE_RESET=y
# CONFIG_ARCH_HAVE_RTC_SUBSECONDS is not set
# CONFIG_ARCH_USE_MPU is not set
# CONFIG_ARCH_IRQPRIO is not set
CONFIG_ARCH_STACKDUMP=y
@ -439,6 +443,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
@ -694,6 +700,7 @@ CONFIG_USART1_2STOP=0
# CONFIG_PSEUDOTERM is not set
# CONFIG_USBDEV is not set
# CONFIG_USBHOST is not set
# CONFIG_USBMISC is not set
# CONFIG_HAVE_USBTRACE is not set
# CONFIG_DRIVERS_WIRELESS is not set
# CONFIG_DRIVERS_CONTACTLESS is not set
@ -702,7 +709,9 @@ CONFIG_USART1_2STOP=0
# System Logging
#
# CONFIG_ARCH_SYSLOG is not set
CONFIG_SYSLOG_WRITE=y
# CONFIG_RAMLOG is not set
# CONFIG_SYSLOG_BUFFER is not set
# CONFIG_SYSLOG_INTBUFFER is not set
# CONFIG_SYSLOG_TIMESTAMP is not set
CONFIG_SYSLOG_SERIAL_CONSOLE=y
@ -778,6 +787,11 @@ CONFIG_MM_REGIONS=1
# CONFIG_ARCH_HAVE_HEAP2 is not set
# CONFIG_GRAN is not set
#
# Common I/O Buffer Support
#
# CONFIG_MM_IOB is not set
#
# Audio Support
#
@ -786,6 +800,7 @@ CONFIG_MM_REGIONS=1
#
# Wireless Support
#
# CONFIG_WIRELESS is not set
#
# Binary Loader
@ -946,7 +961,6 @@ CONFIG_BUILTIN_PROXY_STACKSIZE=1024
# CONFIG_EXAMPLES_MM is not set
# CONFIG_EXAMPLES_MODBUS is not set
# CONFIG_EXAMPLES_MOUNT is not set
# CONFIG_EXAMPLES_NRF24L01TERM is not set
CONFIG_EXAMPLES_NSH=y
# CONFIG_EXAMPLES_NULL is not set
# CONFIG_EXAMPLES_NX is not set
@ -972,12 +986,12 @@ CONFIG_EXAMPLES_NSH=y
# CONFIG_EXAMPLES_SMP is not set
# CONFIG_EXAMPLES_STAT is not set
# CONFIG_EXAMPLES_TCPECHO is not set
# CONFIG_EXAMPLES_TELNETD is not set
# CONFIG_EXAMPLES_TIFF is not set
# CONFIG_EXAMPLES_TOUCHSCREEN is not set
# 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
@ -1086,6 +1100,7 @@ CONFIG_NSH_DISABLE_PRINTF=y
# CONFIG_NSH_DISABLE_SLEEP is not set
# CONFIG_NSH_DISABLE_TIME is not set
# CONFIG_NSH_DISABLE_TEST is not set
# CONFIG_NSH_DISABLE_TELNETD is not set
# CONFIG_NSH_DISABLE_UMOUNT is not set
# CONFIG_NSH_DISABLE_UNAME is not set
# CONFIG_NSH_DISABLE_UNSET is not set
@ -1148,6 +1163,8 @@ CONFIG_I2CTOOL_MAXREGADDR=0xff
CONFIG_I2CTOOL_DEFFREQ=400000
# CONFIG_SYSTEM_INSTALL is not set
CONFIG_SYSTEM_RAMTEST=y
CONFIG_SYSTEM_RAMTEST_PRIORITY=100
CONFIG_SYSTEM_RAMTEST_STACKSIZE=1024
CONFIG_READLINE_HAVE_EXTMATCH=y
CONFIG_SYSTEM_READLINE=y
CONFIG_READLINE_ECHO=y
@ -1159,3 +1176,14 @@ CONFIG_READLINE_ECHO=y
# CONFIG_SYSTEM_UBLOXMODEM is not set
# CONFIG_SYSTEM_VI is not set
# CONFIG_SYSTEM_ZMODEM is not set
#
# Wireless Libraries and NSH Add-Ons
#
#
# IEEE 802.15.4 applications
#
# CONFIG_IEEE802154_LIBMAC is not set
# CONFIG_IEEE802154_LIBUTILS is not set
# CONFIG_IEEE802154_I8SAK is not set

View file

@ -1,7 +1,7 @@
############################################################################
# configs/same70-xplained/src/Makefile
#
# Copyright (C) 2015 Gregory Nutt. All rights reserved.
# Copyright (C) 2015, 2017 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
@ -94,4 +94,8 @@ ifneq (,$(findstring y,$(CONFIG_SAMV7_DAC0) $(CONFIG_SAMV7_DAC1)))
CSRCS += sam_dac.c
endif
ifeq ($(CONFIG_IEEE802154_MRF24J40),y)
CSRCS += sam_mrf24j40.c
endif
include $(TOPDIR)/configs/Board.mk

View file

@ -1,7 +1,7 @@
/****************************************************************************
* config/same70-xplained/src/sam_bringup.c
*
* Copyright (C) 2015, 2016 Gregory Nutt. All rights reserved.
* Copyright (C) 2015-2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -329,10 +329,19 @@ int sam_bringup(void)
}
#endif
#ifdef HAVE_MRF24J40
/* Configure MRF24J40 wireless */
ret = sam_mrf24j40_initialize();
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: sam_mrf24j40_initialize() failed: %d\n", ret);
}
#endif
#ifdef HAVE_ELF
/* Initialize the ELF binary loader */
syslog(LOG_ERR, "Initializing the ELF binary loader\n");
ret = elf_initialize();
if (ret < 0)
{

View file

@ -0,0 +1,347 @@
/****************************************************************************
* configs/same70-xplained/src/sam_mrf24j40.c
*
* Copyright (C) 2017 Gregory Nutt, All rights reserver
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 <nuttx/config.h>
#include <stdio.h>
#include <stdint.h>
#include <errno.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/fs/fs.h>
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
#include <nuttx/wireless/ieee802154/mrf24j40.h>
#include "sam_gpio.h"
#include "sam_spi.h"
#include "same70-xplained.h"
#ifdef HAVE_MRF24J40
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#undef BEE_RESET
/****************************************************************************
* Private Types
****************************************************************************/
struct sam_priv_s
{
struct mrf24j40_lower_s dev;
uint32_t intcfg;
#ifdef BEE_RESET
uint32_t rstcfg;
#endif
uint8_t irq;
uint8_t spidev;
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/* IRQ/GPIO access callbacks. These operations all hidden behind callbacks
* to isolate the MRF24J40 driver from differences in GPIO interrupt handling
* varying boards and MCUs.
*
* irq_attach - Attach the MRF24J40 interrupt handler to the GPIO
interrupt
* irq_enable - Enable or disable the GPIO interrupt
*/
static int sam_attach_irq(FAR const struct mrf24j40_lower_s *lower,
xcpt_t handler, FAR void *arg);
static void sam_enable_irq(FAR const struct mrf24j40_lower_s *lower,
bool state);
static int sam_mrf24j40_devsetup(FAR struct sam_priv_s *priv);
/****************************************************************************
* Private Data
****************************************************************************/
/* A reference to a structure of this type must be passed to the MRF24J40
* driver. This structure provides information about the configuration
* of the MRF24J40 and provides some board-specific hooks.
*
* Memory for this structure is provided by the caller. It is not copied
* by the driver and is presumed to persist while the driver is active. The
* memory must be writable because, under certain circumstances, the driver
* may modify frequency or X plate resistance values.
*/
#ifdef CONFIG_SAME70XPLAINED_MB1_BEE
static struct sam_priv_s g_mrf24j40_mb1_priv =
{
.dev.attach = sam_attach_irq,
.dev.enable = sam_enable_irq,
.intcfg = CLICK_MB1_INTR,
#ifdef BEE_RESET
.rstcfg = CLICK_MB1_RESET,
#endif
.irq = IRQ_MB1,
.spidev = 0,
};
#endif
#ifdef CONFIG_SAME70XPLAINED_MB2_BEE
static struct sam_priv_s g_mrf24j40_mb2_priv =
{
.dev.attach = sam_attach_irq,
.dev.enable = sam_enable_irq,
.intcfg = CLICK_MB2_INTR,
#ifdef BEE_RESET
.rstcfg = CLICK_MB2_RESET,
#endif
.irq = IRQ_MB2,
.spidev = 0,
};
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/* IRQ/GPIO access callbacks. These operations all hidden behind
* callbacks to isolate the MRF24J40 driver from differences in GPIO
* interrupt handling by varying boards and MCUs. If possible,
* interrupts should be configured on both rising and falling edges
* so that contact and loss-of-contact events can be detected.
*
* irq_attach - Attach the MRF24J40 interrupt handler to the GPIO
* interrupt
* irq_enable - Enable or disable the GPIO interrupt
*/
static int sam_attach_irq(FAR const struct mrf24j40_lower_s *lower,
xcpt_t handler, FAR void *arg)
{
FAR struct sam_priv_s *priv = (FAR struct sam_priv_s *)lower;
int ret;
DEBUGASSERT(priv != NULL);
ret = irq_attach(priv->irq, handler, arg);
if (ret < 0)
{
wlerr("ERROR: Failed to attach WM8904 interrupt: %d\n", ret);
}
return ret;
}
static void sam_enable_irq(FAR const struct mrf24j40_lower_s *lower,
bool state)
{
FAR struct sam_priv_s *priv = (FAR struct sam_priv_s *)lower;
static bool enabled;
irqstate_t flags;
/* The caller should not attempt to enable interrupts if the handler
* has not yet been 'attached'
*/
DEBUGASSERT(priv != NULL);
wlinfo("state: %d irq: %u\n", (int)state, priv->irq);
/* Has the interrupt state changed */
flags = enter_critical_section();
if (state != enabled)
{
/* Enable or disable interrupts */
if (state)
{
wlinfo("Enabling\n");
sam_gpioirqenable(priv->irq);
enabled = true;
}
else
{
wlinfo("Disabling\n");
sam_gpioirqdisable(priv->irq);
enabled = false;
}
}
leave_critical_section(flags);
}
/****************************************************************************
* Name: sam_mrf24j40_devsetup
*
* Description:
* Initialize one the MRF24J40 device in one mikroBUS slot
*
* Returned Value:
* Zero is returned on success. Otherwise, a negated errno value is
* returned to indicate the nature of the failure.
*
****************************************************************************/
static int sam_mrf24j40_devsetup(FAR struct sam_priv_s *priv)
{
FAR struct ieee802154_radio_s *radio;
MACHANDLE mac;
FAR struct spi_dev_s *spi;
int ret;
#ifdef BEE_RESET
/* Bring the MRF24J40 out of reset
* NOTE: Not necessary. The RST# input is pulled high on the BEE.
*/
(void)sam_configgpio(priv->rstcfg);
sam_gpiowrite(priv->rstcfg, true);
#endif
/* Configure the interrupt pin */
(void)sam_configgpio(priv->intcfg);
sam_gpioirq(priv->intcfg);
/* Initialize the SPI bus and get an instance of the SPI interface */
spi = sam_spibus_initialize(priv->spidev);
if (spi == NULL)
{
wlerr("ERROR: Failed to initialize SPI bus %d\n", priv->spidev);
return -ENODEV;
}
/* Initialize and register the SPI MRF24J40 device */
radio = mrf24j40_init(spi, &priv->dev);
if (radio == NULL)
{
wlerr("ERROR: Failed to initialize SPI bus %d\n", priv->spidev);
return -ENODEV;
}
/* Create a 802.15.4 MAC device from a 802.15.4 compatible radio device. */
mac = mac802154_create(radio);
if (mac == NULL)
{
wlerr("ERROR: Failed to initialize IEEE802.15.4 MAC\n");
return -ENODEV;
}
#ifdef CONFIG_IEEE802154_NETDEV
/* Use the IEEE802.15.4 MAC interface instance to create a 6LoWPAN
* network interface by wrapping the MAC intrface instance in a
* network device driver via mac802154dev_register().
*/
ret = mac802154netdev_register(mac);
if (ret < 0)
{
wlerr("ERROR: Failed to register the MAC network driver wpan%d: %d\n",
0, ret);
return ret;
}
#endif
#ifdef CONFIG_IEEE802154_MACDEV
/* If want to call these APIs from userspace, you have to wrap the MAC
* interface in a character device viamac802154dev_register().
*/
ret = mac802154dev_register(mac, 0);
if (ret < 0)
{
wlerr("ERROR: Failed to register the MAC character driver /dev/ieee%d: %d\n",
0, ret);
return ret;
}
#endif
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: sam_mrf24j40_initialize
*
* Description:
* Initialize the MRF24J40 device.
*
* Returned Value:
* Zero is returned on success. Otherwise, a negated errno value is
* returned to indicate the nature of the failure.
*
****************************************************************************/
int sam_mrf24j40_initialize(void)
{
int ret;
#ifdef CONFIG_SAME70XPLAINED_MB1_BEE
wlinfo("Configuring BEE in mikroBUS1\n");
ret = sam_mrf24j40_devsetup(&g_mrf24j40_mb1_priv);
if (ret < 0)
{
wlerr("ERROR: Failed to initialize BD in mikroBUS1: %d\n", ret);
}
#endif
#ifdef CONFIG_SAME70XPLAINED_MB2_BEE
wlinfo("Configuring BEE in mikroBUS2\n");
ret = sam_mrf24j40_devsetup(&g_mrf24j40_mb2_priv);
if (ret < 0)
{
wlerr("ERROR: Failed to initialize BD in mikroBUS2: %d\n", ret);
}
#endif
UNUSED(ret);
return OK;
}
#endif /* HAVE_MRF24J40 */

View file

@ -70,6 +70,18 @@
void sam_spidev_initialize(void)
{
#ifdef CONFIG_SAMV7_SPI0_MASTER
#ifdef CONFIG_SAME70XPLAINED_MB1_SPI
/* Enable chip select for mikroBUS1 */
(void)sam_configgpio(CLICK_MB1_CS);
#endif
#ifdef CONFIG_SAME70XPLAINED_MB2_SPI
/* Enable chip select for mikroBUS2 */
(void)sam_configgpio(CLICK_MB2_CS);
#endif
#endif
#ifdef CONFIG_SAMV7_SPI0_SLAVE
@ -143,12 +155,32 @@ void sam_spidev_initialize(void)
#ifdef CONFIG_SAMV7_SPI0_MASTER
void sam_spi0select(uint32_t devid, bool selected)
{
spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert");
switch (devid)
{
#ifdef CONFIG_IEEE802154_MRF24J40
case SPIDEV_IEEE802154(0):
/* Set the GPIO low to select and high to de-select */
#if defined(CONFIG_SAME70XPLAINED_MB1_BEE)
sam_gpiowrite(CLICK_MB1_CS, !selected);
#elif defined(CONFIG_SAME70XPLAINED_MB2_BEE)
sam_gpiowrite(CLICK_MB2_CS, !selected);
#endif
break;
#endif
default:
break;
}
}
#endif
#ifdef CONFIG_SAMV7_SPI1_MASTER
void sam_spi1select(uint32_t devid, bool selected)
{
spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert");
}
#endif

View file

@ -1,7 +1,7 @@
/************************************************************************************
* configs/same70-xplained/src/same70-xplained.h
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2015, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -63,6 +63,7 @@
#define HAVE_MTDCONFIG 1
#define HAVE_PROGMEM_CHARDEV 1
#define HAVE_I2CTOOL 1
#define HAVE_MRF24J40 1
/* HSMCI */
/* Can't support MMC/SD if the card interface is not enabled */
@ -207,6 +208,28 @@
# endif
#endif
/* Check if the MRF24J40 is supported in this configuration */
#ifndef CONFIG_IEEE802154_MRF24J40
# undef HAVE_MRF24J40
#endif
#ifndef CONFIG_SAME70XPLAINED_CLICKSHIELD
# undef HAVE_MRF24J40
#endif
#if !defined(CONFIG_SAME70XPLAINED_MB1_BEE) && !defined(CONFIG_SAME70XPLAINED_MB2_BEE)
# undef HAVE_MRF24J40
#endif
#ifndef CONFIG_SAMV7_SPI0_MASTER
# undef HAVE_MRF24J40
#endif
#ifndef CONFIG_SAMV7_GPIOA_IRQ
# undef HAVE_MRF24J40
#endif
/* SAME70-XPLD GPIO Pin Definitions *************************************************/
/* Ethernet MAC.
@ -299,6 +322,59 @@
#define GPIO_VBUSON (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_SET | \
GPIO_PORT_PIOC | GPIO_PIN16)
/* Click Shield
*
* --- ----- ------------------------------ ---------------------------------
* PIN PORT SHIELD FUNCTION PIN CONFIGURATION
* --- ----- ------------------------------ ---------------------------------
* AD0 PD26 microBUS2 Analog TD PD26 *** Not an AFE pin ***
* AD1 PC31 microBUS2 Analog PC31 AFE1_AD6 GPIO_AFE1_AD6
* AD2 PD30 microBUS2 GPIO reset output PD30
* AD3 PA19 microBUS1 GPIO reset output PA19
* AD4 PC13 (both) I2C-SDA PC13 *** Does not support I2C SDA ***
* AD5 PC30 (both) I2C-SCL PC30 *** Does not support I2C SCL ***
* AD6 PA17 *** Not used ***
* AD7 PC12 *** Not used ***
* D0 PD28 (both) HDR_RX PD28 URXD3 GPIO_UART3_RXD
* D1 PD30 (both) HDR_TX PD30 UTXD3 GPIO_UART3_TXD_1
* D2 PA5 microBUS1 GPIO interrupt input PA5
* D3 PA6 microBUS2 GPIO interrupt input PA6
* D4 PD27 *** Not used ***
* D5 PD11 microBUS2 PWMB PD11 PWMC0_H0
* D6 PC19 microBUS1 PWMA PC19 PWMC0_H2
* D7 PA2 *** Not used ***
* D8 PA17 *** Not used ***
* D9 PC9 microBUS2 CS GPIO output PC9
* D10 PD25 microBUS1 CS GPIO output PD25 SPI0_NPCS1
* D11 PD21 (both) SPI-MOSI PD21 SPI0_MOSI GPIO_SPI0_MOSI
* D12 PD20 (both) SPI-MISO PD20 SPI0_MISO GPIO_SPI0_MISO
* D13 PD22 (both) SPI-SCK PD22 SPI0_SPCK GPIO_SPI0_SPCK
*/
/* Reset (RST#) Pulled-up on the click board */
#define CLICK_MB1_RESET (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_CLEAR | \
GPIO_PORT_PIOA | GPIO_PIN19)
#define CLICK_MB2_RESET (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_CLEAR | \
GPIO_PORT_PIOD | GPIO_PIN30)
/* Interrupts. No pull-ups on the BEE; assumig active low. */
#define CLICK_MB1_INTR (GPIO_INPUT | GPIO_CFG_PULLUP | GPIO_CFG_DEGLITCH | \
GPIO_INT_FALLING | GPIO_PORT_PIOA | GPIO_PIN5)
#define CLICK_MB2_INTR (GPIO_INPUT | GPIO_CFG_PULLUP | GPIO_CFG_DEGLITCH | \
GPIO_INT_FALLING | GPIO_PORT_PIOA | GPIO_PIN6)
#define IRQ_MB1 SAM_IRQ_PA5
#define IRQ_MB2 SAM_IRQ_PA6
/* SP chip selects */
#define CLICK_MB1_CS (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_SET | \
GPIO_PORT_PIOD | GPIO_PIN25)
#define CLICK_MB2_CS (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_SET | \
GPIO_PORT_PIOC | GPIO_PIN9)
/************************************************************************************
* Public Types
************************************************************************************/
@ -536,5 +612,21 @@ bool sam_writeprotected(int slotno);
int sam_at24config(void);
#endif
/****************************************************************************
* Name: stm32_mrf24j40_initialize
*
* Description:
* Initialize the MRF24J40 device.
*
* Returned Value:
* Zero is returned on success. Otherwise, a negated errno value is
* returned to indicate the nature of the failure.
*
****************************************************************************/
#ifdef HAVE_MRF24J40
int sam_mrf24j40_initialize(void);
#endif
#endif /* __ASSEMBLY__ */
#endif /* __CONFIGS_SAME70_XPLAINED_SRC_SAME70_XPLAINED_H */

View file

@ -9,6 +9,37 @@ config SAMV71XULT_MXTXPLND
bool "MaXTouch Xplained connected"
default n
config SAMV71XULT_CLICKSHIELD
bool "Mikroe Click Shield"
default n
---help---
In the mrf24j40-starhub configuration, a click shield from
MikroElectronika was used along with a Click "Bee" module. The
click shield supports two click shields.
config SAMV71XULT_MB1_SPI
bool
default n
config SAMV71XULT_MB2_SPI
bool
default n
choice
prompt "Bee mikroBUS"
depends on SAMV71XULT_CLICKSHIELD && IEEE802154_MRF24J40
default SAMV71XULT_MB1_BEE
config SAMV71XULT_MB1_BEE
bool "MRF24J40 Bee in mikroBUS1"
select SAMV71XULT_MB1_SPI
config SAMV71XULT_MB2_BEE
bool "MRF24J40 Bee in mikroBUS2"
select SAMV71XULT_MB2_SPI
endchoice # Bee mikroBUS
if SAMV71XULT_MXTXPLND
choice

View file

@ -25,6 +25,7 @@ Contents
- maXTouch Xplained Pro
- MCAN1 Loopback Test
- SPI Slave
- Click Shield
- Tickless OS
- Debugging
- Configurations
@ -1437,6 +1438,64 @@ SPI Slave
b) It will hog all of the CPU for the duration of the transfer).
Click Shield
============
In the mrf24j40-starhub configuration, a click shield from
MikroElectronika was used along with a Click "Bee" module. The click
shield supports two click shields and the following tables describe the
relationship between the pins on each click shield, the Arduino
connector and the SAMV71 pins.
--------- ---------------------- -------- --------- ------------------ ----------
mikroBUS1 Arduino SAMV71 mikroBUS2 Arduino SAMV71
--------- ---------------------- -------- --------- ------------------ ----------
AN HD1 A0 AN0 Pin 1 AD0 PD26 AN HD1 A1 AN1 Pin 2 AD1 PC31
RST HD1 A3 Pin 4 AD3 PA19 RST HD1 A2 Pin 3 AD2 PD30
CS HD4 D10 SPI-SS Pin 8 D10 PD25 CS HD4 D9 Pin 9 D9 PC9
SCK HD4 D13 SPI-SCK Pin 5 D13 PD22 SCK Same
MISO HD4 D12 SPI-MISO Pin 6 D12 PD20 MISO Same
MOSI HD4 D11 SPI-MOSI Pin 7 D11 PD21 MOSI Same
3.3V N/A 3.3V N/A
GND N/A GND N/A
PWM HD3 D6 PWMA Pin 2 D6 PC19 PWM HD3 D5 PWMB Pin 5 D5 PD11
INT HD3 D2 INT0 Pin 6 D2 PA5 INT HD3 D3 INT1 Pin 5 D3 PA6
RX HD3 D0 HDR-RX* Pin 8 D0 PD28 RX Same
TX HD3 D1 HDR-TX* Pin 7 D1 PD30 TX Same
SCL HD1 A5 I2C-SCL Pin 5 AD5 PC30 SDA Same
SDA HD1 A4 I2C-SDA Pin 6 AD4 PC13 SCL Same
5V N/A 5V N/A
GND N/A GND N/A
--------- ---------------------- -------- --------- ------------------ ----------
* Depends upon setting of SW1, UART vs PROG.
--- ----- ------------------------------ ---------------------------------
PIN PORT SHIELD FUNCTION SAMV71PIN CONFIGURATION
--- ----- ------------------------------ ---------------------------------
AD0 PD26 microBUS2 Analog TD PD26 *** Not an AFE pin ***
AD1 PC31 microBUS2 Analog PC31 AFE1_AD6 GPIO_AFE1_AD6
AD2 PD30 microBUS2 GPIO reset output PD30
AD3 PA19 microBUS1 GPIO reset output PA19
AD4 PC13 (both) I2C-SDA PC13 *** Does not support I2C SDA ***
AD5 PC30 (both) I2C-SCL PC30 *** Does not support I2C SCL ***
AD6 PA17 *** Not used ***
AD7 PC12 *** Not used ***
D0 PD28 (both) HDR_RX PD28 URXD3 GPIO_UART3_RXD
D1 PD30 (both) HDR_TX PD30 UTXD3 GPIO_UART3_TXD_1
D2 PA5 microBUS1 GPIO interrupt input PA5
D3 PA6 microBUS2 GPIO interrupt input PA6
D4 PD27 *** Not used ***
D5 PD11 microBUS2 PWMB PD11 PWMC0_H0
D6 PC19 microBUS1 PWMA PC19 PWMC0_H2
D7 PA2 *** Not used ***
D8 PA17 *** Not used ***
D9 PC9 microBUS2 CS GPIO output PC9
D10 PD25 microBUS1 CS GPIO output PD25 SPI0_NPCS1
D11 PD21 (both) SPI-MOSI PD21 SPI0_MOSI GPIO_SPI0_MOSI
D12 PD20 (both) SPI-MISO PD20 SPI0_MISO GPIO_SPI0_MISO
D13 PD22 (both) SPI-SCK PD22 SPI0_SPCK GPIO_SPI0_SPCK
Tickless OS
===========
@ -1573,10 +1632,17 @@ Debugging
orientation of the JTAG connection.
I have been using Atmel Studio to write code to flash then I use the Segger
J-Link GDB server to debug. I have been using the 'Device Programming' I
J-Link GDB server to debug. I have been using the 'Device Programming'
available under the Atmel Studio 'Tool' menu. I have to disconnect the
SAM-ICE while programming with the EDBG. I am sure that you could come up
with a GDB server-only solution if you wanted.
SAM-ICE while programming with the EDBG.
You can also load code into flash directory with J-Link:
arm-none-eabi-gdb
(gdb) target remote localhost:2331
(gdb) mon reset
(gdb) mon halt
(gdb) load nuttx
I run GDB like this from the directory containing the NuttX ELF file:
@ -1791,6 +1857,98 @@ Configuration sub-directories
STATUS:
2017-01-30: Does not yet run correctly.
mrf24j40-starhub
This configuration implement a hub node in a 6LoWPAN start network.
It is intended for the us the mrf24j40-starpoint configuration with
the clicker2-stm32 configurations. Essentially, the SAMV71-XULT
plays the roll of the hub in the configuration and the clicker2-stm32
boards are the endpoints in the start.
NOTES:
1. The serial console is configured by default for use with and Arduino
serial shield (UART3). You will need to reconfigure if you will
to use a different U[S]ART.
2. This configuration derives from the netnsh configuration, but adds
support for IPv6, 6LoWPAN, and the MRF24J40 IEEE 802.15.4 radio.
3. This configuration uses the Mikroe BEE MRF24j40 click boards and
connects to the SAMV71-XULT using a click shield as described above.
4. You must must have also have at least two clicker2-stm32 boards each
with an MRF24J40 BEE click board in order to run these tests.
5. The network initialization thread is NOT enabled. As a result, the
startup will hang if the Ethernet cable is not plugged in. For more
information, see the paragraphs above entitled "Network Initialization
Thread" and "Network Monitor".
6. This configuration supports logging of debug output to a circular
buffer in RAM. This feature is discussed fully in this Wiki page:
http://nuttx.org/doku.php?id=wiki:howtos:syslog . Relevant
configuration settings are summarized below:
Device Drivers:
CONFIG_RAMLOG=y : Enable the RAM-based logging feature.
CONFIG_RAMLOG_CONSOLE=n : (We don't use the RAMLOG console)
CONFIG_RAMLOG_SYSLOG=y : This enables the RAM-based logger as the
system logger.
CONFIG_RAMLOG_NONBLOCKING=y : Needs to be non-blocking for dmesg
CONFIG_RAMLOG_BUFSIZE=8192 : Buffer size is 8KiB
NOTE: This RAMLOG feature is really only of value if debug output
is enabled. But, by default, no debug output is disabled in this
configuration. Therefore, there is no logic that will add anything
to the RAM buffer. This feature is configured and in place only
to support any future debugging needs that you may have.
If you don't plan on using the debug features, then by all means
disable this feature and save 8KiB of RAM!
NOTE: There is an issue with capturing data in the RAMLOG: If
the system crashes, all of the crash dump information will go into
the RAMLOG and you will be unable to access it! You can tell that
the system has crashed because (a) it will be unresponsive and (b)
the LD2 will be blinking at about 2Hz.
You can also reconfigure to use stdout for debug output be disabling
all of the CONFIG_RAMLOG* settings listed above and enabling the
following in the .config file:
CONFIG_SYSLOG_CONSOLE=y
CONFIG_SYSLOG_SERIAL_CONSOLE=y
7. Telnet: The clicker2-stm32 star point configuration supports the
Telnet daemon, but not the Telnet client; the star hub configuration
supports the Telnet client, but not the Telnet daemon. Therefore,
the star hub can Telnet to any point in the star, the star endpoints
cannot initiate telnet sessions.
8. TCP and UDP Tests: The same TCP and UDP tests as described for
the clicker2-stm32 mrf24j40-starpoint configuration are supported on
the star endpoints, but NOT on the star hub. Therefore, all network
testing is between endpoints with the hub acting, well, only like a
hub.
The nsh> dmesg command can be use at any time on any node to see
any debug output that you have selected.
Telenet sessions may be initiated only from the hub to a star
endpoint:
C: nsh> telnet <server-ip> <-- Runs the Telnet client
Where <server-ip> is the IP address of either the E1 or I2 endpoints.
STATUS:
2017-07-02: Configurations added. Not yet tested.
2017-07-03: Initial testing, appears to be working, but endpoints
fail to associate; sniffer shows that nothing sent fro the star
hub. I am thinking that there is something wrong with the
GPIO interrupt configuration so that no MRF24J40 interrupt are
being received.
mxtxplnd:
Configures the NuttShell (nsh) located at examples/nsh. There are five

View file

@ -300,7 +300,6 @@
#define GPIO_UART3_TXD GPIO_UART3_TXD_1
/* - Arduino Communications. Additional UART/USART connections are available
* on the Arduino Communications connection J505:
*

View file

@ -0,0 +1,128 @@
############################################################################
# configs/samv71-xult/mrf24j40-starhub/Make.defs
#
# Copyright (C) 2017 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# 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.
#
############################################################################
include ${TOPDIR}/.config
include ${TOPDIR}/tools/Config.mk
include ${TOPDIR}/arch/arm/src/armv7-m/Toolchain.defs
ifeq ($(CONFIG_ARMV7M_DTCM),y)
LDSCRIPT = flash-dtcm.ld
else
LDSCRIPT = flash-sram.ld
endif
ifeq ($(WINTOOL),y)
# Windows-native toolchains
DIRLINK = $(TOPDIR)/tools/copydir.sh
DIRUNLINK = $(TOPDIR)/tools/unlink.sh
MKDEP = $(TOPDIR)/tools/mkwindeps.sh
ARCHINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}"
ARCHXXINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" -isystem "${shell cygpath -w $(TOPDIR)/include/cxx}"
ARCHSCRIPT = -T "${shell cygpath -w $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)}"
else
# Linux/Cygwin-native toolchain
MKDEP = $(TOPDIR)/tools/mkdeps$(HOSTEXEEXT)
ARCHINCLUDES = -I. -isystem $(TOPDIR)/include
ARCHXXINCLUDES = -I. -isystem $(TOPDIR)/include -isystem $(TOPDIR)/include/cxx
ARCHSCRIPT = -T$(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)
endif
CC = $(CROSSDEV)gcc
CXX = $(CROSSDEV)g++
CPP = $(CROSSDEV)gcc -E
LD = $(CROSSDEV)ld
AR = $(CROSSDEV)ar rcs
NM = $(CROSSDEV)nm
OBJCOPY = $(CROSSDEV)objcopy
OBJDUMP = $(CROSSDEV)objdump
ARCHCCVERSION = ${shell $(CC) -v 2>&1 | sed -n '/^gcc version/p' | sed -e 's/^gcc version \([0-9\.]\)/\1/g' -e 's/[-\ ].*//g' -e '1q'}
ARCHCCMAJOR = ${shell echo $(ARCHCCVERSION) | cut -d'.' -f1}
ifeq ($(CONFIG_DEBUG_SYMBOLS),y)
ARCHOPTIMIZATION = -g
endif
ifneq ($(CONFIG_DEBUG_NOOPT),y)
ARCHOPTIMIZATION += $(MAXOPTIMIZATION)
endif
ARCHCFLAGS = -fno-builtin
ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fcheck-new -fno-rtti
ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef -fno-strict-aliasing
ARCHWARNINGSXX = -Wall -Wshadow -Wundef
ARCHDEFINES =
ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10
CFLAGS = $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS)
CXXFLAGS = $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
CPPFLAGS = $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES)
AFLAGS = $(CFLAGS) -D__ASSEMBLY__
NXFLATLDFLAGS1 = -r -d -warn-common
NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -no-check-sections
LDNXFLATFLAGS = -e main -s 2048
# Loadable module definitions
CMODULEFLAGS = $(CFLAGS) -mlong-calls # --target1-abs
LDMODULEFLAGS = -r -e module_initialize
ifeq ($(WINTOOL),y)
LDMODULEFLAGS += -T "${shell cygpath -w $(TOPDIR)/libc/modlib/gnu-elf.ld}"
else
LDMODULEFLAGS += -T $(TOPDIR)/libc/modlib/gnu-elf.ld
endif
ASMEXT = .S
OBJEXT = .o
LIBEXT = .a
EXEEXT =
ifneq ($(CROSSDEV),arm-nuttx-elf-)
LDFLAGS += -nostartfiles -nodefaultlibs
endif
ifeq ($(CONFIG_DEBUG_SYMBOLS),y)
LDFLAGS += -g
endif
HOSTCC = gcc
HOSTINCLUDES = -I.
HOSTCFLAGS = -Wall -Wstrict-prototypes -Wshadow -Wundef -g -pipe
HOSTLDFLAGS =

View file

@ -0,0 +1,377 @@
CONFIG_ARCH_ARM=y
CONFIG_ARCH_BOARD_SAME70_XPLAINED=y
CONFIG_ARCH_BOARD="same70-xplained"
CONFIG_ARCH_BUTTONS=y
CONFIG_ARCH_CHIP_SAME70=y
CONFIG_ARCH_CHIP_SAME70Q=y
CONFIG_ARCH_CHIP_SAME70Q21=y
CONFIG_ARCH_CHIP_SAMV7=y
CONFIG_ARCH_CHIP="samv7"
CONFIG_ARCH_CORTEXM7=y
CONFIG_ARCH_DMA=y
CONFIG_ARCH_DPFPU=y
CONFIG_ARCH_FAMILY="armv7-m"
CONFIG_ARCH_FPU=y
CONFIG_ARCH_HAVE_BUTTONS=y
CONFIG_ARCH_HAVE_CMNVECTOR=y
CONFIG_ARCH_HAVE_CUSTOMOPT=y
CONFIG_ARCH_HAVE_DPFPU=y
CONFIG_ARCH_HAVE_FPU=y
CONFIG_ARCH_HAVE_HEAPCHECK=y
CONFIG_ARCH_HAVE_HIPRI_INTERRUPT=y
CONFIG_ARCH_HAVE_I2CRESET=y
CONFIG_ARCH_HAVE_INTERRUPTSTACK=y
CONFIG_ARCH_HAVE_IRQBUTTONS=y
CONFIG_ARCH_HAVE_IRQPRIO=y
CONFIG_ARCH_HAVE_LEDS=y
CONFIG_ARCH_HAVE_MPU=y
CONFIG_ARCH_HAVE_NET=y
CONFIG_ARCH_HAVE_NETDEV_STATISTICS=y
CONFIG_ARCH_HAVE_PHY=y
CONFIG_ARCH_HAVE_RAMFUNCS=y
CONFIG_ARCH_HAVE_RAMVECTORS=y
CONFIG_ARCH_HAVE_RESET=y
CONFIG_ARCH_HAVE_SDIO=y
CONFIG_ARCH_HAVE_SERIAL_TERMIOS=y
CONFIG_ARCH_HAVE_SPI_BITORDER=y
CONFIG_ARCH_HAVE_SPI_CS_CONTROL=y
CONFIG_ARCH_HAVE_STACKCHECK=y
CONFIG_ARCH_HAVE_TICKLESS=y
CONFIG_ARCH_HAVE_TIMEKEEPING=y
CONFIG_ARCH_HAVE_TLS=y
CONFIG_ARCH_HAVE_VFORK=y
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_IRQBUTTONS=y
CONFIG_ARCH_LEDS=y
CONFIG_ARCH_LOWPUTC=y
CONFIG_ARCH_PHY_INTERRUPT=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_ARCH_TOOLCHAIN_GNU=y
CONFIG_ARCH="arm"
CONFIG_ARM_HAVE_MPU_UNIFIED=y
CONFIG_ARMV7M_CMNVECTOR=y
CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y
CONFIG_ARMV7M_DCACHE=y
CONFIG_ARMV7M_HAVE_DCACHE=y
CONFIG_ARMV7M_HAVE_DTCM=y
CONFIG_ARMV7M_HAVE_ICACHE=y
CONFIG_ARMV7M_HAVE_ITCM=y
CONFIG_ARMV7M_HAVE_STACKCHECK=y
CONFIG_ARMV7M_ICACHE=y
CONFIG_ARMV7M_LAZYFPU=y
CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIW=y
CONFIG_AT24XX_ADDR=0x57
CONFIG_AT24XX_EXTENDED=y
CONFIG_AT24XX_EXTSIZE=160
CONFIG_AT24XX_FREQUENCY=100000
CONFIG_AT24XX_SIZE=2
CONFIG_AT25_SPIFREQUENCY=20000000
CONFIG_AT25_SPIMODE=0
CONFIG_BOARD_INITIALIZE=y
CONFIG_BOARD_LOOPSPERMSEC=51262
CONFIG_BOOT_RUNFROMFLASH=y
CONFIG_BUILD_FLAT=y
CONFIG_BUILTIN_PROXY_STACKSIZE=1024
CONFIG_BUILTIN=y
CONFIG_SAME70XPLND_CLICK_MB1_BEE=y
CONFIG_SAME70XPLND_CLICK_MB1_SPI=y
CONFIG_DEBUG_ALERT=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEV_CONSOLE=y
CONFIG_DEV_NULL=y
CONFIG_DISABLE_OS_API=y
CONFIG_DISABLE_POLL=y
CONFIG_DRIVERS_IEEE802154=y
CONFIG_DRIVERS_WIRELESS=y
CONFIG_EOL_IS_EITHER_CRLF=y
CONFIG_ETH0_PHY_KSZ8081=y
CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y
CONFIG_EXAMPLES_NSH=y
CONFIG_FAT_LCNAMES=y
CONFIG_FAT_LFN=y
CONFIG_FAT_MAXFNAME=32
CONFIG_FS_FAT=y
CONFIG_FS_MQUEUE_MPATH="/var/mqueue"
CONFIG_FS_PROCFS=y
CONFIG_FS_READABLE=y
CONFIG_FS_WRITABLE=y
CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_HOST_WINDOWS=y
CONFIG_IDLETHREAD_STACKSIZE=1024
CONFIG_IEEE802154_DEFAULT_EADDR=0x00fade00deadbeef
CONFIG_IEEE802154_I8SAK_PRIORITY=100
CONFIG_IEEE802154_I8SAK_STACKSIZE=2048
CONFIG_IEEE802154_I8SAK=y
CONFIG_IEEE802154_IND_IRQRESERVE=10
CONFIG_IEEE802154_IND_PREALLOC=32
CONFIG_IEEE802154_LIBMAC=y
CONFIG_IEEE802154_LIBUTILS=y
CONFIG_IEEE802154_MACDEV_RECVRPRIO=0
CONFIG_IEEE802154_MACDEV=y
CONFIG_IEEE802154_MRF24J40=y
CONFIG_IEEE802154_NETDEV_LPWORK=y
CONFIG_IEEE802154_NETDEV_RECVRPRIO=1
CONFIG_IEEE802154_NETDEV=y
CONFIG_INIT_ENTRYPOINT=y
CONFIG_INTELHEX_BINARY=y
CONFIG_IOB_BUFSIZE=128
CONFIG_IOB_NBUFFERS=32
CONFIG_IOB_NCHAINS=16
CONFIG_IOB_THROTTLE=8
CONFIG_LIB_BOARDCTL=y
CONFIG_LIB_HOMEDIR="/"
CONFIG_LIB_RAND_ORDER=1
CONFIG_LIB_SENDFILE_BUFSIZE=512
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_TMPFILE=32
CONFIG_LIBC_NETDB=y
CONFIG_LIBC_TMPDIR="/tmp"
CONFIG_MAC802154_HPWORK=y
CONFIG_MAC802154_NNOTIF=48
CONFIG_MAC802154_NPANDESC=5
CONFIG_MAC802154_NTXDESC=32
CONFIG_MAX_TASKS=16
CONFIG_MAX_WDOGPARMS=2
CONFIG_MCU_SERIAL=y
CONFIG_MM_IOB=y
CONFIG_MM_REGIONS=1
CONFIG_MMCSD_HAVECARDDETECT=y
CONFIG_MMCSD_MULTIBLOCK_DISABLE=y
CONFIG_MMCSD_NSLOTS=1
CONFIG_MMCSD_SDIO=y
CONFIG_MMCSD=y
CONFIG_MQ_MAXMSGSIZE=32
CONFIG_MTD_AT24XX=y
CONFIG_MTD_AT25=y
CONFIG_MTD_CONFIG_ERASEDVALUE=0xff
CONFIG_MTD_CONFIG=y
CONFIG_MTD=y
CONFIG_NAME_MAX=32
CONFIG_NET_6LOWPAN_COMPRESSION_HC06=y
CONFIG_NET_6LOWPAN_COMPRESSION_THRESHOLD=63
CONFIG_NET_6LOWPAN_FRAG=y
CONFIG_NET_6LOWPAN_FRAMELEN=127
CONFIG_NET_6LOWPAN_MAX_MACTRANSMITS=4
CONFIG_NET_6LOWPAN_MAXADDRCONTEXT_PREFIX_0_0=0xaa
CONFIG_NET_6LOWPAN_MAXADDRCONTEXT_PREFIX_0_1=0xaa
CONFIG_NET_6LOWPAN_MAXADDRCONTEXT=1
CONFIG_NET_6LOWPAN_MAXAGE=20
CONFIG_NET_6LOWPAN_MTU=1294
CONFIG_NET_6LOWPAN_TCP_RECVWNDO=1220
CONFIG_NET_6LOWPAN=y
CONFIG_NET_BROADCAST=y
CONFIG_NET_ETH_MTU=590
CONFIG_NET_ETH_TCP_RECVWNDO=536
CONFIG_NET_ETHERNET=y
CONFIG_NET_GUARDSIZE=2
CONFIG_NET_HAVE_STAR=y
CONFIG_NET_HOSTNAME="MRF24J40-Hub"
CONFIG_NET_IPFORWARD=y
# CONFIG_NET_IPv4 is not set
CONFIG_NET_IPv6_NCONF_ENTRIES=8
CONFIG_NET_IPv6=y
CONFIG_NET_MAX_LISTENPORTS=20
CONFIG_NET_NACTIVESOCKETS=16
CONFIG_NET_SOCKOPTS=y
CONFIG_NET_STAR=y
CONFIG_NET_STARHUB=y
CONFIG_NET_STATISTICS=y
CONFIG_NET_TCP_CONNS=8
CONFIG_NET_TCP_NWRBCHAINS=8
CONFIG_NET_TCP_READAHEAD=y
CONFIG_NET_TCP_RECVDELAY=0
CONFIG_NET_TCP_WRITE_BUFFERS=y
CONFIG_NET_TCP=y
CONFIG_NET_TCPBACKLOG=y
CONFIG_NET_UDP_CHECKSUMS=y
CONFIG_NET_UDP_CONNS=8
CONFIG_NET_UDP_READAHEAD=y
CONFIG_NET_UDP=y
CONFIG_NET=y
CONFIG_NETDB_DNSCLIENT_ENTRIES=8
CONFIG_NETDB_DNSCLIENT_LIFESEC=3600
CONFIG_NETDB_DNSCLIENT_MAXRESPONSE=96
CONFIG_NETDB_DNSCLIENT_NAMESIZE=32
CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDB_DNSSERVER_NOADDR=y
CONFIG_NETDEV_IOCTL=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_PHY_IOCTL=y
CONFIG_NETDEV_STATISTICS=y
CONFIG_NETDEV_TELNET=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
CONFIG_NETDEVICES=y
CONFIG_NETUTILS_NETLIB=y
CONFIG_NETUTILS_TELNETC=y
CONFIG_NETUTILS_TELNETD=y
CONFIG_NETUTILS_TFTPC=y
CONFIG_NETUTILS_WEBCLIENT=y
CONFIG_NFILE_DESCRIPTORS=8
CONFIG_NFILE_STREAMS=8
CONFIG_NPTHREAD_KEYS=4
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_ARGCAT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_CMDOPT_HEXDUMP=y
CONFIG_NSH_CMDPARMS=y
CONFIG_NSH_CODECS_BUFSIZE=128
CONFIG_NSH_CONSOLE=y
CONFIG_NSH_DISABLE_DATE=y
CONFIG_NSH_DISABLE_GET=y
CONFIG_NSH_DISABLE_LOSMART=y
CONFIG_NSH_DISABLE_PRINTF=y
CONFIG_NSH_DISABLE_PUT=y
CONFIG_NSH_DISABLE_WGET=y
CONFIG_NSH_DRIPADDR=0x0a000001
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_IOBUFFER_SIZE=512
CONFIG_NSH_IPADDR=0x0a000002
CONFIG_NSH_LIBRARY=y
CONFIG_NSH_LINELEN=64
CONFIG_NSH_MACADDR=0x00fade00deadbeef
CONFIG_NSH_MAX_ROUNDTRIP=20
CONFIG_NSH_MAXARGUMENTS=6
CONFIG_NSH_MMCSDMINOR=0
CONFIG_NSH_MMCSDSLOTNO=0
CONFIG_NSH_NESTDEPTH=3
CONFIG_NSH_NETINIT_MONITOR=y
CONFIG_NSH_NETINIT_RETRYMSEC=2000
CONFIG_NSH_NETINIT_SIGNO=18
CONFIG_NSH_NETINIT_THREAD_PRIORITY=80
CONFIG_NSH_NETINIT_THREAD_STACKSIZE=1568
CONFIG_NSH_NETINIT_THREAD=y
CONFIG_NSH_NETINIT=y
CONFIG_NSH_NETLOCAL=y
CONFIG_NSH_NETMASK=0xffffff00
CONFIG_NSH_NOMAC=y
CONFIG_NSH_PROC_MOUNTPOINT="/proc"
CONFIG_NSH_READLINE=y
CONFIG_NSH_SWMAC=y
CONFIG_NSH_TELNET=y
CONFIG_NSH_TELNETD_CLIENTPRIO=100
CONFIG_NSH_TELNETD_CLIENTSTACKSIZE=2048
CONFIG_NSH_TELNETD_DAEMONPRIO=100
CONFIG_NSH_TELNETD_DAEMONSTACKSIZE=2048
CONFIG_NSH_TELNETD_PORT=23
CONFIG_NSH_WGET_USERAGENT="NuttX/6.xx.x (; http://www.nuttx.org/)"
CONFIG_NSOCKET_DESCRIPTORS=8
CONFIG_NUNGET_CHARS=2
CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=1024
CONFIG_PREALLOC_MQ_MSGS=4
CONFIG_PREALLOC_TIMERS=4
CONFIG_PREALLOC_WDOGS=32
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_DEFAULT=2048
CONFIG_PTHREAD_STACK_MIN=256
CONFIG_RAM_SIZE=393216
CONFIG_RAM_START=0x20400000
CONFIG_RAMLOG_BUFSIZE=8192
CONFIG_RAMLOG_NONBLOCKING=y
CONFIG_RAMLOG_NPOLLWAITERS=4
CONFIG_RAMLOG_SYSLOG=y
CONFIG_RAMLOG=y
CONFIG_RAW_BINARY=y
CONFIG_READLINE_ECHO=y
CONFIG_READLINE_HAVE_EXTMATCH=y
CONFIG_RR_INTERVAL=200
CONFIG_SAMV7_EMAC_HPWORK=y
CONFIG_SAMV7_EMAC=y
CONFIG_SAMV7_EMAC0_AUTONEG=y
CONFIG_SAMV7_EMAC0_ISETH0=y
CONFIG_SAMV7_EMAC0_NRXBUFFERS=16
CONFIG_SAMV7_EMAC0_NTXBUFFERS=8
CONFIG_SAMV7_EMAC0_PHYADDR=1
CONFIG_SAMV7_EMAC0_PHYSR_100FD=0x6
CONFIG_SAMV7_EMAC0_PHYSR_100HD=0x2
CONFIG_SAMV7_EMAC0_PHYSR_10FD=0x5
CONFIG_SAMV7_EMAC0_PHYSR_10HD=0x1
CONFIG_SAMV7_EMAC0_PHYSR_ALTCONFIG=y
CONFIG_SAMV7_EMAC0_PHYSR_ALTMODE=0x7
CONFIG_SAMV7_EMAC0_PHYSR=30
CONFIG_SAMV7_EMAC0_RMII=y
CONFIG_SAMV7_EMAC0=y
CONFIG_SAMV7_ERASE_ENABLE=y
CONFIG_SAMV7_GPIO_IRQ=y
CONFIG_SAMV7_GPIOA_IRQ=y
CONFIG_SAMV7_GPIOC_IRQ=y
CONFIG_SAMV7_HAVE_EBI=y
CONFIG_SAMV7_HAVE_HSMCI0=y
CONFIG_SAMV7_HAVE_MCAN1=y
CONFIG_SAMV7_HAVE_SDRAMC=y
CONFIG_SAMV7_HAVE_SPI0=y
CONFIG_SAMV7_HAVE_SPI1=y
CONFIG_SAMV7_HAVE_TWIHS2=y
CONFIG_SAMV7_HAVE_USART0=y
CONFIG_SAMV7_HAVE_USART1=y
CONFIG_SAMV7_HAVE_USART2=y
CONFIG_SAMV7_HAVE_USBHS=y
CONFIG_SAMV7_HSMCI_DMA=y
CONFIG_SAMV7_HSMCI=y
CONFIG_SAMV7_HSMCI0=y
CONFIG_SAMV7_JTAG_FULL_ENABLE=y
CONFIG_SAMV7_TWIHS0_FREQUENCY=100000
CONFIG_SAMV7_TWIHS0_GLITCH_FILTER=1
CONFIG_SAMV7_TWIHS0=y
# CONFIG_SAMV7_UART0 is not set
# CONFIG_SAMV7_UART1 is not set
# CONFIG_SAMV7_UART2 is not set
# CONFIG_SAMV7_UART3 is not set
# CONFIG_SAMV7_UART4 is not set
CONFIG_SAMV7_USART1=y
CONFIG_SAMV7_XDMAC=y
CONFIG_SCHED_HPWORK=y
CONFIG_SCHED_HPWORKPERIOD=50000
CONFIG_SCHED_HPWORKPRIORITY=224
CONFIG_SCHED_HPWORKSTACKSIZE=2048
CONFIG_SCHED_LPNTHREADS=1
CONFIG_SCHED_LPWORK=y
CONFIG_SCHED_LPWORKPERIOD=50000
CONFIG_SCHED_LPWORKPRIORITY=160
CONFIG_SCHED_LPWORKSTACKSIZE=2048
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_WORKQUEUE=y
CONFIG_SDCLONE_DISABLE=y
CONFIG_SDIO_BLOCKSETUP=y
CONFIG_SDIO_DMA=y
CONFIG_SERIAL_CONSOLE=y
CONFIG_SERIAL_NPOLLWAITERS=2
CONFIG_SERIAL=y
CONFIG_SIG_SIGALARM=3
CONFIG_SIG_SIGCONDTIMEDOUT=16
CONFIG_SIG_SIGUSR1=1
CONFIG_SIG_SIGUSR2=2
CONFIG_SIG_SIGWORK=17
CONFIG_SPI_EXCHANGE=y
CONFIG_SPI=y
CONFIG_STANDARD_SERIAL=y
CONFIG_START_DAY=1
CONFIG_START_MONTH=7
CONFIG_START_YEAR=2017
CONFIG_STDIO_BUFFER_SIZE=64
CONFIG_STDIO_LINEBUFFER=y
CONFIG_SYSTEM_READLINE=y
CONFIG_SYSTEM_TELNET_CLIENT=y
CONFIG_SYSTEM_TELNET_CLIENT_PRIORITY=100
CONFIG_SYSTEM_TELNET_CLIENT_STACKSIZE=2048
CONFIG_TASK_NAME_SIZE=31
CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048
CONFIG_TELNET_RXBUFFER_SIZE=256
CONFIG_TELNET_TXBUFFER_SIZE=256
CONFIG_TOOLCHAIN_WINDOWS=y
CONFIG_USART1_2STOP=0
CONFIG_USART1_BAUD=115200
CONFIG_USART1_BITS=8
CONFIG_USART1_PARITY=0
CONFIG_USART1_RXBUFSIZE=256
CONFIG_USART1_SERIAL_CONSOLE=y
CONFIG_USART1_SERIALDRIVER=y
CONFIG_USART1_TXBUFSIZE=256
CONFIG_USEC_PER_TICK=10000
CONFIG_USER_ENTRYPOINT="nsh_main"
CONFIG_USERMAIN_STACKSIZE=2048
CONFIG_WDOG_INTRESERVE=4
CONFIG_WEBCLIENT_TIMEOUT=10
CONFIG_WINDOWS_CYGWIN=y
CONFIG_WIRELESS_IEEE802154=y
CONFIG_WIRELESS=y

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
############################################################################
# configs/samv71-xult/src/Makefile
#
# Copyright (C) 2015-2016 Gregory Nutt. All rights reserved.
# Copyright (C) 2015-2017 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
@ -115,4 +115,8 @@ CSRCS += sam_maxtouch.c sam_atmxtconfig.c
endif
endif
ifeq ($(CONFIG_IEEE802154_MRF24J40),y)
CSRCS += sam_mrf24j40.c
endif
include $(TOPDIR)/configs/Board.mk

View file

@ -41,7 +41,7 @@
*
* ------ ----------- ---------------------
* SAMV71 Function Shared functionality
* PIO
* GPIO
* ------ ----------- ---------------------
* PA23 Yellow LED0 EDBG GPIO
* PC09 Yellow LED1 LCD, and Shield
@ -103,7 +103,7 @@
void board_autoled_initialize(void)
{
/* Configure LED PIOs for output */
/* Configure LED GPIOs for output */
sam_configgpio(GPIO_LED0);
sam_configgpio(GPIO_LED1);

View file

@ -529,10 +529,19 @@ int sam_bringup(void)
}
#endif
#ifdef HAVE_MRF24J40
/* Configure MRF24J40 wireless */
ret = sam_mrf24j40_initialize();
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: sam_mrf24j40_initialize() failed: %d\n", ret);
}
#endif
#ifdef HAVE_ELF
/* Initialize the ELF binary loader */
syslog(LOG_ERR, "Initializing the ELF binary loader\n");
ret = elf_initialize();
if (ret < 0)
{

View file

@ -146,7 +146,7 @@ void board_button_initialize(void)
regval |= MATRIX_CCFG_SYSIO_SYSIO12;
putreg32(regval, SAM_MATRIX_CCFG_SYSIO);
/* Configure button PIOs */
/* Configure button GPIOs */
(void)sam_configgpio(GPIO_SW0);
(void)sam_configgpio(GPIO_SW1);

View file

@ -84,8 +84,8 @@
struct sam_hsmci_state_s
{
struct sdio_dev_s *hsmci; /* R/W device handle */
gpio_pinset_t cdcfg; /* Card detect PIO pin configuration */
gpio_pinset_t pwrcfg; /* Power PIO pin configuration */
gpio_pinset_t cdcfg; /* Card detect GPIO pin configuration */
gpio_pinset_t pwrcfg; /* Power GPIO pin configuration */
uint8_t irq; /* Interrupt number (same as pid) */
uint8_t slotno; /* Slot number */
bool cd; /* TRUE: card is inserted */
@ -126,7 +126,7 @@ bool sam_cardinserted_internal(struct sam_hsmci_state_s *state)
{
bool inserted;
/* Get the state of the PIO pin */
/* Get the state of the GPIO pin */
inserted = sam_gpioread(state->cdcfg);
mcinfo("Slot %d inserted: %s\n", state->slotno, inserted ? "NO" : "YES");
@ -189,7 +189,7 @@ static int sam_hsmci0_cardetect(int irq, void *regs, FAR void *arg)
* Name: sam_hsmci_state
*
* Description:
* Initialize HSMCI PIOs.
* Initialize HSMCI GPIOs.
*
****************************************************************************/
@ -230,7 +230,7 @@ int sam_hsmci_initialize(int slotno, int minor)
return -EINVAL;
}
/* Initialize card-detect, write-protect, and power enable PIOs */
/* Initialize card-detect, write-protect, and power enable GPIOs */
sam_configgpio(state->cdcfg);
sam_dumpgpio(state->cdcfg, "HSMCI Card Detect");
@ -297,7 +297,7 @@ bool sam_cardinserted(int slotno)
return false;
}
/* Return the state of the PIO pin */
/* Return the state of the GPIO pin */
return sam_cardinserted_internal(state);
}

View file

@ -92,15 +92,15 @@ struct sama5d4ek_tscinfo_s
* Private Function Prototypes
****************************************************************************/
/* IRQ/PIO access callbacks. These operations all hidden behind
* callbacks to isolate the maXTouch driver from differences in PIO
/* IRQ/GPIO access callbacks. These operations all hidden behind
* callbacks to isolate the maXTouch driver from differences in GPIO
* interrupt handling by varying boards and MCUs. If possible,
* interrupts should be configured on both rising and falling edges
* so that contact and loss-of-contact events can be detected.
*
* attach - Attach the maXTouch interrupt handler to the PIO interrupt
* enable - Enable or disable the PIO interrupt
* clear - Acknowledge/clear any pending PIO interrupt
* attach - Attach the maXTouch interrupt handler to the GPIO interrupt
* enable - Enable or disable the GPIO interrupt
* clear - Acknowledge/clear any pending GPIO interrupt
*/
static int mxt_attach(FAR const struct mxt_lower_s *lower, mxt_handler_t isr,
@ -141,15 +141,15 @@ static struct sama5d4ek_tscinfo_s g_mxtinfo =
****************************************************************************/
/****************************************************************************
* IRQ/PIO access callbacks. These operations all hidden behind
* callbacks to isolate the maXTouch driver from differences in PIO
* IRQ/GPIO access callbacks. These operations all hidden behind
* callbacks to isolate the maXTouch driver from differences in GPIO
* interrupt handling by varying boards and MCUs. If possible,
* interrupts should be configured on both rising and falling edges
* so that contact and loss-of-contact events can be detected.
*
* attach - Attach the maXTouch interrupt handler to the PIO interrupt
* enable - Enable or disable the PIO interrupt
* clear - Acknowledge/clear any pending PIO interrupt
* attach - Attach the maXTouch interrupt handler to the GPIO interrupt
* enable - Enable or disable the GPIO interrupt
* clear - Acknowledge/clear any pending GPIO interrupt
*
****************************************************************************/

View file

@ -0,0 +1,347 @@
/****************************************************************************
* configs/samv71-xult/src/sam_mrf24j40.c
*
* Copyright (C) 2017 Gregory Nutt, All rights reserver
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 <nuttx/config.h>
#include <stdio.h>
#include <stdint.h>
#include <errno.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/fs/fs.h>
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
#include <nuttx/wireless/ieee802154/mrf24j40.h>
#include "sam_gpio.h"
#include "sam_spi.h"
#include "samv71-xult.h"
#ifdef HAVE_MRF24J40
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#undef BEE_RESET
/****************************************************************************
* Private Types
****************************************************************************/
struct sam_priv_s
{
struct mrf24j40_lower_s dev;
uint32_t intcfg;
#ifdef BEE_RESET
uint32_t rstcfg;
#endif
uint8_t irq;
uint8_t spidev;
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/* IRQ/GPIO access callbacks. These operations all hidden behind callbacks
* to isolate the MRF24J40 driver from differences in GPIO interrupt handling
* varying boards and MCUs.
*
* irq_attach - Attach the MRF24J40 interrupt handler to the GPIO
interrupt
* irq_enable - Enable or disable the GPIO interrupt
*/
static int sam_attach_irq(FAR const struct mrf24j40_lower_s *lower,
xcpt_t handler, FAR void *arg);
static void sam_enable_irq(FAR const struct mrf24j40_lower_s *lower,
bool state);
static int sam_mrf24j40_devsetup(FAR struct sam_priv_s *priv);
/****************************************************************************
* Private Data
****************************************************************************/
/* A reference to a structure of this type must be passed to the MRF24J40
* driver. This structure provides information about the configuration
* of the MRF24J40 and provides some board-specific hooks.
*
* Memory for this structure is provided by the caller. It is not copied
* by the driver and is presumed to persist while the driver is active. The
* memory must be writable because, under certain circumstances, the driver
* may modify frequency or X plate resistance values.
*/
#ifdef CONFIG_SAMV71XULT_MB1_BEE
static struct sam_priv_s g_mrf24j40_mb1_priv =
{
.dev.attach = sam_attach_irq,
.dev.enable = sam_enable_irq,
.intcfg = CLICK_MB1_INTR,
#ifdef BEE_RESET
.rstcfg = CLICK_MB1_RESET,
#endif
.irq = IRQ_MB1,
.spidev = 0,
};
#endif
#ifdef CONFIG_SAMV71XULT_MB2_BEE
static struct sam_priv_s g_mrf24j40_mb2_priv =
{
.dev.attach = sam_attach_irq,
.dev.enable = sam_enable_irq,
.intcfg = CLICK_MB2_INTR,
#ifdef BEE_RESET
.rstcfg = CLICK_MB2_RESET,
#endif
.irq = IRQ_MB2,
.spidev = 0,
};
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/* IRQ/GPIO access callbacks. These operations all hidden behind
* callbacks to isolate the MRF24J40 driver from differences in GPIO
* interrupt handling by varying boards and MCUs. If possible,
* interrupts should be configured on both rising and falling edges
* so that contact and loss-of-contact events can be detected.
*
* irq_attach - Attach the MRF24J40 interrupt handler to the GPIO
* interrupt
* irq_enable - Enable or disable the GPIO interrupt
*/
static int sam_attach_irq(FAR const struct mrf24j40_lower_s *lower,
xcpt_t handler, FAR void *arg)
{
FAR struct sam_priv_s *priv = (FAR struct sam_priv_s *)lower;
int ret;
DEBUGASSERT(priv != NULL);
ret = irq_attach(priv->irq, handler, arg);
if (ret < 0)
{
wlerr("ERROR: Failed to attach WM8904 interrupt: %d\n", ret);
}
return ret;
}
static void sam_enable_irq(FAR const struct mrf24j40_lower_s *lower,
bool state)
{
FAR struct sam_priv_s *priv = (FAR struct sam_priv_s *)lower;
static bool enabled;
irqstate_t flags;
/* The caller should not attempt to enable interrupts if the handler
* has not yet been 'attached'
*/
DEBUGASSERT(priv != NULL);
wlinfo("state: %d irq: %u\n", (int)state, priv->irq);
/* Has the interrupt state changed */
flags = enter_critical_section();
if (state != enabled)
{
/* Enable or disable interrupts */
if (state)
{
wlinfo("Enabling\n");
sam_gpioirqenable(priv->irq);
enabled = true;
}
else
{
wlinfo("Disabling\n");
sam_gpioirqdisable(priv->irq);
enabled = false;
}
}
leave_critical_section(flags);
}
/****************************************************************************
* Name: sam_mrf24j40_devsetup
*
* Description:
* Initialize one the MRF24J40 device in one mikroBUS slot
*
* Returned Value:
* Zero is returned on success. Otherwise, a negated errno value is
* returned to indicate the nature of the failure.
*
****************************************************************************/
static int sam_mrf24j40_devsetup(FAR struct sam_priv_s *priv)
{
FAR struct ieee802154_radio_s *radio;
MACHANDLE mac;
FAR struct spi_dev_s *spi;
int ret;
#ifdef BEE_RESET
/* Bring the MRF24J40 out of reset
* NOTE: Not necessary. The RST# input is pulled high on the BEE.
*/
(void)sam_configgpio(priv->rstcfg);
sam_gpiowrite(priv->rstcfg, true);
#endif
/* Configure the interrupt pin */
(void)sam_configgpio(priv->intcfg);
sam_gpioirq(priv->intcfg);
/* Initialize the SPI bus and get an instance of the SPI interface */
spi = sam_spibus_initialize(priv->spidev);
if (spi == NULL)
{
wlerr("ERROR: Failed to initialize SPI bus %d\n", priv->spidev);
return -ENODEV;
}
/* Initialize and register the SPI MRF24J40 device */
radio = mrf24j40_init(spi, &priv->dev);
if (radio == NULL)
{
wlerr("ERROR: Failed to initialize SPI bus %d\n", priv->spidev);
return -ENODEV;
}
/* Create a 802.15.4 MAC device from a 802.15.4 compatible radio device. */
mac = mac802154_create(radio);
if (mac == NULL)
{
wlerr("ERROR: Failed to initialize IEEE802.15.4 MAC\n");
return -ENODEV;
}
#ifdef CONFIG_IEEE802154_NETDEV
/* Use the IEEE802.15.4 MAC interface instance to create a 6LoWPAN
* network interface by wrapping the MAC intrface instance in a
* network device driver via mac802154dev_register().
*/
ret = mac802154netdev_register(mac);
if (ret < 0)
{
wlerr("ERROR: Failed to register the MAC network driver wpan%d: %d\n",
0, ret);
return ret;
}
#endif
#ifdef CONFIG_IEEE802154_MACDEV
/* If want to call these APIs from userspace, you have to wrap the MAC
* interface in a character device viamac802154dev_register().
*/
ret = mac802154dev_register(mac, 0);
if (ret < 0)
{
wlerr("ERROR: Failed to register the MAC character driver /dev/ieee%d: %d\n",
0, ret);
return ret;
}
#endif
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: sam_mrf24j40_initialize
*
* Description:
* Initialize the MRF24J40 device.
*
* Returned Value:
* Zero is returned on success. Otherwise, a negated errno value is
* returned to indicate the nature of the failure.
*
****************************************************************************/
int sam_mrf24j40_initialize(void)
{
int ret;
#ifdef CONFIG_SAMV71XULT_MB1_BEE
wlinfo("Configuring BEE in mikroBUS1\n");
ret = sam_mrf24j40_devsetup(&g_mrf24j40_mb1_priv);
if (ret < 0)
{
wlerr("ERROR: Failed to initialize BD in mikroBUS1: %d\n", ret);
}
#endif
#ifdef CONFIG_SAMV71XULT_MB2_BEE
wlinfo("Configuring BEE in mikroBUS2\n");
ret = sam_mrf24j40_devsetup(&g_mrf24j40_mb2_priv);
if (ret < 0)
{
wlerr("ERROR: Failed to initialize BD in mikroBUS2: %d\n", ret);
}
#endif
UNUSED(ret);
return OK;
}
#endif /* HAVE_MRF24J40 */

View file

@ -63,15 +63,27 @@
* Name: sam_spidev_initialize
*
* Description:
* Called to configure SPI chip select PIO pins for the SAMV71-XULT board.
* Called to configure SPI chip select GPIO pins for the SAMV71-XULT board.
*
************************************************************************************/
void sam_spidev_initialize(void)
{
#ifdef CONFIG_SAMV7_SPI0_MASTER
#ifdef CONFIG_SAMV71XULT_MB1_SPI
/* Enable chip select for mikroBUS1 */
(void)sam_configgpio(CLICK_MB1_CS);
#endif
#ifdef CONFIG_SAMV71XULT_MB2_SPI
/* Enable chip select for mikroBUS2 */
(void)sam_configgpio(CLICK_MB2_CS);
#endif
#endif /* CONFIG_SAMV7_SPI0_MASTER */
#ifdef CONFIG_SAMV7_SPI0_SLAVE
#endif
@ -101,10 +113,10 @@ void sam_spidev_initialize(void)
* pins.
* 2. Provide sam_spi[0|1]select() and sam_spi[0|1]status() functions in your board-
* specific logic. These functions will perform chip selection and
* status operations using PIOs in the way your board is configured.
* status operations using GPIOs in the way your board is configured.
* 2. If CONFIG_SPI_CMDDATA is defined in the NuttX configuration, provide
* sam_spi[0|1]cmddata() functions in your board-specific logic. This
* function will perform cmd/data selection operations using PIOs in
* function will perform cmd/data selection operations using GPIOs in
* the way your board is configured.
* 3. Add a call to sam_spibus_initialize() in your low level application
* initialization logic
@ -119,16 +131,16 @@ void sam_spidev_initialize(void)
* Name: sam_spi[0|1]select
*
* Description:
* PIO chip select pins may be programmed by the board specific logic in
* GPIO chip select pins may be programmed by the board specific logic in
* one of two different ways. First, the pins may be programmed as SPI
* peripherals. In that case, the pins are completely controlled by the
* SPI driver. This method still needs to be provided, but it may be only
* a stub.
*
* An alternative way to program the PIO chip select pins is as a normal
* PIO output. In that case, the automatic control of the CS pins is
* An alternative way to program the GPIO chip select pins is as a normal
* GPIO output. In that case, the automatic control of the CS pins is
* bypassed and this function must provide control of the chip select.
* NOTE: In this case, the PIO output pin does *not* have to be the
* NOTE: In this case, the GPIO output pin does *not* have to be the
* same as the NPCS pin normal associated with the chip select number.
*
* Input Parameters:
@ -143,12 +155,32 @@ void sam_spidev_initialize(void)
#ifdef CONFIG_SAMV7_SPI0_MASTER
void sam_spi0select(uint32_t devid, bool selected)
{
spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert");
switch (devid)
{
#ifdef CONFIG_IEEE802154_MRF24J40
case SPIDEV_IEEE802154(0):
/* Set the GPIO low to select and high to de-select */
#if defined(CONFIG_SAMV71XULT_MB1_BEE)
sam_gpiowrite(CLICK_MB1_CS, !selected);
#elif defined(CONFIG_SAMV71XULT_MB2_BEE)
sam_gpiowrite(CLICK_MB2_CS, !selected);
#endif
break;
#endif
default:
break;
}
}
#endif
#ifdef CONFIG_SAMV7_SPI1_MASTER
void sam_spi1select(uint32_t devid, bool selected)
{
spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert");
}
#endif

View file

@ -66,7 +66,7 @@
void board_userled_initialize(void)
{
/* Configure LED PIOs for output */
/* Configure LED GPIOs for output */
sam_configgpio(GPIO_LED0);
sam_configgpio(GPIO_LED1);

View file

@ -87,14 +87,14 @@ struct samv71xult_mwinfo_s
* Private Function Prototypes
****************************************************************************/
/* IRQ/PIO access callbacks. These operations all hidden behind
* callbacks to isolate the WM8904 driver from differences in PIO
/* IRQ/GPIO access callbacks. These operations all hidden behind
* callbacks to isolate the WM8904 driver from differences in GPIO
* interrupt handling by varying boards and MCUs. If possible,
* interrupts should be configured on both rising and falling edges
* so that contact and loss-of-contact events can be detected.
*
* attach - Attach the WM8904 interrupt handler to the PIO interrupt
* enable - Enable or disable the PIO interrupt
* attach - Attach the WM8904 interrupt handler to the GPIO interrupt
* enable - Enable or disable the GPIO interrupt
*/
static int wm8904_attach(FAR const struct wm8904_lower_s *lower,
@ -136,15 +136,15 @@ static struct samv71xult_mwinfo_s g_wm8904info =
****************************************************************************/
/****************************************************************************
* IRQ/PIO access callbacks. These operations all hidden behind
* callbacks to isolate the WM8904 driver from differences in PIO
* IRQ/GPIO access callbacks. These operations all hidden behind
* callbacks to isolate the WM8904 driver from differences in GPIO
* interrupt handling by varying boards and MCUs. If possible,
* interrupts should be configured on both rising and falling edges
* so that contact and loss-of-contact events can be detected.
*
* attach - Attach the WM8904 interrupt handler to the PIO interrupt
* enable - Enable or disable the PIO interrupt
* clear - Acknowledge/clear any pending PIO interrupt
* attach - Attach the WM8904 interrupt handler to the GPIO interrupt
* enable - Enable or disable the GPIO interrupt
* clear - Acknowledge/clear any pending GPIO interrupt
*
****************************************************************************/

View file

@ -1,7 +1,7 @@
/************************************************************************************
* configs/samv71-xult/src/samv71-xult.h
*
* Copyright (C) 2015-2016 Gregory Nutt. All rights reserved.
* Copyright (C) 2015-2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -72,6 +72,7 @@
#define HAVE_RTC_PCF85263 1
#define HAVE_I2CTOOL 1
#define HAVE_LED_DRIVER 1
#define HAVE_MRF24J40 1
/* HSMCI */
/* Can't support MMC/SD if the card interface is not enabled */
@ -87,10 +88,10 @@
# undef HAVE_HSMCI
#endif
/* We need PIO interrupts on GPIOD to support card detect interrupts */
/* We need GPIO interrupts on GPIOD to support card detect interrupts */
#if defined(HAVE_HSMCI) && !defined(CONFIG_SAMV7_GPIOD_IRQ)
# warning PIOD interrupts not enabled. No MMC/SD support.
# warning GPIOD interrupts not enabled. No MMC/SD support.
# undef HAVE_HSMCI
#endif
@ -375,6 +376,28 @@
# endif
#endif
/* Check if the MRF24J40 is supported in this configuration */
#ifndef CONFIG_IEEE802154_MRF24J40
# undef HAVE_MRF24J40
#endif
#ifndef CONFIG_SAMV71XULT_CLICKSHIELD
# undef HAVE_MRF24J40
#endif
#if !defined(CONFIG_SAMV71XULT_MB1_BEE) && !defined(CONFIG_SAMV71XULT_MB2_BEE)
# undef HAVE_MRF24J40
#endif
#ifndef CONFIG_SAMV7_SPI0_MASTER
# undef HAVE_MRF24J40
#endif
#ifndef CONFIG_SAMV7_GPIOA_IRQ
# undef HAVE_MRF24J40
#endif
/* SAMV71-XULT GPIO Pin Definitions *************************************************/
/* Ethernet MAC.
@ -419,7 +442,7 @@
*
* ------ ----------- ---------------------
* SAMV71 Function Shared functionality
* PIO
* GPIO
* ------ ----------- ---------------------
* PA23 Yellow LED0 EDBG GPIO
* PC09 Yellow LED1 LCD, and Shield
@ -440,7 +463,7 @@
*
* ------ ----------- ---------------------
* SAMV71 Function Shared functionality
* PIO
* GPIO
* ------ ----------- ---------------------
* RESET RESET Trace, Shield, and EDBG
* PA09 SW0 EDBG GPIO and Camera
@ -503,7 +526,7 @@
/* WM8904 Audio Codec ***************************************************************/
/* SAMV71 Interface WM8904 Interface
* ---- ------------ ------- ----------------------------------
* PIO Usage Pin Function
* GPIO Usage Pin Function
* ---- ------------ ------- ----------------------------------
* PA3 TWD0 SDA I2C control interface, data line
* PA4 TWCK0 SCLK I2C control interface, clock line
@ -522,8 +545,8 @@
* interrupt on the high level.
*/
#define GPIO_INT_WM8904 (PIO_INPUT | PIO_CFG_DEFAULT | PIO_CFG_DEGLITCH | \
PIO_INT_HIGHLEVEL | PIO_PORT_PIOD | PIO_PIN11)
#define GPIO_INT_WM8904 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_CFG_DEGLITCH | \
GPIO_INT_HIGHLEVEL | GPIO_PORT_PIOD | GPIO_PIN11)
#define IRQ_INT_WM8904 SAM_IRQ_PD11
/* The MW8904 communicates on TWI0, I2C address 0x1a for control operations */
@ -535,6 +558,59 @@
#define WM8904_SSC_BUS 0
/* Click Shield
*
* --- ----- ------------------------------ ---------------------------------
* PIN PORT SHIELD FUNCTION PIN CONFIGURATION
* --- ----- ------------------------------ ---------------------------------
* AD0 PD26 microBUS2 Analog TD PD26 *** Not an AFE pin ***
* AD1 PC31 microBUS2 Analog PC31 AFE1_AD6 GPIO_AFE1_AD6
* AD2 PD30 microBUS2 GPIO reset output PD30
* AD3 PA19 microBUS1 GPIO reset output PA19
* AD4 PC13 (both) I2C-SDA PC13 *** Does not support I2C SDA ***
* AD5 PC30 (both) I2C-SCL PC30 *** Does not support I2C SCL ***
* AD6 PA17 *** Not used ***
* AD7 PC12 *** Not used ***
* D0 PD28 (both) HDR_RX PD28 URXD3 GPIO_UART3_RXD
* D1 PD30 (both) HDR_TX PD30 UTXD3 GPIO_UART3_TXD_1
* D2 PA5 microBUS1 GPIO interrupt input PA5
* D3 PA6 microBUS2 GPIO interrupt input PA6
* D4 PD27 *** Not used ***
* D5 PD11 microBUS2 PWMB PD11 PWMC0_H0
* D6 PC19 microBUS1 PWMA PC19 PWMC0_H2
* D7 PA2 *** Not used ***
* D8 PA17 *** Not used ***
* D9 PC9 microBUS2 CS GPIO output PC9
* D10 PD25 microBUS1 CS GPIO output PD25 SPI0_NPCS1
* D11 PD21 (both) SPI-MOSI PD21 SPI0_MOSI GPIO_SPI0_MOSI
* D12 PD20 (both) SPI-MISO PD20 SPI0_MISO GPIO_SPI0_MISO
* D13 PD22 (both) SPI-SCK PD22 SPI0_SPCK GPIO_SPI0_SPCK
*/
/* Reset (RST#) Pulled-up on the click board */
#define CLICK_MB1_RESET (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_CLEAR | \
GPIO_PORT_PIOA | GPIO_PIN19)
#define CLICK_MB2_RESET (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_CLEAR | \
GPIO_PORT_PIOD | GPIO_PIN30)
/* Interrupts. No pull-ups on the BEE; assumig active low. */
#define CLICK_MB1_INTR (GPIO_INPUT | GPIO_CFG_PULLUP | GPIO_CFG_DEGLITCH | \
GPIO_INT_FALLING | GPIO_PORT_PIOA | GPIO_PIN5)
#define CLICK_MB2_INTR (GPIO_INPUT | GPIO_CFG_PULLUP | GPIO_CFG_DEGLITCH | \
GPIO_INT_FALLING | GPIO_PORT_PIOA | GPIO_PIN6)
#define IRQ_MB1 SAM_IRQ_PA5
#define IRQ_MB2 SAM_IRQ_PA6
/* SP chip selects */
#define CLICK_MB1_CS (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_SET | \
GPIO_PORT_PIOD | GPIO_PIN25)
#define CLICK_MB2_CS (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_SET | \
GPIO_PORT_PIOC | GPIO_PIN9)
/************************************************************************************
* Public Types
************************************************************************************/
@ -800,5 +876,21 @@ int sam_wm8904_initialize(int minor);
int sam_audio_null_initialize(int minor);
#endif /* HAVE_AUDIO_NULL */
/****************************************************************************
* Name: stm32_mrf24j40_initialize
*
* Description:
* Initialize the MRF24J40 device.
*
* Returned Value:
* Zero is returned on success. Otherwise, a negated errno value is
* returned to indicate the nature of the failure.
*
****************************************************************************/
#ifdef HAVE_MRF24J40
int sam_mrf24j40_initialize(void);
#endif
#endif /* __ASSEMBLY__ */
#endif /* __CONFIGS_SAMV71_XULT_SRC_SAMV71_XULT_H */

View file

@ -57,6 +57,14 @@
# include "stm32_usbhost.h"
#endif
#ifdef CONFIG_BUTTONS
# include <nuttx/input/buttons.h>
#endif
#ifdef CONFIG_USERLED
# include <nuttx/leds/userled.h>
#endif
#include "stm32f4discovery.h"
/* Conditional logic in stm32f4discover.h will determine if certain features
@ -179,6 +187,16 @@ int stm32_bringup(void)
}
#endif
#ifdef CONFIG_BUTTONS
/* Register the BUTTON driver */
ret = btn_lower_initialize("/dev/buttons");
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: btn_lower_initialize() failed: %d\n", ret);
}
#endif
#ifdef CONFIG_QENCODER
/* Initialize and register the qencoder driver */
@ -192,6 +210,16 @@ int stm32_bringup(void)
}
#endif
#ifdef CONFIG_USERLED
/* Register the LED driver */
ret = userled_lower_initialize("/dev/userleds");
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: userled_lower_initialize() failed: %d\n", ret);
}
#endif
#ifdef HAVE_RTC_DRIVER
/* Instantiate the STM32 lower-half RTC driver */

View file

@ -769,7 +769,7 @@ static int btn_poll(FAR struct file *filep, FAR struct pollfd *fds,
if (i >= CONFIG_BUTTONS_NPOLLWAITERS)
{
ierr("ERROR: Too man poll waiters\n");
ierr("ERROR: Too many poll waiters\n");
fds->priv = NULL;
ret = -EBUSY;
goto errout_with_dusem;
@ -797,6 +797,7 @@ static int btn_poll(FAR struct file *filep, FAR struct pollfd *fds,
}
errout_with_dusem:
btn_enable(priv);
btn_givesem(&priv->bu_exclsem);
return ret;
}

View file

@ -250,7 +250,9 @@
/* GCC supports both types double and long long */
#ifndef __clang__
# define CONFIG_HAVE_LONG_LONG 1
#endif
# define CONFIG_HAVE_FLOAT 1
# define CONFIG_HAVE_DOUBLE 1
# define CONFIG_HAVE_LONG_DOUBLE 1

View file

@ -1,55 +0,0 @@
/************************************************************************************
* include/nuttx/input/keypad.h
*
* Copyright (C) 2012 Denis Carikli.
* Author: Denis Carikli <GNUtoo@no-log.org>
*
* 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 __INCLUDE_NUTTX_INPUT_KEYPAD_H
#define __INCLUDE_NUTTX_INPUT_KEYPAD_H
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifdef __cplusplus
extern "C"
{
#endif
int keypad_kbdinit(void);
#ifdef __cplusplus
}
#endif
#endif /* __INCLUDE_NUTTX_INPUT_KEYPAD_H */

View file

@ -99,7 +99,26 @@
* Public Type Definitions
****************************************************************************/
/* The ICMP and IP headers */
struct icmp_hdr_s
{
/* ICMP header */
uint8_t type; /* Defines the format of the ICMP message */
uint8_t icode; /* Further qualifies the ICMP messsage */
uint16_t icmpchksum; /* Checksum of ICMP header and data */
/* All ICMP packets have an 8-byte header and variable-sized data section.
* The first 4 bytes of the header have fixed format, while the last 4 bytes
* depend on the type/code of that ICMP packet.
*/
/* ICMP_ECHO_REQUEST and ICMP_ECHO_REPLY data */
uint16_t id; /* Used to match requests with replies */
uint16_t seqno; /* " " "" " " " " " " " " */
};
/* The ICMP and IPv4 headers */
struct icmp_iphdr_s
{
@ -122,8 +141,9 @@ struct icmp_iphdr_s
uint8_t icode; /* Further qualifies the ICMP messsage */
uint16_t icmpchksum; /* Checksum of ICMP header and data */
/* Data following the ICMP header contains the data specific to the
* message type indicated by the Type and Code fields.
/* All ICMP packets have an 8-byte header and variable-sized data section.
* The first 4 bytes of the header have fixed format, while the last 4 bytes
* depend on the type/code of that ICMP packet.
*/
/* ICMP_ECHO_REQUEST and ICMP_ECHO_REPLY data */

View file

@ -127,7 +127,20 @@
* Public Type Definitions
****************************************************************************/
/* The ICMP and IP headers */
/* The ICMPv6 header */
struct icmpv6_hdr_s
{
uint8_t type; /* Defines the format of the ICMP message */
uint8_t code; /* Further qualifies the ICMP messages */
uint16_t chksum; /* Checksum of ICMP header and data */
/* Data following the ICMP header contains the data specific to the
* message type indicated by the Type and Code fields.
*/
};
/* The ICMPv6 and IPv6 headers */
struct icmpv6_iphdr_s
{

View file

@ -137,11 +137,6 @@ struct socketlist
};
#endif
/* Callback from netdev_foreach() */
struct net_driver_s; /* Forward reference. Defined in nuttx/net/netdev.h */
typedef int (*netdev_callback_t)(FAR struct net_driver_s *dev, FAR void *arg);
/****************************************************************************
* Public Data
****************************************************************************/
@ -1177,6 +1172,7 @@ int net_vfcntl(int sockfd, int cmd, va_list ap);
*
****************************************************************************/
struct net_driver_s; /* Forward reference */
int netdev_register(FAR struct net_driver_s *dev, enum net_lltype_e lltype);
/****************************************************************************
@ -1199,28 +1195,6 @@ int netdev_register(FAR struct net_driver_s *dev, enum net_lltype_e lltype);
int netdev_unregister(FAR struct net_driver_s *dev);
/****************************************************************************
* Name: netdev_foreach
*
* Description:
* Enumerate each registered network device.
*
* NOTE: netdev semaphore held throughout enumeration.
*
* Parameters:
* callback - Will be called for each registered device
* arg - User argument passed to callback()
*
* Returned Value:
* 0:Enumeration completed 1:Enumeration terminated early by callback
*
* Assumptions:
* Called from normal user mode
*
****************************************************************************/
int netdev_foreach(netdev_callback_t callback, FAR void *arg);
#undef EXTERN
#ifdef __cplusplus
}

View file

@ -95,9 +95,16 @@
# define TCP_STOPPED 0x10 /* Bit 4: stopped */
/* Bit 5-7: Unused, but not available */
/* TCP header sizes */
/* TCP header sizes
*
* The minimum size header is 5 words and the maximum is 15 words thus
* giving the minimum size of 20 bytes and maximum of 60 bytes, allowing for
* up to 40 bytes of options in the header.
*/
#define TCP_HDRLEN 20 /* Size of TCP header */
#define TCP_HDRLEN 20 /* Size of TCP header (minimum) */
#define TCP_OPT_HDRLEN(n) (20 + ((n) << 2)) /* Size of TCP header w/options */
#define TCP_MAX_HDRLEN 60 /* Maximum size of TCP header */
#ifdef CONFIG_NET_IPv4
# define IPv4TCP_HDRLEN (TCP_HDRLEN + IPv4_HDRLEN) /* Size of IPv4 + TCP header */

View file

@ -299,6 +299,23 @@ config NET_IPFORWARD
reason why IPv4 forwarding has not been implemented, it just has
not yet been done.
config NET_IPFORWARD_NSTRUCT
int "Number of pre-allocated forwarding structures"
default 4
depends on NET_IPFORWARD && CONFIG_NETDEV_MULTINIC
---help---
When packets are forward from on device to another, a structure must
be allocated to hold the state of forwarding across several
asynchronous events. Those structures are pre-allocated for
minimal, deterministic performance and to prevent hogging of memory
(of course, that means that this value must be carefully selected
for your application). This setting defines the number of such pre-
allocated structures.
NOTE: This setting effectively puts a maximum on the number of
packets that may be waiting to be forwarded from one network device
to another.
endmenu # Internet Protocol Selection
source "net/socket/Kconfig"

View file

@ -51,6 +51,12 @@ NET_CSRCS += ipv6_forward.c
endif
endif
ifeq ($(CONFIG_NET_IPFORWARD),y)
ifeq ($(CONFIG_NETDEV_MULTINIC),y)
NET_CSRCS += ip_forward.c devif_forward.c
endif
endif
# I/O buffer chain support required?
ifeq ($(CONFIG_MM_IOB),y)

102
net/devif/devif_forward.c Normal file
View file

@ -0,0 +1,102 @@
/****************************************************************************
* net/devif/devif_forward.c
*
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <string.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/net/netdev.h>
#include "devif/ip_forward.h"
#include "devif/devif.h"
#if defined(CONFIG_NET_IPFORWARD) && defined(CONFIG_NETDEV_MULTINIC)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: devif_forward
*
* Description:
* Called from protocol-specific IP forwarding logic to re-send a packet.
*
* Input Parameters:
* fwd - An initialized instance of the common forwarding structure that
* includes everything needed to perform the forwarding operation.
*
* Returned Value:
* None
*
* Assumptions:
* The network is locked.
*
****************************************************************************/
void devif_forward(FAR struct forward_s *fwd)
{
unsigned int offset;
int ret;
DEBUGASSERT(fwd != NULL && fwd->f_dev != NULL);
offset = NET_LL_HDRLEN(fwd->f_dev);
/* Copy the saved L2 + L3 header */
DEBUGASSERT(offset + fwd->f_hdrsize <= NET_DEV_MTU(fwd->f_dev));
memcpy(&fwd->f_dev->d_buf[offset], &fwd->f_hdr, fwd->f_hdrsize);
offset += fwd->f_hdrsize;
/* Copy the IOB chain that contains the payload */
if (fwd->f_iob != NULL && fwd->f_iob->io_pktlen > 0)
{
DEBUGASSERT(offset + fwd->f_iob->io_pktlen <= NET_DEV_MTU(fwd->f_dev));
ret = iob_copyout(&fwd->f_dev->d_buf[offset], fwd->f_iob,
fwd->f_iob->io_pktlen, 0);
DEBUGASSERT(ret == fwd->f_iob->io_pktlen);
offset += fwd->f_iob->io_pktlen;
}
fwd->f_dev->d_sndlen = offset;
}
#endif /* CONFIG_NET_IPFORWARD && CONFIG_NETDEV_MULTINIC */

View file

@ -1,7 +1,7 @@
/****************************************************************************
* net/devif/devif_initialize.c
*
* Copyright (C) 2007-2011, 2014 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2011, 2014, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Adapted for NuttX from logic in uIP which also has a BSD-like license:
@ -50,6 +50,7 @@
#include <nuttx/net/netstats.h>
#include <nuttx/net/ip.h>
#include "devif/ip_forward.h"
#include "devif/devif.h"
/****************************************************************************
@ -167,5 +168,11 @@ void devif_initialize(void)
/* Initialize callback support */
devif_callback_init();
#ifdef HAVE_FWDALLOC
/* Initialize IP forwarding support */
ip_forward_initialize();
#endif
}
#endif /* CONFIG_NET */

View file

@ -48,34 +48,6 @@
#ifdef CONFIG_MM_IOB
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Type Declarations
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Public Constant Data
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Constant Data
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/

View file

@ -47,33 +47,7 @@
#include <nuttx/net/netdev.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Type Declarations
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Public Constant Data
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Constant Data
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
#include "devif/devif.h"
/****************************************************************************
* Public Functions
@ -87,8 +61,7 @@
* the network interface driver.
*
* Assumptions:
* Called from the interrupt level or, at a minimum, with interrupts
* disabled.
* The network is locked.
*
****************************************************************************/

139
net/devif/ip_forward.c Normal file
View file

@ -0,0 +1,139 @@
/****************************************************************************
* net/devif/ip_forward.c
*
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 <nuttx/config.h>
#include <string.h>
#include <debug.h>
#include <errno.h>
#include "devif/ip_forward.h"
#if defined(CONFIG_NET_IPFORWARD) && defined(CONFIG_NETDEV_MULTINIC)
/****************************************************************************
* Private Data
****************************************************************************/
/* This is an array of pre-allocating forwarding structures */
static struct forward_s g_fwdpool[CONFIG_NET_IPFORWARD_NSTRUCT];
/* This is a list of free forwarding structures */
static FAR struct forward_s *g_fwdfree;
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: ip_forward_initialize
*
* Description:
* Initialize the struct forward_s allocator.
*
* Assumptions:
* Called early in system initialization.
*
****************************************************************************/
void ip_forward_initialize(void)
{
FAR struct forward_s *fwd;
int i;
/* Add all pre-allocated forwarding structures to the free list */
g_fwdfree = NULL;
for (i = 0; i < CONFIG_NET_IPFORWARD_NSTRUCT; i++)
{
fwd = &g_fwdpool[i];
fwd->f_flink = g_fwdfree;
g_fwdfree = fwd;
}
}
/****************************************************************************
* Name: ip_forward_alloc
*
* Description:
* Allocate a forwarding structure by removing a pre-allocated entry from
* a free list.
*
* Assumptions:
* Caller holds the network lock. Mutually excluvive access to the free
* list is assured by this lock.
*
****************************************************************************/
FAR struct forward_s *ip_forward_alloc(void)
{
FAR struct forward_s *fwd;
fwd = g_fwdfree;
if (fwd != NULL)
{
g_fwdfree = fwd->f_flink;
memset (fwd, 0, sizeof(struct forward_s));
}
return fwd;
}
/****************************************************************************
* Name: ip_forward_free
*
* Description:
* Free a forwarding structure by adding it to a free list.
*
* Assumptions:
* Caller holds the network lock. Mutually excluvive access to the free
* list is assured by this lock.
*
****************************************************************************/
void ip_forward_free(FAR struct forward_s *fwd)
{
fwd->f_flink = g_fwdfree;
g_fwdfree = fwd;
}
#endif /* CONFIG_NET_IPFORWARD && CONFIG_NETDEV_MULTINIC */

228
net/devif/ip_forward.h Normal file
View file

@ -0,0 +1,228 @@
/****************************************************************************
* net/devif/ip_forward.h
*
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 __NET_DEVIF_IP_FORWARD_H
#define __NET_DEVIF_IP_FORWARD_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <nuttx/net/ip.h>
#include <nuttx/net/udp.h>
#include <nuttx/net/tcp.h>
#include <nuttx/net/icmpv6.h>
#include "udp/udp.h"
#include "tcp/tcp.h"
#include "icmpv6/icmpv6.h"
#undef HAVE_FWDALLOC
#if defined(CONFIG_NET_IPFORWARD) && defined(CONFIG_NETDEV_MULTINIC)
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define HAVE_FWDALLOC 1
#ifndef CONFIG_NET_IPFORWARD_NSTRUCT
# define CONFIG_NET_IPFORWARD_NSTRUCT 4
#endif
/****************************************************************************
* Public Types
****************************************************************************/
/* IPv4 + L2 header */
#ifdef CONFIG_NET_IPv4
struct fwd_ipv4hdr_u
{
struct ipv4_hdr_s l2;
union
{
#ifdef CONFIG_NET_TCP
uint8_t pad[TCP_MAX_HDRLEN];
struct tcp_hdr_s tcp;
#endif
#ifdef CONFIG_NET_UDP
struct udp_hdr_s udp;
#endif
#ifdef CONFIG_NET_ICMPv6
struct icmp_hdr_s icmp;
#endif
} l3;
};
#endif
/* IPv6 + L2 header */
#ifdef CONFIG_NET_IPv6
struct fwd_ipv6hdr_u
{
struct ipv6_hdr_s l2;
union
{
#ifdef CONFIG_NET_TCP
uint8_t pad[TCP_MAX_HDRLEN];
struct tcp_hdr_s tcp;
#endif
#ifdef CONFIG_NET_UDP
struct udp_hdr_s udp;
#endif
#ifdef CONFIG_NET_ICMPv6
struct icmpv6_hdr_s icmpv6;
#endif
} l3;
};
#endif
/* IPv4 or IPv6 + L2 header */
union fwd_iphdr_u
{
#ifdef CONFIG_NET_IPv4
struct fwd_ipv4hdr_u ipv4;
#endif
#ifdef CONFIG_NET_IPv6
struct fwd_ipv6hdr_u ipv6;
#endif
};
/* Connection structures */
union fwd_conn_u
{
#ifdef CONFIG_NET_TCP
struct tcp_conn_s tcp;
#endif
#ifdef CONFIG_NET_UDP
struct udp_conn_s udp;
#endif
#ifdef CONFIG_NET_ICMPv6
struct icmpv6_conn_s icmpv6;
#endif
};
/* This is the send state structure */
struct devif_callback_s; /* Forward refernce */
struct net_driver_s; /* Forward reference */
struct iob_s; /* Forward reference */
struct forward_s
{
FAR struct forward_s *f_flink; /* Supports a singly linked list */
FAR struct net_driver_s *f_dev; /* Forwarding device */
FAR struct iob_s *f_iob; /* IOBs containing the data payload */
FAR struct devif_callback_s *f_cb; /* Reference to callback instance */
union fwd_iphdr_u f_hdr; /* Copy of original L2+L3 headers */
union fwd_conn_u f_conn; /* Protocol-specific connectin struct */
uint8_t f_hdrsize; /* The size of the L2+L3 headers */
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: ip_forward_initialize
*
* Description:
* Initialize the struct forward_s allocator.
*
* Assumptions:
* Called early in system initialization.
*
****************************************************************************/
void ip_forward_initialize(void);
/****************************************************************************
* Name: ip_forward_alloc
*
* Description:
* Allocate a forwarding structure by removing a pre-allocated entry from
* a free list.
*
* Assumptions:
* Caller holds the network lock. Mutually excluvive access to the free
* list is assured by this lock.
*
****************************************************************************/
FAR struct forward_s *ip_forward_alloc(void);
/****************************************************************************
* Name: ip_forward_free
*
* Description:
* Free a forwarding structure by adding it to a free list.
*
* Assumptions:
* Caller holds the network lock. Mutually excluvive access to the free
* list is assured by this lock.
*
****************************************************************************/
void ip_forward_free(FAR struct forward_s *fwd);
/****************************************************************************
* Name: devif_forward
*
* Description:
* Called from protocol-specific IP forwarding logic to re-send a packet.
*
* Input Parameters:
* fwd - An initialized instance of the common forwarding structure that
* includes everything needed to perform the forwarding operation.
*
* Returned Value:
* None
*
* Assumptions:
* The network is locked.
*
****************************************************************************/
void devif_forward(FAR struct forward_s *fwd);
#endif /* CONFIG_NET_IPFORWARD && CONFIG_NETDEV_MULTINIC */
#endif /* __NET_DEVIF_IP_FORWARD_H */

View file

@ -39,14 +39,21 @@
#include <nuttx/config.h>
#include <string.h>
#include <debug.h>
#include <errno.h>
#include <nuttx/mm/iob.h>
#include <nuttx/net/net.h>
#include <nuttx/net/netdev.h>
#include <nuttx/net/netstats.h>
#include "netdev/netdev.h"
#include "sixlowpan/sixlowpan.h"
#include "udp/udp.h"
#include "tcp/tcp.h"
#include "icmpv6/icmpv6.h"
#include "devif/ip_forward.h"
#include "devif/devif.h"
#if defined(CONFIG_NET_IPFORWARD) && defined(CONFIG_NET_IPv6)
@ -99,24 +106,397 @@ static int ipv6_packet_conversion(FAR struct net_driver_s *dev,
{
/* Otherwise, we will have to drop the packet */
nwarn("WARNING: Dropping. Unsupported 6LoWPAN protocol: %d\n",
nwarn("WARNING: Dropping. Unsupported 6LoWPAN protocol: %d\n",
ipv6->proto);
#ifdef CONFIG_NET_STATISTICS
g_netstats.ipv6.drop++;
#endif
return -EPROTONOSUPPORT;
}
dev->d_len = 0;
return OK;
}
nwarn("WARNING: Dropping. Unsupported link layer\n");
return -EPFNOSUPPORT;
}
#else
# define ipv6_packet_conversion(dev, ipv6)
#endif /* CONFIG_NET_6LOWPAN */
/****************************************************************************
* Name: ipv6_hdrsize
*
* Description:
* Return the size of the IPv6 header and the following.
*
* Input Parameters:
* ipv6 - A pointer to the IPv6 header in within the IPv6 packet. This
* is immeidately followed by the L3 header which may be TCP, UDP,
* or ICMPv6.
*
* Returned Value:
* The size of the combined L2 + L3 headers is returned on success. An
* error is returned only if the prototype is not supported.
*
****************************************************************************/
#ifdef CONFIG_NETDEV_MULTINIC
static int ipv6_hdrsize(FAR struct ipv6_hdr_s *ipv6)
{
/* Size is determined by the following protocol header, */
switch (ipv6->proto)
{
#ifdef CONFIG_NET_TCP
case IP_PROTO_TCP:
{
FAR struct tcp_hdr_s *tcp =
(FAR struct tcp_hdr_s *)((FAR uintptr_t *)ipv6 + IPv6_HDRLEN);
unsigned int tcpsize;
/* The TCP header length is encoded in the top 4 bits of the
* tcpoffset field (in units of 32-bit words).
*/
tcpsize = ((uint16_t)tcp->tcpoffset >> 4) << 2;
return IPv6_HDRLEN + tcpsize;
}
break;
#endif
#ifdef CONFIG_NET_UDP
case IP_PROTO_UDP:
return IPv6_HDRLEN + UDP_HDRLEN;
break;
#endif
#ifdef CONFIG_NET_ICMPv6
case IP_PROTO_ICMP6:
return IPv6_HDRLEN + ICMPv6_HDRLEN;
break;
#endif
default:
nwarn("WARNING: Unrecognized proto: %u\n", ipv6->proto);
return -EPROTONOSUPPORT;
}
}
#endif
/****************************************************************************
* Name: ipv6_dev_forward
*
* Description:
* This function is called from ipv6_forward when it is necessary to
* forward a packet from the current device to different device. In this
* case, the forwarding operation must be performed asynchronously when
* the TX poll is received from the forwarding device.
*
* Input Parameters:
* dev - The device on which the packet was received and which
* contains the IPv6 packet.
* fwdddev - The device on which the packet must be forwarded.
* ipv6 - A pointer to the IPv6 header in within the IPv6 packet
*
* Returned Value:
* Zero is returned if the packet was successfully forward; A negated
* errno value is returned if the packet is not forwardable. In that
* latter case, the caller (ipv6_input()) should drop the packet.
*
****************************************************************************/
#ifdef CONFIG_NETDEV_MULTINIC
static int ipv6_dev_forward(FAR struct net_driver_s *dev,
FAR struct net_driver_s *fwddev,
FAR struct ipv6_hdr_s *ipv6)
{
FAR struct forward_s *fwd = NULL;
int hdrsize;
int ret;
/* Perform any necessary packet conversions. */
ret = ipv6_packet_conversion(dev, fwddev, ipv6);
if (ret < 0)
{
FAR uint8_t *payload;
unsigned int paysize;
/* Verify that the full packet will fit within the forwarding devices
* MTU. We provide no support for fragmenting forwarded packets.
*/
if (NET_LL_HDRLEN(fwddev) + dev->d_len > NET_DEV_MTU(fwddev))
{
nwarn("WARNING: Packet > MTU... Dropping\n");
ret = -EFBIG;
goto errout;
}
/* Get a pre-allocated forwarding structure, This structure will be
* completely zeroed when we receive it.
*/
fwd = ip_forward_alloc();
if (fwd == NULL)
{
nwarn("WARNING: Failed to allocate forwarding structure\n");
ret = -ENOMEM;
goto errout;
}
/* Initialize the easy stuff in the forwarding structure */
fwd->f_dev = fwddev; /* Forwarding device */
/* Get the size of the IPv6 + L3 header. Use this to determine start
* of the data payload.
*
* Remember that the size of the L1 header has already been subtracted
* from dev->d_len.
*
* REVISIT: Consider an alternative design that does not require data
* copying. This would require a pool of d_buf's that are managed by
* the network rather than the network device.
*/
hdrsize = ipv6_hdrsize(ipv6);
if (hdrsize < IPv6_HDRLEN)
{
nwarn("WARNING: Could not determine L2+L3 header size\n");
ret = -EPROTONOSUPPORT;
goto errout_with_fwd;
}
/* Save the entire L2 and L3 headers in the state structure */
if (hdrsize > sizeof(union fwd_iphdr_u))
{
nwarn("WARNING: Header is too big for pre-allocated structure\n");
ret = -E2BIG;
goto errout_with_fwd;
}
memcpy(&fwd->f_hdr, ipv6, hdrsize);
fwd->f_hdrsize = hdrsize;
/* Use the L2 + L3 header size to determine start and size of the data
* payload.
*
* Remember that the size of the L1 header has already been subtracted
* from dev->d_len.
*/
payload = (FAR uint8_t *)ipv6 + hdrsize;
paysize = dev->d_len - hdrsize;
/* If there is a payload, then copy it into an IOB chain.
*
* REVISIT: Consider an alternative design that does not require data
* copying. This would require a pool of d_buf's that are managed by
* the network rather than the network device.
*/
if (paysize > 0)
{
/* Try to allocate the head of an IOB chain. If this fails,
* the the packet will be dropped; we are not operating in a
* context where waiting for an IOB is a good idea
*/
fwd->f_iob = iob_tryalloc(false);
if (fwd->f_iob == NULL)
{
nwarn("WARNING: iob_tryalloc() failed\n");
ret = -ENOMEM;
goto errout_with_fwd;
}
/* Copy the packet data payload into an IOB chain.
* iob_trycopin() will not wait, but will fail there are no
* available IOBs.
*/
ret = iob_trycopyin(fwd->f_iob, payload, paysize, 0, false);
if (ret < 0)
{
nwarn("WARNING: iob_trycopyin() failed: %d\n", ret);
goto errout_with_iobchain;
}
}
/* Then set up to forward the packet according to the protocol.
*
* REVISIT: Are these protocol specific forwarders necessary? I think
* that this could be done with a single forwarding function for all
* protocols.
*/
switch (ipv6->proto)
{
#ifdef CONFIG_NET_TCP
case IP_PROTO_TCP:
{
/* Forward a TCP packet. */
ret = tcp_forward(fwd);
}
break;
#endif
#ifdef CONFIG_NET_UDP
case IP_PROTO_UDP:
{
/* Forward a UDP packet */
ret = udp_forward(fwd);
}
break;
#endif
#ifdef CONFIG_NET_ICMPv6
case IP_PROTO_ICMP6:
{
/* Forward an ICMPv6 packet */
ret = icmpv6_forward(fwd);
}
break;
#endif
default:
nwarn("WARNING: Unrecognized proto: %u\n", ipv6->proto);
ret = -EPROTONOSUPPORT;
break;
}
}
if (ret >= 0)
{
dev->d_len = 0;
return OK;
}
errout_with_iobchain:
if (fwd != NULL && fwd->f_iob != NULL)
{
iob_free_chain(fwd->f_iob);
}
errout_with_fwd:
if (fwd != NULL)
{
ip_forward_free(fwd);
}
errout:
return ret;
}
#endif /* CONFIG_NETDEV_MULTINIC */
/****************************************************************************
* Name: ipv6_decr_ttl
*
* Description:
* Decrement the IPv6 TTL (time to live value). TTL field is set by the
* sender of the packet and reduced by every router on the route to its
* destination. If the TTL field reaches zero before the datagram arrives
* at its destination, then the datagram is discarded and an ICMP error
* packet (11 - Time Exceeded) is sent back to the sender.
*
* The purpose of the TTL field is to avoid a situation in which an
* undeliverable datagram keeps circulating on an Internet system, and
* such a system eventually becoming swamped by such "immortals".
*
* Input Parameters:
* ipv6 - A pointer to the IPv6 header in within the IPv6 packet to be
* forwarded.
*
* Returned Value:
* The new TTL value is returned. A value <= 0 means the hop limit has
* expired.
*
****************************************************************************/
static int ipv6_decr_ttl(FAR struct ipv6_hdr_s *ipv6)
{
int ttl = (int)ipv6->ttl - 1;
if (ttl <= 0)
{
#ifdef CONFIG_NET_ICMPv6
/* Return an ICMPv6 error packet back to the sender. */
#warning Missing logic
#endif
/* Return zero which must cause the packet to be dropped */
return 0;
}
/* Save the updated TTL value */
ipv6->ttl = ttl;
/* NOTE: We do not have to recalculate the IPv6 checksum because (1) the
* IPv6 header does not include a checksum itself and (2) the TTL is not
* included in the sum for the TCP and UDP headers.
*/
return ttl;
}
/****************************************************************************
* Name: ipv6_dropstats
*
* Description:
* Update statistics for a dropped packet.
*
* Input Parameters:
* ipv6 - A convenience pointer to the IPv6 header in within the IPv6
* packet to be dropped.
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_NET_STATISTICS
static void ipv6_dropstats(FAR struct ipv6_hdr_s *ipv6)
{
switch (ipv6->proto)
{
#ifdef CONFIG_NET_TCP
case IP_PROTO_TCP:
g_netstats.tcp.drop++;
break;
#endif
#ifdef CONFIG_NET_UDP
case IP_PROTO_UDP:
g_netstats.udp.drop++;
break;
#endif
#ifdef CONFIG_NET_ICMPv6
case IP_PROTO_ICMP6:
g_netstats.icmpv6.drop++;
break;
#endif
default:
break;
}
g_netstats.ipv6.drop++;
}
#else
# define ipv6_dropstats(ipv6)
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -157,6 +537,16 @@ int ipv6_forward(FAR struct net_driver_s *dev, FAR struct ipv6_hdr_s *ipv6)
FAR struct net_driver_s *fwddev;
int ret;
/* Decrement the TTL. If it decrements to zero, then drop the packet */
ret = ipv6_decr_ttl(ipv6);
if (ret < 1)
{
nwarn("WARNING: Hop limit exceeded... Dropping!\n");
ret = -EMULTIHOP;
goto drop;
}
/* Search for a device that can forward this packet. This is a trivial
* serch if there is only a single network device (CONFIG_NETDEV_MULTINIC
* not defined). But netdev_findby_ipv6addr() will still assure
@ -181,42 +571,25 @@ int ipv6_forward(FAR struct net_driver_s *dev, FAR struct ipv6_hdr_s *ipv6)
if (fwddev != dev)
{
/* Perform any necessary packet conversions. */
/* Send the packet asynchrously on the forwarding device. */
ret = ipv6_packet_conversion(dev, fwddev, ipv6);
ret = ipv6_dev_forward(dev, fwddev, ipv6);
if (ret < 0)
{
/* Extract the IPv6 + L3 header; Move the data payload to an IOB
* chain.
*/
/* Notify the forwarding device that TX data is available */
/* Set up to send the packet when the selected device polls for TX
* data.
*/
/* REVISIT: For Ethernet we may have to fix up the Ethernet header:
* - source MAC, the MAC of the current device.
* - dest MAC, the MAC associated with the destination IPv6 adress.
* This will involve ICMPv6 and Neighbor Discovery.
*/
/* Return success with dev->d_len = 0 */
# warning Missing logic
nwarn("WARNING: Packet forwarding not yet supported "
"across different devices\n");
return -ENOSYS;
nwarn("WARNING: ipv6_dev_forward faield: %d\n", ret);
goto drop;
}
}
else
#endif /* CONFIG_NETDEV_MULTINIC */
#if defined(CONFIG_NET_6LOWPAN) /* REVISIT: Currently only suport for
* 6LoWPAN */
#if defined(CONFIG_NET_6LOWPAN) /* REVISIT: Currently only suport for 6LoWPAN */
{
/* Single network device */
/* Single network device. The use case here is where an endpoint acts
* as a hub in a star configuration. This is typical for a wireless star
* configuration where not all endpoints are accessible from all other
* endpoints, but seems less useful for a wired network.
*/
/* Perform any necessary packet conversions. If the packet was handled
* via a backdoor path (or dropped), then dev->d_len will be zero. If
@ -239,18 +612,21 @@ int ipv6_forward(FAR struct net_driver_s *dev, FAR struct ipv6_hdr_s *ipv6)
/* Nothing other 6LoWPAN forwarding is currently handled and that
* case was dealt with in ipv6_packet_conversion().
*
* REVISIT: Is tht an issue? Do other use cases make sense?
*/
# warning Missing logic
nwarn("WARNING: Packet forwarding supported only for 6LoWPAN\n");
return -ENOSYS;
ret = -ENOSYS;
goto drop;
}
}
#else /* CONFIG_NET_6LOWPAN */
{
nwarn("WARNING: Packet forwarding not supported in this configuration\n");
return -ENOSYS;
ret = -ENOSYS;
goto drop;
}
#endif /* CONFIG_NET_6LOWPAN */
@ -260,6 +636,11 @@ int ipv6_forward(FAR struct net_driver_s *dev, FAR struct ipv6_hdr_s *ipv6)
*/
return OK;
drop:
ipv6_dropstats(ipv6);
dev->d_len = 0;
return ret;
}
#endif /* CONFIG_NET_IPFORWARD && CONFIG_NET_IPv6 */

View file

@ -87,7 +87,6 @@
#include <net/if.h>
#include <nuttx/net/net.h>
#include <nuttx/net/netconfig.h>
#include <nuttx/net/netdev.h>
#include <nuttx/net/netstats.h>
@ -242,6 +241,7 @@ static bool check_destipaddr(FAR struct net_driver_s *dev,
* to this input.
*
* Assumptions:
* The network is locked.
*
****************************************************************************/
@ -370,6 +370,7 @@ int ipv6_input(FAR struct net_driver_s *dev)
{
/* Not destined for us and not forwardable... drop the packet. */
nwarn("WARNING: Not destined for us; not forwardable... Dropping!\n");
#ifdef CONFIG_NET_STATISTICS
g_netstats.ipv6.drop++;
#endif

View file

@ -62,6 +62,15 @@ endif
ifeq ($(CONFIG_NET_ICMPv6_ROUTER),y)
NET_CSRCS += icmpv6_radvertise.c
endif
# IP forwarding
ifeq ($(CONFIG_NET_IPFORWARD),y)
ifeq ($(CONFIG_NETDEV_MULTINIC),y)
NET_CSRCS += icmpv6_forward.c
endif
endif
# Include ICMPv6 build support
DEPPATH += --dep-path icmpv6

View file

@ -55,8 +55,10 @@
/* Allocate a new ICMPv6 data callback */
#define icmpv6_callback_alloc(dev) devif_callback_alloc(dev, &(dev)->d_conncb)
#define icmpv6_callback_free(dev,cb) devif_dev_callback_free(dev, cb)
#define icmpv6_callback_alloc(dev) \
devif_callback_alloc((dev), &(dev)->d_conncb)
#define icmpv6_callback_free(dev,cb) \
devif_dev_callback_free((dev), (cb))
/****************************************************************************
* Public Type Definitions
@ -176,6 +178,34 @@ int icmpv6_neighbor(const net_ipv6addr_t ipaddr);
# define icmpv6_neighbor(i) (0)
#endif
/****************************************************************************
* Name: icmpv6_forward
*
* Description:
* Called by the IP forwarding logic when an ICMPv6 packet is received on
* one network device, but must be forwarded on another network device.
*
* Set up to forward the ICMPv6 packet on the specified device. The
* function will set up a send "interrupt" handler that will perform the
* actual send asynchronously and must return without waiting for the
* send to complete.
*
* Input Parameters:
* fwd - An initialized instance of the common forwarding structure that
* includes everything needed to perform the forwarding operation.
*
* Returned Value:
* Zero is returned if the packet was successfully forwarded; A negated
* errno value is returned if the packet is not forwardable. In that
* latter case, the caller should free the IOB list and drop the packet.
*
****************************************************************************/
#if defined(CONFIG_NETDEV_MULTINIC) && defined(CONFIG_NET_IPFORWARD)
struct forward_s;
int icmpv6_forward(FAR struct forward_s *fwd);
#endif
/****************************************************************************
* Name: icmpv6_poll
*

322
net/icmpv6/icmpv6_forward.c Normal file
View file

@ -0,0 +1,322 @@
/****************************************************************************
* net/icmpv6/icmpv6_forward.c
*
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <net/if.h>
#include <nuttx/mm/iob.h>
#include <nuttx/net/netdev.h>
#include <nuttx/net/ip.h>
#include <nuttx/net/netstats.h>
#include "devif/ip_forward.h"
#include "devif/devif.h"
#include "netdev/netdev.h"
#include "icmpv6/icmpv6.h"
#if defined(CONFIG_NET_IPFORWARD) && defined(CONFIG_NET_ICMPv6) && \
defined(CONFIG_NETDEV_MULTINIC)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: icmpv6_forward_addrchck
*
* Description:
* Check if the destination IP address is in the IPv4 ARP or IPv6 Neighbor
* tables. If not, then the send won't actually make it out... it will be
* replaced with an ARP request (IPv4) or a Neighbor Solicitation (IPv6).
*
* NOTE 1: This could be an expensive check if there are a lot of
* entries in the ARP or Neighbor tables.
*
* NOTE 2: If we are actually harvesting IP addresses on incoming IP
* packets, then this check should not be necessary; the MAC mapping
* should already be in the ARP table in many cases (IPv4 only).
*
* NOTE 3: If CONFIG_NET_ARP_SEND then we can be assured that the IP
* address mapping is already in the ARP table.
*
* Parameters:
* fwd - The forwarding state structure
*
* Returned Value:
* None
*
* Assumptions:
* The network is locked.
*
****************************************************************************/
#ifdef CONFIG_NET_ETHERNET
static inline bool icmpv6_forward_addrchck(FAR struct forward_s *fwd)
{
#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
if (conn->domain == PF_INET)
#endif
{
#if !defined(CONFIG_NET_ARP_IPIN) && !defined(CONFIG_NET_ARP_SEND)
return (arp_find(fwd->f_hdr.ipv4.l2.destipaddr) != NULL);
#else
return true;
#endif
}
#endif /* CONFIG_NET_IPv4 */
#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
else
#endif
{
#if !defined(CONFIG_NET_ICMPv6_NEIGHBOR)
return (neighbor_findentry(fwd->f_hdr.ipv6.l2.destipaddr) != NULL);
#else
return true;
#endif
}
#endif /* CONFIG_NET_IPv6 */
}
#else /* CONFIG_NET_ETHERNET */
# define icmpv6_forward_addrchck(r) (true)
#endif /* CONFIG_NET_ETHERNET */
/****************************************************************************
* Name: icmpv6_dropstats
*
* Description:
* Update statistics for a dropped packet.
*
* Input Parameters:
* fwd - The forwarding state structure
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_NET_STATISTICS
static void icmpv6_dropstats(FAR struct forward_s *fwd)
{
/* Increment the count of dropped ICMPV6 packets */
g_netstats.icmpv6.drop++;
/* Increment the count of dropped IPv4 or IPv6 packets */
#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
if ((fwd->f_hdr.ipv4.l2.vhl & IP_VERSION_MASK) == IPv4_VERSION)
#endif
{
g_netstats.ipv4.drop++;
}
#endif
#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
else
#endif
{
g_netstats.ipv6.drop++;
}
#endif
}
#else
# define icmpv6_dropstats(ipv6)
#endif
/****************************************************************************
* Name: icmpv6_forward_interrupt
*
* Description:
* This function is called from the interrupt level to perform the actual
* send operation when polled by the lower, device interfacing layer.
*
* Parameters:
* dev The structure of the network driver that caused the interrupt
* conn An instance of the ICMPV6 connection structure cast to void *
* pvpriv An instance of struct forward_s cast to void*
* flags Set of events describing why the callback was invoked
*
* Returned Value:
* Modified value of the input flags
*
* Assumptions:
* The network is locked
*
****************************************************************************/
static uint16_t icmpv6_forward_interrupt(FAR struct net_driver_s *dev,
FAR void *conn, FAR void *pvpriv,
uint16_t flags)
{
FAR struct forward_s *fwd = (FAR struct forward_s *)pvpriv;
ninfo("flags: %04x\n", flags);
DEBUGASSERT(fwd != NULL);
/* Make sure that this is from the forwarding device */
if (dev == fwd->f_dev)
{
/* If the network device has gone down, then we will have terminate
* the wait now with an error.
*/
if ((flags & NETDEV_DOWN) != 0)
{
/* Terminate the transfer with an error. */
nwarn("WARNING: Network is down... Dropping\n");
icmpv6_dropstats(fwd);
}
/* Check if the outgoing packet is available. It may have been claimed
* by another send interrupt serving a different thread -OR- if the output
* buffer currently contains unprocessed incoming data. In these cases
* we will just have to wait for the next polling cycle.
*/
else if (dev->d_sndlen > 0 || (flags & ICMPv6_NEWDATA) != 0)
{
/* Another thread has beat us sending data or the buffer is busy,
* Wait for the next polling cycle and check again.
*/
return flags;
}
/* It looks like we are good to forward the data */
else
{
/* Copy the ICMPv6 data into driver's packet buffer and send it. */
devif_forward(fwd);
/* Check if the destination IP address is in the ARP or Neighbor
* table. If not, then the send won't actually make it out... it
* will be replaced with an ARP request or Neighbor Solicitation.
*/
if (!icmpv6_forward_addrchck(fwd))
{
return flags;
}
}
/* Free the allocated callback structure */
fwd->f_cb->flags = 0;
fwd->f_cb->priv = NULL;
fwd->f_cb->event = NULL;
icmpv6_callback_free(dev, fwd->f_cb);
/* Free any IOBs */
if (fwd->f_iob != NULL)
{
iob_free_chain(fwd->f_iob);
}
/* And release the forwarding state structure */
ip_forward_free(fwd);
}
return flags;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: icmpv6_forward
*
* Description:
* Called by the IP forwarding logic when an ICMPV6 packet is received on
* one network device, but must be forwarded on another network device.
*
* Set up to forward the ICMPV6 packet on the specified device. This
* function will set up a send "interrupt" handler that will perform the
* actual send asynchronously and must return without waiting for the
* send to complete.
*
* Input Parameters:
* fwd - An initialized instance of the common forwarding structure that
* includes everything needed to perform the forwarding operation.
*
* Returned Value:
* Zero is returned if the packet was successfully forwarded; A negated
* errno value is returned if the packet is not forwardable. In that
* latter case, the caller should free the IOB list and drop the packet.
*
****************************************************************************/
int icmpv6_forward(FAR struct forward_s *fwd)
{
DEBUGASSERT(fwd != NULL && fwd->f_dev != NULL);
/* Set up the callback in the connection */
fwd->f_cb = icmpv6_callback_alloc(fwd->f_dev);
if (fwd->f_cb != NULL)
{
fwd->f_cb->flags = (ICMPv6_POLL | NETDEV_DOWN);
fwd->f_cb->priv = (FAR void *)fwd;
fwd->f_cb->event = icmpv6_forward_interrupt;
/* Notify the device driver of the availability of TX data */
netdev_txnotify_dev(fwd->f_dev);
return OK;
}
return -EBUSY;
}
#endif /* CONFIG_NET_IPFORWARD && CONFIG_NET_ICMPv6 && CONFIG_NETDEV_MULTINIC */

View file

@ -314,7 +314,7 @@ int icmpv6_neighbor(const net_ipv6addr_t ipaddr)
(void)sem_init(&state.snd_sem, 0, 0); /* Doesn't really fail */
sem_setprotocol(&state.snd_sem, SEM_PRIO_NONE);
state.snd_retries = 0; /* No retries yet */
state.snd_retries = 0; /* No retries yet */
net_ipv6addr_copy(state.snd_ipaddr, lookup); /* IP address to query */
#ifdef CONFIG_NETDEV_MULTINIC

View file

@ -70,6 +70,15 @@ extern "C"
EXTERN struct net_driver_s *g_netdevices;
#endif
/****************************************************************************
* Public Types
****************************************************************************/
/* Callback from netdev_foreach() */
struct net_driver_s; /* Forward reference */
typedef int (*netdev_callback_t)(FAR struct net_driver_s *dev, FAR void *arg);
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
@ -120,6 +129,28 @@ bool netdev_verify(FAR struct net_driver_s *dev);
FAR struct net_driver_s *netdev_findbyname(FAR const char *ifname);
#endif
/****************************************************************************
* Name: netdev_foreach
*
* Description:
* Enumerate each registered network device.
*
* NOTE: netdev semaphore held throughout enumeration.
*
* Parameters:
* callback - Will be called for each registered device
* arg - User argument passed to callback()
*
* Returned Value:
* 0:Enumeration completed 1:Enumeration terminated early by callback
*
* Assumptions:
* Called from normal user mode
*
****************************************************************************/
int netdev_foreach(netdev_callback_t callback, FAR void *arg);
/****************************************************************************
* Name: netdev_findby_ipv4addr
*

View file

@ -41,7 +41,7 @@
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
#include <debug.h>
#include <nuttx/net/net.h>
#include <nuttx/net/netdev.h>
#include "netdev/netdev.h"
@ -66,7 +66,7 @@
* 0:Enumeration completed 1:Enumeration terminated early by callback
*
* Assumptions:
* Called from normal user mode
* The network is locked.
*
****************************************************************************/
@ -75,9 +75,8 @@ int netdev_foreach(netdev_callback_t callback, FAR void *arg)
FAR struct net_driver_s *dev;
int ret = 0;
if (callback)
if (callback != NULL)
{
net_lock();
for (dev = g_netdevices; dev; dev = dev->flink)
{
if (callback(dev, arg) != 0)
@ -86,8 +85,6 @@ int netdev_foreach(netdev_callback_t callback, FAR void *arg)
break;
}
}
net_unlock();
}
return ret;

View file

@ -60,6 +60,7 @@
#include "nuttx/net/netdev.h"
#include "nuttx/net/ip.h"
#include "nuttx/net/icmpv6.h"
#include "nuttx/net/sixlowpan.h"
#include "nuttx/wireless/ieee802154/ieee802154_mac.h"

View file

@ -51,6 +51,7 @@
#include "netdev/netdev.h"
#include "devif/devif.h"
#include "socket/socket.h"
#include "icmpv6/icmpv6.h"
#include "tcp/tcp.h"
#include "utils/utils.h"
#include "sixlowpan/sixlowpan_internal.h"

View file

@ -50,6 +50,7 @@
#include "netdev/netdev.h"
#include "socket/socket.h"
#include "icmpv6/icmpv6.h"
#include "udp/udp.h"
#include "utils/utils.h"
#include "sixlowpan/sixlowpan_internal.h"

View file

@ -1,7 +1,7 @@
############################################################################
# net/tcp/Make.defs
#
# Copyright (C) 2014 Gregory Nutt. All rights reserved.
# Copyright (C) 2014, 2017 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
@ -60,6 +60,14 @@ NET_CSRCS += tcp_conn.c tcp_seqno.c tcp_devpoll.c tcp_finddev.c tcp_timer.c
NET_CSRCS += tcp_send.c tcp_input.c tcp_appsend.c tcp_listen.c
NET_CSRCS += tcp_callback.c tcp_backlog.c tcp_ipselect.c
# IP forwarding
ifeq ($(CONFIG_NET_IPFORWARD),y)
ifeq ($(CONFIG_NETDEV_MULTINIC),y)
NET_CSRCS += tcp_forward.c
endif
endif
# TCP write buffering
ifeq ($(CONFIG_NET_TCP_WRITE_BUFFERS),y)

View file

@ -71,18 +71,18 @@
*/
# define tcp_callback_alloc(conn) \
devif_callback_alloc(conn->dev, &conn->list)
devif_callback_alloc((conn)->dev, &(conn)->list)
# define tcp_callback_free(conn,cb) \
devif_conn_callback_free(conn->dev, cb, &conn->list)
devif_conn_callback_free((conn)->dev, (cb), &(conn)->list)
/* These macros allocate and free callback structures used for receiving
* notifications of device-related events.
*/
# define tcp_monitor_callback_alloc(conn) \
devif_callback_alloc(conn->dev, NULL)
devif_callback_alloc((conn)->dev, NULL)
# define tcp_monitor_callback_free(conn,cb) \
devif_conn_callback_free(conn->dev, cb, NULL)
devif_conn_callback_free((conn)->dev, (cb), NULL)
#else
/* These macros allocate and free callback structures used for receiving
@ -90,9 +90,9 @@
*/
# define tcp_callback_alloc(conn) \
devif_callback_alloc(g_netdevices, &conn->list)
devif_callback_alloc(g_netdevices, &(conn)->list)
# define tcp_callback_free(conn,cb) \
devif_conn_callback_free(g_netdevices, cb, &conn->list)
devif_conn_callback_free(g_netdevices, (cb), &(conn)->list)
/* These macros allocate and free callback structures used for receiving
* notifications of device-related events.
@ -101,7 +101,7 @@
# define tcp_monitor_callback_alloc(conn) \
devif_callback_alloc(g_netdevices, NULL)
# define tcp_monitor_callback_free(conn,cb) \
devif_conn_callback_free(g_netdevices, cb, NULL)
devif_conn_callback_free(g_netdevices, (cb), NULL)
#endif
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
@ -794,6 +794,35 @@ int tcp_accept_connection(FAR struct net_driver_s *dev,
void tcp_send(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
uint16_t flags, uint16_t len);
/****************************************************************************
* Name: tcp_forward
*
* Description:
* Called by the IP forwarding logic when an TCP packet is received on
* one network device, but must be forwarded on another network device.
*
* Set up to forward the TCP packet on the specified device. This
* function will set up a send "interrupt" handler that will perform
* the actual send asynchronously and must return without waiting for the
* send to complete.
*
* Input Parameters:
* fwd - An initialized instance of the common forwarding structure that
* includes everything needed to perform the forwarding operation.
*
* Returned Value:
* Zero is returned if the packet was successfully forwarded; A negated
* errno value is returned if the packet is not forwardable. In that
* latter case, the caller should free the IOB list and drop the packet.
*
****************************************************************************/
#if defined(CONFIG_NET_IPFORWARD) && defined(CONFIG_NET_IPv6) && \
defined(CONFIG_NETDEV_MULTINIC)
struct forward_s; /* Forward reference */
int tcp_forward(FAR struct forward_s *fwd);
#endif
/****************************************************************************
* Name: tcp_reset
*

427
net/tcp/tcp_forward.c Normal file
View file

@ -0,0 +1,427 @@
/****************************************************************************
* net/tcp/tcp_forward.c
*
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <net/if.h>
#include <nuttx/mm/iob.h>
#include <nuttx/net/netdev.h>
#include <nuttx/net/ip.h>
#include <nuttx/net/netstats.h>
#include "devif/ip_forward.h"
#include "devif/devif.h"
#include "netdev/netdev.h"
#include "tcp/tcp.h"
#if defined(CONFIG_NET_IPFORWARD) && defined(CONFIG_NET_TCP) && \
defined(CONFIG_NETDEV_MULTINIC)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: forward_ipselect
*
* Description:
* If both IPv4 and IPv6 support are enabled, then we will need to select
* which one to use when generating the outgoing packet. If only one
* domain is selected, then the setup is already in place and we need do
* nothing.
*
* Parameters:
* fwd - The forwarding state structure
*
* Returned Value:
* None
*
* Assumptions:
* The network is locked.
*
****************************************************************************/
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
static inline void forward_ipselect(FAR struct forward_s *fwd)
{
/* Which domain the connection support */
if (fwd->f_conn.tcp.domain == PF_INET)
{
/* Select the IPv4 domain */
tcp_ipv4_select(dev);
}
else /* if (conn->domain == PF_INET6) */
{
/* Select the IPv6 domain */
DEBUGASSERT(conn->domain == PF_INET6);
tcp_ipv6_select(dev);
}
}
#endif
/****************************************************************************
* Name: tcp_forward_addrchck
*
* Description:
* Check if the destination IP address is in the IPv4 ARP or IPv6 Neighbor
* tables. If not, then the send won't actually make it out... it will be
* replaced with an ARP request (IPv4) or a Neighbor Solicitation (IPv6).
*
* NOTE 1: This could be an expensive check if there are a lot of
* entries in the ARP or Neighbor tables.
*
* NOTE 2: If we are actually harvesting IP addresses on incoming IP
* packets, then this check should not be necessary; the MAC mapping
* should already be in the ARP table in many cases (IPv4 only).
*
* NOTE 3: If CONFIG_NET_ARP_SEND then we can be assured that the IP
* address mapping is already in the ARP table.
*
* Parameters:
* fwd - The forwarding state structure
*
* Returned Value:
* None
*
* Assumptions:
* The network is locked.
*
****************************************************************************/
#ifdef CONFIG_NET_ETHERNET
static inline bool tcp_forward_addrchck(FAR struct forward_s *fwd)
{
FAR struct tcp_conn_s *conn = &fwd->f_conn.tcp;
#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
if (conn->domain == PF_INET)
#endif
{
#if !defined(CONFIG_NET_ARP_IPIN) && !defined(CONFIG_NET_ARP_SEND)
return (arp_find(conn->u.ipv4.raddr) != NULL);
#else
return true;
#endif
}
#endif /* CONFIG_NET_IPv4 */
#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
else
#endif
{
#if !defined(CONFIG_NET_ICMPv6_NEIGHBOR)
return (neighbor_findentry(conn->u.ipv6.raddr) != NULL);
#else
return true;
#endif
}
#endif /* CONFIG_NET_IPv6 */
UNUSED(conn);
}
#else /* CONFIG_NET_ETHERNET */
# define tcp_forward_addrchck(r) (true)
#endif /* CONFIG_NET_ETHERNET */
/****************************************************************************
* Name: tcp_dropstats
*
* Description:
* Update statistics for a dropped packet.
*
* Input Parameters:
* fwd - The forwarding state structure
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_NET_STATISTICS
static void tcp_dropstats(FAR struct forward_s *fwd)
{
/* Increment the count of dropped TCP packets */
g_netstats.tcp.drop++;
/* Increment the count of dropped IPv4 or IPv6 packets */
#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
if (fwd->f_conn.tcp.domain == PF_INET)
#endif
{
g_netstats.ipv4.drop++;
}
#endif
#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
else
#endif
{
g_netstats.ipv6.drop++;
}
#endif
}
#else
# define tcp_dropstats(ipv6)
#endif
/****************************************************************************
* Name: tcp_forward_interrupt
*
* Description:
* This function is called from the interrupt level to perform the actual
* send operation when polled by the lower, device interfacing layer.
*
* NOTE: Our role here is just data passthrough. We don't really care
* about ACKing, dynamic windows or any of the other TCP complexities.
* That is really something between the two endpoints and does not matter
* the forwarding hub.
*
* Parameters:
* dev The structure of the network driver that caused the interrupt
* conn An instance of the TCP connection structure cast to void *
* pvpriv An instance of struct forward_s cast to void*
* flags Set of events describing why the callback was invoked
*
* Returned Value:
* Modified value of the input flags
*
* Assumptions:
* The network is locked
*
****************************************************************************/
static uint16_t tcp_forward_interrupt(FAR struct net_driver_s *dev,
FAR void *conn, FAR void *pvpriv,
uint16_t flags)
{
FAR struct forward_s *fwd = (FAR struct forward_s *)pvpriv;
ninfo("flags: %04x\n", flags);
DEBUGASSERT(fwd != NULL);
/* Make sure that this is from the forwarding device */
if (dev == fwd->f_dev)
{
/* If the network device has gone down, then we will have terminate
* the wait now with an error.
*
* REVISIT: TCP disconnection events should should not be recieved here.
* Rather the disconnection events will be handled by the TCP endpoints.
*/
if ((flags & NETDEV_DOWN) != 0)
{
/* Terminate the transfer with an error. */
nwarn("WARNING: Network is down... Dropping\n");
tcp_dropstats(fwd);
}
/* Check if the outgoing packet is available. It may have been claimed
* by a sendto interrupt serving a different thread -OR- if the output
* buffer currently contains unprocessed incoming data. In these cases
* we will just have to wait for the next polling cycle.
*/
else if (dev->d_sndlen > 0 || (flags & TCP_NEWDATA) != 0)
{
/* Another thread has beat us sending data or the buffer is busy,
* Wait for the next polling cycle and check again.
*/
return flags;
}
/* It looks like we are good to forward the data */
else
{
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
/* If both IPv4 and IPv6 support are enabled, then we will need to
* select which one to use when generating the outgoing packet.
* If only one domain is selected, then the setup is already in
* place and we need do nothing.
*/
forward_ipselect(dev, fwd);
#endif
/* Copy the user data into d_appdata and send it. */
devif_forward(fwd);
/* Check if the destination IP address is in the ARP or Neighbor
* table. If not, then the send won't actually make it out... it
* will be replaced with an ARP request or Neighbor Solicitation.
*/
if (!tcp_forward_addrchck(fwd))
{
return flags;
}
}
/* Free the allocated callback structure */
fwd->f_cb->flags = 0;
fwd->f_cb->priv = NULL;
fwd->f_cb->event = NULL;
tcp_callback_free(&fwd->f_conn.tcp, fwd->f_cb);
/* Free any IOBs */
if (fwd->f_iob != NULL)
{
iob_free_chain(fwd->f_iob);
}
/* And release the forwarding state structure */
ip_forward_free(fwd);
}
return flags;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: tcp_forward
*
* Description:
* Called by the IP forwarding logic when an TCP packet is received on
* one network device, but must be forwarded on another network device.
*
* Set up to forward the TCP packet on the specified device. This
* function will set up a send "interrupt" handler that will perform the
* actual send asynchronously and must return without waiting for the
* send to complete.
*
* Input Parameters:
* fwd - An initialized instance of the common forwarding structure that
* includes everything needed to perform the forwarding operation.
*
* Returned Value:
* Zero is returned if the packet was successfully forwarded; A negated
* errno value is returned if the packet is not forwardable. In that
* latter case, the caller should free the IOB list and drop the packet.
*
****************************************************************************/
int tcp_forward(FAR struct forward_s *fwd)
{
DEBUGASSERT(fwd != NULL && fwd->f_dev != NULL);
FAR struct tcp_conn_s *conn = &fwd->f_conn.tcp;
/* Set up some minimal connection structure so that we appear to be a
* real TCP connection.
*/
conn->dev = fwd->f_dev;
#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
if ((fwd->f_hdr.ipv4.l2.vhl & IP_VERSION_MASK) == IPv4_VERSION)
#endif
{
FAR struct ipv4_hdr_s *ipv4 = &fwd->f_hdr.ipv4.l2;
FAR struct tcp_hdr_s *tcp = &fwd->f_hdr.ipv4.l3.tcp;
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
conn->domain = PF_INET;
#endif
conn->lport = tcp->srcport;
conn->rport = tcp->destport;
net_ipv4addr_copy(conn->u.ipv4.laddr, ipv4->srcipaddr);
net_ipv4addr_copy(conn->u.ipv4.raddr, ipv4->destipaddr);
}
#endif
#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
else
#endif
{
FAR struct ipv6_hdr_s *ipv6 = &fwd->f_hdr.ipv6.l2;
FAR struct tcp_hdr_s *tcp = &fwd->f_hdr.ipv6.l3.tcp;
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
conn->domain = PF_INET6;
#endif
conn->lport = tcp->srcport;
conn->rport = tcp->destport;
net_ipv6addr_copy(conn->u.ipv6.laddr, ipv6->srcipaddr);
net_ipv6addr_copy(conn->u.ipv6.raddr, ipv6->destipaddr);
}
#endif
/* Set up the callback in the connection */
fwd->f_cb = tcp_callback_alloc(conn);
if (fwd->f_cb != NULL)
{
fwd->f_cb->flags = (TCP_POLL | NETDEV_DOWN);
fwd->f_cb->priv = (FAR void *)fwd;
fwd->f_cb->event = tcp_forward_interrupt;
/* Notify the device driver of the availability of TX data */
netdev_txnotify_dev(fwd->f_dev);
return OK;
}
return -EBUSY;
}
#endif /* CONFIG_NET_IPFORWARD && CONFIG_NET_TCP && CONFIG_NETDEV_MULTINIC */

View file

@ -181,7 +181,7 @@ static inline int send_timeout(FAR struct send_s *pstate)
static inline void tcpsend_ipselect(FAR struct net_driver_s *dev,
FAR struct tcp_conn_s *conn)
{
/* Which domain the socket support */
/* Which domain does the socket support */
if (conn->domain == PF_INET)
{

View file

@ -48,6 +48,14 @@ NET_CSRCS += udp_netpoll.c
endif
endif
# IP forwarding
ifeq ($(CONFIG_NET_IPFORWARD),y)
ifeq ($(CONFIG_NETDEV_MULTINIC),y)
NET_CSRCS += udp_forward.c
endif
endif
# Transport layer
NET_CSRCS += udp_conn.c udp_devpoll.c udp_send.c udp_input.c udp_finddev.c

View file

@ -68,10 +68,10 @@
/* Allocate a new UDP data callback */
#define udp_callback_alloc(dev, conn) \
devif_callback_alloc(dev, &conn->list)
#define udp_callback_free(dev, conn,cb) \
devif_conn_callback_free(dev, cb, &conn->list)
#define udp_callback_alloc(dev,conn) \
devif_callback_alloc((dev), &(conn)->list)
#define udp_callback_free(dev,conn,cb) \
devif_conn_callback_free((dev), (cb), &(conn)->list)
/****************************************************************************
* Public Type Definitions
@ -428,6 +428,35 @@ FAR struct net_driver_s *udp_find_raddr_device(FAR struct udp_conn_s *conn);
uint16_t udp_callback(FAR struct net_driver_s *dev,
FAR struct udp_conn_s *conn, uint16_t flags);
/****************************************************************************
* Name: udp_forward
*
* Description:
* Called by the IP forwarding logic when an UDP packet is received on
* one network device, but must be forwarded on another network device.
*
* Set up to forward the UDP packet on the specified device. This
* function will set up a send "interrupt" handler that will perform the
* actual send asynchronously and must return without waiting for the
* send to complete.
*
* Input Parameters:
* fwd - An initialized instance of the common forwarding structure that
* includes everything needed to perform the forwarding operation.
*
* Returned Value:
* Zero is returned if the packet was successfully forwarded; A negated
* errno value is returned if the packet is not forwardable. In that
* latter case, the caller should free the IOB list and drop the packet.
*
****************************************************************************/
#if defined(CONFIG_NET_IPFORWARD) && defined(CONFIG_NET_IPv6) && \
defined(CONFIG_NETDEV_MULTINIC)
struct forward_s; /* Forward reference */
int udp_forward(FAR struct forward_s *fwd);
#endif
/****************************************************************************
* Name: psock_udp_send
*

View file

@ -457,6 +457,7 @@ FAR struct udp_conn_s *udp_alloc(uint8_t domain)
conn->domain = domain;
#endif
conn->lport = 0;
conn->ttl = IP_TTL;
/* Enqueue the connection into the active list */
@ -760,7 +761,6 @@ int udp_connect(FAR struct udp_conn_s *conn, FAR const struct sockaddr *addr)
#endif /* CONFIG_NET_IPv6 */
}
conn->ttl = IP_TTL;
return OK;
}

367
net/udp/udp_forward.c Normal file
View file

@ -0,0 +1,367 @@
/****************************************************************************
* net/udp/udp_forward.c
*
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <net/if.h>
#include <nuttx/mm/iob.h>
#include <nuttx/net/netdev.h>
#include <nuttx/net/ip.h>
#include <nuttx/net/netstats.h>
#include "devif/ip_forward.h"
#include "devif/devif.h"
#include "netdev/netdev.h"
#include "udp/udp.h"
#if defined(CONFIG_NET_IPFORWARD) && defined(CONFIG_NET_UDP) && \
defined(CONFIG_NETDEV_MULTINIC)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: forward_ipselect
*
* Description:
* If both IPv4 and IPv6 support are enabled, then we will need to select
* which one to use when generating the outgoing packet. If only one
* domain is selected, then the setup is already in place and we need do
* nothing.
*
* Parameters:
* fwd - The forwarding state structure
*
* Returned Value:
* None
*
* Assumptions:
* The network is locked.
*
****************************************************************************/
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
static inline void forward_ipselect(FAR struct forward_s *fwd)
{
/* Select IPv4 or IPv6 */
if ((fwd->f_hdr.ipv4.l2.vhl & IP_VERSION_MASK) == IPv4_VERSION)
{
udp_ipv4_select(fwd->f_dev);
}
else
{
udp_ipv6_select(fwd->f_dev);
}
}
#endif
/****************************************************************************
* Name: udp_forward_addrchk
*
* Description:
* Check if the destination IP address is in the IPv4 ARP or IPv6 Neighbor
* tables. If not, then the send won't actually make it out... it will be
* replaced with an ARP request (IPv4) or a Neighbor Solicitation (IPv6).
*
* NOTE 1: This could be an expensive check if there are a lot of
* entries in the ARP or Neighbor tables.
*
* NOTE 2: If we are actually harvesting IP addresses on incoming IP
* packets, then this check should not be necessary; the MAC mapping
* should already be in the ARP table in many cases (IPv4 only).
*
* NOTE 3: If CONFIG_NET_ARP_SEND then we can be assured that the IP
* address mapping is already in the ARP table.
*
* Parameters:
* fwd - The forwarding state structure
*
* Returned Value:
* None
*
* Assumptions:
* The network is locked.
*
****************************************************************************/
#ifdef CONFIG_NET_ETHERNET
static inline bool udp_forward_addrchk(FAR struct forward_s *fwd)
{
#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
if (conn->domain == PF_INET)
#endif
{
#if !defined(CONFIG_NET_ARP_IPIN) && !defined(CONFIG_NET_ARP_SEND)
return (arp_find(fwd->f_hdr.ipv4.l2.destipaddr) != NULL);
#else
return true;
#endif
}
#endif /* CONFIG_NET_IPv4 */
#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
else
#endif
{
#if !defined(CONFIG_NET_ICMPv6_NEIGHBOR)
return (neighbor_findentry(fwd->f_hdr.ipv6.l2.destipaddr) != NULL);
#else
return true;
#endif
}
#endif /* CONFIG_NET_IPv6 */
}
#else /* CONFIG_NET_ETHERNET */
# define udp_forward_addrchk(r) (true)
#endif /* CONFIG_NET_ETHERNET */
/****************************************************************************
* Name: udp_dropstats
*
* Description:
* Update statistics for a dropped packet.
*
* Input Parameters:
* fwd - The forwarding state structure
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_NET_STATISTICS
static void udp_dropstats(FAR struct forward_s *fwd)
{
/* Increment the count of dropped UDP packets */
g_netstats.udp.drop++;
/* Increment the count of dropped IPv4 or IPv6 packets */
#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
if ((fwd->f_hdr.ipv4.l2.vhl & IP_VERSION_MASK) == IPv4_VERSION)
#endif
{
g_netstats.ipv4.drop++;
}
#endif
#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
else
#endif
{
g_netstats.ipv6.drop++;
}
#endif
}
#else
# define udp_dropstats(ipv6)
#endif
/****************************************************************************
* Name: udp_forward_interrupt
*
* Description:
* This function is called from the interrupt level to perform the actual
* send operation when polled by the lower, device interfacing layer.
*
* Parameters:
* dev The structure of the network driver that caused the interrupt
* conn An instance of the UDP connection structure cast to void *
* pvpriv An instance of struct forward_s cast to void*
* flags Set of events describing why the callback was invoked
*
* Returned Value:
* Modified value of the input flags
*
* Assumptions:
* The network is locked
*
****************************************************************************/
static uint16_t udp_forward_interrupt(FAR struct net_driver_s *dev,
FAR void *conn, FAR void *pvpriv,
uint16_t flags)
{
FAR struct forward_s *fwd = (FAR struct forward_s *)pvpriv;
ninfo("flags: %04x\n", flags);
DEBUGASSERT(fwd != NULL);
/* Make sure that this is from the forwarding device */
if (dev == fwd->f_dev)
{
/* If the network device has gone down, then we will have terminate
* the wait now with an error.
*/
if ((flags & NETDEV_DOWN) != 0)
{
/* Terminate the transfer with an error. */
nwarn("WARNING: Network is down... Dropping\n");
udp_dropstats(fwd);
}
/* Check if the outgoing packet is available. It may have been claimed
* by a sendto interrupt serving a different thread -OR- if the output
* buffer currently contains unprocessed incoming data. In these cases
* we will just have to wait for the next polling cycle.
*/
else if (dev->d_sndlen > 0 || (flags & UDP_NEWDATA) != 0)
{
/* Another thread has beat us sending data or the buffer is busy,
* Wait for the next polling cycle and check again.
*/
return flags;
}
/* It looks like we are good to forward the data */
else
{
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
/* If both IPv4 and IPv6 support are enabled, then we will need to
* select which one to use when generating the outgoing packet.
* If only one domain is selected, then the setup is already in
* place and we need do nothing.
*/
forward_ipselect(dev, fwd);
#endif
/* Copy the user data into d_appdata and send it. */
devif_forward(fwd);
/* Check if the destination IP address is in the ARP or Neighbor
* table. If not, then the send won't actually make it out... it
* will be replaced with an ARP request or Neighbor Solicitation.
*/
if (!udp_forward_addrchk(fwd))
{
return flags;
}
}
/* Free the allocated callback structure */
fwd->f_cb->flags = 0;
fwd->f_cb->priv = NULL;
fwd->f_cb->event = NULL;
udp_callback_free(dev, &fwd->f_conn.udp, fwd->f_cb);
/* Free any IOBs */
if (fwd->f_iob != NULL)
{
iob_free_chain(fwd->f_iob);
}
/* And release the forwarding state structure */
ip_forward_free(fwd);
}
return flags;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: udp_forward
*
* Description:
* Called by the IP forwarding logic when an UDP packet is received on
* one network device, but must be forwarded on another network device.
*
* Set up to forward the UDP packet on the specified device. This
* function will set up a send "interrupt" handler that will perform the
* actual send asynchronously and must return without waiting for the
* send to complete.
*
* Input Parameters:
* fwd - An initialized instance of the common forwarding structure that
* includes everything needed to perform the forwarding operation.
*
* Returned Value:
* Zero is returned if the packet was successfully forwarded; A negated
* errno value is returned if the packet is not forwardable. In that
* latter case, the caller should free the IOB list and drop the packet.
*
****************************************************************************/
int udp_forward(FAR struct forward_s *fwd)
{
DEBUGASSERT(fwd != NULL && fwd->f_dev != NULL);
/* Set up the callback in the connection */
fwd->f_cb = udp_callback_alloc(fwd->f_dev, &fwd->f_conn.udp);
if (fwd->f_cb != NULL)
{
fwd->f_cb->flags = (UDP_POLL | NETDEV_DOWN);
fwd->f_cb->priv = (FAR void *)fwd;
fwd->f_cb->event = udp_forward_interrupt;
/* Notify the device driver of the availability of TX data */
netdev_txnotify_dev(fwd->f_dev);
return OK;
}
return -EBUSY;
}
#endif /* CONFIG_NET_IPFORWARD && CONFIG_NET_UDP && CONFIG_NETDEV_MULTINIC */

View file

@ -126,7 +126,7 @@ struct sendto_s
* TRUE:timeout FALSE:no timeout
*
* Assumptions:
* Running at the interrupt level
* The network is locked
*
****************************************************************************/
@ -170,7 +170,7 @@ static inline int send_timeout(FAR struct sendto_s *pstate)
* None
*
* Assumptions:
* Running at the interrupt level
* The network is locked
*
****************************************************************************/
@ -194,7 +194,7 @@ static inline void sendto_ipselect(FAR struct net_driver_s *dev,
/* Select the IPv6 domain */
DEBUGASSERT(psock->s_domain == PF_INET6);
udp_ipv4_select(dev);
udp_ipv6_select(dev);
}
}
#endif
@ -216,7 +216,7 @@ static inline void sendto_ipselect(FAR struct net_driver_s *dev,
* Modified value of the input flags
*
* Assumptions:
* Running at the interrupt level
* The network is locked
*
****************************************************************************/

View file

@ -118,7 +118,7 @@ uint16_t ipv4_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto)
* Name: ipv6_upperlayer_chksum
*
* Description:
* Perform the checksum calcaultion over the IPv6, protocol headers, and
* Perform the checksum calculation over the IPv6, protocol headers, and
* data payload as necessary.
*
* Input Parameters: