diff --git a/components/bootloader/subproject/main/ld/esp32/bootloader.ld b/components/bootloader/subproject/main/ld/esp32/bootloader.ld index 95594fe660..6516fc3c27 100644 --- a/components/bootloader/subproject/main/ld/esp32/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32/bootloader.ld @@ -25,7 +25,7 @@ MEMORY */ iram_seg (RWX) : org = 0x40080400, len = 0xfc00 /* 64k at the end of DRAM, after ROM bootloader stack */ - dram_seg (RW) : org = 0x3FFF0000, len = 0x10000 + dram_seg (RW) : org = 0x3FFF0000, len = 0x6000 } /* Default entry point: */ diff --git a/components/esp_system/ld/esp32/memory.ld.in b/components/esp_system/ld/esp32/memory.ld.in index b974894f70..40af8d847b 100644 --- a/components/esp_system/ld/esp32/memory.ld.in +++ b/components/esp_system/ld/esp32/memory.ld.in @@ -48,6 +48,13 @@ ASSERT((CONFIG_ESP32_FIXED_STATIC_RAM_SIZE <= 0x2c200), #define DRAM0_0_SEG_LEN 0x2c200 #endif +#if CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM +#define SRAM1_IRAM_LEN 0xA000 +#else +#define SRAM1_IRAM_LEN 0x0 +#endif + + MEMORY { /* All these values assume the flash cache is on, and have the blocks this uses subtracted from the length @@ -55,7 +62,7 @@ MEMORY are connected to the data port of the CPU and eg allow bytewise access. */ /* IRAM for PRO cpu. Not sure if happy with this, this is MMU area... */ - iram0_0_seg (RX) : org = 0x40080000, len = 0x20000 + iram0_0_seg (RX) : org = 0x40080000, len = 0x20000 + SRAM1_IRAM_LEN #ifdef CONFIG_APP_BUILD_USE_FLASH_SECTIONS /* Even though the segment name is iram, it is actually mapped to flash @@ -121,8 +128,14 @@ _heap_start = 0x3FFB0000 + DRAM0_0_SEG_LEN; _heap_start = _heap_low_start; #endif -/* Heap ends at top of dram0_0_seg */ +_sram1_iram_start = 0x400A0000; +_sram1_iram_len = ( _iram_end > _sram1_iram_start) ? (_iram_end - _sram1_iram_start) : 0; +_heap_end = ALIGN(0x40000000 - _sram1_iram_len - 3, 4); + +#if CONFIG_ESP32_TRACEMEM_RESERVE_DRAM != 0 _heap_end = 0x40000000 - CONFIG_ESP32_TRACEMEM_RESERVE_DRAM; +#endif + _data_seg_org = ORIGIN(rtc_data_seg); diff --git a/components/esp_system/port/soc/esp32/Kconfig.memory b/components/esp_system/port/soc/esp32/Kconfig.memory index d5214bd0b6..4481fd98d2 100644 --- a/components/esp_system/port/soc/esp32/Kconfig.memory +++ b/components/esp_system/port/soc/esp32/Kconfig.memory @@ -41,4 +41,18 @@ menu "Memory" 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. + menu "Non-backward compatible options" + + config ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM + bool "Reserve parts of SRAM1 for app IRAM (WARNING, read help before enabling)" + depends on !ESP32_TRAX + help + Reserve parts of SRAM1 for app IRAM which was previously reserved for bootloader DRAM. + If booting an app on an older bootloader from before this option was introduced, the app will fail + to boot due to not recognizing the new IRAM memory area. + + If this is the case please test carefully before pushing out any OTA updates. + + endmenu + endmenu # Memory diff --git a/components/heap/port/esp32/memory_layout.c b/components/heap/port/esp32/memory_layout.c index 378273523d..ad0633a17a 100644 --- a/components/heap/port/esp32/memory_layout.c +++ b/components/heap/port/esp32/memory_layout.c @@ -172,7 +172,7 @@ SOC_RESERVE_MEMORY_REGION(0x3fffc000, 0x40000000, trace_mem); //Reserve trace me SOC_RESERVE_MEMORY_REGION(SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_HIGH, spi_ram); #endif -extern int _data_start, _heap_start, _iram_start, _iram_end, _rtc_force_fast_end, _rtc_noinit_end; +extern int _data_start, _heap_start, _heap_end, _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); @@ -180,6 +180,11 @@ 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); +// If IRAM spans into SRAM1 due to CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM, reserve the corresponding part of DRAM +#ifdef CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM +SOC_RESERVE_MEMORY_REGION((intptr_t) &_heap_end, 0x40000000, sram1_iram); +#endif + // RTC Fast RAM region #ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP #ifdef CONFIG_ESP32_RTCDATA_IN_FAST_MEM diff --git a/components/soc/esp32/include/soc/soc.h b/components/soc/esp32/include/soc/soc.h index 16dfa7f0f1..eacf37dc4f 100644 --- a/components/soc/esp32/include/soc/soc.h +++ b/components/soc/esp32/include/soc/soc.h @@ -182,7 +182,7 @@ #define SOC_CACHE_APP_LOW 0x40078000 #define SOC_CACHE_APP_HIGH 0x40080000 #define SOC_IRAM_LOW 0x40080000 -#define SOC_IRAM_HIGH 0x400A0000 +#define SOC_IRAM_HIGH 0x400AA000 #define SOC_RTC_IRAM_LOW 0x400C0000 #define SOC_RTC_IRAM_HIGH 0x400C2000 #define SOC_RTC_DRAM_LOW 0x3FF80000 diff --git a/docs/en/api-guides/bootloader.rst b/docs/en/api-guides/bootloader.rst index 6b61614f58..49617430fc 100644 --- a/docs/en/api-guides/bootloader.rst +++ b/docs/en/api-guides/bootloader.rst @@ -41,6 +41,12 @@ The bootloader does not support booting apps from older versions of ESP-IDF. Whe Bootloaders built from versions of ESP-IDF before V3.1 do not support MD5 checksums in the partition table binary. When using a bootloader from these ESP-IDF versions and building a new app, enable the config option :ref:`CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS`. + + Before ESP-IDF V5.1 + ^^^^^^^^^^^^^^^^^^^ + + Bootloaders built from versions of ESP-IDF prior to V5.1 do not support :ref:`CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM`. When using a bootloader from these ESP-IDF versions and building a new app you should not use this option. + SPI Flash Configuration ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/en/api-guides/performance/ram-usage.rst b/docs/en/api-guides/performance/ram-usage.rst index ff08a79075..1550a3f748 100644 --- a/docs/en/api-guides/performance/ram-usage.rst +++ b/docs/en/api-guides/performance/ram-usage.rst @@ -142,6 +142,26 @@ The following options will reduce IRAM usage of some ESP-IDF features: - Setting :ref:`CONFIG_HAL_DEFAULT_ASSERTION_LEVEL` to disable assertion for HAL component will save some IRAM especially for HAL code who calls `HAL_ASSERT` a lot and resides in IRAM. - Refer to sdkconfig menu ``Auto-detect flash chips`` and you can disable flash drivers which you don't need to save some IRAM. +.. only:: esp32 + + Using SRAM1 for IRAM + ^^^^^^^^^^^^^^^^^^^^ + + The SRAM1 memory area is normally used for DRAM, but it is possible to use parts of it for IRAM with :ref:`CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM`. This memory would previously be reserved for DRAM data usage (e.g. bss) by the software bootloader and later added to the heap. After this option was introduced, the bootloader DRAM size was reduced to a value closer to what it normally actually needs. + + This option depends on IDF being able to recognize that the new SRAM1 area is also a valid load address for an image segment. If the software bootloader was compiled before this option existed, then the bootloader will not be able to load an app which has code placed in this new extended IRAM area. This would typically happen if you are doing an OTA update, where only the app would be updated. + + If the IRAM section were to be placed in an invalid area then this would be detected during the bootup process and result in a failed boot: + + .. code-block:: text + + E (204) esp_image: Segment 5 0x400845f8-0x400a126c invalid: bad load address range + + .. warning:: + + Apps compiled with :ref:`CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM`, may fail to boot if used together with a software bootloader compiled before this config option was introduced. If you are using an older bootloader and updating over OTA, please test carefully before pushing any update. + + Any memory which ends up not being used for static IRAM will be added to the heap. .. only:: esp32c3 diff --git a/tools/ci/build_template_app.sh b/tools/ci/build_template_app.sh index f214b87986..4e9cb82e12 100755 --- a/tools/ci/build_template_app.sh +++ b/tools/ci/build_template_app.sh @@ -23,6 +23,8 @@ gen_configs() { # CONFIG_COMPILER_OPTIMIZATION_PERF with flag -O2 echo "CONFIG_COMPILER_OPTIMIZATION_PERF=y" > esp-idf-template/sdkconfig.ci.O2 echo "CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF=y" >> esp-idf-template/sdkconfig.ci.O2 + # -O2 makes the bootloader too large to fit in the default space, otherwise(!) + echo "CONFIG_PARTITION_TABLE_OFFSET=0x10000" >> esp-idf-template/sdkconfig.ci.O2 # This part will be built in earlier stage (pre_build job) with only cmake. Built with make in later stage # CONFIG_COMPILER_OPTIMIZATION_DEFAULT with flag -Og diff --git a/tools/test_apps/system/startup/sdkconfig.ci.sram1_iram b/tools/test_apps/system/startup/sdkconfig.ci.sram1_iram new file mode 100644 index 0000000000..de3b7675ff --- /dev/null +++ b/tools/test_apps/system/startup/sdkconfig.ci.sram1_iram @@ -0,0 +1,3 @@ +# Only ESP32 has this option +CONFIG_IDF_TARGET="esp32" +CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM=y