Merge branch 'bugfix/spiram_malloc_reserve_internal_fragments' into 'master'

esp32: Allow SPIRAM_MALLOC_RESERVE_INTERNAL to span multiple regions of memory

See merge request idf/esp-idf!2891
This commit is contained in:
Angus Gratton 2018-08-16 11:19:39 +08:00
commit 4f227a4ce3
3 changed files with 34 additions and 13 deletions

View file

@ -143,7 +143,7 @@ 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
default 32768
range 0 131072
range 0 262144
help
Because the external/internal RAM allocation strategy is not always perfect, it sometimes may happen
that the internal memory is entirely filled up. This causes allocations that are specifically done in
@ -156,6 +156,10 @@ config SPIRAM_MALLOC_RESERVE_INTERNAL
Note that because FreeRTOS stacks are forced to internal memory, they will also use this memory pool;
be sure to keep this in mind when adjusting this value.
Note also that the DMA reserved pool may not be one single contiguous memory region, depending on the
configured size and the static memory usage of the app.
config SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY
bool "Allow external memory as an argument to xTaskCreateStatic"
default n

View file

@ -270,13 +270,6 @@ void start_cpu0_default(void)
ESP_EARLY_LOGE(TAG, "External RAM could not be added to heap!");
abort();
}
#if CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL
r=esp_spiram_reserve_dma_pool(CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL);
if (r != ESP_OK) {
ESP_EARLY_LOGE(TAG, "Could not reserve internal/DMA pool!");
abort();
}
#endif
#if CONFIG_SPIRAM_USE_MALLOC
heap_caps_malloc_extmem_enable(CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL);
#endif
@ -446,6 +439,15 @@ static void main_task(void* args)
//Enable allocation in region where the startup stacks were located.
heap_caps_enable_nonos_stack_heaps();
// Now we have startup stack RAM available for heap, enable any DMA pool memory
#if CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL
esp_err_t r = esp_spiram_reserve_dma_pool(CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL);
if (r != ESP_OK) {
ESP_EARLY_LOGE(TAG, "Could not reserve internal/DMA pool (error 0x%x)", r);
abort();
}
#endif
//Initialize task wdt if configured to do so
#ifdef CONFIG_TASK_WDT_PANIC
ESP_ERROR_CHECK(esp_task_wdt_init(CONFIG_TASK_WDT_TIMEOUT_S, true))

View file

@ -19,6 +19,7 @@ we add more types of external RAM memory, this can be made into a more intellige
#include <stdint.h>
#include <string.h>
#include <sys/param.h>
#include "sdkconfig.h"
#include "esp_attr.h"
@ -172,12 +173,26 @@ esp_err_t esp_spiram_add_to_heapalloc()
static uint8_t *dma_heap;
esp_err_t esp_spiram_reserve_dma_pool(size_t size) {
if (size==0) return ESP_OK; //no-op
ESP_EARLY_LOGI(TAG, "Reserving pool of %dK of internal memory for DMA/internal allocations", size/1024);
dma_heap=heap_caps_malloc(size, MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL);
if (!dma_heap) return ESP_ERR_NO_MEM;
uint32_t caps[]={MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL, 0, MALLOC_CAP_8BIT|MALLOC_CAP_32BIT};
return heap_caps_add_region_with_caps(caps, (intptr_t) dma_heap, (intptr_t) dma_heap+size-1);
/* Pool may be allocated in multiple non-contiguous chunks, depending on available RAM */
while (size > 0) {
size_t next_size = heap_caps_get_largest_free_block(MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL);
next_size = MIN(next_size, size);
ESP_EARLY_LOGD(TAG, "Allocating block of size %d bytes", next_size);
dma_heap = heap_caps_malloc(next_size, MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL);
if (!dma_heap || next_size == 0) {
return ESP_ERR_NO_MEM;
}
uint32_t caps[] = { MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL, 0, MALLOC_CAP_8BIT|MALLOC_CAP_32BIT };
esp_err_t e = heap_caps_add_region_with_caps(caps, (intptr_t) dma_heap, (intptr_t) dma_heap+next_size-1);
if (e != ESP_OK) {
return e;
}
size -= next_size;
}
return ESP_OK;
}
size_t esp_spiram_get_size()