mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-03 04:34:31 +02:00
doc: update document of external memory
This commit is contained in:
@@ -74,7 +74,13 @@ else()
|
|||||||
target_link_libraries(esp32 coexist core espnow mesh net80211 phy pp rtc smartconfig wpa2 wpa wps)
|
target_link_libraries(esp32 coexist core espnow mesh net80211 phy pp rtc smartconfig wpa2 wpa wps)
|
||||||
endif()
|
endif()
|
||||||
target_linker_script(esp32 "${CMAKE_CURRENT_BINARY_DIR}/esp32_out.ld")
|
target_linker_script(esp32 "${CMAKE_CURRENT_BINARY_DIR}/esp32_out.ld")
|
||||||
target_linker_script(esp32 "${CMAKE_CURRENT_BINARY_DIR}/esp32.common_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
|
target_linker_script(esp32
|
||||||
"ld/esp32.rom.ld"
|
"ld/esp32.rom.ld"
|
||||||
@@ -114,14 +120,7 @@ else()
|
|||||||
COMMENT "Generating linker script..."
|
COMMENT "Generating linker script..."
|
||||||
VERBATIM)
|
VERBATIM)
|
||||||
|
|
||||||
# Preprocess esp32.common.ld linker script to include configuration, becomes esp32.common_out.ld
|
add_custom_target(esp32_linker_script DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/esp32_out.ld)
|
||||||
add_custom_command(
|
|
||||||
OUTPUT esp32.common_out.ld
|
|
||||||
COMMAND "${CMAKE_C_COMPILER}" -C -P -x c -E -o esp32.common_out.ld -I ${CONFIG_DIR} ${LD_DIR}/esp32.common.ld
|
|
||||||
MAIN_DEPENDENCY ${LD_DIR}/esp32.common.ld ${SDKCONFIG_H}
|
|
||||||
COMMENT "Generating linker script..."
|
|
||||||
VERBATIM)
|
|
||||||
add_custom_target(esp32_linker_script DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/esp32_out.ld ${CMAKE_CURRENT_BINARY_DIR}/esp32.common_out.ld)
|
|
||||||
add_dependencies(esp32 esp32_linker_script)
|
add_dependencies(esp32 esp32_linker_script)
|
||||||
|
|
||||||
if(CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION)
|
if(CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION)
|
||||||
|
@@ -41,7 +41,7 @@ config SPIRAM_BOOT_INIT
|
|||||||
config SPIRAM_IGNORE_NOTFOUND
|
config SPIRAM_IGNORE_NOTFOUND
|
||||||
bool "Ignore PSRAM when not found"
|
bool "Ignore PSRAM when not found"
|
||||||
default "n"
|
default "n"
|
||||||
depends on SPIRAM_BOOT_INIT
|
depends on SPIRAM_BOOT_INIT && !SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
||||||
help
|
help
|
||||||
Normally, if psram initialization is enabled during compile time but not found at runtime, it
|
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
|
is seen as an error making the ESP32 panic. If this is enabled, the ESP32 will keep on
|
||||||
@@ -178,7 +178,8 @@ config SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
|||||||
depends on SPIRAM_SUPPORT
|
depends on SPIRAM_SUPPORT
|
||||||
help
|
help
|
||||||
If enabled the option,and add EXT_RAM_ATTR defined your variable,then your variable will be placed
|
If enabled the option,and add EXT_RAM_ATTR defined your variable,then your variable will be placed
|
||||||
in PSRAM instead of internal memory.
|
in PSRAM instead of internal memory, and placed most of variables of lwip,net802.11,pp,bluedroid library
|
||||||
|
to external memory defaultly.
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
|
@@ -8,11 +8,15 @@ ifndef CONFIG_NO_BLOBS
|
|||||||
LIBS += core rtc net80211 pp wpa smartconfig coexist wps wpa2 espnow phy mesh
|
LIBS += core rtc net80211 pp wpa smartconfig coexist wps wpa2 espnow phy mesh
|
||||||
endif
|
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.
|
#Linker scripts used to link the final application.
|
||||||
#Warning: These linker scripts are only used when the normal app is compiled; the bootloader
|
#Warning: These linker scripts are only used when the normal app is compiled; the bootloader
|
||||||
#specifies its own scripts.
|
#specifies its own scripts.
|
||||||
|
LINKER_SCRIPTS += esp32.common.ld esp32.rom.ld esp32.peripherals.ld
|
||||||
LINKER_SCRIPTS += esp32.rom.ld esp32.peripherals.ld
|
|
||||||
|
|
||||||
#Force pure functions from libgcc.a to be linked from ROM
|
#Force pure functions from libgcc.a to be linked from ROM
|
||||||
LINKER_SCRIPTS += esp32.rom.libgcc.ld
|
LINKER_SCRIPTS += esp32.rom.libgcc.ld
|
||||||
@@ -39,7 +43,6 @@ COMPONENT_ADD_LDFLAGS += $(COMPONENT_PATH)/libhal.a \
|
|||||||
$(addprefix -l,$(LIBS)) \
|
$(addprefix -l,$(LIBS)) \
|
||||||
-L $(COMPONENT_PATH)/ld \
|
-L $(COMPONENT_PATH)/ld \
|
||||||
-T esp32_out.ld \
|
-T esp32_out.ld \
|
||||||
-T esp32.common_out.ld \
|
|
||||||
-u ld_include_panic_highint_hdl \
|
-u ld_include_panic_highint_hdl \
|
||||||
$(addprefix -T ,$(LINKER_SCRIPTS))
|
$(addprefix -T ,$(LINKER_SCRIPTS))
|
||||||
|
|
||||||
@@ -55,17 +58,12 @@ COMPONENT_ADD_LINKER_DEPS := $(ALL_LIB_FILES) $(addprefix ld/,$(LINKER_SCRIPTS))
|
|||||||
#
|
#
|
||||||
# The library doesn't really depend on esp32_out.ld, but it
|
# The library doesn't really depend on esp32_out.ld, but it
|
||||||
# saves us from having to add the target to a Makefile.projbuild
|
# saves us from having to add the target to a Makefile.projbuild
|
||||||
$(COMPONENT_LIBRARY): esp32_out.ld esp32.common_out.ld
|
$(COMPONENT_LIBRARY): esp32_out.ld
|
||||||
|
|
||||||
esp32_out.ld: $(COMPONENT_PATH)/ld/esp32.ld ../include/sdkconfig.h
|
esp32_out.ld: $(COMPONENT_PATH)/ld/esp32.ld ../include/sdkconfig.h
|
||||||
$(CC) -I ../include -C -P -x c -E $< -o $@
|
$(CC) -I ../include -C -P -x c -E $< -o $@
|
||||||
|
|
||||||
# Preprocess esp32.common.ld linker script to include configuration, becomes esp32.common_out.ld
|
|
||||||
esp32.common_out.ld: $(COMPONENT_PATH)/ld/esp32.common.ld ../include/sdkconfig.h
|
|
||||||
$(CC) -I ../include -C -P -x c -E $< -o $@
|
|
||||||
|
|
||||||
COMPONENT_EXTRA_CLEAN := esp32_out.ld
|
COMPONENT_EXTRA_CLEAN := esp32_out.ld
|
||||||
COMPONENT_EXTRA_CLEAN += esp32.common_out.ld
|
|
||||||
|
|
||||||
# disable stack protection in files which are involved in initialization of that feature
|
# disable stack protection in files which are involved in initialization of that feature
|
||||||
stack_check.o: CFLAGS := $(filter-out -fstack-protector%, $(CFLAGS))
|
stack_check.o: CFLAGS := $(filter-out -fstack-protector%, $(CFLAGS))
|
||||||
|
@@ -158,7 +158,7 @@ void IRAM_ATTR call_start_cpu0()
|
|||||||
esp_spiram_init_cache();
|
esp_spiram_init_cache();
|
||||||
if (esp_spiram_init() != ESP_OK) {
|
if (esp_spiram_init() != ESP_OK) {
|
||||||
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
||||||
ESP_EARLY_LOGE(TAG, "Failed to init external RAM and place some block started symbol in it");
|
ESP_EARLY_LOGE(TAG, "Failed to init external RAM, needed for external .bss segment");
|
||||||
abort();
|
abort();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
#include "sdkconfig.h"
|
|
||||||
|
|
||||||
/* Default entry point: */
|
/* Default entry point: */
|
||||||
ENTRY(call_start_cpu0);
|
ENTRY(call_start_cpu0);
|
||||||
|
|
||||||
@@ -52,20 +50,6 @@ SECTIONS
|
|||||||
_rtc_noinit_end = ABSOLUTE(.);
|
_rtc_noinit_end = ABSOLUTE(.);
|
||||||
} > rtc_slow_seg
|
} > rtc_slow_seg
|
||||||
|
|
||||||
#ifdef CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
|
||||||
/* 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
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Send .iram0 code to iram */
|
/* Send .iram0 code to iram */
|
||||||
.iram0.vectors :
|
.iram0.vectors :
|
||||||
{
|
{
|
||||||
@@ -183,7 +167,7 @@ SECTIONS
|
|||||||
{
|
{
|
||||||
. = ALIGN (8);
|
. = ALIGN (8);
|
||||||
_bss_start = ABSOLUTE(.);
|
_bss_start = ABSOLUTE(.);
|
||||||
*(.ext_ram.bss)
|
*(.ext_ram.bss*)
|
||||||
_bt_bss_start = ABSOLUTE(.);
|
_bt_bss_start = ABSOLUTE(.);
|
||||||
*libbt.a:(.bss .bss.* COMMON)
|
*libbt.a:(.bss .bss.* COMMON)
|
||||||
. = ALIGN (4);
|
. = 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
|
||||||
|
}
|
@@ -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.
|
``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
|
* 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``.
|
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.
|
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
|
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 :envvar:`CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY` will eliminate
|
on code in ROM in any way, directly or indirectly, the menuconfig option :envvar:`CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY` will eliminate
|
||||||
the check in xTaskCreateStatic, allowing task stack in external RAM. Using this is not advised, however.
|
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
|
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
|
internal memory, there is a pool reserved specifically for requests that cannot be resolved from external memory; allocating task
|
||||||
|
Reference in New Issue
Block a user