From 3c81f7d5875c699112da9f01decda755384c3052 Mon Sep 17 00:00:00 2001 From: Our Air Quality Date: Wed, 24 Jan 2018 14:56:24 +1100 Subject: [PATCH] lwip update * The mdns responder has been reworked to lower stack and memory usage. This is a variation on the upstream code, it use malloc whereas the upstream code uses pools. The high stack usage of the mdns responder was problem for esp-open-rtos, so we might have to maintain the differences for now. * Improved lwip core locking, and lock checking. Upstream improvements, that need some added support from esp-open-rtos specific code. More core lock is performed when calling from the esp-open-rtos code now, so a little safer. The checking is not enforced, but projects might see warning messages and might want to look into them. * The esp-open-rtos lwip support has been sync'ed with the new freertos port included with lwip. There are still some minor differences. * A few lwip timer bugs have been resolved. This might help resolve some issues. * Plus it picks up all the other upstream fixes and improvements. * The default lwip stack has been lowered from 768 words to 480 words, due to the reduced stack usage by the mdns responder. --- core/app_main.c | 6 + extras/wificfg/wificfg.c | 12 +- lwip/include/arch/cc.h | 8 +- lwip/include/arch/sys_arch.h | 120 ++++----- lwip/include/lwipopts.h | 80 +++++- lwip/lwip | 2 +- lwip/sys_arch.c | 273 ++++++++++++-------- open_esplibs/libmain/user_interface.c | 12 +- open_esplibs/libnet80211/ieee80211_hostap.c | 6 + open_esplibs/libnet80211/ieee80211_sta.c | 5 +- open_esplibs/libnet80211/wl_cnx.c | 2 + open_esplibs/libwpa/wpa_main.c | 4 + 12 files changed, 345 insertions(+), 185 deletions(-) diff --git a/core/app_main.c b/core/app_main.c index cd59c79..9c3918c 100644 --- a/core/app_main.c +++ b/core/app_main.c @@ -373,16 +373,22 @@ void sdk_user_init_task(void *params) { sdk_wifi_mode_set(sdk_g_ic.s.wifi_mode); if (sdk_g_ic.s.wifi_mode == STATION_MODE) { sdk_wifi_station_start(); + LOCK_TCPIP_CORE(); netif_set_default(sdk_g_ic.v.station_netif_info->netif); + UNLOCK_TCPIP_CORE(); } if (sdk_g_ic.s.wifi_mode == SOFTAP_MODE) { sdk_wifi_softap_start(); + LOCK_TCPIP_CORE(); netif_set_default(sdk_g_ic.v.softap_netif_info->netif); + UNLOCK_TCPIP_CORE(); } if (sdk_g_ic.s.wifi_mode == STATIONAP_MODE) { sdk_wifi_station_start(); sdk_wifi_softap_start(); + LOCK_TCPIP_CORE(); netif_set_default(sdk_g_ic.v.station_netif_info->netif); + UNLOCK_TCPIP_CORE(); } if (sdk_wifi_station_get_auto_connect()) { sdk_wifi_station_connect(); diff --git a/extras/wificfg/wificfg.c b/extras/wificfg/wificfg.c index 430740c..804adad 100644 --- a/extras/wificfg/wificfg.c +++ b/extras/wificfg/wificfg.c @@ -1689,7 +1689,9 @@ static void server_task(void *pvParameters) struct netif *softap_netif = sdk_system_get_netif(SOFTAP_IF); if ((wifi_sta_mdns && station_netif) || (wifi_ap_mdns && softap_netif)) { #if LWIP_MDNS_RESPONDER + LOCK_TCPIP_CORE(); mdns_resp_init(); + UNLOCK_TCPIP_CORE(); #endif #if EXTRAS_MDNS_RESPONDER mdns_init(); @@ -1697,16 +1699,22 @@ static void server_task(void *pvParameters) #endif } #if LWIP_MDNS_RESPONDER + LOCK_TCPIP_CORE(); if (wifi_sta_mdns && station_netif) { + LOCK_TCPIP_CORE(); mdns_resp_add_netif(station_netif, hostname, 120); mdns_resp_add_service(station_netif, hostname, "_http", DNSSD_PROTO_TCP, 80, 3600, NULL, NULL); + UNLOCK_TCPIP_CORE(); } if (wifi_ap_mdns && softap_netif) { + LOCK_TCPIP_CORE(); mdns_resp_add_netif(softap_netif, hostname, 120); mdns_resp_add_service(softap_netif, hostname, "_http", DNSSD_PROTO_TCP, 80, 3600, NULL, NULL); + UNLOCK_TCPIP_CORE(); } + UNLOCK_TCPIP_CORE(); #endif free(hostname); @@ -2233,10 +2241,6 @@ void wificfg_init(uint32_t port, const wificfg_dispatch *dispatch) params->dispatch = dispatch; size_t stack_size = 464; -#if LWIP_MDNS_RESPONDER - /* Uses a lot of stack space, so allocate extra. */ - stack_size += 128; -#endif xTaskCreate(server_task, "WiFi Cfg HTTP", stack_size, params, 2, NULL); } } diff --git a/lwip/include/arch/cc.h b/lwip/include/arch/cc.h index 5787157..a88c413 100644 --- a/lwip/include/arch/cc.h +++ b/lwip/include/arch/cc.h @@ -87,14 +87,9 @@ typedef int sys_prot_t; } while(0) #define LWIP_PLATFORM_ASSERT(x) do { printf("Assertion \"%s\" failed at line %d in %s\n", \ x, __LINE__, __FILE__); abort(); } while(0) - -#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \ - printf("Assertion \"%s\" failed at line %d in %s\n", message, __LINE__, __FILE__); \ - handler;} } while(0) #else #define LWIP_PLATFORM_DIAG(x) #define LWIP_PLATFORM_ASSERT(x) -#define LWIP_ERROR(m,e,h) #endif #define LWIP_PLATFORM_BYTESWAP 1 @@ -104,4 +99,7 @@ typedef int sys_prot_t; #define LWIP_RAND() hwrand() +/* Newlib includes this definition so use it. */ +#define lwip_strnstr(buffer, token, n) strnstr(buffer, token, n) + #endif /* __ARCH_CC_H__ */ diff --git a/lwip/include/arch/sys_arch.h b/lwip/include/arch/sys_arch.h index 0dfa482..00f7957 100644 --- a/lwip/include/arch/sys_arch.h +++ b/lwip/include/arch/sys_arch.h @@ -1,58 +1,62 @@ -/* - * Copyright (c) 2001-2003 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 __ARCH_SYS_ARCH_H__ -#define __ARCH_SYS_ARCH_H__ - -#include "FreeRTOS.h" -#include "task.h" -#include "queue.h" -#include "semphr.h" - -/* MBOX primitives */ - -#define SYS_MBOX_NULL ( ( QueueHandle_t ) NULL ) -#define SYS_SEM_NULL ( ( SemaphoreHandle_t ) NULL ) -#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE - -typedef SemaphoreHandle_t sys_sem_t; -typedef SemaphoreHandle_t sys_mutex_t; -typedef QueueHandle_t sys_mbox_t; -typedef TaskHandle_t sys_thread_t; - -#define sys_mbox_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE ) -#define sys_mbox_set_invalid( x ) ( ( *x ) = NULL ) -#define sys_sem_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE ) -#define sys_sem_set_invalid( x ) ( ( *x ) = NULL ) - - -#endif /* __ARCH_SYS_ARCH_H__ */ - +/* + * Copyright (c) 2001-2003 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 __ARCH_SYS_ARCH_H__ +#define __ARCH_SYS_ARCH_H__ + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +/* MBOX primitives */ + +#define SYS_MBOX_NULL ( ( QueueHandle_t ) NULL ) +#define SYS_SEM_NULL ( ( SemaphoreHandle_t ) NULL ) +#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE + +typedef SemaphoreHandle_t sys_sem_t; +typedef SemaphoreHandle_t sys_mutex_t; +typedef QueueHandle_t sys_mbox_t; +typedef TaskHandle_t sys_thread_t; + +#define sys_mbox_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE ) +#define sys_mbox_set_invalid( x ) ( ( *x ) = NULL ) +#define sys_sem_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE ) +#define sys_sem_set_invalid( x ) ( ( *x ) = NULL ) + +#define sys_jiffies() xTaskGetTickCount() + +void sys_arch_msleep(uint32_t ms); +#define sys_msleep(ms) sys_arch_msleep(ms) + +#endif /* __ARCH_SYS_ARCH_H__ */ + diff --git a/lwip/include/lwipopts.h b/lwip/include/lwipopts.h index d2c7323..57c6f05 100644 --- a/lwip/include/lwipopts.h +++ b/lwip/include/lwipopts.h @@ -81,7 +81,9 @@ * UNLOCK_TCPIP_CORE(). * Your system should provide mutexes supporting priority inversion to use this. */ +#ifndef LWIP_TCPIP_CORE_LOCKING #define LWIP_TCPIP_CORE_LOCKING 1 +#endif /** * LWIP_TCPIP_CORE_LOCKING_INPUT: when LWIP_TCPIP_CORE_LOCKING is enabled, @@ -95,6 +97,48 @@ #define LWIP_TCPIP_CORE_LOCKING_INPUT 0 #endif +/** + * Macro/function to check whether lwIP's threading/locking + * requirements are satisfied during current function call. + * This macro usually calls a function that is implemented in the OS-dependent + * sys layer and performs the following checks: + * - Not in ISR + * - If @ref LWIP_TCPIP_CORE_LOCKING = 1: TCPIP core lock is held + * - If @ref LWIP_TCPIP_CORE_LOCKING = 0: function is called from TCPIP thread + * @see @ref multithreading + */ +#ifndef LWIP_ASSERT_CORE_LOCKED +void sys_check_core_locking(void); +#define LWIP_ASSERT_CORE_LOCKED() sys_check_core_locking() +#endif + +/** + * Called as first thing in the lwIP TCPIP thread. Can be used in conjunction + * with @ref LWIP_ASSERT_CORE_LOCKED to check core locking. + * @see @ref multithreading + */ +#ifndef LWIP_MARK_TCPIP_THREAD +void sys_mark_tcpip_thread(void); +#define LWIP_MARK_TCPIP_THREAD() sys_mark_tcpip_thread() +#endif + +#if LWIP_TCPIP_CORE_LOCKING + +#ifndef LOCK_TCPIP_CORE +void sys_lock_tcpip_core(void); +#define LOCK_TCPIP_CORE() sys_lock_tcpip_core() +#endif + +#ifndef UNLOCK_TCPIP_CORE +void sys_unlock_tcpip_core(void); +#define UNLOCK_TCPIP_CORE() sys_unlock_tcpip_core() +#endif + +#else +#define LOCK_TCPIP_CORE() +#define UNLOCK_TCPIP_CORE() +#endif /* LWIP_TCPIP_CORE_LOCKING */ + /* ------------------------------------ ---------- Memory options ---------- @@ -483,6 +527,21 @@ #define LWIP_NETIF_HOSTNAME 1 #endif +/** + * LWIP_NETIF_API==1: Support netif api (in netifapi.c) + */ +#ifndef LWIP_NETIF_API +#define LWIP_NETIF_API 0 +#endif + +/** + * LWIP_NETIF_STATUS_CALLBACK==1: Support a callback function whenever an interface + * changes its up/down status (i.e., due to DHCP IP acquisition) + */ +#ifndef LWIP_NETIF_STATUS_CALLBACK +#define LWIP_NETIF_STATUS_CALLBACK 0 +#endif + /** * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP *tries* to put all data * to be sent into one single pbuf. This is for compatibility with DMA-enabled @@ -515,7 +574,7 @@ * sys_thread_new() when the thread is created. */ #ifndef TCPIP_THREAD_STACKSIZE -#define TCPIP_THREAD_STACKSIZE 768 +#define TCPIP_THREAD_STACKSIZE 480 #endif /** @@ -672,6 +731,20 @@ --------------------------------------- */ +/* + --------------------------------------- + ---------- mDNS options --------------- + --------------------------------------- +*/ + +/** + * LWIP_MDNS_RESPONDER_QUEUE_ANNOUNCEMENTS==1: Unsolicited announcements are + * queued and run from a timer callback. + */ +#ifndef LWIP_MDNS_RESPONDER_QUEUE_ANNOUNCEMENTS +#define LWIP_MDNS_RESPONDER_QUEUE_ANNOUNCEMENTS 1 +#endif + /* --------------------------------------- ---------- Debugging options ---------- @@ -855,6 +928,11 @@ */ #define IP6_DEBUG LWIP_DBG_OFF +/** + * MDNS_DEBUG: Enable debugging for multicast DNS. + */ +#define MDNS_DEBUG LWIP_DBG_OFF + /* -------------------------------------------------- ---------- Performance tracking options ---------- diff --git a/lwip/lwip b/lwip/lwip index 4e87c66..9f70dbe 160000 --- a/lwip/lwip +++ b/lwip/lwip @@ -1 +1 @@ -Subproject commit 4e87c66bff75fbd02be86522de0f0bcf40a11f34 +Subproject commit 9f70dbe91a68df81c6bbcb48306a590359a41d3f diff --git a/lwip/sys_arch.c b/lwip/sys_arch.c index 1a9c5f9..36a6eae 100644 --- a/lwip/sys_arch.c +++ b/lwip/sys_arch.c @@ -48,6 +48,11 @@ #include "lwip/sys.h" #include "lwip/mem.h" #include "lwip/stats.h" +#include "lwip/tcpip.h" + +#if configUSE_16_BIT_TICKS == 1 +#error This port requires 32 bit ticks or timer overflow will fail +#endif /*---------------------------------------------------------------------------* * Routine: sys_sem_new @@ -62,24 +67,23 @@ * Outputs: * sys_sem_t -- Created semaphore or 0 if could not create. *---------------------------------------------------------------------------*/ -err_t sys_sem_new(sys_sem_t *pxSemaphore, u8_t ucCount) +err_t sys_sem_new(sys_sem_t *pxSemaphore, u8_t initial_count) { - err_t xReturn = ERR_MEM; + LWIP_ASSERT("initial_count invalid (not 0 or 1)", + (initial_count == 0) || (initial_count == 1)); - vSemaphoreCreateBinary(*pxSemaphore); - - if (*pxSemaphore != NULL) { - if (ucCount == 0U) { - xSemaphoreTake(*pxSemaphore, 1UL); - } - - xReturn = ERR_OK; - SYS_STATS_INC_USED(sem); - } else { + *pxSemaphore = xSemaphoreCreateBinary(); + if (*pxSemaphore == NULL) { SYS_STATS_INC(sem.err); + return ERR_MEM; } + SYS_STATS_INC_USED(sem); - return xReturn; + if (initial_count == 1) { + BaseType_t ret = xSemaphoreGive(*pxSemaphore); + LWIP_ASSERT("sys_sem_new: initial give failed", ret == pdTRUE); + } + return ERR_OK; } /*---------------------------------------------------------------------------* @@ -93,7 +97,8 @@ err_t sys_sem_new(sys_sem_t *pxSemaphore, u8_t ucCount) void sys_sem_free(sys_sem_t *pxSemaphore) { SYS_STATS_DEC(sem.used); - vQueueDelete(*pxSemaphore); + vSemaphoreDelete(*pxSemaphore); + *pxSemaphore = NULL; } /*---------------------------------------------------------------------------* @@ -131,22 +136,19 @@ void sys_sem_signal(sys_sem_t *pxSemaphore) * Outputs: * u32_t -- SYS_ARCH_TIMEOUT on timeout, any other value on success *---------------------------------------------------------------------------*/ -u32_t sys_arch_sem_wait(sys_sem_t *pxSemaphore, u32_t ulTimeout) +u32_t sys_arch_sem_wait(sys_sem_t *pxSemaphore, u32_t timeout_ms) { - u32_t ulReturn; - - if (ulTimeout != 0UL) { - if (xSemaphoreTake(*pxSemaphore, ulTimeout / portTICK_PERIOD_MS) == pdTRUE) { - ulReturn = 0; - } else { - ulReturn = SYS_ARCH_TIMEOUT; - } - } else { + if (timeout_ms == 0) { + /* Wait infinite */ while (xSemaphoreTake(*pxSemaphore, portMAX_DELAY) != pdTRUE); - ulReturn = 0; + return 0; } - return ulReturn; + if (xSemaphoreTake(*pxSemaphore, timeout_ms / portTICK_PERIOD_MS) == pdTRUE) { + return 0; + } else { + return SYS_ARCH_TIMEOUT; + } } /** Create a new mutex @@ -154,33 +156,30 @@ u32_t sys_arch_sem_wait(sys_sem_t *pxSemaphore, u32_t ulTimeout) * @return a new mutex */ err_t sys_mutex_new(sys_mutex_t *pxMutex) { - err_t xReturn; + *pxMutex = xSemaphoreCreateRecursiveMutex(); - *pxMutex = xSemaphoreCreateMutex(); - - if (*pxMutex != NULL) { - xReturn = ERR_OK; - SYS_STATS_INC_USED(mutex); - } else { - xReturn = ERR_MEM; + if (*pxMutex == NULL) { SYS_STATS_INC(mutex.err); + return ERR_MEM; } - return xReturn; + SYS_STATS_INC_USED(mutex); + return ERR_OK; } /** Lock a mutex * @param mutex the mutex to lock */ void sys_mutex_lock(sys_mutex_t *pxMutex) { - while (xSemaphoreTake(*pxMutex, portMAX_DELAY) != pdPASS); + while (xSemaphoreTakeRecursive(*pxMutex, portMAX_DELAY) != pdTRUE); } /** Unlock a mutex * @param mutex the mutex to unlock */ void sys_mutex_unlock(sys_mutex_t *pxMutex) { - xSemaphoreGive(*pxMutex); + BaseType_t ret = xSemaphoreGiveRecursive(*pxMutex); + LWIP_ASSERT("failed to give the mutex", ret == pdTRUE); } @@ -189,7 +188,8 @@ void sys_mutex_unlock(sys_mutex_t *pxMutex) void sys_mutex_free(sys_mutex_t *pxMutex) { SYS_STATS_DEC(mutex.used); - vQueueDelete(*pxMutex); + vSemaphoreDelete(*pxMutex); + *pxMutex = NULL; } /*---------------------------------------------------------------------------* @@ -202,21 +202,21 @@ void sys_mutex_free(sys_mutex_t *pxMutex) * Outputs: * sys_mbox_t -- Handle to new mailbox *---------------------------------------------------------------------------*/ -err_t sys_mbox_new(sys_mbox_t *pxMailBox, int iSize) +err_t sys_mbox_new(sys_mbox_t *mbox, int size) { - err_t xReturn = ERR_MEM; + LWIP_ASSERT("size > 0", size > 0); - *pxMailBox = xQueueCreate(iSize, sizeof(void *)); + *mbox = xQueueCreate(size, sizeof(void *)); - if (*pxMailBox != NULL) { - xReturn = ERR_OK; - SYS_STATS_INC_USED(mbox); + if (*mbox == NULL) { + SYS_STATS_INC(mbox.err); + return ERR_MEM; } - return xReturn; + SYS_STATS_INC_USED(mbox); + return ERR_OK; } - /*---------------------------------------------------------------------------* * Routine: sys_mbox_free *---------------------------------------------------------------------------* @@ -229,24 +229,21 @@ err_t sys_mbox_new(sys_mbox_t *pxMailBox, int iSize) * Outputs: * sys_mbox_t -- Handle to new mailbox *---------------------------------------------------------------------------*/ -void sys_mbox_free(sys_mbox_t *pxMailBox) +void sys_mbox_free(sys_mbox_t *mbox) { - unsigned long ulMessagesWaiting; + UBaseType_t msgs_waiting; - ulMessagesWaiting = uxQueueMessagesWaiting(*pxMailBox); - configASSERT(ulMessagesWaiting == 0); + msgs_waiting = uxQueueMessagesWaiting(*mbox); + configASSERT(msgs_waiting == 0); - #if SYS_STATS - { - if (ulMessagesWaiting != 0UL) { - SYS_STATS_INC(mbox.err); - } - - SYS_STATS_DEC(mbox.used); +#if SYS_STATS + if (msgs_waiting != 0) { + SYS_STATS_INC(mbox.err); } - #endif /* SYS_STATS */ + SYS_STATS_DEC(mbox.used); +#endif /* SYS_STATS */ - vQueueDelete(*pxMailBox); + vQueueDelete(*mbox); } /*---------------------------------------------------------------------------* @@ -258,9 +255,9 @@ void sys_mbox_free(sys_mbox_t *pxMailBox) * sys_mbox_t mbox -- Handle of mailbox * void *data -- Pointer to data to post *---------------------------------------------------------------------------*/ -void sys_mbox_post(sys_mbox_t *pxMailBox, void *pxMessageToPost) +void sys_mbox_post(sys_mbox_t *mbox, void *msg) { - while (xQueueSendToBack(*pxMailBox, &pxMessageToPost, portMAX_DELAY) != pdTRUE); + while (xQueueSendToBack(*mbox, &msg, portMAX_DELAY) != pdTRUE); } /*---------------------------------------------------------------------------* @@ -276,19 +273,15 @@ void sys_mbox_post(sys_mbox_t *pxMailBox, void *pxMessageToPost) * err_t -- ERR_OK if message posted, else ERR_MEM * if not. *---------------------------------------------------------------------------*/ -err_t sys_mbox_trypost(sys_mbox_t *pxMailBox, void *pxMessageToPost) +err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) { - err_t xReturn; - - if (xQueueSend(*pxMailBox, &pxMessageToPost, 0)) { - xReturn = ERR_OK; - } else { - /* The queue was already full. */ - xReturn = ERR_MEM; - SYS_STATS_INC( mbox.err ); + if (xQueueSendToBack(*mbox, &msg, 0) == pdTRUE) { + return ERR_OK; } - return xReturn; + /* The queue was already full. */ + SYS_STATS_INC(mbox.err); + return ERR_MEM; } /*---------------------------------------------------------------------------* @@ -315,29 +308,26 @@ err_t sys_mbox_trypost(sys_mbox_t *pxMailBox, void *pxMessageToPost) * Outputs: * u32_t -- SYS_ARCH_TIMEOUT on timeout, any other value if a message has been received *---------------------------------------------------------------------------*/ -u32_t sys_arch_mbox_fetch(sys_mbox_t *pxMailBox, void **ppvBuffer, u32_t ulTimeOut) +u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) { - void *pvDummy; - unsigned long ulReturn; + void *msg_dummy; - if (ppvBuffer == NULL) { - ppvBuffer = &pvDummy; + if (msg == NULL) { + msg = &msg_dummy; } - if (ulTimeOut != 0UL) { - if (xQueueReceive(*pxMailBox, &(*ppvBuffer), ulTimeOut / portTICK_PERIOD_MS) == pdTRUE) { - ulReturn = 0; - } else { - /* Timed out. */ - *ppvBuffer = NULL; - ulReturn = SYS_ARCH_TIMEOUT; - } - } else { - while (xQueueReceive(*pxMailBox, &(*ppvBuffer), portMAX_DELAY) != pdTRUE); - ulReturn = 0; + if (timeout == 0) { + while (xQueueReceive(*mbox, &(*msg), portMAX_DELAY) != pdTRUE); + return 0; } - return ulReturn; + if (xQueueReceive(*mbox, &(*msg), timeout / portTICK_PERIOD_MS) == pdTRUE) { + return 0; + } + + /* Timed out. */ + *msg = NULL; + return SYS_ARCH_TIMEOUT; } /*---------------------------------------------------------------------------* @@ -354,22 +344,20 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t *pxMailBox, void **ppvBuffer, u32_t ulTimeO * u32_t -- SYS_MBOX_EMPTY if no messages. Otherwise, * return ERR_OK. *---------------------------------------------------------------------------*/ -u32_t sys_arch_mbox_tryfetch(sys_mbox_t *pxMailBox, void **ppvBuffer) +u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) { - void *pvDummy; - unsigned long ulReturn; + void *msg_dummy; - if (ppvBuffer== NULL) { - ppvBuffer = &pvDummy; + if (msg == NULL) { + msg = &msg_dummy; } - if (xQueueReceive(*pxMailBox, &(*ppvBuffer), 0UL) == pdPASS) { - ulReturn = ERR_OK; - } else { - ulReturn = SYS_MBOX_EMPTY; + if (xQueueReceive(*mbox, &(*msg), 0) == pdTRUE) { + return ERR_OK; } - return ulReturn; + *msg = NULL; + return SYS_MBOX_EMPTY; } /*---------------------------------------------------------------------------* @@ -387,6 +375,12 @@ u32_t sys_now(void) return xTaskGetTickCount() * portTICK_PERIOD_MS; } +void sys_arch_msleep(u32_t delay_ms) +{ + TickType_t delay_ticks = delay_ms / portTICK_PERIOD_MS; + vTaskDelay(delay_ticks); +} + /*---------------------------------------------------------------------------* * Routine: sys_thread_new *---------------------------------------------------------------------------* @@ -405,21 +399,19 @@ u32_t sys_now(void) * Outputs: * sys_thread_t -- Pointer to per-thread timeouts. *---------------------------------------------------------------------------*/ -sys_thread_t sys_thread_new(const char *pcName, void(*pxThread)(void *pvParameters), void *pvArg, int iStackSize, int iPriority) +sys_thread_t sys_thread_new(const char *pcName, void(*pxThread)(void *pvParameters), void *pvArg, int stacksize, int iPriority) { TaskHandle_t xCreatedTask; - portBASE_TYPE xResult; - sys_thread_t xReturn; + BaseType_t xResult; - xResult = xTaskCreate(pxThread, pcName, iStackSize, pvArg, iPriority, &xCreatedTask); + xResult = xTaskCreate(pxThread, pcName, stacksize, pvArg, iPriority, &xCreatedTask); + LWIP_ASSERT("task creation failed", xResult == pdPASS); if (xResult == pdPASS) { - xReturn = xCreatedTask; - } else { - xReturn = NULL; + return xCreatedTask; } - return xReturn; + return NULL; } /*---------------------------------------------------------------------------* @@ -441,12 +433,13 @@ sys_thread_t sys_thread_new(const char *pcName, void(*pxThread)(void *pvParamete * Outputs: * sys_prot_t -- Previous protection level (not used here) *---------------------------------------------------------------------------*/ -static uint32_t my_nesting = 0; +static sys_prot_t critical_nesting; sys_prot_t sys_arch_protect(void) { + sys_prot_t prev; taskENTER_CRITICAL(); - uint32_t prev = my_nesting; - my_nesting++; + prev = critical_nesting; + critical_nesting++; return prev; //return (sys_prot_t)1; } @@ -462,16 +455,70 @@ sys_prot_t sys_arch_protect(void) * Inputs: * sys_prot_t -- Previous protection level (not used here) *---------------------------------------------------------------------------*/ -void sys_arch_unprotect(sys_prot_t xValue) +void sys_arch_unprotect(sys_prot_t pval) { //(void) xValue; - my_nesting--; - if (xValue != my_nesting) { - printf("lwip nesting %d\n", my_nesting); + critical_nesting--; + //LWIP_ASSERT("unexpected critical_nestion", pval == critical_nesting); + if (pval != critical_nesting) { + printf("lwip nesting %d\n", critical_nesting); } taskEXIT_CRITICAL(); } +#if LWIP_TCPIP_CORE_LOCKING + +/** Flag the core lock held. A counter for recusive locks. */ +u8_t lwip_core_lock_count; +TaskHandle_t lwip_core_lock_holder_thread; +void sys_lock_tcpip_core(void) +{ + sys_mutex_lock(&lock_tcpip_core); + if (lwip_core_lock_count == 0) { + lwip_core_lock_holder_thread = xTaskGetCurrentTaskHandle(); + } + lwip_core_lock_count++; +} + +void sys_unlock_tcpip_core(void) +{ + lwip_core_lock_count--; + if (lwip_core_lock_count == 0) { + lwip_core_lock_holder_thread = 0; + } + sys_mutex_unlock(&lock_tcpip_core); +} + +#endif /* LWIP_TCPIP_CORE_LOCKING */ + +TaskHandle_t lwip_tcpip_thread; +void sys_mark_tcpip_thread(void) +{ + lwip_tcpip_thread = xTaskGetCurrentTaskHandle(); +} + +void sys_check_core_locking(void) +{ + /* Embedded systems should check we are NOT in an interrupt context here */ + + if (lwip_tcpip_thread != 0) { + TaskHandle_t current_thread = xTaskGetCurrentTaskHandle(); + +#if LWIP_TCPIP_CORE_LOCKING + if (current_thread != lwip_core_lock_holder_thread || + lwip_core_lock_count == 0) { + printf("Function called without core lock\n"); + } + //LWIP_ASSERT("Function called without core lock", current_thread == lwip_core_lock_holder_thread && lwip_core_lock_count > 0); +#else + if (current_thread != lwip_tcpip_thread) { + printf("Function called from wrong thread\n"); + } + //LWIP_ASSERT("Function called from wrong thread", current_thread == lwip_tcpip_thread); +#endif /* LWIP_TCPIP_CORE_LOCKING */ + } +} + /*-------------------------------------------------------------------------* * End of File: sys_arch.c *-------------------------------------------------------------------------*/ diff --git a/open_esplibs/libmain/user_interface.c b/open_esplibs/libmain/user_interface.c index 1fd73b5..4483e5d 100644 --- a/open_esplibs/libmain/user_interface.c +++ b/open_esplibs/libmain/user_interface.c @@ -546,10 +546,13 @@ bool sdk_wifi_station_dhcpc_start(void) { sdk_info.sta_ipaddr.addr = 0; sdk_info.sta_netmask.addr = 0; sdk_info.sta_gw.addr = 0; + LOCK_TCPIP_CORE(); netif_set_addr(netif, &sdk_info.sta_ipaddr, &sdk_info.sta_netmask, &sdk_info.sta_gw); if (dhcp_start(netif)) { + UNLOCK_TCPIP_CORE(); return false; } + UNLOCK_TCPIP_CORE(); } sdk_dhcpc_flag = DHCP_STARTED; return true; @@ -561,9 +564,11 @@ bool sdk_wifi_station_dhcpc_stop(void) { return false; } if (netif && sdk_dhcpc_flag == DHCP_STARTED) { + LOCK_TCPIP_CORE(); dhcp_stop(netif); + sdk_dhcpc_flag = DHCP_STOPPED; + UNLOCK_TCPIP_CORE(); } - sdk_dhcpc_flag = DHCP_STOPPED; return true; } @@ -616,8 +621,11 @@ bool sdk_wifi_set_ip_info(uint8_t if_index, struct ip_info *info) { } struct netif *netif = _get_netif(if_index); - if (netif) + if (netif) { + LOCK_TCPIP_CORE(); netif_set_addr(netif, &info->ip, &info->netmask, &info->gw); + UNLOCK_TCPIP_CORE(); + } return true; } diff --git a/open_esplibs/libnet80211/ieee80211_hostap.c b/open_esplibs/libnet80211/ieee80211_hostap.c index 74f9675..fec4801 100644 --- a/open_esplibs/libnet80211/ieee80211_hostap.c +++ b/open_esplibs/libnet80211/ieee80211_hostap.c @@ -216,13 +216,17 @@ bool sdk_wifi_softap_start() { struct netif *netif = (struct netif *)malloc(sizeof(struct netif)); netif_info->netif = netif; memcpy(&netif->hwaddr, mac_addr, 6); + LOCK_TCPIP_CORE(); netif_add(netif, &sdk_info.softap_ipaddr, &sdk_info.softap_netmask, &sdk_info.softap_gw, netif_info, ethernetif_init, tcpip_input); + UNLOCK_TCPIP_CORE(); } sdk_ic_set_vif(1, 1, mac_addr, 1, 0); + LOCK_TCPIP_CORE(); netif_set_up(netif_info->netif); + UNLOCK_TCPIP_CORE(); if (sdk_wifi_get_opmode() != 3 || !sdk_g_ic.v.station_netif_info || @@ -293,7 +297,9 @@ bool sdk_wifi_softap_stop() { } while (count < end); } + LOCK_TCPIP_CORE(); netif_set_down(netif_info->netif); + UNLOCK_TCPIP_CORE(); sdk_TmpSTAAPCloseAP = 1; sdk_ets_timer_disarm(&hostap_timer); sdk_ic_bss_info_update(1, &sdk_info.softap_mac_addr, 2, 0); diff --git a/open_esplibs/libnet80211/ieee80211_sta.c b/open_esplibs/libnet80211/ieee80211_sta.c index 3e7f695..7c405cb 100644 --- a/open_esplibs/libnet80211/ieee80211_sta.c +++ b/open_esplibs/libnet80211/ieee80211_sta.c @@ -42,7 +42,10 @@ bool sdk_wifi_station_start() { struct netif *netif = (struct netif *)malloc(sizeof(struct netif)); netif_info->netif = netif; memcpy(&netif->hwaddr, &sdk_info.sta_mac_addr, 6); - netif_add(netif, &sdk_info.sta_ipaddr, &sdk_info.sta_netmask, &sdk_info.sta_gw, netif_info, ethernetif_init, tcpip_input); + LOCK_TCPIP_CORE(); + netif_add(netif, &sdk_info.sta_ipaddr, &sdk_info.sta_netmask, + &sdk_info.sta_gw, netif_info, ethernetif_init, tcpip_input); + UNLOCK_TCPIP_CORE(); sdk_wpa_attach(&sdk_g_ic); } sdk_ic_set_vif(0, 1, &sdk_info.sta_mac_addr, 0, 0); diff --git a/open_esplibs/libnet80211/wl_cnx.c b/open_esplibs/libnet80211/wl_cnx.c index 2d29960..bb5ec12 100644 --- a/open_esplibs/libnet80211/wl_cnx.c +++ b/open_esplibs/libnet80211/wl_cnx.c @@ -24,8 +24,10 @@ extern void *sdk_g_cnx_probe_rc_list_cb; */ void dhcp_if_down(struct netif *netif) { + LOCK_TCPIP_CORE(); dhcp_release_and_stop(netif); netif_set_down(netif); + UNLOCK_TCPIP_CORE(); } struct sdk_cnx_node *sdk_cnx_rc_search(uint8_t *hwaddr) { diff --git a/open_esplibs/libwpa/wpa_main.c b/open_esplibs/libwpa/wpa_main.c index e13e3b6..1c5646e 100644 --- a/open_esplibs/libwpa/wpa_main.c +++ b/open_esplibs/libwpa/wpa_main.c @@ -97,8 +97,10 @@ void sdk_eagle_auth_done() { if (sdk_dhcpc_flag != DHCP_STOPPED) { printf("dhcp client start...\n"); + LOCK_TCPIP_CORE(); netif_set_up(netif); dhcp_start(netif); + UNLOCK_TCPIP_CORE(); return; } @@ -107,8 +109,10 @@ void sdk_eagle_auth_done() { return; } + LOCK_TCPIP_CORE(); netif_set_addr(netif, &sdk_info.sta_ipaddr, &sdk_info.sta_netmask, &sdk_info.sta_gw); netif_set_up(netif); + UNLOCK_TCPIP_CORE(); sdk_system_station_got_ip_set(ip_2_ip4(&netif->ip_addr), ip_2_ip4(&netif->netmask), ip_2_ip4(&netif->gw));