diff --git a/components/esp_psram/esp32s2/Kconfig.spiram b/components/esp_psram/esp32s2/Kconfig.spiram index 19444ccf9e..4f6d701100 100644 --- a/components/esp_psram/esp32s2/Kconfig.spiram +++ b/components/esp_psram/esp32s2/Kconfig.spiram @@ -56,21 +56,26 @@ menu "SPI RAM config" help The PSRAM CS IO can be any unused GPIO, user can config it based on hardware design. endmenu + config SPIRAM_FETCH_INSTRUCTIONS - bool "Cache fetch instructions from SPI RAM" + bool "Move Instructions in Flash to PSRAM" default n help - If enabled, instruction in flash will be copied into SPIRAM. - If SPIRAM_RODATA also enabled, - you can run the instruction when erasing or programming the flash. + If enabled, instructions in flash will be moved into PSRAM on startup. + If SPIRAM_RODATA is also enabled, code that requires execution during an SPI1 Flash operation + can forgo being placed in IRAM, thus optimizing RAM usage (see External RAM documentation + for more details). + config SPIRAM_RODATA - bool "Cache load read only data from SPI RAM" + bool "Move Read-Only Data in Flash to PSRAM" default n help - If enabled, radata in flash will be copied into SPIRAM. - If SPIRAM_FETCH_INSTRUCTIONS also enabled, - you can run the instruction when erasing or programming the flash. + If enabled, instructions in flash will be moved into PSRAM on startup. + If SPIRAM_FETCH_INSTRUCTIONS is also enabled, code that requires execution during an SPI1 Flash operation + can forgo being placed in IRAM, thus optimizing RAM usage (see External RAM documentation + for more details). + choice SPIRAM_SPEED prompt "Set RAM clock speed" diff --git a/components/esp_psram/esp32s3/Kconfig.spiram b/components/esp_psram/esp32s3/Kconfig.spiram index 48fe595370..0b37d84f23 100644 --- a/components/esp_psram/esp32s3/Kconfig.spiram +++ b/components/esp_psram/esp32s3/Kconfig.spiram @@ -65,20 +65,25 @@ menu "SPI RAM config" help The PSRAM CS IO can be any unused GPIO, please refer to your hardware design. endmenu + config SPIRAM_FETCH_INSTRUCTIONS - bool "Cache fetch instructions from SPI RAM" + bool "Move Instructions in Flash to PSRAM" default n help - If enabled, instruction in flash will be copied into SPIRAM. - If SPIRAM_RODATA also enabled, you can run the instruction when erasing or programming the flash. + If enabled, instructions in flash will be moved into PSRAM on startup. + If SPIRAM_RODATA is also enabled, code that requires execution during an SPI1 Flash operation + can forgo being placed in IRAM, thus optimizing RAM usage (see External RAM documentation + for more details). + config SPIRAM_RODATA - bool "Cache load read only data from SPI RAM" + bool "Move Read-Only Data in Flash to PSRAM" default n help - If enabled, rodata in flash will be copied into SPIRAM. - If SPIRAM_FETCH_INSTRUCTIONS is also enabled, - you can run the instruction when erasing or programming the flash. + If enabled, instructions in flash will be moved into PSRAM on startup. + If SPIRAM_FETCH_INSTRUCTIONS is also enabled, code that requires execution during an SPI1 Flash operation + can forgo being placed in IRAM, thus optimizing RAM usage (see External RAM documentation + for more details). choice SPIRAM_SPEED prompt "Set RAM clock speed" diff --git a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in index b1970101cc..710f6b3ac8 100644 --- a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in @@ -731,6 +731,10 @@ config SOC_SPIRAM_SUPPORTED bool default y +config SOC_SPIRAM_XIP_SUPPORTED + bool + default y + config SOC_USB_PERIPH_NUM bool default y diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index aefedba59d..08f6fae526 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -321,7 +321,8 @@ #define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */ /*-------------------------- SPIRAM CAPS -------------------------------------*/ -#define SOC_SPIRAM_SUPPORTED 1 +#define SOC_SPIRAM_SUPPORTED 1 +#define SOC_SPIRAM_XIP_SUPPORTED 1 /*-------------------------- USB CAPS ----------------------------------------*/ #define SOC_USB_PERIPH_NUM 1 diff --git a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in index c1525cee68..a75fb3d1c9 100644 --- a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in @@ -719,6 +719,10 @@ config SOC_SPIRAM_SUPPORTED bool default y +config SOC_SPIRAM_XIP_SUPPORTED + bool + default y + config SOC_SYSTIMER_COUNTER_NUM int default 2 diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index e635328a5c..1341c78a57 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -294,6 +294,7 @@ /*-------------------------- SPIRAM CAPS ----------------------------------------*/ #define SOC_SPIRAM_SUPPORTED 1 +#define SOC_SPIRAM_XIP_SUPPORTED 1 /*-------------------------- SYS TIMER CAPS ----------------------------------*/ #define SOC_SYSTIMER_COUNTER_NUM 2 // Number of counter units diff --git a/docs/en/api-guides/external-ram.rst b/docs/en/api-guides/external-ram.rst index f01bfb67e2..0cf3242105 100644 --- a/docs/en/api-guides/external-ram.rst +++ b/docs/en/api-guides/external-ram.rst @@ -41,13 +41,17 @@ ESP-IDF fully supports the use of external RAM in applications. Once the externa * :ref:`external_ram_config_memory_map` * :ref:`external_ram_config_capability_allocator` * :ref:`external_ram_config_malloc` (default) - :esp32 or esp32s2: * :ref:`external_ram_config_bss` + * :ref:`external_ram_config_bss` :esp32: * :ref:`external_ram_config_noinit` + :esp32s2 or esp32s3: * :ref:`external_ram_config_instructions` + :esp32s2 or esp32s3: * :ref:`external_ram_config_rodata` .. _external_ram_config_memory_map: + Integrate RAM into the {IDF_TARGET_NAME} Memory Map --------------------------------------------------- + {IDF_TARGET_PSRAM_ADDR_START:default="Value not updated", esp32="0x3F800000", esp32s2="0x3F500000", esp32s3="0x3D000000"} Select this option by choosing "Integrate RAM into memory map" from :ref:`CONFIG_SPIRAM_USE`. @@ -91,25 +95,22 @@ If a suitable block of preferred internal/external memory is not available, the Because some buffers can only be allocated in internal memory, a second configuration item :ref:`CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL` defines a pool of internal memory which is reserved for *only* explicitly internal allocations (such as memory for DMA use). Regular ``malloc()`` will not allocate from this pool. The :ref:`MALLOC_CAP_DMA ` and ``MALLOC_CAP_INTERNAL`` flags can be used to allocate memory from this pool. -.. only:: SOC_SPIRAM_SUPPORTED +.. _external_ram_config_bss: - .. _external_ram_config_bss: +Allow .bss Segment to be Placed in External Memory +-------------------------------------------------- - Allow .bss Segment to be Placed in External Memory - ------------------------------------------------------- +Enable this option by checking :ref:`CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY`. - Enable this option by checking :ref:`CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY`. This configuration setting is independent of the other three. +If enabled, a region of the address space starting from {IDF_TARGET_PSRAM_ADDR_START} will be used to store zero-initialized data (BSS segment) from the lwIP, net80211, libpp, and bluedroid ESP-IDF libraries. - If enabled, a region of the address space starting from {IDF_TARGET_PSRAM_ADDR_START} will be used to store zero-initialized data (BSS segment) from the lwIP, net80211, libpp, and bluedroid ESP-IDF libraries. +Additional data can be moved from the internal BSS segment to external RAM by applying the macro ``EXT_RAM_BSS_ATTR`` to any static declaration (which is not initialized to a non-zero value). - Additional data can be moved from the internal BSS segment to external RAM by applying the macro ``EXT_RAM_BSS_ATTR`` to any static declaration (which is not initialized to a non-zero value). +It is also possible to place the BSS section of a component or a library to external RAM using linker fragment scheme ``extram_bss``. - It is also possible to place the BSS section of a component or a library to external RAM using linker fragment scheme ``extram_bss``. - - This option reduces the internal static memory used by the BSS segment. - - Remaining external RAM can also be added to the capability heap allocator using the method shown above. +This option reduces the internal static memory used by the BSS segment. +Remaining external RAM can also be added to the capability heap allocator using the method shown above. .. only:: esp32 @@ -122,6 +123,38 @@ Because some buffers can only be allocated in internal memory, a second configur By applying the macro ``EXT_RAM_NOINIT_ATTR``, data could be moved from the internal NOINIT segment to external RAM. Remaining external RAM can still be added to the capability heap allocator using the method shown above, :ref:`external_ram_config_capability_allocator`. +.. only:: SOC_SPIRAM_XIP_SUPPORTED + + .. _external_ram_config_instructions: + + Move Instructions in Flash to PSRAM + ----------------------------------- + + The :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` option allows the flash ``.text`` sections (use for instructions) to be placed in PSRAM. + + By enabling the :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` option + + - Instructions from the ``.text`` sections of flash are moved into PSRAM on system startup. + + - The corresponding virtual memory range of those instructions will also be re-mapped to PSRAM. + + If :ref:`CONFIG_SPIRAM_RODATA` is also enabled, the Cache won't be disabled during an SPI1 Flash operation. You don't need to make sure ISRs, ISR callbacks and involved data are placed in internal RAM, thus internal RAM usage can be optimized. + + .. _external_ram_config_rodata: + + Move Read-Only Data in Flash to PSRAM + --------------------------------------- + + The :ref:`CONFIG_SPIRAM_RODATA` option allows the flash ``.rodata`` sections (use for read only data) to be placed in PSRAM. + + By enabling the :ref:`CONFIG_SPIRAM_RODATA` option + + - Instructions from the ``.rodata`` sections of flash are moved into PSRAM on system startup. + + - The corresponding virtual memory range of those rodata will also be re-mapped to PSRAM. + + If :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` is also enabled, the Cache won't be disabled during an SPI1 Flash operation. You don't need to make sure ISRs, ISR callbacks and involved data are placed in internal RAM, thus internal RAM usage can be optimized. + Restrictions ============ diff --git a/docs/en/api-reference/storage/spi_flash_concurrency.rst b/docs/en/api-reference/storage/spi_flash_concurrency.rst index 4b85e0e30c..deb26a0e82 100644 --- a/docs/en/api-reference/storage/spi_flash_concurrency.rst +++ b/docs/en/api-reference/storage/spi_flash_concurrency.rst @@ -5,7 +5,7 @@ Concurrency Constraints for flash on SPI1 The SPI0/1 bus is shared between the instruction & data cache (for firmware execution) and the SPI1 peripheral (controlled by the drivers including this SPI Flash driver). Hence, operations to SPI1 will cause significant influence to the whole system. This kind of operations include calling SPI Flash API or other drivers on SPI1 bus, any operations like read/write/erase or other user defined SPI operations, regardless to the main flash or other SPI slave devices. -.. only:: not esp32c3 +.. only:: not (esp32c3 or SOC_SPIRAM_XIP_SUPPORTED) On {IDF_TARGET_NAME}, these caches must be disabled while reading/writing/erasing. @@ -15,6 +15,11 @@ The SPI0/1 bus is shared between the instruction & data cache (for firmware exec If this option is disabled, the caches must be disabled while reading/writing/erasing operations. There are some constraints using driver on the SPI1 bus, see :ref:`impact_disabled_cache`. This constraints will cause more IRAM/DRAM usages. +.. only:: SOC_SPIRAM_XIP_SUPPORTED + + On {IDF_TARGET_NAME}, the config option :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` (disabled by default) and :ref:`CONFIG_SPIRAM_RODATA` (disabled by default) allow the cache to read/write PSRAM concurrently with SPI1 operations. See :ref:`xip_from_psram` for more details. + + If this option is disabled, the caches must be disabled while reading/writing/erasing operations. There are some constraints using driver on the SPI1 bus, see :ref:`impact_disabled_cache`. This constraints will cause more IRAM/DRAM usages. .. _impact_disabled_cache: @@ -25,7 +30,15 @@ Under this condition, all CPUs should always execute code and access data from i .. only:: esp32c3 - However, when :ref:`CONFIG_SPI_FLASH_AUTO_SUSPEND` is enabled, these APIs won't disable the caches. The hardware will handle the arbitration between them. + .. note:: + + When :ref:`CONFIG_SPI_FLASH_AUTO_SUSPEND` is enabled, these APIs won't disable the caches. The hardware will handle the arbitration between them. + +.. only:: SOC_SPIRAM_XIP_SUPPORTED + + .. note:: + + When :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` and :ref:`CONFIG_SPIRAM_RODATA` are both enabled, these APIs won't disable the caches. .. only:: not CONFIG_FREERTOS_UNICORE @@ -66,3 +79,7 @@ If the ``ESP_INTR_FLAG_IRAM`` flag is not set when registering, the interrupt ha .. only:: esp32c3 .. include:: auto_suspend.inc + +.. only:: SOC_SPIRAM_XIP_SUPPORTED + + .. include:: xip_from_psram.inc \ No newline at end of file diff --git a/docs/en/api-reference/storage/xip_from_psram.inc b/docs/en/api-reference/storage/xip_from_psram.inc new file mode 100644 index 0000000000..d0af4a89be --- /dev/null +++ b/docs/en/api-reference/storage/xip_from_psram.inc @@ -0,0 +1,12 @@ +.. _xip_from_psram: + +XIP from PSRAM Feature +---------------------- + +If :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` is enabled, the flash ``.text`` sections (used for instructions) will be placed in PSRAM. + +If :ref:`CONFIG_SPIRAM_RODATA` is enabled, the flash ``.rodata`` sections (used for read only data) will be placed in PSRAM. + +The corresponding virtual memory range will be re-mapped to PSRAM. + +If both of the above options are enabled, the Cache won't be disabled during an SPI1 Flash operation. You don't need to make sure ISRs, ISR callbacks and involved data are placed in internal RAM. diff --git a/docs/zh_CN/api-reference/storage/xip_from_psram.inc b/docs/zh_CN/api-reference/storage/xip_from_psram.inc new file mode 100644 index 0000000000..e69de29bb2