From 48026bb824fd2d9cfb00ecd040db6ef3a416bae9 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Fri, 22 Jan 2021 21:43:36 -0500 Subject: upload initial port --- ChibiOS_20.3.2/os/various/lwip_bindings/arch/cc.h | 89 ++++ .../os/various/lwip_bindings/arch/sys_arch.c | 239 ++++++++++ .../os/various/lwip_bindings/arch/sys_arch.h | 68 +++ ChibiOS_20.3.2/os/various/lwip_bindings/lwip.mk | 23 + .../os/various/lwip_bindings/lwipthread.c | 530 +++++++++++++++++++++ .../os/various/lwip_bindings/lwipthread.h | 275 +++++++++++ ChibiOS_20.3.2/os/various/lwip_bindings/readme.txt | 6 + .../os/various/lwip_bindings/static_lwipopts.h | 42 ++ 8 files changed, 1272 insertions(+) create mode 100644 ChibiOS_20.3.2/os/various/lwip_bindings/arch/cc.h create mode 100644 ChibiOS_20.3.2/os/various/lwip_bindings/arch/sys_arch.c create mode 100644 ChibiOS_20.3.2/os/various/lwip_bindings/arch/sys_arch.h create mode 100644 ChibiOS_20.3.2/os/various/lwip_bindings/lwip.mk create mode 100644 ChibiOS_20.3.2/os/various/lwip_bindings/lwipthread.c create mode 100644 ChibiOS_20.3.2/os/various/lwip_bindings/lwipthread.h create mode 100644 ChibiOS_20.3.2/os/various/lwip_bindings/readme.txt create mode 100644 ChibiOS_20.3.2/os/various/lwip_bindings/static_lwipopts.h (limited to 'ChibiOS_20.3.2/os/various/lwip_bindings') diff --git a/ChibiOS_20.3.2/os/various/lwip_bindings/arch/cc.h b/ChibiOS_20.3.2/os/various/lwip_bindings/arch/cc.h new file mode 100644 index 0000000..5258a84 --- /dev/null +++ b/ChibiOS_20.3.2/os/various/lwip_bindings/arch/cc.h @@ -0,0 +1,89 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +/* + * **** This file incorporates work covered by the following copyright and **** + * **** permission notice: **** + * + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#ifndef __CC_H__ +#define __CC_H__ + +#include + +/* Use errno provided by system. */ +#define LWIP_ERRNO_INCLUDE + +/** + * @brief Use system provided struct timeval by default. + */ +#ifndef LWIP_TIMEVAL_PRIVATE +#define LWIP_TIMEVAL_PRIVATE 0 +#include +#endif + +/** + * @brief Use a no-op diagnostic output macro by default. + */ +#if !defined(LWIP_PLATFORM_DIAG) +#define LWIP_PLATFORM_DIAG(x) +#endif + +/** + * @brief Halt the system on lwIP assert failure by default. + */ +#if !defined(LWIP_PLATFORM_ASSERT) +#define LWIP_PLATFORM_ASSERT(x) osalSysHalt(x) +#endif + +/** + * @brief The NETIF API is required by lwipthread. + */ +#ifdef LWIP_NETIF_API +#undef LWIP_NETIF_API +#endif +#define LWIP_NETIF_API 1 + +#endif /* __CC_H__ */ diff --git a/ChibiOS_20.3.2/os/various/lwip_bindings/arch/sys_arch.c b/ChibiOS_20.3.2/os/various/lwip_bindings/arch/sys_arch.c new file mode 100644 index 0000000..7a7d5ea --- /dev/null +++ b/ChibiOS_20.3.2/os/various/lwip_bindings/arch/sys_arch.c @@ -0,0 +1,239 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +/* + * **** This file incorporates work covered by the following copyright and **** + * **** permission notice: **** + * + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* + * See http://lwip.wikia.com/wiki/Porting_for_an_OS for instructions. + */ + +#include "hal.h" + +#include "lwip/opt.h" +#include "lwip/mem.h" +#include "lwip/sys.h" +#include "lwip/stats.h" + +#include "arch/cc.h" +#include "arch/sys_arch.h" + +void sys_init(void) { + +} + +err_t sys_sem_new(sys_sem_t *sem, u8_t count) { + + *sem = chHeapAlloc(NULL, sizeof(semaphore_t)); + if (*sem == 0) { + SYS_STATS_INC(sem.err); + return ERR_MEM; + } + else { + chSemObjectInit(*sem, (cnt_t)count); + SYS_STATS_INC_USED(sem); + return ERR_OK; + } +} + +void sys_sem_free(sys_sem_t *sem) { + + chHeapFree(*sem); + *sem = SYS_SEM_NULL; + SYS_STATS_DEC(sem.used); +} + +void sys_sem_signal(sys_sem_t *sem) { + + chSemSignal(*sem); +} + +/* CHIBIOS FIX: specific variant of this call to be called from within + a lock.*/ +void sys_sem_signal_S(sys_sem_t *sem) { + + chSemSignalI(*sem); + chSchRescheduleS(); +} + +u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) { + systime_t start; + sysinterval_t tmo, remaining; + + chSysLock(); + tmo = timeout > 0 ? TIME_MS2I((time_msecs_t)timeout) : TIME_INFINITE; + start = chVTGetSystemTimeX(); + if (chSemWaitTimeoutS(*sem, tmo) != MSG_OK) { + chSysUnlock(); + return SYS_ARCH_TIMEOUT; + } + remaining = chTimeDiffX(start, chVTGetSystemTimeX()); + chSysUnlock(); + return (u32_t)TIME_I2MS(remaining); +} + +int sys_sem_valid(sys_sem_t *sem) { + return *sem != SYS_SEM_NULL; +} + +// typically called within lwIP after freeing a semaphore +// to make sure the pointer is not left pointing to invalid data +void sys_sem_set_invalid(sys_sem_t *sem) { + *sem = SYS_SEM_NULL; +} + +err_t sys_mbox_new(sys_mbox_t *mbox, int size) { + + *mbox = chHeapAlloc(NULL, sizeof(mailbox_t) + sizeof(msg_t) * size); + if (*mbox == 0) { + SYS_STATS_INC(mbox.err); + return ERR_MEM; + } + else { + chMBObjectInit(*mbox, (void *)(((uint8_t *)*mbox) + sizeof(mailbox_t)), size); + SYS_STATS_INC(mbox.used); + return ERR_OK; + } +} + +void sys_mbox_free(sys_mbox_t *mbox) { + cnt_t tmpcnt; + + chSysLock(); + tmpcnt = chMBGetUsedCountI(*mbox); + chSysUnlock(); + + if (tmpcnt != 0) { + // If there are messages still present in the mailbox when the mailbox + // is deallocated, it is an indication of a programming error in lwIP + // and the developer should be notified. + SYS_STATS_INC(mbox.err); + chMBReset(*mbox); + } + chHeapFree(*mbox); + *mbox = SYS_MBOX_NULL; + SYS_STATS_DEC(mbox.used); +} + +void sys_mbox_post(sys_mbox_t *mbox, void *msg) { + + chMBPostTimeout(*mbox, (msg_t)msg, TIME_INFINITE); +} + +err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) { + + if (chMBPostTimeout(*mbox, (msg_t)msg, TIME_IMMEDIATE) == MSG_TIMEOUT) { + SYS_STATS_INC(mbox.err); + return ERR_MEM; + } + return ERR_OK; +} + +u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) { + systime_t start; + sysinterval_t tmo, remaining; + + chSysLock(); + tmo = timeout > 0 ? TIME_MS2I((time_msecs_t)timeout) : TIME_INFINITE; + start = chVTGetSystemTimeX(); + if (chMBFetchTimeoutS(*mbox, (msg_t *)msg, tmo) != MSG_OK) { + chSysUnlock(); + return SYS_ARCH_TIMEOUT; + } + remaining = chTimeDiffX(start, chVTGetSystemTimeX()); + chSysUnlock(); + return (u32_t)TIME_I2MS(remaining); +} + +u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) { + + if (chMBFetchTimeout(*mbox, (msg_t *)msg, TIME_IMMEDIATE) == MSG_TIMEOUT) + return SYS_MBOX_EMPTY; + return 0; +} + +int sys_mbox_valid(sys_mbox_t *mbox) { + return *mbox != SYS_MBOX_NULL; +} + +// typically called within lwIP after freeing an mbox +// to make sure the pointer is not left pointing to invalid data +void sys_mbox_set_invalid(sys_mbox_t *mbox) { + *mbox = SYS_MBOX_NULL; +} + +sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, + void *arg, int stacksize, int prio) { + thread_t *tp; + + tp = chThdCreateFromHeap(NULL, THD_WORKING_AREA_SIZE(stacksize), + name, prio, (tfunc_t)thread, arg); + return (sys_thread_t)tp; +} + +sys_prot_t sys_arch_protect(void) { + + return chSysGetStatusAndLockX(); +} + +void sys_arch_unprotect(sys_prot_t pval) { + + chSysRestoreStatusX((syssts_t)pval); +} + +u32_t sys_now(void) { + +#if OSAL_ST_FREQUENCY == 1000 + return (u32_t)chVTGetSystemTimeX(); +#elif (OSAL_ST_FREQUENCY / 1000) >= 1 && (OSAL_ST_FREQUENCY % 1000) == 0 + return ((u32_t)chVTGetSystemTimeX() - 1) / (OSAL_ST_FREQUENCY / 1000) + 1; +#elif (1000 / OSAL_ST_FREQUENCY) >= 1 && (1000 % OSAL_ST_FREQUENCY) == 0 + return ((u32_t)chVTGetSystemTimeX() - 1) * (1000 / OSAL_ST_FREQUENCY) + 1; +#else + return (u32_t)(((u64_t)(chVTGetSystemTimeX() - 1) * 1000) / OSAL_ST_FREQUENCY) + 1; +#endif +} diff --git a/ChibiOS_20.3.2/os/various/lwip_bindings/arch/sys_arch.h b/ChibiOS_20.3.2/os/various/lwip_bindings/arch/sys_arch.h new file mode 100644 index 0000000..bbb3531 --- /dev/null +++ b/ChibiOS_20.3.2/os/various/lwip_bindings/arch/sys_arch.h @@ -0,0 +1,68 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +/* + * **** This file incorporates work covered by the following copyright and **** + * **** permission notice: **** + * + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include + +#ifndef __SYS_ARCH_H__ +#define __SYS_ARCH_H__ + +typedef semaphore_t * sys_sem_t; +typedef mailbox_t * sys_mbox_t; +typedef thread_t * sys_thread_t; +typedef syssts_t sys_prot_t; + +#define SYS_MBOX_NULL (mailbox_t *)0 +#define SYS_THREAD_NULL (thread_t *)0 +#define SYS_SEM_NULL (semaphore_t *)0 + +/* let sys.h use binary semaphores for mutexes */ +#define LWIP_COMPAT_MUTEX 1 + +#endif /* __SYS_ARCH_H__ */ diff --git a/ChibiOS_20.3.2/os/various/lwip_bindings/lwip.mk b/ChibiOS_20.3.2/os/various/lwip_bindings/lwip.mk new file mode 100644 index 0000000..961e710 --- /dev/null +++ b/ChibiOS_20.3.2/os/various/lwip_bindings/lwip.mk @@ -0,0 +1,23 @@ +# List of the required lwIP files. +LWIPDIR = $(CHIBIOS)/ext/lwip/src + +# The various blocks of files are outlined in Filelists.mk. +include $(LWIPDIR)/Filelists.mk + +LWBINDSRC = \ + $(CHIBIOS)/os/various/lwip_bindings/lwipthread.c \ + $(CHIBIOS)/os/various/lwip_bindings/arch/sys_arch.c + + +# Add blocks of files from Filelists.mk as required for enabled options +LWSRC_REQUIRED = $(COREFILES) $(CORE4FILES) $(APIFILES) $(LWBINDSRC) $(NETIFFILES) +LWSRC_EXTRAS ?= $(HTTPFILES) + +LWINC = \ + $(CHIBIOS)/os/various/lwip_bindings \ + $(LWIPDIR)/include + +# Shared variables +ALLCSRC += $(LWSRC_REQUIRED) $(LWSRC_EXTRAS) +ALLINC += $(LWINC) \ + $(CHIBIOS)/os/various diff --git a/ChibiOS_20.3.2/os/various/lwip_bindings/lwipthread.c b/ChibiOS_20.3.2/os/various/lwip_bindings/lwipthread.c new file mode 100644 index 0000000..ee4303f --- /dev/null +++ b/ChibiOS_20.3.2/os/various/lwip_bindings/lwipthread.c @@ -0,0 +1,530 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +/* + * **** This file incorporates work covered by the following copyright and **** + * **** permission notice: **** + * + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/** + * @file lwipthread.c + * @brief LWIP wrapper thread code. + * @addtogroup LWIP_THREAD + * @{ + */ + +#include "hal.h" +#include "evtimer.h" + +#include "lwipthread.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if LWIP_DHCP +#include +#endif + +#if LWIP_AUTOIP +#include +#endif + +#define PERIODIC_TIMER_ID 1 +#define FRAME_RECEIVED_ID 2 + +/* + * Suspension point for initialization procedure. + */ +thread_reference_t lwip_trp = NULL; + +/* + * Stack area for the LWIP-MAC thread. + */ +static THD_WORKING_AREA(wa_lwip_thread, LWIP_THREAD_STACK_SIZE); + +/* + * Initialization. + */ +static void low_level_init(struct netif *netif) { + /* set MAC hardware address length */ + netif->hwaddr_len = ETHARP_HWADDR_LEN; + + /* maximum transfer unit */ + netif->mtu = LWIP_NETIF_MTU; + + /* device capabilities */ + /* don't set NETIF_FLAG_ETHARP if this device is not an Ethernet one */ + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; + + /* Do whatever else is needed to initialize interface. */ +} + +/* + * This function does the actual transmission of the packet. The packet is + * contained in the pbuf that is passed to the function. This pbuf + * might be chained. + * + * @param netif the lwip network interface structure for this ethernetif + * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) + * @return ERR_OK if the packet could be sent + * an err_t value if the packet couldn't be sent + * + * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to + * strange results. You might consider waiting for space in the DMA queue + * to become available since the stack doesn't retry to send a packet + * dropped because of memory failure (except for the TCP timers). + */ +static err_t low_level_output(struct netif *netif, struct pbuf *p) { + struct pbuf *q; + MACTransmitDescriptor td; + + (void)netif; + if (macWaitTransmitDescriptor(ÐD1, &td, TIME_MS2I(LWIP_SEND_TIMEOUT)) != MSG_OK) + return ERR_TIMEOUT; + +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + + /* Iterates through the pbuf chain. */ + for(q = p; q != NULL; q = q->next) + macWriteTransmitDescriptor(&td, (uint8_t *)q->payload, (size_t)q->len); + macReleaseTransmitDescriptor(&td); + + MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len); + if (((u8_t*)p->payload)[0] & 1) { + /* broadcast or multicast packet*/ + MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts); + } + else { + /* unicast packet */ + MIB2_STATS_NETIF_INC(netif, ifoutucastpkts); + } + /* increase ifoutdiscards or ifouterrors on error */ + +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + + LINK_STATS_INC(link.xmit); + + return ERR_OK; +} + +/* + * Receives a frame. + * Allocates a pbuf and transfers the bytes of the incoming + * packet from the interface into the pbuf. + * + * @param netif the lwip network interface structure for this ethernetif + * @return a pbuf filled with the received packet (including MAC header) + * NULL on memory error + */ +static bool low_level_input(struct netif *netif, struct pbuf **pbuf) { + MACReceiveDescriptor rd; + struct pbuf *q; + u16_t len; + + (void)netif; + + osalDbgAssert(pbuf != NULL, "invalid null pointer"); + + if (macWaitReceiveDescriptor(ÐD1, &rd, TIME_IMMEDIATE) != MSG_OK) + return false; + + len = (u16_t)rd.size; + +#if ETH_PAD_SIZE + len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ +#endif + + /* We allocate a pbuf chain of pbufs from the pool. */ + *pbuf = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + + if (*pbuf != NULL) { +#if ETH_PAD_SIZE + pbuf_header(*pbuf, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + + /* Iterates through the pbuf chain. */ + for(q = *pbuf; q != NULL; q = q->next) + macReadReceiveDescriptor(&rd, (uint8_t *)q->payload, (size_t)q->len); + macReleaseReceiveDescriptor(&rd); + + MIB2_STATS_NETIF_ADD(netif, ifinoctets, (*pbuf)->tot_len); + + if (*(uint8_t *)((*pbuf)->payload) & 1) { + /* broadcast or multicast packet*/ + MIB2_STATS_NETIF_INC(netif, ifinnucastpkts); + } + else { + /* unicast packet*/ + MIB2_STATS_NETIF_INC(netif, ifinucastpkts); + } + +#if ETH_PAD_SIZE + pbuf_header(*pbuf, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + + LINK_STATS_INC(link.recv); + } + else { + macReleaseReceiveDescriptor(&rd); // Drop packet + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + MIB2_STATS_NETIF_INC(netif, ifindiscards); + } + + return true; +} + +/* + * Called at the beginning of the program to set up the + * network interface. It calls the function low_level_init() to do the + * actual setup of the hardware. + * + * This function should be passed as a parameter to netifapi_netif_add(). + * + * @param netif the lwip network interface structure for this ethernetif + * @return ERR_OK if the loopif is initialised + * ERR_MEM if private data couldn't be allocated + * any other err_t on error + */ +static err_t ethernetif_init(struct netif *netif) { + osalDbgAssert((netif != NULL), "netif != NULL"); + + /* + * Initialize the snmp variables and counters inside the struct netif. + * The last argument should be replaced with your link speed, in units + * of bits per second. + */ + MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LWIP_LINK_SPEED); + + netif->state = NULL; + netif->name[0] = LWIP_IFNAME0; + netif->name[1] = LWIP_IFNAME1; + /* We directly use etharp_output() here to save a function call. + * You can instead declare your own function an call etharp_output() + * from it if you have to do some checks before sending (e.g. if link + * is available...) */ + netif->output = etharp_output; + netif->linkoutput = low_level_output; + + /* initialize the hardware */ + low_level_init(netif); + + return ERR_OK; +} + +static net_addr_mode_t addressMode; +static ip4_addr_t ip, gateway, netmask; +static struct netif thisif; + +void lwipDefaultLinkUpCB(void *p) +{ + struct netif *ifc = (struct netif*) p; + (void) ifc; +#if LWIP_AUTOIP + if (addressMode == NET_ADDRESS_AUTO) + autoip_start(ifc); +#endif +#if LWIP_DHCP + if (addressMode == NET_ADDRESS_DHCP) + dhcp_start(ifc); +#endif +} + +void lwipDefaultLinkDownCB(void *p) +{ + struct netif *ifc = (struct netif*) p; + (void) ifc; +#if LWIP_AUTOIP + if (addressMode == NET_ADDRESS_AUTO) + autoip_stop(ifc); +#endif +#if LWIP_DHCP + if (addressMode == NET_ADDRESS_DHCP) + dhcp_stop(ifc); +#endif +} + +/** + * @brief LWIP handling thread. + * + * @param[in] p pointer to a @p lwipthread_opts structure or @p NULL + * @return The function does not return. + */ +static THD_FUNCTION(lwip_thread, p) { + event_timer_t evt; + event_listener_t el0, el1; + static const MACConfig mac_config = {thisif.hwaddr}; + err_t result; + tcpip_callback_fn link_up_cb = NULL; + tcpip_callback_fn link_down_cb = NULL; + + chRegSetThreadName(LWIP_THREAD_NAME); + + /* Initializes the thing.*/ + tcpip_init(NULL, NULL); + + /* TCP/IP parameters, runtime or compile time.*/ + if (p) { + lwipthread_opts_t *opts = p; + unsigned i; + + for (i = 0; i < 6; i++) + thisif.hwaddr[i] = opts->macaddress[i]; + ip.addr = opts->address; + gateway.addr = opts->gateway; + netmask.addr = opts->netmask; + addressMode = opts->addrMode; +#if LWIP_NETIF_HOSTNAME + thisif.hostname = opts->ourHostName; +#endif + link_up_cb = opts->link_up_cb; + link_down_cb = opts->link_down_cb; + } + else { + thisif.hwaddr[0] = LWIP_ETHADDR_0; + thisif.hwaddr[1] = LWIP_ETHADDR_1; + thisif.hwaddr[2] = LWIP_ETHADDR_2; + thisif.hwaddr[3] = LWIP_ETHADDR_3; + thisif.hwaddr[4] = LWIP_ETHADDR_4; + thisif.hwaddr[5] = LWIP_ETHADDR_5; + LWIP_IPADDR(&ip); + LWIP_GATEWAY(&gateway); + LWIP_NETMASK(&netmask); +#if LWIP_DHCP + addressMode = NET_ADDRESS_DHCP; +#elif LWIP_AUTOIP + addressMode = NET_ADDRESS_AUTO; +#else + addressMode = NET_ADDRESS_STATIC; +#endif +#if LWIP_NETIF_HOSTNAME + thisif.hostname = NULL; +#endif + } + + if (!link_up_cb) + link_up_cb = lwipDefaultLinkUpCB; + if (!link_down_cb) + link_down_cb = lwipDefaultLinkDownCB; + +#if LWIP_NETIF_HOSTNAME + if (thisif.hostname == NULL) + thisif.hostname = LWIP_NETIF_HOSTNAME_STRING; +#endif + + macStart(ÐD1, &mac_config); + + MIB2_INIT_NETIF(&thisif, snmp_ifType_ethernet_csmacd, 0); + + /* Add interface. */ + result = netifapi_netif_add(&thisif, &ip, &netmask, &gateway, NULL, ethernetif_init, tcpip_input); + if (result != ERR_OK) + { + chThdSleepMilliseconds(1000); // Give some time to print any other diagnostics. + osalSysHalt("netif_add error"); // Not sure what else we can do if an error occurs here. + }; + + netifapi_netif_set_default(&thisif); + netifapi_netif_set_up(&thisif); + + /* Setup event sources.*/ + evtObjectInit(&evt, LWIP_LINK_POLL_INTERVAL); + evtStart(&evt); + chEvtRegisterMask(&evt.et_es, &el0, PERIODIC_TIMER_ID); + chEvtRegisterMask(macGetReceiveEventSource(ÐD1), &el1, FRAME_RECEIVED_ID); + chEvtAddEvents(PERIODIC_TIMER_ID | FRAME_RECEIVED_ID); + + /* Resumes the caller and goes to the final priority.*/ + chThdResume(&lwip_trp, MSG_OK); + chThdSetPriority(LWIP_THREAD_PRIORITY); + + while (true) { + eventmask_t mask = chEvtWaitAny(ALL_EVENTS); + if (mask & PERIODIC_TIMER_ID) { + bool current_link_status = macPollLinkStatus(ÐD1); + if (current_link_status != netif_is_link_up(&thisif)) { + if (current_link_status) { + tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_up, + &thisif, 0); + tcpip_callback_with_block(link_up_cb, &thisif, 0); + } + else { + tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_down, + &thisif, 0); + tcpip_callback_with_block(link_down_cb, &thisif, 0); + } + } + } + + if (mask & FRAME_RECEIVED_ID) { + struct pbuf *p; + while (low_level_input(&thisif, &p)) { + if (p != NULL) { + struct eth_hdr *ethhdr = p->payload; + switch (htons(ethhdr->type)) { + /* IP or ARP packet? */ + case ETHTYPE_IP: + case ETHTYPE_ARP: + /* full packet send to tcpip_thread to process */ + if (thisif.input(p, &thisif) == ERR_OK) + break; + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); + /* Falls through */ + default: + pbuf_free(p); + } + } + } + } + } +} + +/** + * @brief Initializes the lwIP subsystem. + * @note The function exits after the initialization is finished. + * + * @param[in] opts pointer to the configuration structure, if @p NULL + * then the static configuration is used. + */ +void lwipInit(const lwipthread_opts_t *opts) { + + /* Creating the lwIP thread (it changes priority internally).*/ + chThdCreateStatic(wa_lwip_thread, sizeof (wa_lwip_thread), + chThdGetPriorityX() - 1, lwip_thread, (void *)opts); + + /* Waiting for the lwIP thread complete initialization. Note, + this thread reaches the thread reference object first because + the relative priorities.*/ + chSysLock(); + chThdSuspendS(&lwip_trp); + chSysUnlock(); +} + +typedef struct lwip_reconf_params { + const lwipreconf_opts_t *opts; + semaphore_t completion; +} lwip_reconf_params_t; + +static void do_reconfigure(void *p) +{ + lwip_reconf_params_t *reconf = (lwip_reconf_params_t*) p; + + switch (addressMode) { +#if LWIP_DHCP + case NET_ADDRESS_DHCP: { + if (netif_is_up(&thisif)) + dhcp_stop(&thisif); + break; + } +#endif + case NET_ADDRESS_STATIC: { + ip4_addr_t zero = { 0 }; + netif_set_ipaddr(&thisif, &zero); + netif_set_netmask(&thisif, &zero); + netif_set_gw(&thisif, &zero); + break; + } +#if LWIP_AUTOIP + case NET_ADDRESS_AUTO: { + if (netif_is_up(&thisif)) + autoip_stop(&thisif); + break; + } +#endif + } + + ip.addr = reconf->opts->address; + gateway.addr = reconf->opts->gateway; + netmask.addr = reconf->opts->netmask; + addressMode = reconf->opts->addrMode; + + switch (addressMode) { +#if LWIP_DHCP + case NET_ADDRESS_DHCP: { + if (netif_is_up(&thisif)) + dhcp_start(&thisif); + break; + } +#endif + case NET_ADDRESS_STATIC: { + netif_set_ipaddr(&thisif, &ip); + netif_set_netmask(&thisif, &netmask); + netif_set_gw(&thisif, &gateway); + break; + } +#if LWIP_AUTOIP + case NET_ADDRESS_AUTO: { + if (netif_is_up(&thisif)) + autoip_start(&thisif); + break; + } +#endif + } + + chSemSignal(&reconf->completion); +} + +void lwipReconfigure(const lwipreconf_opts_t *opts) +{ + lwip_reconf_params_t params; + params.opts = opts; + chSemObjectInit(¶ms.completion, 0); + tcpip_callback_with_block(do_reconfigure, ¶ms, 0); + chSemWait(¶ms.completion); +} + +/** @} */ diff --git a/ChibiOS_20.3.2/os/various/lwip_bindings/lwipthread.h b/ChibiOS_20.3.2/os/various/lwip_bindings/lwipthread.h new file mode 100644 index 0000000..b40d05f --- /dev/null +++ b/ChibiOS_20.3.2/os/various/lwip_bindings/lwipthread.h @@ -0,0 +1,275 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file lwipthread.h + * @brief LWIP wrapper thread macros and structures. + * @addtogroup LWIP_THREAD + * @{ + */ + +#ifndef LWIPTHREAD_H +#define LWIPTHREAD_H + +#include + +/** + * @brief lwIP default network interface maximum transmission unit (MTU). + */ +#if !defined(LWIP_NETIF_MTU) || defined(__DOXYGEN__) +#define LWIP_NETIF_MTU 1500 +#endif + +/** + * @brief Default network interface hostname. + */ +#if !defined(LWIP_NETIF_HOSTNAME_STRING) || defined(__DOXYGEN__) +#define LWIP_NETIF_HOSTNAME_STRING "lwip" +#endif + +/** + * @brief Default network interface hostname. + */ +#if !defined(LWIP_THREAD_NAME) || defined(__DOXYGEN__) +#define LWIP_THREAD_NAME "lwipthread" +#endif + +/** + * @brief lwIP thread priority. + */ +#ifndef LWIP_THREAD_PRIORITY +#define LWIP_THREAD_PRIORITY LOWPRIO +#endif + +/** + * @brief lwIP thread stack size. + */ +#if !defined(LWIP_THREAD_STACK_SIZE) || defined(__DOXYGEN__) +#define LWIP_THREAD_STACK_SIZE 672 +#endif + +/** + * @brief Link poll interval. + */ +#if !defined(LWIP_LINK_POLL_INTERVAL) || defined(__DOXYGEN__) +#define LWIP_LINK_POLL_INTERVAL TIME_S2I(5) +#endif + +/** + * @brief IP Address. + */ +#if !defined(LWIP_IPADDR) || defined(__DOXYGEN__) +#define LWIP_IPADDR(p) IP4_ADDR(p, 192, 168, 1, 10) +#endif + +/** + * @brief IP Gateway. + */ +#if !defined(LWIP_GATEWAY) || defined(__DOXYGEN__) +#define LWIP_GATEWAY(p) IP4_ADDR(p, 192, 168, 1, 1) +#endif + +/** + * @brief IP netmask. + */ +#if !defined(LWIP_NETMASK) || defined(__DOXYGEN__) +#define LWIP_NETMASK(p) IP4_ADDR(p, 255, 255, 255, 0) +#endif + +/** + * @brief Transmission timeout. + */ +#if !defined(LWIP_SEND_TIMEOUT) || defined(__DOXYGEN__) +#define LWIP_SEND_TIMEOUT 50 +#endif + +/** + * @brief Link speed. + */ +#if !defined(LWIP_LINK_SPEED) || defined(__DOXYGEN__) +#define LWIP_LINK_SPEED 100000000 +#endif + +/** + * @brief MAC Address byte 0. + */ +#if !defined(LWIP_ETHADDR_0) || defined(__DOXYGEN__) +#define LWIP_ETHADDR_0 0xC2 +#endif + +/** + * @brief MAC Address byte 1. + */ +#if !defined(LWIP_ETHADDR_1) || defined(__DOXYGEN__) +#define LWIP_ETHADDR_1 0xAF +#endif + +/** + * @brief MAC Address byte 2. + */ +#if !defined(LWIP_ETHADDR_2) || defined(__DOXYGEN__) +#define LWIP_ETHADDR_2 0x51 +#endif + +/** + * @brief MAC Address byte 3. + */ +#if !defined(LWIP_ETHADDR_3) || defined(__DOXYGEN__) +#define LWIP_ETHADDR_3 0x03 +#endif + +/** + * @brief MAC Address byte 4. + */ +#if !defined(LWIP_ETHADDR_4) || defined(__DOXYGEN__) +#define LWIP_ETHADDR_4 0xCF +#endif + +/** + * @brief MAC Address byte 5. + */ +#if !defined(LWIP_ETHADDR_5) || defined(__DOXYGEN__) +#define LWIP_ETHADDR_5 0x46 +#endif + +/** + * @brief Interface name byte 0. + */ +#if !defined(LWIP_IFNAME0) || defined(__DOXYGEN__) +#define LWIP_IFNAME0 'm' +#endif + +/** + * @brief Interface name byte 1. + */ +#if !defined(LWIP_IFNAME1) || defined(__DOXYGEN__) +#define LWIP_IFNAME1 's' +#endif + +/** + * @brief Utility macro to define an IPv4 address. + * + * @note Within the networking subsystem, IPv4 network addresses are + * stored with LS byte of network address in MS byte of unsigned int. + */ +#if BYTE_ORDER == LITTLE_ENDIAN +#define IP4_ADDR_VALUE(a,b,c,d) \ + (((u32_t)((d) & 0xff) << 24) | \ + ((u32_t)((c) & 0xff) << 16) | \ + ((u32_t)((b) & 0xff) << 8) | \ + (u32_t)((a) & 0xff)) +#else +#define IP4_ADDR_VALUE(a,b,c,d) \ + (((u32_t)((a) & 0xff) << 24) | \ + ((u32_t)((b) & 0xff) << 16) | \ + ((u32_t)((c) & 0xff) << 8) | \ + (u32_t)((d) & 0xff)) +#endif + +/** + * @brief Startup network assigning modes. + */ +typedef enum { +#if LWIP_DHCP || defined(__DOXYGEN__) + /** + * @brief Assign a DHCP given address. + */ + NET_ADDRESS_DHCP = 1, +#endif + /** + * @brief Assign a statically IPv4 address. + */ + NET_ADDRESS_STATIC = 2, +#if LWIP_AUTOIP || defined(__DOXYGEN__) + /** + * @brief Assign an IPv4 link-Local address. + */ + NET_ADDRESS_AUTO = 3 +#endif +} net_addr_mode_t; + +/** + * @brief Runtime TCP/IP settings. + */ +typedef struct lwipthread_opts { + /** + * @brief Pointer to MAC address as an array of 6 unsigned bytes. + */ + uint8_t *macaddress; + /** + * @brief Network address as 32-bit unsigned integer. + */ + uint32_t address; + /** + * @brief Network subnet mask as 32-bit unsigned integer. + */ + uint32_t netmask; + /** + * @brief Network gateway as 32-bit unsigned integer. + */ + uint32_t gateway; + /** + * @brief Startup network addressing mode - static, DHCP, auto. + */ + net_addr_mode_t addrMode; + /** + * @brief Host name. If NULL, a default string is used. + * @note Not checked for validity. In particular, spaces not allowed. + */ +#if LWIP_NETIF_HOSTNAME || defined(__DOXYGEN__) + const char *ourHostName; +#endif + /** + * @brief Link up callback. + * + * @note Called from the tcpip thread when the link goes up. + * Can be NULL to default to lwipDefaultLinkUpCB. + */ + void (*link_up_cb)(void*); + /** + * @brief Link down callback. + * + * @note Called from the tcpip thread when the link goes down. + * Can be NULL to default to lwipDefaultLinkDownCB. + */ + void (*link_down_cb)(void*); +} lwipthread_opts_t; + +/** + * @brief Parameters for lwipReconfigure. + * @note Same meaning as in lwipthread_opts_t. + */ +typedef struct lwipreconf_opts { + uint32_t address; + uint32_t netmask; + uint32_t gateway; + net_addr_mode_t addrMode; +} lwipreconf_opts_t; + +#ifdef __cplusplus +extern "C" { +#endif + void lwipDefaultLinkUpCB(void *p); + void lwipDefaultLinkDownCB(void *p); + void lwipInit(const lwipthread_opts_t *opts); + void lwipReconfigure(const lwipreconf_opts_t *opts); +#ifdef __cplusplus +} +#endif + +#endif /* LWIPTHREAD_H */ + +/** @} */ diff --git a/ChibiOS_20.3.2/os/various/lwip_bindings/readme.txt b/ChibiOS_20.3.2/os/various/lwip_bindings/readme.txt new file mode 100644 index 0000000..07544e2 --- /dev/null +++ b/ChibiOS_20.3.2/os/various/lwip_bindings/readme.txt @@ -0,0 +1,6 @@ +This directory contains the ChibiOS "official" bindings with the lwIP +TCP/IP stack: http://savannah.nongnu.org/projects/lwip + +In order to use lwIP within ChibiOS/RT project, unzip lwIP under +./ext/lwip then include $(CHIBIOS)/os/various/lwip_bindings/lwip.mk +in your makefile. diff --git a/ChibiOS_20.3.2/os/various/lwip_bindings/static_lwipopts.h b/ChibiOS_20.3.2/os/various/lwip_bindings/static_lwipopts.h new file mode 100644 index 0000000..7baa387 --- /dev/null +++ b/ChibiOS_20.3.2/os/various/lwip_bindings/static_lwipopts.h @@ -0,0 +1,42 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file static_lwipopts.h + * + * @addtogroup static_lwipopts + * @{ + */ + +#ifndef STATIC_LWIPOPTS_H +#define STATIC_LWIPOPTS_H + +#define NO_SYS 0 + +#define LWIP_TIMERS 1 +#define LWIP_TIMERS_CUSTOM 0 + +#define LWIP_TCPIP_CORE_LOCKING 1 +#define LWIP_TCPIP_CORE_LOCKING_INPUT 0 +#define LWIP_COMPAT_MUTEX_ALLOWED + +#define SYS_LIGHTWEIGHT_PROT 1 + +#define MEM_ALIGNMENT 4 + +#endif /* STATIC_LWIPOPTS_H */ + +/** @} */ -- cgit v1.2.3