diff --git a/components/esp32/spiram.c b/components/esp32/spiram.c index e7ee354cfd..30ef09872c 100644 --- a/components/esp32/spiram.c +++ b/components/esp32/spiram.c @@ -175,7 +175,6 @@ esp_err_t esp_spiram_init(void) return ESP_OK; } - esp_err_t esp_spiram_add_to_heapalloc(void) { //Add entire external RAM region to heap allocator. Heap allocator knows the capabilities of this type of memory, so there's @@ -189,10 +188,11 @@ esp_err_t esp_spiram_add_to_heapalloc(void) #endif } - -static uint8_t *dma_heap; - esp_err_t esp_spiram_reserve_dma_pool(size_t size) { + if (size == 0) { + return ESP_OK; + } + ESP_EARLY_LOGI(TAG, "Reserving pool of %dK of internal memory for DMA/internal allocations", size/1024); /* Pool may be allocated in multiple non-contiguous chunks, depending on available RAM */ while (size > 0) { @@ -200,7 +200,8 @@ esp_err_t esp_spiram_reserve_dma_pool(size_t size) { 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); + + uint8_t *dma_heap = heap_caps_malloc(next_size, MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL); if (!dma_heap || next_size == 0) { return ESP_ERR_NO_MEM; } diff --git a/components/esp32s2/spiram.c b/components/esp32s2/spiram.c index 6b0c7f2a61..ce370d1fbc 100644 --- a/components/esp32s2/spiram.c +++ b/components/esp32s2/spiram.c @@ -284,7 +284,6 @@ esp_err_t esp_spiram_init(void) return ESP_OK; } - esp_err_t esp_spiram_add_to_heapalloc(void) { size_t recycle_pages_size = 0; @@ -339,15 +338,32 @@ esp_err_t esp_spiram_add_to_heapalloc(void) return heap_caps_add_region(map_vaddr, map_vaddr + FREE_DRAM0_DRAM1_DPORT_CACHE_SIZE -1); } -static uint8_t *dma_heap; - esp_err_t esp_spiram_reserve_dma_pool(size_t size) { - if (size==0) return ESP_OK; //no-op + if (size == 0) { + return ESP_OK; + } + 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); + + uint8_t *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[] = { 0, MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL, 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(void) diff --git a/components/esp32s3/spiram.c b/components/esp32s3/spiram.c index f6a0e30ec2..cf56766f72 100644 --- a/components/esp32s3/spiram.c +++ b/components/esp32s3/spiram.c @@ -265,7 +265,6 @@ esp_err_t esp_spiram_init(void) return ESP_OK; } - esp_err_t esp_spiram_add_to_heapalloc(void) { size_t spiram_size = esp_spiram_get_size(); @@ -277,21 +276,32 @@ esp_err_t esp_spiram_add_to_heapalloc(void) return heap_caps_add_region((intptr_t)SOC_EXTRAM_DATA_HIGH - spiram_size + size_for_flash, (intptr_t)SOC_EXTRAM_DATA_HIGH - 1); } - -static uint8_t *dma_heap; - -esp_err_t esp_spiram_reserve_dma_pool(size_t size) -{ +esp_err_t esp_spiram_reserve_dma_pool(size_t size) { if (size == 0) { - return ESP_OK; //no-op + return ESP_OK; } - 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; + + ESP_EARLY_LOGI(TAG, "Reserving pool of %dK of internal memory for DMA/internal allocations", size/1024); + /* 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); + + uint8_t *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[] = { 0, MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL, 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; } - 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); + return ESP_OK; } size_t esp_spiram_get_size(void)