Merge branch 'feature/alloc_memories_of_wifi_and_lwip_in_spiram_first' into 'master'

Allocate some memories in SPIRAM first.

See merge request !1367
This commit is contained in:
Jiang Jiang Jian 2017-10-13 15:47:27 +08:00
commit 6ff5c32ae5
14 changed files with 245 additions and 17 deletions

View file

@ -128,6 +128,13 @@ config SPIRAM_MALLOC_ALWAYSINTERNAL
If allocation from the preferred region fails, an attempt is made to allocate from the non-preferred
region instead, so malloc() will not suddenly fail when either internal or external memory is full.
config WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST
bool "Try to allocate memories of WiFi and LWIP in SPIRAM firstly. If failed, allocate internal memory"
depends on SPIRAM_USE_CAPS_ALLOC || SPIRAM_USE_MALLOC
default "n"
help
Try to allocate memories of WiFi and LWIP in SPIRAM firstly. If failed, try to allocate internal memory then.
config SPIRAM_MALLOC_RESERVE_INTERNAL
int "Reserve this amount of bytes for data that specifically needs to be in DMA or internal memory"
depends on SPIRAM_USE_MALLOC

View file

@ -121,6 +121,41 @@ esp_err_t esp_wifi_internal_reg_rxcb(wifi_interface_t ifx, wifi_rxcb_t fn);
*/
esp_err_t esp_wifi_internal_set_sta_ip(void);
/**
* @brief Allocate a chunk of memory for WiFi driver
*
* @attention This API is not used for DMA memory allocation.
*
* @param size_t size : Size, in bytes, of the amount of memory to allocate
*
* @return A pointer to the memory allocated on success, NULL on failure
*/
void *wifi_malloc( size_t size );
/**
* @brief Reallocate a chunk of memory for WiFi driver
*
* @attention This API is not used for DMA memory allocation.
*
* @param void * ptr : Pointer to previously allocated memory, or NULL for a new allocation.
* @param size_t size : Size, in bytes, of the amount of memory to allocate
*
* @return A pointer to the memory allocated on success, NULL on failure
*/
void *wifi_realloc( void *ptr, size_t size );
/**
* @brief Callocate memory for WiFi driver
*
* @attention This API is not used for DMA memory allocation.
*
* @param size_t n : Number of continuing chunks of memory to allocate
* @param size_t size : Size, in bytes, of the amount of memory to allocate
*
* @return A pointer to the memory allocated on success, NULL on failure
*/
void *wifi_calloc( size_t n, size_t size );
#ifdef __cplusplus
}
#endif

@ -1 +1 @@
Subproject commit 1c132fda65587f87e677d6ae2ed5d0ae68431956
Subproject commit 1f583184974518ad959c5510fff310170c6aaebd

View file

@ -0,0 +1,56 @@
// Copyright 2015-2017 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 "esp_attr.h"
#include "esp_heap_caps.h"
#include "sdkconfig.h"
/*
If CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST is enabled. Prefer to allocate a chunk of memory in SPIRAM firstly.
If failed, try to allocate it in internal memory then.
*/
IRAM_ATTR void *wifi_malloc( size_t size )
{
#if CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST
return heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
#else
return malloc(size);
#endif
}
/*
If CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST is enabled. Prefer to allocate a chunk of memory in SPIRAM firstly.
If failed, try to allocate it in internal memory then.
*/
IRAM_ATTR void *wifi_realloc( void *ptr, size_t size )
{
#if CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST
return heap_caps_realloc_prefer(ptr, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
#else
return realloc(ptr, size);
#endif
}
/*
If CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST is enabled. Prefer to allocate a chunk of memory in SPIRAM firstly.
If failed, try to allocate it in internal memory then.
*/
IRAM_ATTR void *wifi_calloc( size_t n, size_t size )
{
#if CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST
return heap_caps_calloc_prefer(n, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
#else
return calloc(n, size);
#endif
}

View file

@ -188,6 +188,60 @@ IRAM_ATTR void *heap_caps_realloc_default( void *ptr, size_t size )
}
}
/*
Memory allocation as preference in decreasing order.
*/
IRAM_ATTR void *heap_caps_malloc_prefer( size_t size, size_t num, ... )
{
va_list argp;
va_start( argp, num );
void *r = NULL;
while (num--) {
uint32_t caps = va_arg( argp, uint32_t );
r = heap_caps_malloc( size, caps );
if (r != NULL) {
break;
}
}
va_end( argp );
return r;
}
/*
Memory reallocation as preference in decreasing order.
*/
IRAM_ATTR void *heap_caps_realloc_prefer( void *ptr, size_t size, size_t num, ... )
{
va_list argp;
va_start( argp, num );
void *r = NULL;
while (num--) {
uint32_t caps = va_arg( argp, uint32_t );
r = heap_caps_realloc( ptr, size, caps );
if (r != NULL || size == 0) {
break;
}
}
va_end( argp );
return r;
}
/*
Memory callocation as preference in decreasing order.
*/
IRAM_ATTR void *heap_caps_calloc_prefer( size_t n, size_t size, size_t num, ... )
{
va_list argp;
va_start( argp, num );
void *r = NULL;
while (num--) {
uint32_t caps = va_arg( argp, uint32_t );
r = heap_caps_calloc( n, size, caps );
if (r != NULL) break;
}
va_end( argp );
return r;
}
/* Find the heap which belongs to ptr, or return NULL if it's
not in any heap.
@ -269,6 +323,16 @@ IRAM_ATTR void *heap_caps_realloc( void *ptr, size_t size, int caps)
return NULL;
}
IRAM_ATTR void *heap_caps_calloc( size_t n, size_t size, uint32_t caps)
{
void *r;
r = heap_caps_malloc(n*size, caps);
if (r != NULL) {
bzero(r, n*size);
}
return r;
}
size_t heap_caps_get_free_size( uint32_t caps )
{
size_t ret = 0;

View file

@ -81,6 +81,21 @@ void heap_caps_free( void *ptr);
*/
void *heap_caps_realloc( void *ptr, size_t size, int caps);
/**
* @brief Allocate a chunk of memory which has the given capabilities. The initialized value in the memory is set to zero.
*
* Equivalent semantics to libc calloc(), for capability-aware memory.
*
* In IDF, ``calloc(p)`` is equivalent to ``heaps_caps_calloc(p, MALLOC_CAP_8BIT)``.
*
* @param n Number of continuing chunks of memory to allocate
* @param size Size, in bytes, of a chunk of memory to allocate
* @param caps Bitwise OR of MALLOC_CAP_* flags indicating the type
* of memory to be returned
*
* @return A pointer to the memory allocated on success, NULL on failure
*/
void *heap_caps_calloc(size_t n, size_t size, uint32_t caps);
/**
* @brief Get the total free size of all the regions that have the given capabilities
@ -224,3 +239,40 @@ bool heap_caps_check_integrity_addr(intptr_t addr, bool print_errors);
* @param limit Limit, in bytes.
*/
void heap_caps_malloc_extmem_enable(size_t limit);
/**
* @brief Allocate a chunk of memory as preference in decreasing order.
*
* @attention The variable parameters are bitwise OR of MALLOC_CAP_* flags indicating the type of memory.
* This API prefers to allocate memory with the first parameter. If failed, allocate memory with
* the next parameter. It will try in this order until allocating a chunk of memory successfully
* or fail to allocate memories with any of the parameters.
*
* @param size Size, in bytes, of the amount of memory to allocate
* @param num Number of variable paramters
*
* @return A pointer to the memory allocated on success, NULL on failure
*/
void *heap_caps_malloc_prefer( size_t size, size_t num, ... );
/**
* @brief Allocate a chunk of memory as preference in decreasing order.
*
* @param ptr Pointer to previously allocated memory, or NULL for a new allocation.
* @param size Size of the new buffer requested, or 0 to free the buffer.
* @param num Number of variable paramters
*
* @return Pointer to a new buffer of size 'size', or NULL if allocation failed.
*/
void *heap_caps_realloc_prefer( void *ptr, size_t size, size_t num, ... );
/**
* @brief Allocate a chunk of memory as preference in decreasing order.
*
* @param n Number of continuing chunks of memory to allocate
* @param size Size, in bytes, of a chunk of memory to allocate
* @param num Number of variable paramters
*
* @return A pointer to the memory allocated on success, NULL on failure
*/
void *heap_caps_calloc_prefer( size_t n, size_t size, size_t num, ... );

View file

@ -800,13 +800,13 @@ static s16_t parse_msg(struct dhcps_msg *m, u16_t len)
pdhcps_pool = NULL;
pnode = NULL;
} else {
pdhcps_pool = (struct dhcps_pool *)malloc(sizeof(struct dhcps_pool));
pdhcps_pool = (struct dhcps_pool *)mem_malloc(sizeof(struct dhcps_pool));
memset(pdhcps_pool , 0x00 , sizeof(struct dhcps_pool));
pdhcps_pool->ip.addr = client_address.addr;
memcpy(pdhcps_pool->mac, m->chaddr, sizeof(pdhcps_pool->mac));
pdhcps_pool->lease_timer = lease_timer;
pnode = (list_node *)malloc(sizeof(list_node));
pnode = (list_node *)mem_malloc(sizeof(list_node));
memset(pnode , 0x00 , sizeof(list_node));
pnode->pnode = pdhcps_pool;
@ -905,7 +905,7 @@ static void handle_dhcp(void *arg,
malloc_len = p->tot_len;
}
pmsg_dhcps = (struct dhcps_msg *)malloc(malloc_len);
pmsg_dhcps = (struct dhcps_msg *)mem_malloc(malloc_len);
if (NULL == pmsg_dhcps) {
pbuf_free(p);
return;

View file

@ -54,12 +54,26 @@ typedef size_t mem_size_t;
#ifndef mem_free
#define mem_free free
#endif
/**
* lwip_malloc: if CONFIG_ALLOC_MEMORY_IN_SPIRAM_FIRST is enabled, Try to
* allocate memory for lwip in SPIRAM firstly. If failed, try to allocate
* internal memory then.
*/
#if CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST
#ifndef mem_malloc
#define mem_malloc(size) heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL)
#endif
#ifndef mem_calloc
#define mem_calloc(n, size) heap_caps_calloc_prefer(n, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL)
#endif
#else
#ifndef mem_malloc
#define mem_malloc malloc
#endif
#ifndef mem_calloc
#define mem_calloc calloc
#endif
#endif
/* Since there is no C library allocation function to shrink memory without
moving it, define this to nothing. */

View file

@ -509,7 +509,7 @@ set_noauth_addr(argv)
int l = strlen(addr) + 1;
struct wordlist *wp;
wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l);
wp = (struct wordlist *) mem_malloc(sizeof(struct wordlist) + l);
if (wp == NULL)
novm("allow-ip argument");
wp->word = (char *) (wp + 1);
@ -531,7 +531,7 @@ set_permitted_number(argv)
int l = strlen(number) + 1;
struct wordlist *wp;
wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l);
wp = (struct wordlist *) mem_malloc(sizeof(struct wordlist) + l);
if (wp == NULL)
novm("allow-number argument");
wp->word = (char *) (wp + 1);
@ -2048,7 +2048,7 @@ set_allowed_addrs(unit, addrs, opts)
n = wordlist_count(addrs) + wordlist_count(noauth_addrs);
if (n == 0)
return;
ip = (struct permitted_ip *) malloc((n + 1) * sizeof(struct permitted_ip));
ip = (struct permitted_ip *) mem_malloc((n + 1) * sizeof(struct permitted_ip));
if (ip == 0)
return;
@ -2417,7 +2417,7 @@ scan_authfile(f, client, server, secret, addrs, opts, filename, flags)
if (!getword(f, word, &newline, filename) || newline)
break;
ap = (struct wordlist *)
malloc(sizeof(struct wordlist) + strlen(word) + 1);
mem_malloc(sizeof(struct wordlist) + strlen(word) + 1);
if (ap == NULL)
novm("authorized addresses");
ap->word = (char *) (ap + 1);

View file

@ -89,7 +89,7 @@ demand_conf()
if (framemax < PPP_MRU) */
framemax = PPP_MRU;
framemax += PPP_HDRLEN + PPP_FCSLEN;
frame = malloc(framemax);
frame = mem_malloc(framemax);
if (frame == NULL)
novm("demand frame");
framelen = 0;
@ -296,7 +296,7 @@ loop_frame(frame, len)
if (!active_packet(frame, len))
return 0;
pkt = (struct packet *) malloc(sizeof(struct packet) + len);
pkt = (struct packet *) mem_malloc(sizeof(struct packet) + len);
if (pkt != NULL) {
pkt->length = len;
pkt->next = NULL;

View file

@ -1215,7 +1215,7 @@ name_of_pn_file()
}
file = _PATH_PSEUDONYM;
pl = strlen(user) + strlen(file) + 2;
path = malloc(pl);
path = mem_malloc(pl);
if (path == NULL)
return (NULL);
(void) slprintf(path, pl, "%s/%s", user, file);

View file

@ -170,7 +170,7 @@ mp_join_bundle()
l += 3 * ho->endpoint.length + 8;
if (bundle_name)
l += 3 * strlen(bundle_name) + 2;
bundle_id = malloc(l);
bundle_id = mem_malloc(l);
if (bundle_id == 0)
novm("bundle identifier");
@ -186,7 +186,7 @@ mp_join_bundle()
/* Make the key for the list of links belonging to the bundle */
l = p - bundle_id;
blinks_id = malloc(l + 7);
blinks_id = mem_malloc(l + 7);
if (blinks_id == NULL)
novm("bundle links key");
slprintf(blinks_id, l + 7, "BUNDLE_LINKS=%s", bundle_id + 7);
@ -322,7 +322,7 @@ static void make_bundle_links(int append)
return;
}
l = rec.dsize + strlen(entry);
p = malloc(l);
p = mem_malloc(l);
if (p == NULL)
novm("bundle link list");
slprintf(p, l, "%s%s", rec.dptr, entry);

View file

@ -40,7 +40,7 @@ static void dbg_lwip_tcp_pcb_cnt_show(struct tcp_pcb *pcb)
char *p;
int i;
buf = malloc(512);
buf = mem_malloc(512);
if (!buf) {
return;
}

View file

@ -195,7 +195,7 @@ sys_sem_free(sys_sem_t *sem)
err_t
sys_mbox_new(sys_mbox_t *mbox, int size)
{
*mbox = malloc(sizeof(struct sys_mbox_s));
*mbox = mem_malloc(sizeof(struct sys_mbox_s));
if (*mbox == NULL){
LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("fail to new *mbox\n"));
return ERR_MEM;
@ -513,7 +513,7 @@ static void sys_thread_tls_free(int index, void* data)
sys_sem_t* sys_thread_sem_init(void)
{
sys_sem_t *sem = (sys_sem_t*)malloc(sizeof(sys_sem_t*));
sys_sem_t *sem = (sys_sem_t*)mem_malloc(sizeof(sys_sem_t*));
if (!sem){
ESP_LOGE(TAG, "thread_sem_init: out of memory");