diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index 3f87bcce54..307a4e73b5 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -564,7 +564,8 @@ idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "${include_dirs}" PRIV_INCLUDE_DIRS "${priv_include_dirs}" REQUIRES nvs_flash soc esp_timer esp_pm - PRIV_REQUIRES esp_ipc) + PRIV_REQUIRES esp_ipc + LDFRAGMENTS "linker.lf") if(CONFIG_BT_ENABLED) target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-implicit-fallthrough -Wno-unused-const-variable) diff --git a/components/bt/linker.lf b/components/bt/linker.lf new file mode 100644 index 0000000000..f239404450 --- /dev/null +++ b/components/bt/linker.lf @@ -0,0 +1,5 @@ +[mapping:bt] +archive: libbt.a +entries: + if SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y: + * (extram_bss) diff --git a/components/esp32/CMakeLists.txt b/components/esp32/CMakeLists.txt index fb8dad87df..b805a5c539 100644 --- a/components/esp32/CMakeLists.txt +++ b/components/esp32/CMakeLists.txt @@ -42,12 +42,6 @@ else() target_linker_script(${COMPONENT_LIB} INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/esp32_out.ld") - - if(CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY) - # This has to be linked before esp32.project.ld - target_linker_script(${COMPONENT_LIB} INTERFACE "ld/esp32.extram.bss.ld") - endif() - # Process the template file through the linker script generation mechanism, and use the output for linking the # final binary target_linker_script(${COMPONENT_LIB} INTERFACE "${CMAKE_CURRENT_LIST_DIR}/ld/esp32.project.ld.in" diff --git a/components/esp32/component.mk b/components/esp32/component.mk index b3fc34d33f..8eed73f91e 100644 --- a/components/esp32/component.mk +++ b/components/esp32/component.mk @@ -4,11 +4,6 @@ COMPONENT_SRCDIRS := . -ifdef CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY - # This linker script must come before esp32.project.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. diff --git a/components/esp32/ld/esp32.extram.bss.ld b/components/esp32/ld/esp32.extram.bss.ld deleted file mode 100644 index 582f6eb6ea..0000000000 --- a/components/esp32/ld/esp32.extram.bss.ld +++ /dev/null @@ -1,18 +0,0 @@ -/* 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) - . = ALIGN(4); - _ext_ram_bss_end = ABSOLUTE(.); - } > extern_ram_seg -} diff --git a/components/esp32/ld/esp32.project.ld.in b/components/esp32/ld/esp32.project.ld.in index 7405ec19db..3f8c8165b6 100644 --- a/components/esp32/ld/esp32.project.ld.in +++ b/components/esp32/ld/esp32.project.ld.in @@ -232,12 +232,22 @@ SECTIONS _noinit_end = ABSOLUTE(.); } > dram0_0_seg + /* external memory bss, from any global variable with EXT_RAM_ATTR attribute*/ + .ext_ram.bss (NOLOAD) : + { + _ext_ram_bss_start = ABSOLUTE(.); + + mapping[extern_ram] + + . = ALIGN(4); + _ext_ram_bss_end = ABSOLUTE(.); + } > extern_ram_seg + /* Shared RAM */ .dram0.bss (NOLOAD) : { . = ALIGN (8); _bss_start = ABSOLUTE(.); - *(.ext_ram.bss*) _bt_bss_start = ABSOLUTE(.); *libbt.a:(.bss .bss.* COMMON) . = ALIGN (4); @@ -253,18 +263,6 @@ SECTIONS mapping[dram0_bss] - *(.dynsbss) - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb.*) - *(.scommon) - *(.sbss2) - *(.sbss2.*) - *(.gnu.linkonce.sb2.*) - *(.dynbss) - *(.share.mem) - *(.gnu.linkonce.b.*) - . = ALIGN (8); _bss_end = ABSOLUTE(.); } > dram0_0_seg diff --git a/components/esp32/ld/esp32_fragments.lf b/components/esp32/ld/esp32_fragments.lf index 2ab27f1091..feaec8b1ac 100644 --- a/components/esp32/ld/esp32_fragments.lf +++ b/components/esp32/ld/esp32_fragments.lf @@ -15,6 +15,18 @@ entries: entries: COMMON +[sections:legacy_bss] +entries: + .dynsbss + .sbss+ + .gnu.linkonce.sb+ + .scommon + .sbss2+ + .gnu.linkonce.sb2+ + .dynbss + .share.mem + .gnu.linkonce.b+ + [sections:rodata] entries: .rodata+ @@ -64,6 +76,10 @@ entries: entries: .iram.bss+ +[sections:extram_bss] +entries: + .ext_ram.bss+ + [sections:dram] entries: .dram1+ @@ -87,6 +103,11 @@ entries: data -> dram0_data bss -> dram0_bss common -> dram0_bss + if SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y: + extram_bss -> extern_ram + else: + extram_bss -> dram0_bss + legacy_bss -> dram0_bss iram -> iram0_text iram_data -> iram0_data iram_bss -> iram0_bss @@ -130,3 +151,8 @@ entries: [scheme:wifi_rx_iram] entries: wifi_rx_iram -> iram0_text + +[scheme:extram_bss] +entries: + bss -> extern_ram + common -> extern_ram diff --git a/components/esp_common/Kconfig.spiram.common b/components/esp_common/Kconfig.spiram.common index f71f6624a4..bf45f1e0e3 100644 --- a/components/esp_common/Kconfig.spiram.common +++ b/components/esp_common/Kconfig.spiram.common @@ -94,6 +94,9 @@ config SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY default n depends on SPIRAM 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. + If enabled, variables with EXT_RAM_ATTR attribute will be placed in SPIRAM instead of internal DRAM. + BSS section of `lwip`, `net80211`, `pp`, `bt` libraries will be automatically placed + in SPIRAM. BSS sections from other object files and libraries can also be placed in SPIRAM through + linker fragment scheme `extram_bss`. + + Note that the variables placed in SPIRAM using EXT_RAM_ATTR will be zero initialized. diff --git a/components/esp_wifi/linker.lf b/components/esp_wifi/linker.lf index 9e63817e79..9acda0dfc8 100644 --- a/components/esp_wifi/linker.lf +++ b/components/esp_wifi/linker.lf @@ -17,6 +17,9 @@ entries: if ESP32_WIFI_RX_IRAM_OPT = y: * (wifi_rx_iram) + if SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y: + * (extram_bss) + [mapping:net80211] archive: libnet80211.a entries: @@ -25,3 +28,6 @@ entries: if ESP32_WIFI_RX_IRAM_OPT = y: * (wifi_rx_iram) + + if SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y: + * (extram_bss) diff --git a/components/lwip/linker.lf b/components/lwip/linker.lf index 2c722f85e0..6d95da947e 100644 --- a/components/lwip/linker.lf +++ b/components/lwip/linker.lf @@ -85,3 +85,6 @@ entries: else: * (default) + + if SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y: + * (extram_bss) diff --git a/docs/en/api-guides/external-ram.rst b/docs/en/api-guides/external-ram.rst index 96d6f9467c..36f2125a4b 100644 --- a/docs/en/api-guides/external-ram.rst +++ b/docs/en/api-guides/external-ram.rst @@ -95,6 +95,8 @@ If enabled, a region of the address space starting from 0x3F800000 will be used Additional data can be moved from the internal BSS segment to external RAM by applying the macro ``EXT_RAM_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``. + 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.