Allocate some memories in SPIRAM first.

Try to allocate some WiFi and LWIP memories in SPIRAM first. If
    failed, try to allocate in internal RAM then.
This commit is contained in:
XiaXiaotian 2017-09-30 15:28:41 +08:00
parent 73462c052e
commit 5df39cd4b6
14 changed files with 245 additions and 17 deletions

View file

@ -127,6 +127,13 @@ config SPIRAM_MALLOC_ALWAYSINTERNAL
than this size in internal memory, while allocations larger than this will be done from external RAM.
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"

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");