diff --git a/components/bt/bt.c b/components/bt/bt.c index b90ccc8ea..c30f332a7 100644 --- a/components/bt/bt.c +++ b/components/bt/bt.c @@ -103,6 +103,14 @@ extern void bredr_sco_datapath_set(uint8_t data_path); extern char _bss_start_btdm; extern char _bss_end_btdm; +extern uint32_t _bt_bss_start; +extern uint32_t _bt_bss_end; +extern uint32_t _btdm_bss_start; +extern uint32_t _btdm_bss_end; +extern uint32_t _bt_data_start; +extern uint32_t _bt_data_end; +extern uint32_t _btdm_data_start; +extern uint32_t _btdm_data_end; extern char _data_start_btdm; extern char _data_end_btdm; extern uint32_t _data_start_btdm_rom; @@ -769,17 +777,50 @@ esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode) continue; } else { ESP_LOGD(BTDM_LOG_TAG, "Release DRAM [0x%08x] - [0x%08x]\n", mem_start, mem_end); - ESP_ERROR_CHECK( heap_caps_add_region(mem_start, mem_end)); + ESP_ERROR_CHECK(heap_caps_add_region(mem_start, mem_end)); update = true; } } else { mem_end = btdm_dram_available_region[i].end; ESP_LOGD(BTDM_LOG_TAG, "Release DRAM [0x%08x] - [0x%08x]\n", mem_start, mem_end); - ESP_ERROR_CHECK( heap_caps_add_region(mem_start, mem_end)); + ESP_ERROR_CHECK(heap_caps_add_region(mem_start, mem_end)); update = true; } } + if (mode == ESP_BT_MODE_BTDM) { + mem_start = (intptr_t)&_btdm_bss_start; + mem_end = (intptr_t)&_btdm_bss_end; + ESP_LOGD(BTDM_LOG_TAG, "Release BTDM BSS [0x%08x] - [0x%08x]\n", mem_start, mem_end); + ESP_ERROR_CHECK(heap_caps_add_region(mem_start, mem_end)); + mem_start = (intptr_t)&_btdm_data_start; + mem_end = (intptr_t)&_btdm_data_end; + ESP_LOGD(BTDM_LOG_TAG, "Release BTDM Data [0x%08x] - [0x%08x]\n", mem_start, mem_end); + ESP_ERROR_CHECK(heap_caps_add_region(mem_start, mem_end)); + } + return ESP_OK; +} + +esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) +{ + int ret; + intptr_t mem_start, mem_end; + + ret = esp_bt_controller_mem_release(mode); + if (ret != ESP_OK) { + return ret; + } + + if (mode == ESP_BT_MODE_BTDM) { + mem_start = (intptr_t)&_bt_bss_start; + mem_end = (intptr_t)&_bt_bss_end; + ESP_LOGD(BTDM_LOG_TAG, "Release BT BSS [0x%08x] - [0x%08x]\n", mem_start, mem_end); + ESP_ERROR_CHECK(heap_caps_add_region(mem_start, mem_end)); + mem_start = (intptr_t)&_bt_data_start; + mem_end = (intptr_t)&_bt_data_end; + ESP_LOGD(BTDM_LOG_TAG, "Release BT Data [0x%08x] - [0x%08x]\n", mem_start, mem_end); + ESP_ERROR_CHECK(heap_caps_add_region(mem_start, mem_end)); + } return ESP_OK; } diff --git a/components/bt/include/esp_bt.h b/components/bt/include/esp_bt.h index fe594b038..6ab606ff6 100644 --- a/components/bt/include/esp_bt.h +++ b/components/bt/include/esp_bt.h @@ -298,33 +298,62 @@ void esp_vhci_host_send_packet(uint8_t *data, uint16_t len); void esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback); /** @brief esp_bt_controller_mem_release - * release the memory by mode, if never use the bluetooth mode - * it can release the .bss, .data and other section to heap. - * The total size is about 70k bytes. + * release the controller memory as per the mode + * + * This function releases the BSS, data and other sections of the controller to heap. The total size is about 70k bytes. * * esp_bt_controller_mem_release(mode) should be called only before esp_bt_controller_init() * or after esp_bt_controller_deinit(). * - * Note that once BT controller memory is released, the process cannot be reversed. It means you can not use the bluetooth + * Note that once BT controller memory is released, the process cannot be reversed. It means you cannot use the bluetooth * mode which you have released by this function. * * If your firmware will later upgrade the Bluetooth controller mode (BLE -> BT Classic or disabled -> enabled) * then do not call this function. * * If the app calls esp_bt_controller_enable(ESP_BT_MODE_BLE) to use BLE only then it is safe to call - * esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT) at initialisation time to free unused BT Classic memory. + * esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT) at initialization time to free unused BT Classic memory. * - * If user never use bluetooth controller, could call esp_bt_controller_mem_release(ESP_BT_MODE_BTDM) - * before esp_bt_controller_init or after esp_bt_controller_deinit. - * - * For example, user only use bluetooth to config SSID and PASSWORD of WIFI, after config, will never use bluetooth. - * Then, could call esp_bt_controller_mem_release(ESP_BT_MODE_BTDM) after esp_bt_controller_deinit. + * If the mode is ESP_BT_MODE_BTDM, then it may be useful to call API esp_bt_mem_release(ESP_BT_MODE_BTDM) instead, + * which internally calls esp_bt_controller_mem_release(ESP_BT_MODE_BTDM) and additionally releases the BSS and data + * consumed by the BT/BLE host stack to heap. For more details about usage please refer to the documentation of + * esp_bt_mem_release() function * * @param mode : the mode want to release memory * @return ESP_OK - success, other - failed */ esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode); +/** @brief esp_bt_mem_release + * release controller memory and BSS and data section of the BT/BLE host stack as per the mode + * + * This function first releases controller memory by internally calling esp_bt_controller_mem_release(). + * Additionally, if the mode is set to ESP_BT_MODE_BTDM, it also releases the BSS and data consumed by the BT/BLE host stack to heap + * + * Note that once BT memory is released, the process cannot be reversed. It means you cannot use the bluetooth + * mode which you have released by this function. + * + * If your firmware will later upgrade the Bluetooth controller mode (BLE -> BT Classic or disabled -> enabled) + * then do not call this function. + * + * If you never intend to use bluetooth in a current boot-up cycle, you can call esp_bt_mem_release(ESP_BT_MODE_BTDM) + * before esp_bt_controller_init or after esp_bt_controller_deinit. + * + * For example, if a user only uses bluetooth for setting the WiFi configuration, and does not use bluetooth in the rest of the product operation". + * In such cases, after receiving the WiFi configuration, you can disable/deinit bluetooth and release its memory. + * Below is the sequence of APIs to be called for such scenarios: + * + * esp_bluedroid_disable(); + * esp_bluedroid_deinit(); + * esp_bt_controller_disable(); + * esp_bt_controller_deinit(); + * esp_bt_mem_release(ESP_BT_MODE_BTDM); + * + * @param mode : the mode whose memory is to be released + * @return ESP_OK - success, other - failed + */ +esp_err_t esp_bt_mem_release(esp_bt_mode_t mode); + /** * @brief enable bluetooth to enter modem sleep * diff --git a/components/esp32/ld/esp32.common.ld b/components/esp32/ld/esp32.common.ld index 26acd7b2d..1f3947baa 100644 --- a/components/esp32/ld/esp32.common.ld +++ b/components/esp32/ld/esp32.common.ld @@ -116,6 +116,14 @@ SECTIONS .dram0.data : { _data_start = ABSOLUTE(.); + _bt_data_start = ABSOLUTE(.); + *libbt.a:(.data .data.*) + . = ALIGN (4); + _bt_data_end = ABSOLUTE(.); + _btdm_data_start = ABSOLUTE(.); + *libbtdm_app.a:(.data .data.*) + . = ALIGN (4); + _btdm_data_end = ABSOLUTE(.); *(.data) *(.data.*) *(.gnu.linkonce.d.*) @@ -159,6 +167,14 @@ SECTIONS { . = ALIGN (8); _bss_start = ABSOLUTE(.); + _bt_bss_start = ABSOLUTE(.); + *libbt.a:(.bss .bss.* COMMON) + . = ALIGN (4); + _bt_bss_end = ABSOLUTE(.); + _btdm_bss_start = ABSOLUTE(.); + *libbtdm_app.a:(.bss .bss.* COMMON) + . = ALIGN (4); + _btdm_bss_end = ABSOLUTE(.); *(.dynsbss) *(.sbss) *(.sbss.*)