Merge branch 'bugfix/fix_iram_pbuf_never_send' into 'master'

Fix iram pbuf never send

See merge request sdk/ESP8266_RTOS_SDK!331
This commit is contained in:
Dong Heng
2018-07-26 12:08:10 +08:00
4 changed files with 105 additions and 17 deletions

View File

@ -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) {

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