diff --git a/components/lwip/api/sockets.c b/components/lwip/api/sockets.c index 5b109eb375..91a5222e68 100755 --- a/components/lwip/api/sockets.c +++ b/components/lwip/api/sockets.c @@ -388,19 +388,30 @@ static void lwip_socket_drop_registered_memberships(int s); #endif /* LWIP_IGMP */ #ifdef LWIP_ESP8266 -extern size_t system_get_free_heap_size(void); -#define DELAY_WHEN_MEMORY_NOT_ENOUGH() \ -do{\ - uint8_t _wait_delay = 0;\ - while (system_get_free_heap_size() < HEAP_HIGHWAT){\ - vTaskDelay(_wait_delay/portTICK_RATE_MS);\ - if (_wait_delay < 64) _wait_delay *= 2;\ - }\ -}while(0) +/* Since esp_wifi_tx_is_stop/system_get_free_heap_size are not an public wifi API, so extern them here*/ +extern size_t system_get_free_heap_size(void); +extern bool esp_wifi_tx_is_stop(void); + +/* Please be notified that this flow control is just a workaround for fixing wifi Q full issue. + * Under UDP/TCP pressure test, we found that the sockets may cause wifi tx queue full if the socket + * sending speed is faster than the wifi sending speed, it will finally cause the packet to be dropped + * in wifi layer, it's not acceptable in some application. That's why we introdue the tx flow control here. + * However, current solution is just a workaround, we need to consider the return value of wifi tx interface, + * and feedback the return value to lwip and let lwip do the flow control itself. + */ +static inline void esp32_tx_flow_ctrl(void) +{ + uint8_t _wait_delay = 0; + + while ((system_get_free_heap_size() < HEAP_HIGHWAT) || esp_wifi_tx_is_stop()){ + vTaskDelay(_wait_delay/portTICK_RATE_MS); + if (_wait_delay < 64) _wait_delay *= 2; + } +} #else -#define DELAY_WHEN_MEMORY_NOT_ENOUGH() +#define esp32_tx_flow_ctrl() #endif /** The global array of available sockets */ @@ -1219,7 +1230,7 @@ lwip_send(int s, const void *data, size_t size, int flags) #endif /* (LWIP_UDP || LWIP_RAW) */ } - DELAY_WHEN_MEMORY_NOT_ENOUGH(); + esp32_tx_flow_ctrl(); write_flags = NETCONN_COPY | ((flags & MSG_MORE) ? NETCONN_MORE : 0) | @@ -1402,7 +1413,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags, #endif /* LWIP_TCP */ } - DELAY_WHEN_MEMORY_NOT_ENOUGH(); + esp32_tx_flow_ctrl(); if ((to != NULL) && !SOCK_ADDR_TYPE_MATCH(to, sock)) { /* sockaddr does not match socket type (IPv4/IPv6) */ diff --git a/components/lwip/include/lwip/port/arch/sys_arch.h b/components/lwip/include/lwip/port/arch/sys_arch.h index 945b4e170a..be8ff72260 100644 --- a/components/lwip/include/lwip/port/arch/sys_arch.h +++ b/components/lwip/include/lwip/port/arch/sys_arch.h @@ -68,7 +68,5 @@ void sys_delay_ms(uint32_t ms); sys_sem_t* sys_thread_sem_init(void); void sys_thread_sem_deinit(void); sys_sem_t* sys_thread_sem_get(void); - - #endif /* __SYS_ARCH_H__ */