Ver código fonte

heap: add rtc fast memory region to dynamic pool

- for ESP32 only enabled in case of unicore config
- capability wise this region (8K) is same as DRAM, except non-DMA capable
- also fixed small issue in reserved memory region processing when (start == end)
Mahavir Jain 5 anos atrás
pai
commit
1aac284dda

+ 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)`
             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
 
 menu "Power Management"

+ 10 - 0
components/esp32s2/Kconfig

@@ -498,6 +498,16 @@ menu "ESP32S2-specific"
             If enabled, this disables the linking of binary libraries in the application build. Note
             that after enabling this Wi-Fi/Bluetooth will not work.
 
+    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
 
 menu "Power Management"

+ 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;
     bool r;
     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_SIZE != -1 // Fixed size, can be more accurate
     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;
     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);
+#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;
 }
 

+ 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},
     { "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},
-#ifdef CONFIG_SPIRAM
     //Type 15: SPI SRAM data
     { "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);
@@ -88,6 +88,9 @@ Because of requirements in the coalescing code which merges adjacent regions, th
 from low to high start address.
 */
 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
     { SOC_EXTRAM_DATA_LOW, RESERVE_SPIRAM_SIZE, 15, 0}, //SPI SRAM, if available
 #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
 #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
 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
 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 */

+ 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
     //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},
+    //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
@@ -68,6 +70,9 @@ Because of requirements in the coalescing code which merges adjacent regions, th
 from low to high start address.
 */
 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
     { SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_HIGH - SOC_EXTRAM_DATA_LOW, 4, 0}, //SPI SRAM, if available
 #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 _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
 
@@ -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);
 #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

+ 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].start & ~3; /* expand all reserved areas to word boundaries */
         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) {
             assert(reserved[i + 1].start > reserved[i].start);
             if (reserved[i].end > reserved[i + 1].start) {