mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/bss_seg_in_external_memory' into 'master'
memory: support .bss segment can be in psram See merge request idf/esp-idf!2236
This commit is contained in:
commit
31cf117404
@ -75,8 +75,14 @@ else()
|
||||
endif()
|
||||
target_linker_script(esp32 "${CMAKE_CURRENT_BINARY_DIR}/esp32_out.ld")
|
||||
|
||||
if(CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY)
|
||||
# This has to be linked before esp32.common.ld
|
||||
target_linker_script(esp32 "ld/esp32.extram.bss.ld")
|
||||
endif()
|
||||
|
||||
target_linker_script(esp32 "ld/esp32.common.ld")
|
||||
|
||||
target_linker_script(esp32
|
||||
"ld/esp32.common.ld"
|
||||
"ld/esp32.rom.ld"
|
||||
"ld/esp32.peripherals.ld"
|
||||
"ld/esp32.rom.libgcc.ld"
|
||||
@ -113,6 +119,7 @@ else()
|
||||
MAIN_DEPENDENCY ${LD_DIR}/esp32.ld ${SDKCONFIG_H}
|
||||
COMMENT "Generating linker script..."
|
||||
VERBATIM)
|
||||
|
||||
add_custom_target(esp32_linker_script DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/esp32_out.ld)
|
||||
add_dependencies(esp32 esp32_linker_script)
|
||||
|
||||
|
@ -41,7 +41,7 @@ config SPIRAM_BOOT_INIT
|
||||
config SPIRAM_IGNORE_NOTFOUND
|
||||
bool "Ignore PSRAM when not found"
|
||||
default "n"
|
||||
depends on SPIRAM_BOOT_INIT
|
||||
depends on SPIRAM_BOOT_INIT && !SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
||||
help
|
||||
Normally, if psram initialization is enabled during compile time but not found at runtime, it
|
||||
is seen as an error making the ESP32 panic. If this is enabled, the ESP32 will keep on
|
||||
@ -172,6 +172,15 @@ config SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY
|
||||
ROM code in any way (no direct calls, but also no Bluetooth/WiFi), you can try to disable this and use
|
||||
xTaskCreateStatic to create the tasks stack in external memory.
|
||||
|
||||
config SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
||||
bool "Allow .bss segment placed in external memory"
|
||||
default n
|
||||
depends on SPIRAM_SUPPORT
|
||||
help
|
||||
If enabled the option,and add EXT_RAM_ATTR defined your variable,then your variable will be placed
|
||||
in PSRAM instead of internal memory, and placed most of variables of lwip,net802.11,pp,bluedroid library
|
||||
to external memory defaultly.
|
||||
|
||||
endmenu
|
||||
|
||||
config MEMMAP_TRACEMEM
|
||||
|
@ -8,6 +8,11 @@ ifndef CONFIG_NO_BLOBS
|
||||
LIBS += core rtc net80211 pp wpa smartconfig coexist wps wpa2 espnow phy mesh
|
||||
endif
|
||||
|
||||
ifdef CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
||||
# This linker script must come before esp32.common.ld
|
||||
LINKER_SCRIPTS += esp32.extram.bss.ld
|
||||
endif
|
||||
|
||||
#Linker scripts used to link the final application.
|
||||
#Warning: These linker scripts are only used when the normal app is compiled; the bootloader
|
||||
#specifies its own scripts.
|
||||
|
@ -93,6 +93,10 @@ extern int _bss_start;
|
||||
extern int _bss_end;
|
||||
extern int _rtc_bss_start;
|
||||
extern int _rtc_bss_end;
|
||||
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
||||
extern int _ext_ram_bss_start;
|
||||
extern int _ext_ram_bss_end;
|
||||
#endif
|
||||
extern int _init_start;
|
||||
extern void (*__init_array_start)(void);
|
||||
extern void (*__init_array_end)(void);
|
||||
@ -154,6 +158,11 @@ void IRAM_ATTR call_start_cpu0()
|
||||
#if CONFIG_SPIRAM_BOOT_INIT
|
||||
esp_spiram_init_cache();
|
||||
if (esp_spiram_init() != ESP_OK) {
|
||||
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
||||
ESP_EARLY_LOGE(TAG, "Failed to init external RAM, needed for external .bss segment");
|
||||
abort();
|
||||
#endif
|
||||
|
||||
#if CONFIG_SPIRAM_IGNORE_NOTFOUND
|
||||
ESP_EARLY_LOGI(TAG, "Failed to init external RAM; continuing without it.");
|
||||
s_spiram_okay = false;
|
||||
@ -207,7 +216,9 @@ void IRAM_ATTR call_start_cpu0()
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
||||
memset(&_ext_ram_bss_start, 0, (&_ext_ram_bss_end - &_ext_ram_bss_start) * sizeof(_ext_ram_bss_start));
|
||||
#endif
|
||||
/* Initialize heap allocator. WARNING: This *needs* to happen *after* the app cpu has booted.
|
||||
If the heap allocator is initialized first, it will put free memory linked list items into
|
||||
memory also used by the ROM. Starting the app cpu will let its ROM initialize that memory,
|
||||
|
@ -39,6 +39,13 @@
|
||||
// Forces code into RTC fast memory. See "docs/deep-sleep-stub.rst"
|
||||
#define RTC_IRAM_ATTR __attribute__((section(".rtc.text")))
|
||||
|
||||
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
||||
// Forces bss variable into external memory. "
|
||||
#define EXT_RAM_ATTR __attribute__((section(".ext_ram.bss")))
|
||||
#else
|
||||
#define EXT_RAM_ATTR
|
||||
#endif
|
||||
|
||||
// Forces data into RTC slow memory. See "docs/deep-sleep-stub.rst"
|
||||
// Any variable marked with this attribute will keep its value
|
||||
// during a deep sleep / wake cycle.
|
||||
|
@ -229,6 +229,7 @@ SECTIONS
|
||||
{
|
||||
. = ALIGN (8);
|
||||
_bss_start = ABSOLUTE(.);
|
||||
*(.ext_ram.bss*)
|
||||
_bt_bss_start = ABSOLUTE(.);
|
||||
*libbt.a:(.bss .bss.* COMMON)
|
||||
. = ALIGN (4);
|
||||
|
17
components/esp32/ld/esp32.extram.bss.ld
Normal file
17
components/esp32/ld/esp32.extram.bss.ld
Normal file
@ -0,0 +1,17 @@
|
||||
/* This section is only included if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
||||
is set, to link some sections to BSS in PSRAM */
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* external memory bss, from any global variable with EXT_RAM_ATTR attribute*/
|
||||
.ext_ram.bss (NOLOAD) :
|
||||
{
|
||||
_ext_ram_bss_start = ABSOLUTE(.);
|
||||
*(.ext_ram.bss*)
|
||||
*libnet80211.a:(.dynsbss .sbss .sbss.* .gnu.linkonce.sb.* .scommon .sbss2.* .gnu.linkonce.sb2.* .dynbss .bss .bss.* .share.mem .gnu.linkonce.b.* COMMON)
|
||||
*libpp.a:(.dynsbss .sbss .sbss.* .gnu.linkonce.sb.* .scommon .sbss2.* .gnu.linkonce.sb2.* .dynbss .bss .bss.* .share.mem .gnu.linkonce.b.* COMMON)
|
||||
*liblwip.a:(.dynsbss .sbss .sbss.* .gnu.linkonce.sb.* .scommon .sbss2.* .gnu.linkonce.sb2.* .dynbss .bss .bss.* .share.mem .gnu.linkonce.b.* COMMON)
|
||||
*libbt.a:(EXCLUDE_FILE (libbtdm_app.a) .dynsbss .sbss .sbss.* .gnu.linkonce.sb.* .scommon .sbss2.* .gnu.linkonce.sb2.* .dynbss .bss .bss.* .share.mem .gnu.linkonce.b.* COMMON)
|
||||
_ext_ram_bss_end = ABSOLUTE(.);
|
||||
} > extern_ram_seg
|
||||
}
|
@ -71,6 +71,10 @@ MEMORY
|
||||
*/
|
||||
rtc_slow_seg(RW) : org = 0x50000000 + CONFIG_ULP_COPROC_RESERVE_MEM,
|
||||
len = 0x1000 - CONFIG_ULP_COPROC_RESERVE_MEM
|
||||
|
||||
/* external memory ,including data and text */
|
||||
extern_ram_seg(RWX) : org = 0x3F800000,
|
||||
len = 0x400000
|
||||
}
|
||||
|
||||
/* Heap ends at top of dram0_0_seg */
|
||||
|
@ -59,7 +59,9 @@ static const char* TAG = "spiram";
|
||||
#error "FLASH speed can only be equal to or higher than SRAM speed while SRAM is enabled!"
|
||||
#endif
|
||||
|
||||
|
||||
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
||||
extern int _ext_ram_bss_start, _ext_ram_bss_end;
|
||||
#endif
|
||||
static bool spiram_inited=false;
|
||||
|
||||
|
||||
@ -145,11 +147,16 @@ esp_err_t esp_spiram_init()
|
||||
|
||||
|
||||
esp_err_t esp_spiram_add_to_heapalloc()
|
||||
{
|
||||
ESP_EARLY_LOGI(TAG, "Adding pool of %dK of external SPI memory to heap allocator", CONFIG_SPIRAM_SIZE/1024);
|
||||
{
|
||||
//Add entire external RAM region to heap allocator. Heap allocator knows the capabilities of this type of memory, so there's
|
||||
//no need to explicitly specify them.
|
||||
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
||||
ESP_EARLY_LOGI(TAG, "Adding pool of %dK of external SPI memory to heap allocator", (CONFIG_SPIRAM_SIZE - (&_ext_ram_bss_end - &_ext_ram_bss_start))/1024);
|
||||
return heap_caps_add_region((intptr_t)&_ext_ram_bss_end, (intptr_t)SOC_EXTRAM_DATA_LOW + CONFIG_SPIRAM_SIZE-1);
|
||||
#else
|
||||
ESP_EARLY_LOGI(TAG, "Adding pool of %dK of external SPI memory to heap allocator", CONFIG_SPIRAM_SIZE/1024);
|
||||
return heap_caps_add_region((intptr_t)SOC_EXTRAM_DATA_LOW, (intptr_t)SOC_EXTRAM_DATA_LOW + CONFIG_SPIRAM_SIZE-1);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -46,6 +46,9 @@ ESP-IDF fully supports integrating external memory use into your applications. E
|
||||
``heap_caps_malloc(size, MALLOC_CAP_SPIRAM)``. This memory can be used and subsequently freed using a normal ``free()`` call.
|
||||
* Initialize RAM, add it to the capability allocator and add memory to the pool of RAM that can be returned by ``malloc()``. This allows
|
||||
any application to use the external RAM without having to rewrite the code to use ``heap_caps_malloc``.
|
||||
* Initialize RAM, use a region start from 0x3F800000 for storing zero initialized data(BSS segment) of lwip,net802.11,pp,bluedroid library
|
||||
by enabling :ref: `CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY` in menuconfig,this way can save some internal memory,because the BSS segment
|
||||
originally stored in internal memory,and the rest of external RAM can be add the capability allocator and add memory to the pool of RAM as above way
|
||||
|
||||
All these options can be selected from the menuconfig menu.
|
||||
|
||||
@ -67,7 +70,11 @@ The use of external RAM has a few restrictions:
|
||||
for stack and task TCBs and xTaskCreateStatic-type functions will check if the buffers passed are internal. However, for tasks not calling
|
||||
on code in ROM in any way, directly or indirectly, the menuconfig option :ref:`CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY` will eliminate
|
||||
the check in xTaskCreateStatic, allowing task stack in external RAM. Using this is not advised, however.
|
||||
|
||||
* External RAM initialized failed can not be ignored if enabled :ref:`CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY`; because of this, some BSS segment
|
||||
can not be placed into external memory if PSRAM can't work normally and can not be moved to internal memory at runtime because the address of
|
||||
them is defined by linkfile, the :ref:`CONFIG_SPIRAM_IGNORE_NOTFOUND` can't handle this situation,if you want to enable :ref:
|
||||
`CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY` the :ref:`CONFIG_SPIRAM_IGNORE_NOTFOUND` will be disabled, and if initialize SPIRAM failed,the system
|
||||
will invoke abort.
|
||||
|
||||
Because there are a fair few situations that have a specific need for internal memory, but it is also possible to use malloc() to exhaust
|
||||
internal memory, there is a pool reserved specifically for requests that cannot be resolved from external memory; allocating task
|
||||
|
Loading…
x
Reference in New Issue
Block a user