mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
feat(bt): Frees BLE memory when no longer in use
It will free libble.a & libbt all txt, data and bss segment memory. This memory is combined into one large memory and put into the heap pool.
This commit is contained in:
parent
55d3bc2d37
commit
ea06b047c2
@ -2,6 +2,7 @@ if(CONFIG_BT_ENABLED)
|
|||||||
|
|
||||||
set(srcs "")
|
set(srcs "")
|
||||||
set(include_dirs "")
|
set(include_dirs "")
|
||||||
|
set(ldfragments "linker.lf")
|
||||||
|
|
||||||
if(CONFIG_IDF_TARGET_ESP32)
|
if(CONFIG_IDF_TARGET_ESP32)
|
||||||
list(APPEND srcs "controller/esp32/bt.c"
|
list(APPEND srcs "controller/esp32/bt.c"
|
||||||
@ -18,6 +19,7 @@ if(CONFIG_BT_ENABLED)
|
|||||||
list(APPEND include_dirs include/esp32c3/include)
|
list(APPEND include_dirs include/esp32c3/include)
|
||||||
|
|
||||||
elseif(CONFIG_IDF_TARGET_ESP32C2)
|
elseif(CONFIG_IDF_TARGET_ESP32C2)
|
||||||
|
set(ldfragments "linker.lf.esp32c2")
|
||||||
list(APPEND srcs "controller/esp32c2/bt.c")
|
list(APPEND srcs "controller/esp32c2/bt.c")
|
||||||
list(APPEND include_dirs include/esp32c2/include)
|
list(APPEND include_dirs include/esp32c2/include)
|
||||||
|
|
||||||
@ -695,13 +697,12 @@ if(CONFIG_BT_ENABLED)
|
|||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# requirements can't depend on config
|
|
||||||
idf_component_register(SRCS "${srcs}"
|
idf_component_register(SRCS "${srcs}"
|
||||||
INCLUDE_DIRS "${include_dirs}"
|
INCLUDE_DIRS "${include_dirs}"
|
||||||
PRIV_INCLUDE_DIRS "${priv_include_dirs}"
|
PRIV_INCLUDE_DIRS "${priv_include_dirs}"
|
||||||
REQUIRES esp_timer esp_wifi
|
REQUIRES esp_timer esp_wifi
|
||||||
PRIV_REQUIRES nvs_flash soc esp_pm esp_phy esp_coex mbedtls driver vfs
|
PRIV_REQUIRES nvs_flash soc esp_pm esp_phy esp_coex mbedtls driver vfs
|
||||||
LDFRAGMENTS "linker.lf")
|
LDFRAGMENTS "${ldfragments}")
|
||||||
|
|
||||||
if(CONFIG_BT_ENABLED)
|
if(CONFIG_BT_ENABLED)
|
||||||
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-implicit-fallthrough -Wno-unused-const-variable)
|
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-implicit-fallthrough -Wno-unused-const-variable)
|
||||||
|
@ -68,6 +68,17 @@ menu "Bluetooth"
|
|||||||
source "$IDF_PATH/components/bt/controller/$IDF_TARGET/Kconfig.in"
|
source "$IDF_PATH/components/bt/controller/$IDF_TARGET/Kconfig.in"
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
|
config BT_RELEASE_IRAM
|
||||||
|
depends on BT_ENABLED && BT_LE_RELEASE_IRAM_SUPPORTED
|
||||||
|
bool "Release Bluetooth text (READ DOCS FIRST)"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
This option release Bluetooth text section and merge Bluetooth data, bss & text into
|
||||||
|
a large free heap region when esp_bt_mem_release is called, total saving ~21kB or more of IRAM.
|
||||||
|
ESP32-C2 only 3 configurable PMP entries available, rest of them are hard-coded.
|
||||||
|
We cannot split the memory into 3 different regions (IRAM, BLE-IRAM, DRAM).
|
||||||
|
So this option will disable the PMP (ESP_SYSTEM_PMP_IDRAM_SPLIT)
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
menuconfig BLE_MESH
|
menuconfig BLE_MESH
|
||||||
|
@ -425,3 +425,6 @@ config BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD
|
|||||||
of ADV packets lost in the controller reaches this threshold. It is better to set a larger value.
|
of ADV packets lost in the controller reaches this threshold. It is better to set a larger value.
|
||||||
If you set `BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD` to a small value or printf every adv lost event, it
|
If you set `BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD` to a small value or printf every adv lost event, it
|
||||||
may cause adv packets lost more.
|
may cause adv packets lost more.
|
||||||
|
config BT_LE_RELEASE_IRAM_SUPPORTED
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
@ -156,14 +156,14 @@ extern int ble_txpwr_set(esp_ble_enhanced_power_type_t power_type, uint16_t hand
|
|||||||
extern int ble_txpwr_get(esp_ble_enhanced_power_type_t power_type, uint16_t handle);
|
extern int ble_txpwr_get(esp_ble_enhanced_power_type_t power_type, uint16_t handle);
|
||||||
extern int ble_get_npl_element_info(esp_bt_controller_config_t *cfg, ble_npl_count_info_t * npl_info);
|
extern int ble_get_npl_element_info(esp_bt_controller_config_t *cfg, ble_npl_count_info_t * npl_info);
|
||||||
extern void bt_track_pll_cap(void);
|
extern void bt_track_pll_cap(void);
|
||||||
extern uint32_t _bt_bss_start;
|
|
||||||
|
#if CONFIG_BT_RELEASE_IRAM
|
||||||
|
extern uint32_t _iram_bt_text_start;
|
||||||
|
extern uint32_t _bss_bt_end;
|
||||||
|
#else
|
||||||
extern uint32_t _bt_bss_end;
|
extern uint32_t _bt_bss_end;
|
||||||
extern uint32_t _nimble_bss_start;
|
extern uint32_t _bt_controller_data_start;
|
||||||
extern uint32_t _nimble_bss_end;
|
#endif
|
||||||
extern uint32_t _nimble_data_start;
|
|
||||||
extern uint32_t _nimble_data_end;
|
|
||||||
extern uint32_t _bt_data_start;
|
|
||||||
extern uint32_t _bt_data_end;
|
|
||||||
|
|
||||||
/* Local Function Declaration
|
/* Local Function Declaration
|
||||||
*********************************************************************
|
*********************************************************************
|
||||||
@ -832,32 +832,28 @@ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode)
|
|||||||
{
|
{
|
||||||
intptr_t mem_start, mem_end;
|
intptr_t mem_start, mem_end;
|
||||||
|
|
||||||
|
#if CONFIG_BT_RELEASE_IRAM && CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT
|
||||||
|
/* Release Bluetooth text section and merge Bluetooth data, bss & text into a large free heap
|
||||||
|
* region when esp_bt_mem_release is called, total saving ~21kB or more of IRAM. ESP32-C2 has
|
||||||
|
* only 3 configurable PMP entries available, rest of them are hard-coded. We cannot split the
|
||||||
|
* memory into 3 different regions (IRAM, BLE-IRAM, DRAM). So `ESP_SYSTEM_PMP_IDRAM_SPLIT` needs
|
||||||
|
* to be disabled.
|
||||||
|
*/
|
||||||
|
ESP_LOGE(NIMBLE_PORT_LOG_TAG, "`ESP_SYSTEM_PMP_IDRAM_SPLIT` should be disabled!");
|
||||||
|
assert(0);
|
||||||
|
#endif // CONFIG_BT_RELEASE_IRAM && CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT
|
||||||
|
|
||||||
if (mode & ESP_BT_MODE_BLE) {
|
if (mode & ESP_BT_MODE_BLE) {
|
||||||
mem_start = (intptr_t)&_bt_bss_start;
|
#if CONFIG_BT_RELEASE_IRAM
|
||||||
|
mem_start = (intptr_t)MAP_IRAM_TO_DRAM((intptr_t)&_iram_bt_text_start);
|
||||||
|
mem_end = (intptr_t)&_bss_bt_end;
|
||||||
|
#else
|
||||||
|
mem_start = (intptr_t)&_bt_controller_data_start;
|
||||||
mem_end = (intptr_t)&_bt_bss_end;
|
mem_end = (intptr_t)&_bt_bss_end;
|
||||||
|
#endif // CONFIG_BT_RELEASE_IRAM
|
||||||
if (mem_start != mem_end) {
|
if (mem_start != mem_end) {
|
||||||
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release BT BSS [0x%08x] - [0x%08x]", mem_start, mem_end);
|
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Release BLE [0x%08x] - [0x%08x], len %d", mem_start,
|
||||||
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
|
mem_end, mem_end - mem_start);
|
||||||
}
|
|
||||||
|
|
||||||
mem_start = (intptr_t)&_bt_data_start;
|
|
||||||
mem_end = (intptr_t)&_bt_data_end;
|
|
||||||
if (mem_start != mem_end) {
|
|
||||||
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release BT Data [0x%08x] - [0x%08x]", mem_start, mem_end);
|
|
||||||
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
|
|
||||||
}
|
|
||||||
|
|
||||||
mem_start = (intptr_t)&_nimble_bss_start;
|
|
||||||
mem_end = (intptr_t)&_nimble_bss_end;
|
|
||||||
if (mem_start != mem_end) {
|
|
||||||
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release NimBLE BSS [0x%08x] - [0x%08x]", mem_start, mem_end);
|
|
||||||
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
|
|
||||||
}
|
|
||||||
|
|
||||||
mem_start = (intptr_t)&_nimble_data_start;
|
|
||||||
mem_end = (intptr_t)&_nimble_data_end;
|
|
||||||
if (mem_start != mem_end) {
|
|
||||||
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release NimBLE Data [0x%08x] - [0x%08x]", mem_start, mem_end);
|
|
||||||
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
|
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
60
components/bt/linker.lf.esp32c2
Normal file
60
components/bt/linker.lf.esp32c2
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
[sections:bt_text]
|
||||||
|
entries:
|
||||||
|
.iram1+
|
||||||
|
|
||||||
|
[sections:bt_bss]
|
||||||
|
entries:
|
||||||
|
.bss+
|
||||||
|
.sbss+
|
||||||
|
|
||||||
|
[sections:bt_data]
|
||||||
|
entries:
|
||||||
|
.data+
|
||||||
|
.sdata+
|
||||||
|
.dram1+
|
||||||
|
|
||||||
|
[sections:bt_common]
|
||||||
|
entries:
|
||||||
|
COMMON
|
||||||
|
|
||||||
|
[scheme:bt_start_end]
|
||||||
|
entries:
|
||||||
|
bt_text -> iram0_bt_text
|
||||||
|
bt_bss -> dram0_bt_bss
|
||||||
|
bt_common -> dram0_bt_bss
|
||||||
|
bt_data -> dram0_bt_data
|
||||||
|
|
||||||
|
# For the following fragments, order matters for
|
||||||
|
# 'ALIGN(4) ALIGN(4, post) SURROUND(sym)', which generates:
|
||||||
|
#
|
||||||
|
# . = ALIGN(4)
|
||||||
|
# _sym_start
|
||||||
|
# ...
|
||||||
|
# . = ALIGN(4)
|
||||||
|
# _sym_end
|
||||||
|
|
||||||
|
[mapping:bt]
|
||||||
|
archive: libbt.a
|
||||||
|
entries:
|
||||||
|
* (bt_start_end);
|
||||||
|
bt_bss -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_bss),
|
||||||
|
bt_common -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_common),
|
||||||
|
bt_data -> dram0_bt_data ALIGN(4) ALIGN(4, post) SURROUND(bt_data)
|
||||||
|
if ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y:
|
||||||
|
* (extram_bss)
|
||||||
|
|
||||||
|
[mapping:btdm]
|
||||||
|
archive: libbtdm_app.a
|
||||||
|
entries:
|
||||||
|
* (bt_start_end);
|
||||||
|
bt_bss -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(btdm_bss),
|
||||||
|
bt_common -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(btdm_common),
|
||||||
|
bt_data -> dram0_bt_data ALIGN(4) ALIGN(4, post) SURROUND(btdm_data)
|
||||||
|
|
||||||
|
[mapping:bt_controller]
|
||||||
|
archive: libble_app.a
|
||||||
|
entries:
|
||||||
|
* (bt_start_end);
|
||||||
|
bt_bss -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_bss),
|
||||||
|
bt_common -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_common),
|
||||||
|
bt_data -> dram0_bt_data ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_data)
|
@ -35,9 +35,27 @@ SECTIONS
|
|||||||
. = ORIGIN(dram0_0_seg) + _iram_end - _iram_start;
|
. = ORIGIN(dram0_0_seg) + _iram_end - _iram_start;
|
||||||
} > dram0_0_seg
|
} > dram0_0_seg
|
||||||
|
|
||||||
.dram0.data :
|
/**
|
||||||
|
* This section MUST be placed at the beginning of the DRAM0,
|
||||||
|
* which will be released along with iram0_bt.text when Bluetooth is no longer in use
|
||||||
|
*/
|
||||||
|
.dram0.bt.data :
|
||||||
{
|
{
|
||||||
_data_start = ABSOLUTE(.);
|
_data_start = ABSOLUTE(.);
|
||||||
|
mapping[dram0_bt_data]
|
||||||
|
. = ALIGN(8);
|
||||||
|
} > dram0_0_seg
|
||||||
|
|
||||||
|
.dram0.bt.bss (NOLOAD) :
|
||||||
|
{
|
||||||
|
. = ALIGN (8);
|
||||||
|
_bss_bt_start = ABSOLUTE(.);
|
||||||
|
mapping[dram0_bt_bss]
|
||||||
|
_bss_bt_end = ABSOLUTE(.);
|
||||||
|
} > dram0_0_seg
|
||||||
|
|
||||||
|
.dram0.data :
|
||||||
|
{
|
||||||
*(.gnu.linkonce.d.*)
|
*(.gnu.linkonce.d.*)
|
||||||
*(.data1)
|
*(.data1)
|
||||||
__global_pointer$ = . + 0x800;
|
__global_pointer$ = . + 0x800;
|
||||||
@ -289,6 +307,18 @@ SECTIONS
|
|||||||
mapping[iram0_bss]
|
mapping[iram0_bss]
|
||||||
|
|
||||||
_iram_bss_end = ABSOLUTE(.);
|
_iram_bss_end = ABSOLUTE(.);
|
||||||
|
} > iram0_0_seg
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This section needs to be placed at the end of the IRAM0,
|
||||||
|
* which will be released along with dram0_bt_data and dram0_bt_bss when Bluetooth is no longer in use
|
||||||
|
*/
|
||||||
|
.iram0.bt.text :
|
||||||
|
{
|
||||||
|
. = ALIGN(16);
|
||||||
|
_iram_bt_text_start = ABSOLUTE(.);
|
||||||
|
mapping[iram0_bt_text]
|
||||||
|
|
||||||
. = ALIGN(16);
|
. = ALIGN(16);
|
||||||
_iram_end = ABSOLUTE(.);
|
_iram_end = ABSOLUTE(.);
|
||||||
} > iram0_0_seg
|
} > iram0_0_seg
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -108,7 +108,10 @@ extern int _bss_start;
|
|||||||
extern int _bss_end;
|
extern int _bss_end;
|
||||||
extern int _rtc_bss_start;
|
extern int _rtc_bss_start;
|
||||||
extern int _rtc_bss_end;
|
extern int _rtc_bss_end;
|
||||||
|
#if CONFIG_BT_LE_RELEASE_IRAM_SUPPORTED
|
||||||
|
extern int _bss_bt_start;
|
||||||
|
extern int _bss_bt_end;
|
||||||
|
#endif // CONFIG_BT_LE_RELEASE_IRAM_SUPPORTED
|
||||||
extern int _instruction_reserved_start;
|
extern int _instruction_reserved_start;
|
||||||
extern int _instruction_reserved_end;
|
extern int _instruction_reserved_end;
|
||||||
extern int _rodata_reserved_start;
|
extern int _rodata_reserved_start;
|
||||||
@ -328,6 +331,11 @@ void IRAM_ATTR call_start_cpu0(void)
|
|||||||
//Clear BSS. Please do not attempt to do any complex stuff (like early logging) before this.
|
//Clear BSS. Please do not attempt to do any complex stuff (like early logging) before this.
|
||||||
memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start));
|
memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start));
|
||||||
|
|
||||||
|
#if CONFIG_BT_LE_RELEASE_IRAM_SUPPORTED
|
||||||
|
// Clear Bluetooth bss
|
||||||
|
memset(&_bss_bt_start, 0, (&_bss_bt_end - &_bss_bt_start) * sizeof(_bss_bt_start));
|
||||||
|
#endif // CONFIG_BT_LE_RELEASE_IRAM_SUPPORTED
|
||||||
|
|
||||||
#if defined(CONFIG_IDF_TARGET_ESP32) && defined(CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY)
|
#if defined(CONFIG_IDF_TARGET_ESP32) && defined(CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY)
|
||||||
// Clear IRAM BSS
|
// Clear IRAM BSS
|
||||||
memset(&_iram_bss_start, 0, (&_iram_bss_end - &_iram_bss_start) * sizeof(_iram_bss_start));
|
memset(&_iram_bss_start, 0, (&_iram_bss_end - &_iram_bss_start) * sizeof(_iram_bss_start));
|
||||||
|
@ -161,6 +161,7 @@ The following options will reduce IRAM usage of some ESP-IDF features:
|
|||||||
- Setting :ref:`CONFIG_HAL_DEFAULT_ASSERTION_LEVEL` to disable assertion for HAL component saves some IRAM, especially for HAL code who calls ``HAL_ASSERT`` a lot and resides in IRAM.
|
- Setting :ref:`CONFIG_HAL_DEFAULT_ASSERTION_LEVEL` to disable assertion for HAL component saves some IRAM, especially for HAL code who calls ``HAL_ASSERT`` a lot and resides in IRAM.
|
||||||
- Refer to the sdkconfig menu ``Auto-detect Flash chips``, and you can disable flash drivers which you do not need to save some IRAM.
|
- Refer to the sdkconfig menu ``Auto-detect Flash chips``, and you can disable flash drivers which you do not need to save some IRAM.
|
||||||
- Enable :ref:`CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH`. Provided that :ref:`CONFIG_SPI_MASTER_ISR_IN_IRAM` is not enabled and the heap functions are not incorrectly used from ISRs, this option is safe to enable in all configurations.
|
- Enable :ref:`CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH`. Provided that :ref:`CONFIG_SPI_MASTER_ISR_IN_IRAM` is not enabled and the heap functions are not incorrectly used from ISRs, this option is safe to enable in all configurations.
|
||||||
|
:esp32c2: - Enable :ref:`CONFIG_BT_RELEASE_IRAM`. Release BT text section and merge BT data, bss & text into a large free heap region when ``esp_bt_mem_release`` is called. This makes Bluetooth unavailable until the next restart, but saving ~22 KB or more of IRAM.
|
||||||
|
|
||||||
.. only:: esp32
|
.. only:: esp32
|
||||||
|
|
||||||
|
@ -161,6 +161,7 @@ IRAM 优化
|
|||||||
- 设置 :ref:`CONFIG_HAL_DEFAULT_ASSERTION_LEVEL` 为禁用 HAL 组件的断言,可以节省 IRAM 空间,对于经常调用 ``HAL_ASSERT`` 且位于 IRAM 中的 HAL 代码尤为如此。
|
- 设置 :ref:`CONFIG_HAL_DEFAULT_ASSERTION_LEVEL` 为禁用 HAL 组件的断言,可以节省 IRAM 空间,对于经常调用 ``HAL_ASSERT`` 且位于 IRAM 中的 HAL 代码尤为如此。
|
||||||
- 要禁用不需要的 flash 驱动程序,节省 IRAM 空间,请参阅 sdkconfig 菜单中的 ``Auto-detect Flash chips`` 选项。
|
- 要禁用不需要的 flash 驱动程序,节省 IRAM 空间,请参阅 sdkconfig 菜单中的 ``Auto-detect Flash chips`` 选项。
|
||||||
- 启用 :ref:`CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH`。只要未启用 :ref:`CONFIG_SPI_MASTER_ISR_IN_IRAM` 选项,且没有从 ISR 中错误地调用堆函数,就可以在所有配置中安全启用此选项。
|
- 启用 :ref:`CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH`。只要未启用 :ref:`CONFIG_SPI_MASTER_ISR_IN_IRAM` 选项,且没有从 ISR 中错误地调用堆函数,就可以在所有配置中安全启用此选项。
|
||||||
|
:esp32c2: - 启用 :ref:`CONFIG_BT_RELEASE_IRAM`。 蓝牙所使用的 data,bss 和 text 段已经被分配在连续的RAM区间。当调用 ``esp_bt_mem_release`` 时,这些段都会被添加到 Heap 中。 这将节省约 22 KB 的 RAM。但要再次使用蓝牙功能,需要重启程序。
|
||||||
|
|
||||||
.. only:: esp32
|
.. only:: esp32
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user