]> granicus.if.org Git - esp-idf/commitdiff
esp32: Allow SPIRAM_MALLOC_RESERVE_INTERNAL to span multiple regions of memory
authorAngus Gratton <angus@espressif.com>
Tue, 31 Jul 2018 05:17:07 +0000 (15:17 +1000)
committerAngus Gratton <gus@projectgus.com>
Tue, 31 Jul 2018 05:17:07 +0000 (15:17 +1000)
- Allocate this pool after main_task is running, so it can use startup stack RAM
- Raise the maximum allowed value in KConfig to 256KB
- Based on forum discussions https://esp32.com/viewtopic.php?f=2&t=6550&sid=76cd27bda76c6d0e83d3fcc9ec30c650&start=10#p28253

components/esp32/Kconfig
components/esp32/cpu_start.c
components/esp32/spiram.c

index 7824823a4458823f38703bf2f68ce62b9320ca07..dc897dff2f24f717a24e09d8a547d9e1f5b43727 100644 (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
index 4d907f333c805253e139d305f9e057c72d185d00..01642432d87b2e8de36c9e67991f25c1bd06358c 100644 (file)
@@ -269,13 +269,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
@@ -445,6 +438,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))
index dccc3bc33e0328420c818ef2ff038fb601d7df21..8ae7c0ec0b28f381c45f93af70089e55979c1e85 100644 (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"
@@ -138,12 +139,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()