mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 17:19:09 -04:00
feat(psram): add psram noinit segment support on S2/S3/P4/C5
Closes https://github.com/espressif/esp-idf/issues/14253
This commit is contained in:
parent
6d947cdb2d
commit
58c3ee2c89
@ -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.
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) :
|
||||
{
|
||||
|
@ -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) :
|
||||
{
|
||||
|
@ -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 <dma-capable-memory>` 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.
|
||||
|
||||
|
||||
.. only:: esp32
|
||||
.. _external_ram_config_noinit:
|
||||
|
||||
.. _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, 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.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
============
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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 <dma-capable-memory>` 和 ``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 也可以通过上述方法添加到堆分配器中。
|
||||
|
||||
|
||||
.. only:: esp32
|
||||
.. _external_ram_config_noinit:
|
||||
|
||||
.. _external_ram_config_noinit:
|
||||
允许 .noinit 段放入片外存储器
|
||||
-------------------------------------
|
||||
|
||||
允许 .noinit 段放入片外存储器
|
||||
-------------------------------------
|
||||
通过勾选 :ref:`CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY` 启用该选项。启用该选项后,PSRAM 被映射到的数据虚拟地址空间将用于存储未初始化的数据。即使在启动或重新启动期间,放置在该段中的值也不会被初始化或修改。
|
||||
|
||||
通过勾选 :ref:`CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY` 启用该选项。启用该选项后,外部 RAM 中提供的地址空间区域将用于存储未初始化的数据。即使在启动或重新启动期间,放置在该段中的值也不会被初始化或修改。
|
||||
|
||||
通过应用 ``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 使用限制
|
||||
===================
|
||||
|
@ -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`` 部分。
|
||||
|
||||
|
7
tools/unit-test-app/configs/psram_noinit
Normal file
7
tools/unit-test-app/configs/psram_noinit
Normal file
@ -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"
|
Loading…
x
Reference in New Issue
Block a user