diff options
author | David Crocker <dcrocker@eschertech.com> | 2019-10-26 11:46:31 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2019-10-26 11:46:31 +0300 |
commit | 587f49d5699a6a0fc3cb8307e17dd5c2fa43f73b (patch) | |
tree | 311cc1342502b74cad2808ee6bf4e9cb66a7ac4c /src/Networking/LwipEthernet | |
parent | c25d73194252791ceb479ced79ffc77b31c810fe (diff) |
Cached memory and Lwip networking changes
Put CAN, GMAC and some DMA buffers in new .ram_nocache memory section (needs new linker script in CoreNG)
Added option to use separate Ethernet GMAC task (not working yet, so disabled - see LWIP_GMAC_TASK in compiler settings)
Added code to set up non-cached memory usnig MPU (not working yet, so disabled)
Diffstat (limited to 'src/Networking/LwipEthernet')
-rw-r--r-- | src/Networking/LwipEthernet/GMAC/ethernet_sam.cpp | 2 | ||||
-rw-r--r-- | src/Networking/LwipEthernet/GMAC/same70_gmac.cpp (renamed from src/Networking/LwipEthernet/GMAC/same70_gmac.c) | 105 | ||||
-rw-r--r-- | src/Networking/LwipEthernet/Lwip/lwipopts.h | 12 | ||||
-rw-r--r-- | src/Networking/LwipEthernet/Lwip/src/core/sys.c | 105 | ||||
-rw-r--r-- | src/Networking/LwipEthernet/Lwip/src/core/sys.cpp | 255 | ||||
-rw-r--r-- | src/Networking/LwipEthernet/Lwip/src/include/arch/cc.h | 2 | ||||
-rw-r--r-- | src/Networking/LwipEthernet/Lwip/src/include/arch/sys_arch.h | 10 | ||||
-rw-r--r-- | src/Networking/LwipEthernet/Lwip/src/include/lwip/sys.h | 15 | ||||
-rw-r--r-- | src/Networking/LwipEthernet/LwipEthernetInterface.cpp | 16 |
9 files changed, 345 insertions, 177 deletions
diff --git a/src/Networking/LwipEthernet/GMAC/ethernet_sam.cpp b/src/Networking/LwipEthernet/GMAC/ethernet_sam.cpp index 1b685f93..a1ac7db8 100644 --- a/src/Networking/LwipEthernet/GMAC/ethernet_sam.cpp +++ b/src/Networking/LwipEthernet/GMAC/ethernet_sam.cpp @@ -214,8 +214,10 @@ bool ethernet_link_established(void) */ void ethernet_task(void) { +#if !LWIP_GMAC_TASK /* Run polling tasks */ while (ethernetif_input(&gs_net_if)) { } +#endif /* Run periodic tasks */ ethernet_timers_update(); diff --git a/src/Networking/LwipEthernet/GMAC/same70_gmac.c b/src/Networking/LwipEthernet/GMAC/same70_gmac.cpp index 1d22d5cc..12f070c8 100644 --- a/src/Networking/LwipEthernet/GMAC/same70_gmac.c +++ b/src/Networking/LwipEthernet/GMAC/same70_gmac.cpp @@ -41,13 +41,13 @@ * */ -#include "ethernet_phy.h" #include "same70_gmac.h" -#include "pmc.h" -#include "sysclk.h" +#include "pmc/pmc.h" #include "conf_eth.h" -#include <string.h> +#include <cstring> +extern "C" { +#include "ethernet_phy.h" #include "lwip/def.h" #include "lwip/mem.h" #include "lwip/opt.h" @@ -56,7 +56,20 @@ #include "lwip/stats.h" #include "lwip/sys.h" #include "netif/etharp.h" +} + +#define __nocache __attribute__((section(".ram_nocache"))) + +#if LWIP_GMAC_TASK + +// We can't #include RepRapFirmware.h here because that leads to a duplicate definition of ERR_TIMEOUT +#include <RTOSIface/RTOSIface.h> +#include <TaskPriorities.h> +constexpr size_t EthernetTaskStackWords = 200; +static Task<EthernetTaskStackWords> ethernetTask; + +#endif /** Network interface identifier. */ #define IFNAME0 'e' @@ -68,11 +81,10 @@ /** Network link speed. */ #define NET_LINK_SPEED 100000000 -#if (NO_SYS == 0) +#if LWIP_GMAC_TASK /* Interrupt priorities. (lowest value = highest priority) */ /* ISRs using FreeRTOS *FromISR APIs must have priorities below or equal to */ /* configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY. */ -#define INT_PRIORITY_GMAC 12 /** The GMAC interrupts to enable */ #define GMAC_INT_GROUP (GMAC_ISR_RCOMP | GMAC_ISR_ROVR | GMAC_ISR_HRESP | GMAC_ISR_TCOMP | GMAC_ISR_TUR | GMAC_ISR_TFC) @@ -126,18 +138,12 @@ struct gmac_device { /** Reference to lwIP netif structure. */ struct netif *netif; - -#if NO_SYS == 0 - /** RX task notification semaphore. */ - sys_sem_t rx_sem; -#endif }; /** * GMAC driver instance. */ -COMPILER_ALIGNED(8) -static struct gmac_device gs_gmac_dev; +__nocache __aligned(8) static struct gmac_device gs_gmac_dev; /** * MAC address to use. @@ -167,32 +173,30 @@ static gmac_dev_tx_cb_t gmac_rx_cb = NULL; */ void GMAC_Handler(void) { -#if 1 - volatile uint32_t ul_isr; - +#if LWIP_GMAC_TASK /* Get interrupt status. */ - ul_isr = gmac_get_interrupt_status(GMAC); + const uint32_t ul_isr = gmac_get_interrupt_status(GMAC); /* RX interrupts. */ - if ((ul_isr & GMAC_INT_GROUP) != 0 && gmac_rx_cb != NULL) + if (ul_isr & GMAC_INT_GROUP) { - gmac_rx_cb(ul_isr); + ethernetTask.GiveFromISR(); } -#elif NO_SYS == 1 - NVIC_DisableIRQ(GMAC_IRQn); #else +# if 1 volatile uint32_t ul_isr; - portBASE_TYPE xGMACTaskWoken = pdFALSE; /* Get interrupt status. */ ul_isr = gmac_get_interrupt_status(GMAC); /* RX interrupts. */ - if (ul_isr & GMAC_INT_GROUP) { - xSemaphoreGiveFromISR(gs_gmac_dev.rx_sem, &xGMACTaskWoken); + if ((ul_isr & GMAC_INT_GROUP) != 0 && gmac_rx_cb != NULL) + { + gmac_rx_cb(ul_isr); } - - portEND_SWITCHING_ISR(xGMACTaskWoken); +# else + NVIC_DisableIRQ(GMAC_IRQn); +# endif #endif } @@ -340,7 +344,7 @@ static void gmac_low_level_init(struct netif *netif) #endif /* Init MAC PHY driver. */ - if (ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, sysclk_get_cpu_hz()) != GMAC_OK) { + if (ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, SystemCoreClock) != GMAC_OK) { LWIP_DEBUGF(NETIF_DEBUG, ("gmac_low_level_init: PHY init ERROR!\n")); return; } @@ -376,7 +380,7 @@ static void gmac_low_level_init(struct netif *netif) */ static err_t gmac_low_level_output(struct netif *netif, struct pbuf *p) { - struct gmac_device *ps_gmac_dev = netif->state; + struct gmac_device *ps_gmac_dev = static_cast<gmac_device *>(netif->state); struct pbuf *q = NULL; uint8_t *buffer = 0; @@ -398,6 +402,9 @@ static err_t gmac_low_level_output(struct netif *netif, struct pbuf *p) gmac_enable_transmit(GMAC, true); } + //TODO check buffer is free!!! + //TODO what if message is too long? + buffer = (uint8_t*)ps_gmac_dev->tx_desc[ps_gmac_dev->us_tx_idx].addr; /* Copy pbuf chain into TX buffer. */ @@ -437,7 +444,7 @@ static err_t gmac_low_level_output(struct netif *netif, struct pbuf *p) */ static struct pbuf *gmac_low_level_input(struct netif *netif) { - struct gmac_device *ps_gmac_dev = netif->state; + struct gmac_device *ps_gmac_dev = static_cast<gmac_device *>(netif->state); struct pbuf *p = 0; uint32_t length = 0; uint32_t ul_index = 0; @@ -497,14 +504,14 @@ static struct pbuf *gmac_low_level_input(struct netif *netif) ps_gmac_dev->us_rx_idx = (ps_gmac_dev->us_rx_idx + 1) % GMAC_RX_BUFFERS; #if LWIP_STATS - lwip_rx_count += length; + lwip_rx_count += length; #endif } return p; } -#if NO_SYS == 0 +#if LWIP_GMAC_TASK /** * \brief GMAC task function. This function waits for the notification * semaphore from the interrupt, processes the incoming packet and then @@ -512,16 +519,16 @@ static struct pbuf *gmac_low_level_input(struct netif *netif) * * \param pvParameters A pointer to the gmac_device instance. */ -static void gmac_task(void *pvParameters) +extern "C" void gmac_task(void *pvParameters) { - struct gmac_device *ps_gmac_dev = pvParameters; + gmac_device * const ps_gmac_dev = static_cast<gmac_device*>(pvParameters); while (1) { - /* Wait for the RX notification semaphore. */ - sys_arch_sem_wait(&ps_gmac_dev->rx_sem, 0); + /* Process the incoming packets */ + while (ethernetif_input(ps_gmac_dev->netif)) { } - /* Process the incoming packet. */ - ethernetif_input(ps_gmac_dev->netif); + /* Wait for the RX notification from the ISR */ + TaskBase::Take(); } } #endif @@ -548,7 +555,7 @@ bool ethernetif_input(struct netif *netif) } /* Points to packet payload, which starts with an Ethernet header. */ - ethhdr = p->payload; + ethhdr = static_cast<struct eth_hdr*>(p->payload); switch (htons(ethhdr->type)) { case ETHTYPE_IP: @@ -618,23 +625,8 @@ err_t ethernetif_init(struct netif *netif) /* Initialize the hardware */ gmac_low_level_init(netif); -#if NO_SYS == 0 - err_t err; - sys_thread_t id; - - /* Incoming packet notification semaphore. */ - err = sys_sem_new(&gs_gmac_dev.rx_sem, 0); - LWIP_ASSERT("ethernetif_init: GMAC RX semaphore allocation ERROR!\n", - (err == ERR_OK)); - if (err == ERR_MEM) - return ERR_MEM; - - id = sys_thread_new("GMAC", gmac_task, &gs_gmac_dev, - netifINTERFACE_TASK_STACK_SIZE, netifINTERFACE_TASK_PRIORITY); - LWIP_ASSERT("ethernetif_init: GMAC Task allocation ERROR!\n", - (id != 0)); - if (id == 0) - return ERR_MEM; +#if LWIP_GMAC_TASK + ethernetTask.Create(gmac_task, "ETHERNET", &gs_gmac_dev, TaskPriority::EthernetPriority); #endif return ERR_OK; @@ -783,9 +775,10 @@ void ethernetif_set_mac_address(const uint8_t macAddress[]) } } +extern "C" u32_t millis(); + u32_t sys_now(void) { - extern u32_t millis(); return millis(); } diff --git a/src/Networking/LwipEthernet/Lwip/lwipopts.h b/src/Networking/LwipEthernet/Lwip/lwipopts.h index cd6e92a9..367f37c8 100644 --- a/src/Networking/LwipEthernet/Lwip/lwipopts.h +++ b/src/Networking/LwipEthernet/Lwip/lwipopts.h @@ -56,7 +56,11 @@ * use lwIP facilities. * Uses Raw API only. */ -#define NO_SYS 1 +#ifndef LWIP_GMAC_TASK +# error LWIP_GMAC_TASK must be defined in compiler settings +#endif + +#define NO_SYS (!LWIP_GMAC_TASK) /** * LWIP_NETIF_STATUS_CALLBACK==1: Support a callback function whenever an interface @@ -271,17 +275,19 @@ extern uint32_t trueRandom(void); ------------------------------------ */ +#define FreeRtosIdlePriority 0 + /** The stack sizes allocated to the netif stack: (256 * 4) = 1048 bytes. */ #define netifINTERFACE_TASK_STACK_SIZE 256 /** The priority of the netif stack. */ -#define netifINTERFACE_TASK_PRIORITY (tskIDLE_PRIORITY + 4) +#define netifINTERFACE_TASK_PRIORITY (FreeRtosIdlePriority + 4) //TODO adjust /** The stack sizes allocated to the TCPIP stack: (256 * 4) = 1048 bytes. */ #define TCPIP_THREAD_STACKSIZE 256 /** The priority of the TCPIP stack. */ -#define TCPIP_THREAD_PRIO (tskIDLE_PRIORITY + 5) +#define TCPIP_THREAD_PRIO (FreeRtosIdlePriority + 5) //TODO adjust /** The mailbox size for the tcpip thread messages */ #define TCPIP_MBOX_SIZE 16 diff --git a/src/Networking/LwipEthernet/Lwip/src/core/sys.c b/src/Networking/LwipEthernet/Lwip/src/core/sys.c deleted file mode 100644 index d96efc8d..00000000 --- a/src/Networking/LwipEthernet/Lwip/src/core/sys.c +++ /dev/null @@ -1,105 +0,0 @@ -/** - * @file - * lwIP Operating System abstraction - * - */ - -/* - * 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 <adam@sics.se> - * - */ - -/** - * @defgroup sys_layer Porting (system abstraction layer) - * @ingroup lwip - * @verbinclude "sys_arch.txt" - * - * @defgroup sys_os OS abstraction layer - * @ingroup sys_layer - * No need to implement functions in this section in NO_SYS mode. - * - * @defgroup sys_sem Semaphores - * @ingroup sys_os - * - * @defgroup sys_mutex Mutexes - * @ingroup sys_os - * Mutexes are recommended to correctly handle priority inversion, - * especially if you use LWIP_CORE_LOCKING . - * - * @defgroup sys_mbox Mailboxes - * @ingroup sys_os - * - * @defgroup sys_time Time - * @ingroup sys_layer - * - * @defgroup sys_prot Critical sections - * @ingroup sys_layer - * Used to protect short regions of code against concurrent access. - * - Your system is a bare-metal system (probably with an RTOS) - * and interrupts are under your control: - * Implement this as LockInterrupts() / UnlockInterrupts() - * - Your system uses an RTOS with deferred interrupt handling from a - * worker thread: Implement as a global mutex or lock/unlock scheduler - * - Your system uses a high-level OS with e.g. POSIX signals: - * Implement as a global mutex - * - * @defgroup sys_misc Misc - * @ingroup sys_os - */ - -#include <Lwip/src/include/lwip/opt.h> -#include <Lwip/src/include/lwip/sys.h> - -/* Most of the functions defined in sys.h must be implemented in the - * architecture-dependent file sys_arch.c */ - -#if !NO_SYS - -#ifndef sys_msleep -/** - * Sleep for some ms. Timeouts are NOT processed while sleeping. - * - * @param ms number of milliseconds to sleep - */ -void -sys_msleep(u32_t ms) -{ - if (ms > 0) { - sys_sem_t delaysem; - err_t err = sys_sem_new(&delaysem, 0); - if (err == ERR_OK) { - sys_arch_sem_wait(&delaysem, ms); - sys_sem_free(&delaysem); - } - } -} -#endif /* sys_msleep */ - -#endif /* !NO_SYS */ diff --git a/src/Networking/LwipEthernet/Lwip/src/core/sys.cpp b/src/Networking/LwipEthernet/Lwip/src/core/sys.cpp new file mode 100644 index 00000000..fed46104 --- /dev/null +++ b/src/Networking/LwipEthernet/Lwip/src/core/sys.cpp @@ -0,0 +1,255 @@ +/** + * @file + * lwIP Operating System abstraction + * + */ + +/* + * 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 <adam@sics.se> + * + */ + +/** + * @defgroup sys_layer Porting (system abstraction layer) + * @ingroup lwip + * @verbinclude "sys_arch.txt" + * + * @defgroup sys_os OS abstraction layer + * @ingroup sys_layer + * No need to implement functions in this section in NO_SYS mode. + * + * @defgroup sys_sem Semaphores + * @ingroup sys_os + * + * @defgroup sys_mutex Mutexes + * @ingroup sys_os + * Mutexes are recommended to correctly handle priority inversion, + * especially if you use LWIP_CORE_LOCKING . + * + * @defgroup sys_mbox Mailboxes + * @ingroup sys_os + * + * @defgroup sys_time Time + * @ingroup sys_layer + * + * @defgroup sys_prot Critical sections + * @ingroup sys_layer + * Used to protect short regions of code against concurrent access. + * - Your system is a bare-metal system (probably with an RTOS) + * and interrupts are under your control: + * Implement this as LockInterrupts() / UnlockInterrupts() + * - Your system uses an RTOS with deferred interrupt handling from a + * worker thread: Implement as a global mutex or lock/unlock scheduler + * - Your system uses a high-level OS with e.g. POSIX signals: + * Implement as a global mutex + * + * @defgroup sys_misc Misc + * @ingroup sys_os + */ + +extern "C" { + +#include <Lwip/src/include/lwip/opt.h> +#include <Lwip/src/include/lwip/sys.h> + +} + +#if !NO_SYS + +#include <RTOSIface/RTOSIface.h> + +extern void delay(uint32_t ms); +extern uint32_t millis(); + +extern "C" { + +/* Most of the functions defined in sys.h must be implemented in the + * architecture-dependent file sys_arch.c */ + +/* sys_init() must be called before anything else. */ +void sys_init() +{ + // nothing needed yet +} + +/** + * @ingroup sys_mutex + * Create a new mutex. + * Note that mutexes are expected to not be taken recursively by the lwIP code, + * so both implementation types (recursive or non-recursive) should work. + * @param mutex pointer to the mutex to create + * @return ERR_OK if successful, another err_t otherwise + */ +err_t sys_mutex_new(sys_mutex_t *mutex) +{ + mutex->m = new Mutex; + mutex->m->Create("LWIP"); // note, this will give duplicate mutex names but we can't help that + return ERR_OK; +} + +/** + * @ingroup sys_mutex + * Lock a mutex + * @param mutex the mutex to lock + */ +void sys_mutex_lock(sys_mutex_t *mutex) +{ + mutex->m->Take(); +} + +/** + * @ingroup sys_mutex + * Unlock a mutex + * @param mutex the mutex to unlock + */ +void sys_mutex_unlock(sys_mutex_t *mutex) +{ + mutex->m->Release(); +} + +/* Mailbox functions. */ + +/** + * @ingroup sys_mbox + * Create a new mbox of specified size + * @param mbox pointer to the mbox to create + * @param size (minimum) number of messages in this mbox + * @return ERR_OK if successful, another err_t otherwise + */ +err_t sys_mbox_new(sys_mbox_t *mbox, int size) +{ + auto q = new Queue<void *>; + q->Create("LWIP", size); + mbox->m = q; + return (q->IsValid()) ? ERR_OK : ERR_MEM; +} + +/** + * @ingroup sys_mbox + * Post a message to an mbox - may not fail + * -> blocks if full, only used from tasks not from ISR + * @param mbox mbox to posts the message + * @param msg message to post (ATTENTION: can be NULL) + */ +void sys_mbox_post(sys_mbox_t *mbox, void *msg) +{ + static_cast<Queue<void*>*>(mbox->m)->PutToBack(msg, Mutex::TimeoutUnlimited); +} + +/** + * @ingroup sys_mbox + * Try to post a message to an mbox - may fail if full or ISR + * @param mbox mbox to posts the message + * @param msg message to post (ATTENTION: can be NULL) + */ +err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) +{ + return (static_cast<Queue<void*>*>(mbox->m)->PutToBack(msg, 0)) ? ERR_OK : ERR_WOULDBLOCK; +} + +/** + * @ingroup sys_mbox + * Wait for a new message to arrive in the mbox + * @param mbox mbox to get a message from + * @param msg pointer where the message is stored + * @param timeout maximum time (in milliseconds) to wait for a message (0 = wait forever) + * @return time (in milliseconds) waited for a message, may be 0 if not waited + or SYS_ARCH_TIMEOUT on timeout + * The returned time has to be accurate to prevent timer jitter! + */ +u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) +{ + const uint32_t now = millis(); + return ((static_cast<Queue<void*>*>(mbox->m)->Get(*msg, timeout))) + ? millis() - now + : SYS_ARCH_TIMEOUT; +} + +/** + * @ingroup sys_mbox + * Wait for a new message to arrive in the mbox + * @param mbox mbox to get a message from + * @param msg pointer where the message is stored + * @return 0 (milliseconds) if a message has been received + * or SYS_MBOX_EMPTY if the mailbox is empty + */ +u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) +{ + return ((static_cast<Queue<void*>*>(mbox->m)->Get(*msg, 0))) + ? 0 + : SYS_MBOX_EMPTY; +} + +/** + * @ingroup sys_mbox + * Delete an mbox + * @param mbox mbox to delete + */ +void sys_mbox_free(sys_mbox_t *mbox); + +/** + * @ingroup sys_mbox + * Check if an mbox is valid/allocated: return 1 for valid, 0 for invalid + */ +int sys_mbox_valid(sys_mbox_t *mbox); + +/** + * @ingroup sys_mbox + * Set an mbox invalid so that sys_mbox_valid returns 0 + */ +void sys_mbox_set_invalid(sys_mbox_t *mbox); + +#ifndef sys_mbox_valid_val +/** + * Same as sys_mbox_valid() but taking a value, not a pointer + */ +#define sys_mbox_valid_val(mbox) sys_mbox_valid(&(mbox)) +#endif +#ifndef sys_mbox_set_invalid_val +/** + * Same as sys_mbox_set_invalid() but taking a value, not a pointer + */ +#define sys_mbox_set_invalid_val(mbox) sys_mbox_set_invalid(&(mbox)) +#endif + + +/** + * Sleep for some ms. Timeouts are NOT processed while sleeping. + * + * @param ms number of milliseconds to sleep + */ +void sys_msleep(u32_t ms) +{ + delay(ms); +} + +} + +#endif /* !NO_SYS */ diff --git a/src/Networking/LwipEthernet/Lwip/src/include/arch/cc.h b/src/Networking/LwipEthernet/Lwip/src/include/arch/cc.h index e7a123b5..c9132ea7 100644 --- a/src/Networking/LwipEthernet/Lwip/src/include/arch/cc.h +++ b/src/Networking/LwipEthernet/Lwip/src/include/arch/cc.h @@ -96,7 +96,7 @@ typedef uintptr_t mem_ptr_t; to let sys.h use binary semaphores instead of mutexes - as before in 1.3.2 Refer CHANGELOG */ -#define LWIP_COMPAT_MUTEX 1 +#define LWIP_COMPAT_MUTEX 0 /* Make lwip/arch.h define the codes which are used throughout */ #define LWIP_PROVIDE_ERRNO diff --git a/src/Networking/LwipEthernet/Lwip/src/include/arch/sys_arch.h b/src/Networking/LwipEthernet/Lwip/src/include/arch/sys_arch.h index b8a2a709..d077feed 100644 --- a/src/Networking/LwipEthernet/Lwip/src/include/arch/sys_arch.h +++ b/src/Networking/LwipEthernet/Lwip/src/include/arch/sys_arch.h @@ -8,8 +8,16 @@ typedef void * sys_prot_t; typedef void * sys_sem_t; -typedef void * sys_mbox_t; +typedef struct +{ + struct QueueBase *m; +} sys_mbox_t; typedef void * sys_thread_t; +typedef struct +{ + struct Mutex *m; +} sys_mutex_t; + #endif /* __ARCH_SYS_ARCH_H__ */ diff --git a/src/Networking/LwipEthernet/Lwip/src/include/lwip/sys.h b/src/Networking/LwipEthernet/Lwip/src/include/lwip/sys.h index a3e4f0aa..3bfa245f 100644 --- a/src/Networking/LwipEthernet/Lwip/src/include/lwip/sys.h +++ b/src/Networking/LwipEthernet/Lwip/src/include/lwip/sys.h @@ -267,8 +267,6 @@ err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg); * The returned time has to be accurate to prevent timer jitter! */ u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout); -/* Allow port to override with a macro, e.g. special timeout for sys_arch_mbox_fetch() */ -#ifndef sys_arch_mbox_tryfetch /** * @ingroup sys_mbox * Wait for a new message to arrive in the mbox @@ -278,32 +276,27 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout); * or SYS_MBOX_EMPTY if the mailbox is empty */ u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg); -#endif -/** - * For now, we map straight to sys_arch implementation. - */ + #define sys_mbox_tryfetch(mbox, msg) sys_arch_mbox_tryfetch(mbox, msg) +#define sys_mbox_fetch(mbox, msg) sys_arch_mbox_fetch(mbox, msg, 0) + /** * @ingroup sys_mbox * Delete an mbox * @param mbox mbox to delete */ void sys_mbox_free(sys_mbox_t *mbox); -#define sys_mbox_fetch(mbox, msg) sys_arch_mbox_fetch(mbox, msg, 0) -#ifndef sys_mbox_valid /** * @ingroup sys_mbox * Check if an mbox is valid/allocated: return 1 for valid, 0 for invalid */ int sys_mbox_valid(sys_mbox_t *mbox); -#endif -#ifndef sys_mbox_set_invalid /** * @ingroup sys_mbox * Set an mbox invalid so that sys_mbox_valid returns 0 */ void sys_mbox_set_invalid(sys_mbox_t *mbox); -#endif + #ifndef sys_mbox_valid_val /** * Same as sys_mbox_valid() but taking a value, not a pointer diff --git a/src/Networking/LwipEthernet/LwipEthernetInterface.cpp b/src/Networking/LwipEthernet/LwipEthernetInterface.cpp index f0f00961..c9e14533 100644 --- a/src/Networking/LwipEthernet/LwipEthernetInterface.cpp +++ b/src/Networking/LwipEthernet/LwipEthernetInterface.cpp @@ -49,7 +49,10 @@ static LwipEthernetInterface *ethernetInterface; extern "C" { static volatile bool lwipLocked = false; + +#if !LWIP_GMAC_TASK static volatile bool resetCallback = false; +#endif // Lock functions for LwIP (LwIP isn't thread-safe when working with the raw API) bool LockLWIP() @@ -70,6 +73,8 @@ void UnlockLWIP() // Callback functions for the GMAC driver and for LwIP +#if !LWIP_GMAC_TASK + // Called from ISR static void ethernet_rx_callback(uint32_t ul_status) { @@ -87,15 +92,20 @@ static void ethernet_rx_callback(uint32_t ul_status) } } +#endif + // Task function to keep the GMAC and LwIP running void DoEthernetTask() { ethernet_task(); + +#if !LWIP_GMAC_TASK if (resetCallback) { resetCallback = false; ethernet_set_rx_callback(ðernet_rx_callback); } +#endif } // Callback functions for LWIP (may be called from ISR) @@ -385,7 +395,9 @@ void LwipEthernetInterface::Start() initialised = true; } +#if !LWIP_GMAC_TASK resetCallback = true; // reset EMAC RX callback on next Spin call +#endif state = NetworkState::establishingLink; } @@ -395,7 +407,9 @@ void LwipEthernetInterface::Stop() if (state != NetworkState::disabled) { netif_set_down(&gs_net_if); +#if !LWIP_GMAC_TASK resetCallback = false; +#endif ethernet_set_rx_callback(nullptr); #if defined(DUET3) @@ -520,11 +534,13 @@ void LwipEthernetInterface::Spin(bool full) void LwipEthernetInterface::Interrupt() { +#if !LWIP_GMAC_TASK if (initialised && LockLWIP()) { ethernet_timers_update(); UnlockLWIP(); } +#endif } void LwipEthernetInterface::Diagnostics(MessageType mtype) |