diff --git a/components/esp8266/source/startup.c b/components/esp8266/source/startup.c index a7b81d8c..c1744a78 100644 --- a/components/esp8266/source/startup.c +++ b/components/esp8266/source/startup.c @@ -26,6 +26,7 @@ #include "esp_image_format.h" #include "esp_phy_init.h" #include "esp_wifi_osi.h" +#include "internal/esp_wifi_internal.h" #define FLASH_MAP_ADDR 0x40200000 @@ -60,6 +61,7 @@ static void user_init_entry(void *param) assert(wifi_timer_init() == 0); tcpip_adapter_init(); + esp_wifi_set_rx_pbuf_mem_type(WIFI_RX_PBUF_DRAM); app_main(); diff --git a/components/lwip/Kconfig b/components/lwip/Kconfig index 46666098..39da85f4 100644 --- a/components/lwip/Kconfig +++ b/components/lwip/Kconfig @@ -1,5 +1,9 @@ menu "LWIP" +config LWIP_USE_IRAM + bool "Enable lwip use iram option" + default n + menu "ARP" config LWIP_ARP_TABLE_SIZE @@ -610,4 +614,9 @@ config LWIP_THREAD_SAFE_DEBUG depends on LWIP_DEBUG default n +config LWIP_PBUF_CACHE_DEBUG + bool "Enable debugging for LWIP pbuf cache." + depends on LWIP_DEBUG + default n + endmenu diff --git a/components/lwip/lwip/src/core/timeouts.c b/components/lwip/lwip/src/core/timeouts.c index ce1e4b55..2e0ec540 100644 --- a/components/lwip/lwip/src/core/timeouts.c +++ b/components/lwip/lwip/src/core/timeouts.c @@ -412,6 +412,9 @@ again: return; } + extern void send_from_list(); + send_from_list(); + sleeptime = sys_timeouts_sleeptime(); if (sleeptime == 0 || sys_arch_mbox_fetch(mbox, msg, sleeptime) == SYS_ARCH_TIMEOUT) { /* If a SYS_ARCH_TIMEOUT value is returned, a timeout occurred diff --git a/components/lwip/port/esp8266/include/lwipopts.h b/components/lwip/port/esp8266/include/lwipopts.h index 7bd39f1d..66b6204a 100644 --- a/components/lwip/port/esp8266/include/lwipopts.h +++ b/components/lwip/port/esp8266/include/lwipopts.h @@ -219,9 +219,15 @@ void *memp_malloc_ll(size_t type); /** * Use DRAM instead of IRAM */ +#if CONFIG_LWIP_USE_IRAM #define mem_clib_free free #define mem_clib_malloc malloc #define mem_clib_calloc calloc +#else +#define mem_clib_free os_free +#define mem_clib_malloc os_malloc +#define mem_clib_calloc os_calloc +#endif /** * MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. @@ -2175,6 +2181,15 @@ void *memp_malloc_ll(size_t type); #define ESP_THREAD_SAFE_DEBUG LWIP_DBG_OFF #endif +/** + * PBUF_CACHE_DEBUG: Enable debugging for SNTP. + */ +#if CONFIG_LWIP_PBUF_CACHE_DEBUG +#define PBUF_CACHE_DEBUG LWIP_DBG_ON +#else +#define PBUF_CACHE_DEBUG LWIP_DBG_OFF +#endif + /** * @} */ diff --git a/components/lwip/port/esp8266/netif/ethernetif.c b/components/lwip/port/esp8266/netif/ethernetif.c index ae4abfe3..e9c5c185 100644 --- a/components/lwip/port/esp8266/netif/ethernetif.c +++ b/components/lwip/port/esp8266/netif/ethernetif.c @@ -21,6 +21,9 @@ #include "esp_wifi.h" #include "tcpip_adapter.h" #include "esp_socket.h" +#include "freertos/semphr.h" +#include "lwip/tcpip.h" +#include "stdlib.h" #include "esp8266/eagle_soc.h" @@ -31,6 +34,137 @@ void wifi_station_set_default_hostname(uint8_t* hwaddr); #define IFNAME0 'e' #define IFNAME1 'n' + +typedef struct pbuf_send_list { + struct pbuf_send_list* next; + struct pbuf* p; + int aiofd; + int err_cnt; +} pbuf_send_list_t; + +static pbuf_send_list_t* pbuf_list_head = NULL; +static int pbuf_send_list_num = 0; +static int low_level_send_cb(esp_aio_t* aio); + +static inline bool check_pbuf_to_insert(struct pbuf* p) +{ + uint8_t* buf = (uint8_t *)p->payload; + /*Check if pbuf is tcp ip*/ + if (buf[12] == 0x08 && buf[13] == 0x00 && buf[23] == 0x06) { + return true; + } + return false; +} + +static void insert_to_list(int fd, struct pbuf* p) +{ + pbuf_send_list_t* tmp_pbuf_list1; + pbuf_send_list_t* tmp_pbuf_list2; + + if (pbuf_send_list_num > (TCP_SND_QUEUELEN * MEMP_NUM_TCP_PCB + MEMP_NUM_TCP_PCB)) { + return; + } + + if (!check_pbuf_to_insert(p)) { + return; + } + + LWIP_DEBUGF(PBUF_CACHE_DEBUG, ("Insert %p,%d\n",p,pbuf_send_list_num)); + if (pbuf_list_head == NULL) { + pbuf_list_head = (pbuf_send_list_t* )malloc(sizeof(pbuf_send_list_t)); + pbuf_send_list_num++; + + if (!pbuf_list_head) { + LWIP_DEBUGF(PBUF_CACHE_DEBUG, ("no menory malloc pbuf list error\n")); + return; + } + pbuf_ref(p); + pbuf_list_head->aiofd = fd; + pbuf_list_head->p = p; + pbuf_list_head->next = NULL; + pbuf_list_head->err_cnt = 0; + return; + } + + tmp_pbuf_list1 = pbuf_list_head; + tmp_pbuf_list2 = tmp_pbuf_list1; + + while (tmp_pbuf_list1 != NULL) { + if (tmp_pbuf_list1->p == p) { + tmp_pbuf_list1->err_cnt ++; + return; + } + tmp_pbuf_list2 = tmp_pbuf_list1; + tmp_pbuf_list1 = tmp_pbuf_list2->next; + } + + tmp_pbuf_list2->next = (pbuf_send_list_t*)malloc(sizeof(pbuf_send_list_t)); + pbuf_send_list_num++; + tmp_pbuf_list1 = tmp_pbuf_list2->next; + + if (!tmp_pbuf_list1) { + LWIP_DEBUGF(PBUF_CACHE_DEBUG, ("no menory malloc pbuf list error\n")); + return; + } + + pbuf_ref(p); + tmp_pbuf_list1->aiofd = fd; + tmp_pbuf_list1->p = p; + tmp_pbuf_list1->next = NULL; + tmp_pbuf_list1->err_cnt = 0; +} + +void send_from_list() +{ + pbuf_send_list_t* tmp_pbuf_list1; + + while (pbuf_list_head != NULL) { + if (pbuf_list_head->p->ref == 1) { + tmp_pbuf_list1 = pbuf_list_head->next; + LWIP_DEBUGF(PBUF_CACHE_DEBUG, ("Delete %p,%d\n",pbuf_list_head->p,pbuf_send_list_num)); + pbuf_free(pbuf_list_head->p); + free(pbuf_list_head); + pbuf_send_list_num--; + pbuf_list_head = tmp_pbuf_list1; + } else { + esp_aio_t aio; + esp_err_t err; + aio.fd = (int)pbuf_list_head->aiofd; + aio.pbuf = pbuf_list_head->p->payload; + aio.len = pbuf_list_head->p->len; + aio.cb = low_level_send_cb; + aio.arg = pbuf_list_head->p; + aio.ret = 0; + + err = esp_aio_sendto(&aio, NULL, 0); + tmp_pbuf_list1 = pbuf_list_head->next; + + if (err == ERR_MEM) { + pbuf_list_head->err_cnt++; + if (pbuf_list_head->err_cnt >= 3) { + LWIP_DEBUGF(PBUF_CACHE_DEBUG, ("Delete %p,%d\n",pbuf_list_head->p,pbuf_send_list_num)); + pbuf_free(pbuf_list_head->p); + free(pbuf_list_head); + pbuf_send_list_num--; + pbuf_list_head = tmp_pbuf_list1; + } + return; + } else if (err == ERR_OK){ + LWIP_DEBUGF(PBUF_CACHE_DEBUG, ("Delete %p,%d\n",pbuf_list_head->p,pbuf_send_list_num)); + free(pbuf_list_head); + pbuf_send_list_num--; + pbuf_list_head = tmp_pbuf_list1; + } else { + LWIP_DEBUGF(PBUF_CACHE_DEBUG, ("Delete %p,%d\n",pbuf_list_head->p,pbuf_send_list_num)); + pbuf_free(pbuf_list_head->p); + free(pbuf_list_head); + pbuf_send_list_num--; + pbuf_list_head = tmp_pbuf_list1; + } + } + } +} + /** * In this function, the hardware should be initialized. * Called from ethernetif_init(). @@ -169,8 +303,10 @@ static int8_t low_level_output(struct netif* netif, struct pbuf* p) */ err = esp_aio_sendto(&aio, NULL, 0); if (err != ERR_OK) { - if (err == ERR_MEM) + if (err == ERR_MEM){ + insert_to_list(aio.fd, p); err = ERR_OK; + } pbuf_free(p); }