diff --git a/components/esp_common/test/test_attr.c b/components/esp_common/test/test_attr.c index 23e7603145b..c4499cbacc6 100644 --- a/components/esp_common/test/test_attr.c +++ b/components/esp_common/test/test_attr.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,6 +15,8 @@ #endif #include "test_utils.h" +#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1)) + extern int _rtc_noinit_start; extern int _rtc_noinit_end; extern int _rtc_data_start; @@ -30,7 +32,6 @@ extern int _ext_ram_noinit_end; extern int _ext_ram_bss_start; extern int _ext_ram_bss_end; - #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) //IDF-5045 //Variables for test: Attributes place variables into correct sections @@ -95,7 +96,13 @@ static void write_spiram_and_reset(void) } printf("Flushing cache\n"); // Flush the cache out to SPIRAM before resetting. +#if CONFIG_IDF_TARGET_ESP32 esp_psram_extram_writeback_cache(); +#else + uint32_t ext_noinit_size = sizeof(s_noinit_buffer); + extern int Cache_WriteBack_Addr(uint32_t addr, uint32_t size); + Cache_WriteBack_Addr((uint32_t)s_noinit_buffer, ext_noinit_size); +#endif printf("Restarting\n"); // Reset to test that noinit memory is left intact. diff --git a/components/esp_psram/Kconfig.spiram.common b/components/esp_psram/Kconfig.spiram.common index 9fb2a6bb9da..abd44d851a2 100644 --- a/components/esp_psram/Kconfig.spiram.common +++ b/components/esp_psram/Kconfig.spiram.common @@ -23,8 +23,8 @@ config SPIRAM_IGNORE_NOTFOUND ESP_WIFI_CACHE_TX_BUFFER_NUM and use static WiFi Tx buffer may cause potential memory exhaustion issues. Suggest disable SPIRAM_TRY_ALLOCATE_WIFI_LWIP. Suggest disable ESP_WIFI_AMSDU_TX_ENABLED. - Suggest disable ESP_WIFI_CACHE_TX_BUFFER_NUM, need clear CONFIG_FEATURE_CACHE_TX_BUF_BIT of - config->feature_caps. + Suggest disable ESP_WIFI_CACHE_TX_BUFFER_NUM, + need clear CONFIG_FEATURE_CACHE_TX_BUF_BIT of config->feature_caps. Suggest change ESP_WIFI_TX_BUFFER from static to dynamic. Also suggest to adjust some buffer numbers to the values used without PSRAM case. Such as, ESP_WIFI_STATIC_TX_BUFFER_NUM, ESP_WIFI_DYNAMIC_TX_BUFFER_NUM. @@ -110,7 +110,7 @@ config SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY config SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY bool "Allow .noinit segment placed in external memory" default n - depends on SPIRAM && IDF_TARGET_ESP32 + depends on SPIRAM help If enabled, noinit variables can be placed in PSRAM using EXT_RAM_NOINIT_ATTR. diff --git a/components/esp_system/ld/esp32s2/memory.ld.in b/components/esp_system/ld/esp32s2/memory.ld.in index ecf54461590..8d10d31468a 100644 --- a/components/esp_system/ld/esp32s2/memory.ld.in +++ b/components/esp_system/ld/esp32s2/memory.ld.in @@ -127,8 +127,7 @@ _data_seg_org = ORIGIN(rtc_data_seg); /* The lines below define location alias for .rtc.data section based on Kconfig option. When the option is not defined then use slow 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 */ + else the data will be placed in fast memory segment */ #ifndef CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM REGION_ALIAS("rtc_data_location", rtc_slow_seg ); #else diff --git a/components/esp_system/ld/esp32s2/sections.ld.in b/components/esp_system/ld/esp32s2/sections.ld.in index 681e686c851..be8cb863674 100644 --- a/components/esp_system/ld/esp32s2/sections.ld.in +++ b/components/esp_system/ld/esp32s2/sections.ld.in @@ -247,7 +247,7 @@ SECTIONS _noinit_end = ABSOLUTE(.); } > dram0_0_seg - /* external memory bss, from any global variable with EXT_RAM_BSS_ATTR attribute*/ + /* External Memory BSS. (Variables with EXT_RAM_BSS_ATTR attribute). */ .ext_ram.bss (NOLOAD) : { _ext_ram_bss_start = ABSOLUTE(.); @@ -258,6 +258,20 @@ SECTIONS _ext_ram_bss_end = ABSOLUTE(.); } > extern_ram_seg + /** + * This section holds data that won't be initialised when startup. + * This section locates in External RAM region. + */ + .ext_ram_noinit (NOLOAD) : + { + _ext_ram_noinit_start = ABSOLUTE(.); + + *(.ext_ram_noinit*) + + . = ALIGN(4); + _ext_ram_noinit_end = ABSOLUTE(.); + } > extern_ram_seg + /* Shared RAM */ .dram0.bss (NOLOAD) : { diff --git a/components/esp_system/ld/esp32s3/sections.ld.in b/components/esp_system/ld/esp32s3/sections.ld.in index 5cb29893896..e3f402105a5 100644 --- a/components/esp_system/ld/esp32s3/sections.ld.in +++ b/components/esp_system/ld/esp32s3/sections.ld.in @@ -421,6 +421,20 @@ SECTIONS _ext_ram_bss_end = ABSOLUTE(.); } > extern_ram_seg + /** + * This section holds data that won't be initialised when startup. + * This section locates in External RAM region. + */ + .ext_ram_noinit (NOLOAD) : + { + _ext_ram_noinit_start = ABSOLUTE(.); + + *(.ext_ram_noinit*) + + . = ALIGN(4); + _ext_ram_noinit_end = ABSOLUTE(.); + } > extern_ram_seg + /* Marks the end of IRAM code segment */ .iram0.text_end (NOLOAD) : { diff --git a/docs/en/api-guides/external-ram.rst b/docs/en/api-guides/external-ram.rst index e44e096979b..c83265fe247 100644 --- a/docs/en/api-guides/external-ram.rst +++ b/docs/en/api-guides/external-ram.rst @@ -44,8 +44,8 @@ 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` - :esp32: * :ref:`external_ram_config_noinit` + * :ref:`external_ram_config_bss` + * :ref:`external_ram_config_noinit` .. _external_ram_config_memory_map: @@ -94,36 +94,32 @@ 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`. This configuration setting is independent of the other three. - Enable this option by checking :ref:`CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY`. This configuration setting is independent of the other three. +If enabled, the region of the data virtual address space where the PSRAM is mapped to will be used to store zero-initialized data (BSS segment) from the lwIP, net80211, libpp, wpa_supplicant and bluedroid ESP-IDF libraries. - If enabled, the region of the data virtual address space where the PSRAM is mapped to will be used to store zero-initialized data (BSS segment) from the lwIP, net80211, libpp, wpa_supplicant 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. - 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. - Remaining external RAM can also be added to the capability heap allocator using the method shown above. +.. _external_ram_config_noinit: -.. only:: esp32 - - .. _external_ram_config_noinit: - - Allow .noinit Segment to be Placed in External Memory - -------------------------------------------------------------- +Allow .noinit Segment to Be Placed in External Memory +-------------------------------------------------------------- - Enable this option by checking :ref:`CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY`. If enabled, a region of the address space provided in external RAM will be used to store non-initialized data. The values placed in this segment will not be initialized or modified even during startup or restart. +Enable this option by checking :ref:`CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY`. If enabled, the region of the data virtual address space where the PSRAM is mapped to will be used to store non-initialized data. The values placed in this segment will not be initialized or modified even during startup or restart. - 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`. +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`. Restrictions ============ diff --git a/docs/en/api-guides/memory-types.rst b/docs/en/api-guides/memory-types.rst index 8cc3bddb8e4..1ac629af5aa 100644 --- a/docs/en/api-guides/memory-types.rst +++ b/docs/en/api-guides/memory-types.rst @@ -38,7 +38,7 @@ Constant data may also be placed into DRAM, for example if it is used in an non- The macro ``__NOINIT_ATTR`` can be used as attribute to place data into ``.noinit`` section. The values placed into this section will not be initialized at startup and should keep its value after software restart. -.. only:: esp32 +.. only:: SOC_SPIRAM_SUPPORTED By applying the ``EXT_RAM_NOINIT_ATTR`` macro, non-initialized value could also be placed in external RAM. To do this, the :ref:`CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY` needs to be enabled. See :ref:`external_ram_config_noinit`. If the :ref:`CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY` is not enabled, ``EXT_RAM_NOINIT_ATTR`` will behave just as ``__NOINIT_ATTR``, it will make data to be placed into ``.noinit`` segment in internal RAM. diff --git a/docs/zh_CN/api-guides/external-ram.rst b/docs/zh_CN/api-guides/external-ram.rst index 7fcb40121ab..4c0e04b45bd 100644 --- a/docs/zh_CN/api-guides/external-ram.rst +++ b/docs/zh_CN/api-guides/external-ram.rst @@ -41,8 +41,8 @@ ESP-IDF 完全支持将片外 RAM 集成到您的应用程序中。在启动并 * :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` - :esp32: * :ref:`external_ram_config_noinit` + * :ref:`external_ram_config_bss` + * :ref:`external_ram_config_noinit` .. _external_ram_config_memory_map: @@ -91,36 +91,32 @@ ESP-IDF 启动过程中,片外 RAM 被映射到以 {IDF_TARGET_PSRAM_ADDR_STAR 由于有些内存缓冲器仅可在内部存储器中分配,因此需要使用第二个配置项 :ref:`CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL` 定义一个内部内存池,仅限显式的内部存储器分配使用(例如用于 DMA 的存储器)。常规 ``malloc()`` 将不会从该池中分配,但可以使用 :ref:`MALLOC_CAP_DMA ` 和 ``MALLOC_CAP_INTERNAL`` 标志从该池中分配存储器。 -.. only:: SOC_SPIRAM_SUPPORTED +.. _external_ram_config_bss: - .. _external_ram_config_bss: +允许 .bss 段放入片外存储器 +----------------------------------- - 允许 .bss 段放入片外存储器 - ----------------------------------- +通过勾选 :ref:`CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY` 启用该选项,此选项配置与其它三个选项互不影响。 - 通过勾选 :ref:`CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY` 启用该选项,此选项配置与其它三个选项互不影响。 +启用该选项后,PSRAM 被映射到的数据虚拟地址空间将用于存储来自 lwip、net80211、libpp, wpa_supplicant 和 bluedroid ESP-IDF 库中零初始化的数据(BSS 段)。 - 启用该选项后,PSRAM 被映射到的数据虚拟地址空间将用于存储来自 lwip、net80211、libpp, wpa_supplicant 和 bluedroid ESP-IDF 库中零初始化的数据(BSS 段)。 +``EXT_RAM_BSS_ATTR`` 宏应用于任何静态声明(未初始化为非零值)之后,可以将附加数据从内部 BSS 段移到片外 RAM。 - ``EXT_RAM_BSS_ATTR`` 宏应用于任何静态声明(未初始化为非零值)之后,可以将附加数据从内部 BSS 段移到片外 RAM。 +也可以使用链接器片段方案 ``extram_bss`` 将组件或库的 BSS 段放到片外 RAM 中。 - 也可以使用链接器片段方案 ``extram_bss`` 将组件或库的 BSS 段放到片外 RAM 中。 +启用此选项可以减少 BSS 段占用的内部静态存储。 - 启用此选项可以减少 BSS 段占用的内部静态存储。 +剩余的片外 RAM 也可以通过上述方法添加到堆分配器中。 - 剩余的片外 RAM 也可以通过上述方法添加到堆分配器中。 +.. _external_ram_config_noinit: -.. only:: esp32 - - .. _external_ram_config_noinit: - - 允许 .noinit 段放入片外存储器 - ------------------------------------- +允许 .noinit 段放入片外存储器 +------------------------------------- - 通过勾选 :ref:`CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY` 启用该选项。启用该选项后,外部 RAM 中提供的地址空间区域将用于存储未初始化的数据。即使在启动或重新启动期间,放置在该段中的值也不会被初始化或修改。 +通过勾选 :ref:`CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY` 启用该选项。启用该选项后,PSRAM 被映射到的数据虚拟地址空间将用于存储未初始化的数据。即使在启动或重新启动期间,放置在该段中的值也不会被初始化或修改。 - 通过应用 ``EXT_RAM_NOINIT_ATTR`` 宏,可以将数据从内部 NOINIT 段移到片外 RAM。剩余的片外 RAM 也可以通过上述方法添加到堆分配器中,具体请参考 :ref:`external_ram_config_capability_allocator`。 +通过应用 ``EXT_RAM_NOINIT_ATTR`` 宏,可以将数据从内部 NOINIT 段移到片外 RAM。剩余的片外 RAM 也可以通过上述方法添加到堆分配器中,具体请参考 :ref:`external_ram_config_capability_allocator`。 片外 RAM 使用限制 =================== diff --git a/docs/zh_CN/api-guides/memory-types.rst b/docs/zh_CN/api-guides/memory-types.rst index c49eb76849b..2f494503b82 100644 --- a/docs/zh_CN/api-guides/memory-types.rst +++ b/docs/zh_CN/api-guides/memory-types.rst @@ -38,7 +38,7 @@ DRAM(数据 RAM) 可以将 ``__NOINIT_ATTR`` 宏用作属性,从而将数据放入 ``.noinit`` 部分。放入该部分的值在启动时不会被初始化,在软件重启后也会保持值不变。 -.. only:: esp32 +.. only:: SOC_SPIRAM_SUPPORTED 通过使用 ``EXT_RAM_NOINIT_ATTR`` 宏,noinit 数据也可以放入外部 RAM 中。为此,需要启用 :ref:`CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY`,可参考 :ref:`external_ram_config_noinit`。如果没有启用 :ref:`CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY`, ``EXT_RAM_NOINIT_ATTR`` 会和 ``__NOINIT_ATTR`` 一样,将数据放入内部 RAM 的 ``.noinit`` 部分。 diff --git a/tools/unit-test-app/configs/psram_noinit b/tools/unit-test-app/configs/psram_noinit new file mode 100644 index 00000000000..64b1aa63826 --- /dev/null +++ b/tools/unit-test-app/configs/psram_noinit @@ -0,0 +1,7 @@ +TEST_COMPONENTS=spi_flash + +CONFIG_SPIRAM=y +CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY=y +CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y + +CONFIG_IDF_TARGET="esp32s2"