Преглед на файлове

Merge branch 'feature/allow_rtc_memory_for_task_stacks' into 'master'

Add RTC Fast Memory to Dynamic Memory Pool

See merge request espressif/esp-idf!8390
Angus Gratton преди 5 години
родител
ревизия
59f29cbca8

+ 12 - 0
components/esp32/Kconfig

@@ -739,6 +739,18 @@ menu "ESP32-specific"
             This is possible due to handling of exceptions `LoadStoreError (3)` and `LoadStoreAlignmentError (9)`
             This is possible due to handling of exceptions `LoadStoreError (3)` and `LoadStoreAlignmentError (9)`
             Each unaligned read/write access will incur a penalty of maximum of 167 CPU cycles.
             Each unaligned read/write access will incur a penalty of maximum of 167 CPU cycles.
 
 
+    config ESP32_ALLOW_RTC_FAST_MEM_AS_HEAP
+        bool "Enable RTC fast memory for dynamic allocations"
+        default y
+        depends on FREERTOS_UNICORE
+        help
+            This config option allows to add RTC fast memory region to system heap with capability
+            similar to that of DRAM region but without DMA. This memory will be consumed first per
+            heap initialization order by early startup services and scheduler related code. Speed
+            wise RTC fast memory operates on APB clock and hence does not have much performance impact.
+            RTC fast memory is accessible to PRO cpu only and hence this is allowed for single core
+            configuration only for ESP32.
+
 endmenu  # ESP32-Specific
 endmenu  # ESP32-Specific
 
 
 menu "Power Management"
 menu "Power Management"

+ 17 - 0
components/esp32s2/Kconfig

@@ -498,6 +498,23 @@ menu "ESP32S2-specific"
             If enabled, this disables the linking of binary libraries in the application build. Note
             If enabled, this disables the linking of binary libraries in the application build. Note
             that after enabling this Wi-Fi/Bluetooth will not work.
             that after enabling this Wi-Fi/Bluetooth will not work.
 
 
+    config ESP32S2_RTCDATA_IN_FAST_MEM
+        bool "Place RTC_DATA_ATTR and RTC_RODATA_ATTR variables into RTC fast memory segment"
+        default n
+        help
+            This option allows to place .rtc_data and .rtc_rodata sections into
+            RTC fast memory segment to free the slow memory region for ULP programs.
+
+    config ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP
+        bool "Enable RTC fast memory for dynamic allocations"
+        depends on !ESP32S2_MEMPROT_FEATURE
+        default y
+        help
+            This config option allows to add RTC fast memory region to system heap with capability
+            similar to that of DRAM region but without DMA. This memory will be consumed first per
+            heap initialization order by early startup services and scheduler related code. Speed
+            wise RTC fast memory operates on APB clock and hence does not have much performance impact.
+
 endmenu  # ESP32S2-Specific
 endmenu  # ESP32S2-Specific
 
 
 menu "Power Management"
 menu "Power Management"

+ 1 - 1
components/esp32s2/ld/esp32s2.ld

@@ -96,7 +96,7 @@ _data_seg_org = ORIGIN(rtc_data_seg);
    When the option is not defined then use slow memory segment
    When the option is not defined then use slow memory segment
    else the data will be placed in fast memory segment
    else the data will be placed in fast memory segment
    TODO: check whether the rtc_data_location is correct for esp32s2 - IDF-761 */
    TODO: check whether the rtc_data_location is correct for esp32s2 - IDF-761 */
-#ifndef CONFIG_ESP32_RTCDATA_IN_FAST_MEM
+#ifndef CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM
 REGION_ALIAS("rtc_data_location", rtc_slow_seg );
 REGION_ALIAS("rtc_data_location", rtc_slow_seg );
 #else
 #else
 REGION_ALIAS("rtc_data_location", rtc_data_seg );
 REGION_ALIAS("rtc_data_location", rtc_data_seg );

+ 2 - 2
components/esp32s2/ld/esp32s2.project.ld.in

@@ -46,7 +46,7 @@ SECTIONS
      named rtc_wake_stub*.c and the data marked with
      named rtc_wake_stub*.c and the data marked with
      RTC_DATA_ATTR, RTC_RODATA_ATTR attributes.
      RTC_DATA_ATTR, RTC_RODATA_ATTR attributes.
      The memory location of the data is dependent on
      The memory location of the data is dependent on
-     CONFIG_ESP32_RTCDATA_IN_FAST_MEM option.
+     CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM option.
   */
   */
   .rtc.data :
   .rtc.data :
   {
   {
@@ -75,7 +75,7 @@ SECTIONS
      User data marked with RTC_NOINIT_ATTR will be placed
      User data marked with RTC_NOINIT_ATTR will be placed
      into this section. See the file "esp_attr.h" for more information.
      into this section. See the file "esp_attr.h" for more information.
 	 The memory location of the data is dependent on
 	 The memory location of the data is dependent on
-     CONFIG_ESP32_RTCDATA_IN_FAST_MEM option.
+     CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM option.
   */
   */
   .rtc_noinit (NOLOAD):
   .rtc_noinit (NOLOAD):
   {
   {

+ 4 - 0
components/mbedtls/port/esp32s2/aes.c

@@ -448,6 +448,10 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input,
             input_needs_realloc = true;
             input_needs_realloc = true;
         }
         }
 
 
+        if (!esp_ptr_dma_ext_capable(output) && !esp_ptr_dma_capable(output)) {
+            output_needs_realloc = true;
+        }
+
         /* If either input or output is unaccessible to the DMA then they need to be reallocated */
         /* If either input or output is unaccessible to the DMA then they need to be reallocated */
         if (input_needs_realloc || output_needs_realloc) {
         if (input_needs_realloc || output_needs_realloc) {
             return esp_aes_process_dma_ext_ram(ctx, input, output, len, stream_out, input_needs_realloc, output_needs_realloc);
             return esp_aes_process_dma_ext_ram(ctx, input, output, len, stream_out, input_needs_realloc, output_needs_realloc);

+ 12 - 0
components/soc/include/soc/soc_memory_layout.h

@@ -176,6 +176,12 @@ inline static bool IRAM_ATTR esp_ptr_byte_accessible(const void *p)
     intptr_t ip = (intptr_t) p;
     intptr_t ip = (intptr_t) p;
     bool r;
     bool r;
     r = (ip >= SOC_BYTE_ACCESSIBLE_LOW && ip < SOC_BYTE_ACCESSIBLE_HIGH);
     r = (ip >= SOC_BYTE_ACCESSIBLE_LOW && ip < SOC_BYTE_ACCESSIBLE_HIGH);
+#if CONFIG_ESP32_ALLOW_RTC_FAST_MEM_AS_HEAP
+    /* For ESP32 case, RTC fast memory is accessible to PRO cpu only and hence
+     * for single core configuration (where it gets added to system heap) following
+     * additional check is required */
+    r |= (ip >= SOC_RTC_DRAM_LOW && ip < SOC_RTC_DRAM_HIGH);
+#endif
 #if CONFIG_SPIRAM
 #if CONFIG_SPIRAM
 #if CONFIG_SPIRAM_SIZE != -1 // Fixed size, can be more accurate
 #if CONFIG_SPIRAM_SIZE != -1 // Fixed size, can be more accurate
     r |= (ip >= SOC_EXTRAM_DATA_LOW && ip < (SOC_EXTRAM_DATA_LOW + CONFIG_SPIRAM_SIZE));
     r |= (ip >= SOC_EXTRAM_DATA_LOW && ip < (SOC_EXTRAM_DATA_LOW + CONFIG_SPIRAM_SIZE));
@@ -190,6 +196,12 @@ inline static bool IRAM_ATTR esp_ptr_internal(const void *p) {
     bool r;
     bool r;
     r = ((intptr_t)p >= SOC_MEM_INTERNAL_LOW && (intptr_t)p < SOC_MEM_INTERNAL_HIGH);
     r = ((intptr_t)p >= SOC_MEM_INTERNAL_LOW && (intptr_t)p < SOC_MEM_INTERNAL_HIGH);
     r |= ((intptr_t)p >= SOC_RTC_DATA_LOW && (intptr_t)p < SOC_RTC_DATA_HIGH);
     r |= ((intptr_t)p >= SOC_RTC_DATA_LOW && (intptr_t)p < SOC_RTC_DATA_HIGH);
+#if CONFIG_ESP32_ALLOW_RTC_FAST_MEM_AS_HEAP
+    /* For ESP32 case, RTC fast memory is accessible to PRO cpu only and hence
+     * for single core configuration (where it gets added to system heap) following
+     * additional check is required */
+    r |= ((intptr_t)p >= SOC_RTC_DRAM_LOW && (intptr_t)p < SOC_RTC_DRAM_HIGH);
+#endif
     return r;
     return r;
 }
 }
 
 

+ 14 - 3
components/soc/src/esp32/soc_memory_layout.c

@@ -66,10 +66,10 @@ const soc_memory_type_desc_t soc_memory_types[] = {
     { "PID5DRAM", { MALLOC_CAP_PID5|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT|MALLOC_CAP_DEFAULT }, false, false},
     { "PID5DRAM", { MALLOC_CAP_PID5|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT|MALLOC_CAP_DEFAULT }, false, false},
     { "PID6DRAM", { MALLOC_CAP_PID6|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT|MALLOC_CAP_DEFAULT }, false, false},
     { "PID6DRAM", { MALLOC_CAP_PID6|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT|MALLOC_CAP_DEFAULT }, false, false},
     { "PID7DRAM", { MALLOC_CAP_PID7|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT|MALLOC_CAP_DEFAULT }, false, false},
     { "PID7DRAM", { MALLOC_CAP_PID7|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT|MALLOC_CAP_DEFAULT }, false, false},
-#ifdef CONFIG_SPIRAM
     //Type 15: SPI SRAM data
     //Type 15: SPI SRAM data
     { "SPIRAM", { MALLOC_CAP_SPIRAM|MALLOC_CAP_DEFAULT, 0, MALLOC_CAP_8BIT|MALLOC_CAP_32BIT}, false, false},
     { "SPIRAM", { MALLOC_CAP_SPIRAM|MALLOC_CAP_DEFAULT, 0, MALLOC_CAP_8BIT|MALLOC_CAP_32BIT}, false, false},
-#endif
+    //Type 16: RTC Fast RAM
+    { "RTCRAM", { MALLOC_CAP_8BIT|MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL|MALLOC_CAP_32BIT, 0 }, false, false},
 };
 };
 
 
 const size_t soc_memory_type_count = sizeof(soc_memory_types)/sizeof(soc_memory_type_desc_t);
 const size_t soc_memory_type_count = sizeof(soc_memory_types)/sizeof(soc_memory_type_desc_t);
@@ -88,6 +88,9 @@ Because of requirements in the coalescing code which merges adjacent regions, th
 from low to high start address.
 from low to high start address.
 */
 */
 const soc_memory_region_t soc_memory_regions[] = {
 const soc_memory_region_t soc_memory_regions[] = {
+#ifdef CONFIG_ESP32_ALLOW_RTC_FAST_MEM_AS_HEAP
+    { SOC_RTC_DRAM_LOW, 0x2000, 16, 0}, //RTC Fast Memory
+#endif
 #ifdef CONFIG_SPIRAM
 #ifdef CONFIG_SPIRAM
     { SOC_EXTRAM_DATA_LOW, RESERVE_SPIRAM_SIZE, 15, 0}, //SPI SRAM, if available
     { SOC_EXTRAM_DATA_LOW, RESERVE_SPIRAM_SIZE, 15, 0}, //SPI SRAM, if available
 #endif
 #endif
@@ -183,7 +186,7 @@ SOC_RESERVE_MEMORY_REGION(0x3fffc000, 0x40000000, trace_mem); //Reserve trace me
 SOC_RESERVE_MEMORY_REGION(SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_LOW + RESERVE_SPIRAM_SIZE, spi_ram); //SPI RAM gets added later if needed, in spiram.c; reserve it for now
 SOC_RESERVE_MEMORY_REGION(SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_LOW + RESERVE_SPIRAM_SIZE, spi_ram); //SPI RAM gets added later if needed, in spiram.c; reserve it for now
 #endif
 #endif
 
 
-extern int _data_start, _heap_start, _iram_start, _iram_end;
+extern int _data_start, _heap_start, _iram_start, _iram_end, _rtc_force_fast_end, _rtc_noinit_end;
 // Static data region. DRAM used by data+bss and possibly rodata
 // Static data region. DRAM used by data+bss and possibly rodata
 SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_data);
 SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_data);
 
 
@@ -191,5 +194,13 @@ SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_d
 // ESP32 has an IRAM-only region 0x4008_0000 - 0x4009_FFFF, reserve the used part
 // ESP32 has an IRAM-only region 0x4008_0000 - 0x4009_FFFF, reserve the used part
 SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start, (intptr_t)&_iram_end, iram_code);
 SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start, (intptr_t)&_iram_end, iram_code);
 
 
+// RTC Fast RAM region
+#ifdef CONFIG_ESP32_ALLOW_RTC_FAST_MEM_AS_HEAP
+#ifdef CONFIG_ESP32_RTCDATA_IN_FAST_MEM
+SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_noinit_end, rtcram_data);
+#else
+SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_force_fast_end, rtcram_data);
+#endif
+#endif
 
 
 #endif /* BOOTLOADER_BUILD */
 #endif /* BOOTLOADER_BUILD */

+ 15 - 1
components/soc/src/esp32s2/soc_memory_layout.c

@@ -51,6 +51,8 @@ const soc_memory_type_desc_t soc_memory_types[] = {
     //Type 4: SPI SRAM data
     //Type 4: SPI SRAM data
     //TODO, in fact, part of them support EDMA, to be supported.
     //TODO, in fact, part of them support EDMA, to be supported.
     { "SPIRAM", { MALLOC_CAP_SPIRAM|MALLOC_CAP_DEFAULT, 0, MALLOC_CAP_8BIT|MALLOC_CAP_32BIT}, false, false},
     { "SPIRAM", { MALLOC_CAP_SPIRAM|MALLOC_CAP_DEFAULT, 0, MALLOC_CAP_8BIT|MALLOC_CAP_32BIT}, false, false},
+    //Type 5: RTC Fast RAM
+    { "RTCRAM", { MALLOC_CAP_8BIT|MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL|MALLOC_CAP_32BIT, 0 }, false, false},
 };
 };
 
 
 #ifdef CONFIG_ESP32S2_MEMPROT_FEATURE
 #ifdef CONFIG_ESP32S2_MEMPROT_FEATURE
@@ -68,6 +70,9 @@ Because of requirements in the coalescing code which merges adjacent regions, th
 from low to high start address.
 from low to high start address.
 */
 */
 const soc_memory_region_t soc_memory_regions[] = {
 const soc_memory_region_t soc_memory_regions[] = {
+#ifdef CONFIG_ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP
+    { SOC_RTC_DRAM_LOW, 0x2000, 5, 0}, //RTC Fast Memory
+#endif
 #ifdef CONFIG_SPIRAM
 #ifdef CONFIG_SPIRAM
     { SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_HIGH - SOC_EXTRAM_DATA_LOW, 4, 0}, //SPI SRAM, if available
     { SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_HIGH - SOC_EXTRAM_DATA_LOW, 4, 0}, //SPI SRAM, if available
 #endif
 #endif
@@ -115,7 +120,7 @@ const size_t soc_memory_region_count = sizeof(soc_memory_regions)/sizeof(soc_mem
 
 
 
 
 extern int _dram0_rtos_reserved_start;
 extern int _dram0_rtos_reserved_start;
-extern int _data_start, _heap_start, _iram_start, _iram_end;
+extern int _data_start, _heap_start, _iram_start, _iram_end, _rtc_force_fast_end, _rtc_noinit_end;
 
 
 /* Reserved memory regions
 /* Reserved memory regions
 
 
@@ -141,4 +146,13 @@ SOC_RESERVE_MEMORY_REGION( SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_HIGH, extram_dat
 SOC_RESERVE_MEMORY_REGION(0x3fffc000 - CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM, 0x3fffc000, trace_mem);
 SOC_RESERVE_MEMORY_REGION(0x3fffc000 - CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM, 0x3fffc000, trace_mem);
 #endif
 #endif
 
 
+// RTC Fast RAM region
+#ifdef CONFIG_ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP
+#ifdef CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM
+SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_noinit_end, rtcram_data);
+#else
+SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_force_fast_end, rtcram_data);
+#endif
+#endif
+
 #endif // BOOTLOADER_BUILD
 #endif // BOOTLOADER_BUILD

+ 1 - 1
components/soc/src/memory_layout_utils.c

@@ -68,7 +68,7 @@ static void s_prepare_reserved_regions(soc_reserved_region_t *reserved, size_t c
                        reserved[i].start, reserved[i].end);
                        reserved[i].start, reserved[i].end);
         reserved[i].start = reserved[i].start & ~3; /* expand all reserved areas to word boundaries */
         reserved[i].start = reserved[i].start & ~3; /* expand all reserved areas to word boundaries */
         reserved[i].end = (reserved[i].end + 3) & ~3;
         reserved[i].end = (reserved[i].end + 3) & ~3;
-        assert(reserved[i].start < reserved[i].end);
+        assert(reserved[i].start <= reserved[i].end);
         if (i < count - 1) {
         if (i < count - 1) {
             assert(reserved[i + 1].start > reserved[i].start);
             assert(reserved[i + 1].start > reserved[i].start);
             if (reserved[i].end > reserved[i + 1].start) {
             if (reserved[i].end > reserved[i + 1].start) {

+ 1 - 1
tools/unit-test-app/configs/single_core_2_s2

@@ -3,4 +3,4 @@ CONFIG_IDF_TARGET="esp32s2"
 TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32s2 esp_ipc esp_timer driver heap pthread soc spi_flash vfs
 TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32s2 esp_ipc esp_timer driver heap pthread soc spi_flash vfs
 CONFIG_MEMMAP_SMP=n
 CONFIG_MEMMAP_SMP=n
 CONFIG_FREERTOS_UNICORE=y
 CONFIG_FREERTOS_UNICORE=y
-CONFIG_ESP32_RTCDATA_IN_FAST_MEM=y
+CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM=y

+ 1 - 1
tools/unit-test-app/configs/single_core_s2

@@ -3,4 +3,4 @@ CONFIG_IDF_TARGET="esp32s2"
 TEST_COMPONENTS=freertos esp32s2 esp_timer driver heap pthread soc spi_flash vfs test_utils
 TEST_COMPONENTS=freertos esp32s2 esp_timer driver heap pthread soc spi_flash vfs test_utils
 CONFIG_MEMMAP_SMP=n
 CONFIG_MEMMAP_SMP=n
 CONFIG_FREERTOS_UNICORE=y
 CONFIG_FREERTOS_UNICORE=y
-CONFIG_ESP32_RTCDATA_IN_FAST_MEM=y
+CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM=y