diff --git a/components/lwip/lwip/src/core/pbuf.c b/components/lwip/lwip/src/core/pbuf.c index 059f83a5..67d9b449 100644 --- a/components/lwip/lwip/src/core/pbuf.c +++ b/components/lwip/lwip/src/core/pbuf.c @@ -282,7 +282,12 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) switch (type) { case PBUF_POOL: /* allocate head of pbuf chain into p */ +#ifdef ESP_LWIP + /* Only DRAM data can be sent by low-level WIFI */ + p = (struct pbuf *)memp_malloc_ll(MEMP_PBUF_POOL); +#else p = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL); +#endif LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc: allocated pbuf %p\n", (void *)p)); if (p == NULL) { PBUF_POOL_IS_EMPTY(); @@ -315,7 +320,12 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) rem_len = length - p->len; /* any remaining pbufs to be allocated? */ while (rem_len > 0) { +#ifdef ESP_LWIP + /* Only DRAM data can be sent by low-level WIFI */ + q = (struct pbuf *)memp_malloc_ll(MEMP_PBUF_POOL); +#else q = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL); +#endif if (q == NULL) { PBUF_POOL_IS_EMPTY(); /* free chain so far allocated */ @@ -357,9 +367,14 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) if (alloc_len < LWIP_MEM_ALIGN_SIZE(length)) { return NULL; } - + /* If pbuf is to be allocated in RAM, allocate memory for it. */ +#ifdef ESP_LWIP + /* Only DRAM data can be sent by low-level WIFI */ + p = (struct pbuf*)mem_malloc_ll(alloc_len); +#else p = (struct pbuf*)mem_malloc(alloc_len); +#endif } if (p == NULL) { diff --git a/components/lwip/port/esp8266/freertos/heap.c b/components/lwip/port/esp8266/freertos/heap.c new file mode 100644 index 00000000..bae921cd --- /dev/null +++ b/components/lwip/port/esp8266/freertos/heap.c @@ -0,0 +1,55 @@ +// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD +// +// 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. + +#include +#include "lwip/opt.h" +#include "lwip/memp.h" +#include "FreeRTOS.h" +#include "esp8266/eagle_soc.h" + +#ifdef ESP_LWIP +/* + * @brief allocate an only DRAM memory block for LWIP pbuf + * + * @param s memory size + * + * @return memory block pointer + */ +void *mem_malloc_ll(size_t s) +{ + void *p; + void *return_addr = (void *)__builtin_return_address(0); + + p = pvPortMalloc_trace(s, return_addr, (unsigned)-1, false); + if (IS_IRAM(p)) { + vPortFree_trace(p, return_addr, (unsigned)-1); + p = NULL; + } + + return p; +} + +void *memp_malloc_ll(size_t type) +{ + extern const struct memp_desc* const memp_pools[MEMP_MAX]; + + uint8_t *p; + const struct memp_desc *desc = memp_pools[type]; + + p = (uint8_t *)mem_malloc_ll(MEMP_SIZE + MEMP_ALIGN_SIZE(desc->size)); + + return p + MEMP_SIZE; +} + +#endif diff --git a/components/lwip/port/esp8266/include/lwipopts.h b/components/lwip/port/esp8266/include/lwipopts.h index 9e0dbfff..7bd39f1d 100644 --- a/components/lwip/port/esp8266/include/lwipopts.h +++ b/components/lwip/port/esp8266/include/lwipopts.h @@ -50,6 +50,8 @@ #include "esp_libc.h" #include "esp_system.h" +#define ESP_LWIP 1 + #ifdef CONFIG_LWIP_SOCKET_MULTITHREAD #define SOCKETS_MT #endif @@ -194,12 +196,32 @@ */ #define MEM_LIBC_MALLOC 1 +#ifdef ESP_LWIP +/* + * @brief allocate an only DRAM memory block for LWIP pbuf + * + * @param s memory size + * + * @return memory block pointer + */ +void *mem_malloc_ll(size_t s); + +/* + * @brief allocate an only DRAM memory pool for LWIP pbuf + * + * @param type memory type + * + * @return memory pool pointer + */ +void *memp_malloc_ll(size_t type); +#endif + /** * Use DRAM instead of IRAM */ -#define mem_clib_free os_free -#define mem_clib_malloc os_malloc -#define mem_clib_calloc os_calloc +#define mem_clib_free free +#define mem_clib_malloc malloc +#define mem_clib_calloc calloc /** * MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. diff --git a/components/lwip/port/esp8266/netif/ethernetif.c b/components/lwip/port/esp8266/netif/ethernetif.c index 5f140846..ae4abfe3 100644 --- a/components/lwip/port/esp8266/netif/ethernetif.c +++ b/components/lwip/port/esp8266/netif/ethernetif.c @@ -89,7 +89,7 @@ static inline struct pbuf *ethernetif_transform_pbuf(struct pbuf *pbuf) { struct pbuf *p; - if (!(pbuf->flags & PBUF_FLAG_IS_CUSTOM)) { + if (!(pbuf->flags & PBUF_FLAG_IS_CUSTOM) && IS_DRAM(pbuf->payload)) { /* * Add ref to pbuf to avoid it to be freed by upper layer. */ @@ -101,6 +101,12 @@ static inline struct pbuf *ethernetif_transform_pbuf(struct pbuf *pbuf) if (!p) return NULL; + if (IS_IRAM(p->payload)) { + LWIP_DEBUGF(NETIF_DEBUG, ("low_level_output: data in IRAM\n")); + pbuf_free(p); + return NULL; + } + memcpy(p->payload, pbuf->payload, pbuf->len); /* @@ -147,12 +153,7 @@ static int8_t low_level_output(struct netif* netif, struct pbuf* p) p = ethernetif_transform_pbuf(p); if (!p) { LWIP_DEBUGF(NETIF_DEBUG, ("low_level_output: lack memory\n")); - goto exit; // return ERR_OK - } - - if (IS_IRAM(p->payload)) { - LWIP_DEBUGF(NETIF_DEBUG, ("low_level_output: data in IRAM\n")); - goto error; // return ERR_OK + return ERR_OK; } aio.fd = (int)netif->state; @@ -171,11 +172,9 @@ static int8_t low_level_output(struct netif* netif, struct pbuf* p) if (err == ERR_MEM) err = ERR_OK; - goto error; + pbuf_free(p); } - return ERR_OK; - // signal that packet should be sent(); #if ETH_PAD_SIZE @@ -185,9 +184,6 @@ static int8_t low_level_output(struct netif* netif, struct pbuf* p) #if LWIP_STATS LINK_STATS_INC(link.xmit); #endif -error: - pbuf_free(p); -exit: return err; }