feat(LWIP): Fix IRAM pbuf never send

WIFI only can send DRAM data, so if upper layer pbuf payload is
IRAM data, here it must be copy to DRAM.

We add "pbuf_alloc_ll" to reduce this happen.
This commit is contained in:
Dong Heng
2018-07-25 16:25:56 +08:00
parent fea25d234e
commit 74e013e493
4 changed files with 105 additions and 17 deletions

View File

@ -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 <stddef.h>
#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

View File

@ -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.

View File

@ -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;
}