diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index 52411786737d..6a87a3e177e7 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -67,37 +67,40 @@ if(CONFIG_IDF_DOC_BUILD) ${nimble_hci_include_dirs}) endif() - if(CONFIG_BT_ENABLED) set(srcs "") set(include_dirs "") - set(ldfragments "linker.lf") + set(ldscripts "linker_common.lf") if(CONFIG_BT_CONTROLLER_ENABLED) if(CONFIG_IDF_TARGET_ESP32) list(APPEND srcs "controller/esp32/bt.c" "controller/esp32/hli_api.c" "controller/esp32/hli_vectors.S") + list(APPEND ldscripts "linker_rw_bt_controller.lf") elseif(CONFIG_IDF_TARGET_ESP32C3) list(APPEND srcs "controller/esp32c3/bt.c") + list(APPEND ldscripts "linker_rw_bt_controller.lf") elseif(CONFIG_IDF_TARGET_ESP32S3) list(APPEND srcs "controller/esp32c3/bt.c") + list(APPEND ldscripts "linker_rw_bt_controller.lf") elseif(CONFIG_IDF_TARGET_ESP32C2) - set(ldfragments "linker.lf.esp32c2") list(APPEND srcs "controller/esp32c2/bt.c") + set(ldscripts "linker_esp32c2.lf") elseif(CONFIG_IDF_TARGET_ESP32C6) list(APPEND srcs "controller/esp32c6/bt.c") + list(APPEND ldscripts "linker_esp_ble_controller.lf") elseif(CONFIG_IDF_TARGET_ESP32H2) list(APPEND srcs "controller/esp32h2/bt.c") + list(APPEND ldscripts "linker_esp_ble_controller.lf") endif() list(APPEND include_dirs ${target_specific_include_dirs}) - endif() # Common @@ -820,7 +823,7 @@ idf_component_register(SRCS "${srcs}" PRIV_INCLUDE_DIRS "${priv_include_dirs}" REQUIRES esp_timer esp_wifi PRIV_REQUIRES nvs_flash soc esp_pm esp_phy esp_coex mbedtls driver vfs - LDFRAGMENTS "${ldfragments}") + LDFRAGMENTS "${ldscripts}") if(CONFIG_BT_ENABLED) target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-implicit-fallthrough -Wno-unused-const-variable) diff --git a/components/bt/controller/esp32/bt.c b/components/bt/controller/esp32/bt.c index 10604e9d98bf..f2489b837a27 100644 --- a/components/bt/controller/esp32/bt.c +++ b/components/bt/controller/esp32/bt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -233,16 +233,12 @@ extern uint32_t _data_end_btdm_rom; extern uint32_t _bt_bss_start; extern uint32_t _bt_bss_end; -extern uint32_t _nimble_bss_start; -extern uint32_t _nimble_bss_end; -extern uint32_t _btdm_bss_start; -extern uint32_t _btdm_bss_end; +extern uint32_t _bt_controller_bss_start; +extern uint32_t _bt_controller_bss_end; extern uint32_t _bt_data_start; extern uint32_t _bt_data_end; -extern uint32_t _nimble_data_start; -extern uint32_t _nimble_data_end; -extern uint32_t _btdm_data_start; -extern uint32_t _btdm_data_end; +extern uint32_t _bt_controller_data_start; +extern uint32_t _bt_controller_data_end; extern void config_bt_funcs_reset(void); extern void config_ble_funcs_reset(void); @@ -760,7 +756,7 @@ static int32_t queue_send_hlevel_wrapper(void *queue, void *item, uint32_t block * @param item The message which will be send * @param hptw need do task yield or not * @return send success or not - * There is an issue here: When the queue is full, it may reture true but it send fail to the queue, sometimes. + * There is an issue here: When the queue is full, it may return true but it send fail to the queue, sometimes. * But in Bluetooth controller's isr, We don't care about the return value. * It only required tp send success when the queue is empty all the time. * So, this function meets the requirement. @@ -1281,7 +1277,45 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end) return ret; } -esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode) +typedef struct { + intptr_t start; + intptr_t end; + const char* name; +} bt_area_t; + + +static esp_err_t esp_bt_mem_release_area(const bt_area_t *area) +{ + esp_err_t ret = ESP_OK; + intptr_t mem_start = area->start; + intptr_t mem_end = area->end; + if (mem_start != mem_end) { + ESP_LOGD(BTDM_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start); + ret = try_heap_caps_add_region(mem_start, mem_end); + } + return ret; +} + +static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2) +{ + esp_err_t ret = ESP_OK; + + if (area1->end == area2->start) { + bt_area_t merged_area = { + .start = area1->start, + .end = area2->end, + .name = area1->name + }; + ret = esp_bt_mem_release_area(&merged_area); + } else { + esp_bt_mem_release_area(area1); + ret = esp_bt_mem_release_area(area2); + } + + return ret; +} + +static esp_err_t esp_bt_controller_rom_mem_release(esp_bt_mode_t mode) { bool update = true; intptr_t mem_start=(intptr_t) NULL, mem_end=(intptr_t) NULL; @@ -1332,61 +1366,86 @@ esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode) } } + return ESP_OK; +} + +esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode) +{ + esp_err_t ret = ESP_OK; + + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return ESP_ERR_INVALID_STATE; + } + if (mode == ESP_BT_MODE_BTDM) { - mem_start = (intptr_t)&_btdm_bss_start; - mem_end = (intptr_t)&_btdm_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(BTDM_LOG_TAG, "Release BTDM 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)&_btdm_data_start; - mem_end = (intptr_t)&_btdm_data_end; - if (mem_start != mem_end) { - ESP_LOGD(BTDM_LOG_TAG, "Release BTDM Data [0x%08x] - [0x%08x]", mem_start, mem_end); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + bt_area_t cont_bss = { + .start = (intptr_t)&_bt_controller_bss_start, + .end = (intptr_t)&_bt_controller_bss_end, + .name = "BT Controller BSS", + }; + bt_area_t cont_data = { + .start = (intptr_t)&_bt_controller_data_start, + .end = (intptr_t)&_bt_controller_data_end, + .name = "BT Controller Data" + }; + + ret = esp_bt_mem_release_areas(&cont_data, &cont_bss); } - return ESP_OK; + + if (ret == ESP_OK) { + ret = esp_bt_controller_rom_mem_release(mode); + } + + return ret; } esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) { - int ret; - intptr_t mem_start, mem_end; + esp_err_t ret = ESP_OK; - ret = esp_bt_controller_mem_release(mode); - if (ret != ESP_OK) { - return ret; + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return ESP_ERR_INVALID_STATE; } + bt_area_t bss = { + .start = (intptr_t)&_bt_bss_start, + .end = (intptr_t)&_bt_bss_end, + .name = "BT BSS", + }; + bt_area_t cont_bss = { + .start = (intptr_t)&_bt_controller_bss_start, + .end = (intptr_t)&_bt_controller_bss_end, + .name = "BT Controller BSS", + }; + bt_area_t data = { + .start = (intptr_t)&_bt_data_start, + .end = (intptr_t)&_bt_data_end, + .name = "BT Data", + }; + bt_area_t cont_data = { + .start = (intptr_t)&_bt_controller_data_start, + .end = (intptr_t)&_bt_controller_data_end, + .name = "BT Controller Data" + }; + if (mode == ESP_BT_MODE_BTDM) { - mem_start = (intptr_t)&_bt_bss_start; - mem_end = (intptr_t)&_bt_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(BTDM_LOG_TAG, "Release BT 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)&_bt_data_start; - mem_end = (intptr_t)&_bt_data_end; - if (mem_start != mem_end) { - ESP_LOGD(BTDM_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)); + /* Start by freeing Bluetooth BSS section */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&bss, &cont_bss); } - mem_start = (intptr_t)&_nimble_bss_start; - mem_end = (intptr_t)&_nimble_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(BTDM_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(BTDM_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)); + /* Do the same thing with the Bluetooth data section */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&data, &cont_data); } } - return ESP_OK; + + /* free data and BSS section for Bluetooth controller ROM code */ + if (ret == ESP_OK) { + ret = esp_bt_controller_rom_mem_release(mode); + } + + return ret; } #if CONFIG_BTDM_CTRL_HLI @@ -1695,7 +1754,7 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) sdk_config_set_bt_pll_track_enable(true); - // inititalize bluetooth baseband + // initialize bluetooth baseband btdm_check_and_init_bb(); ret = btdm_controller_enable(mode); @@ -1858,7 +1917,7 @@ esp_err_t esp_ble_scan_dupilcate_list_flush(void) /** * This function re-write controller's function, - * As coredump can not show paramerters in function which is in a .a file. + * As coredump can not show parameters in function which is in a .a file. * * After coredump fixing this issue, just delete this function. */ diff --git a/components/bt/controller/esp32c2/bt.c b/components/bt/controller/esp32c2/bt.c index ae699b380f65..b89e9535993d 100644 --- a/components/bt/controller/esp32c2/bt.c +++ b/components/bt/controller/esp32c2/bt.c @@ -168,10 +168,16 @@ extern const char *r_ble_controller_get_rom_compile_version(void); #if CONFIG_BT_RELEASE_IRAM extern uint32_t _iram_bt_text_start; extern uint32_t _bss_bt_end; -#else +#endif + +extern uint32_t _bt_bss_start; extern uint32_t _bt_bss_end; +extern uint32_t _bt_controller_bss_start; +extern uint32_t _bt_controller_bss_end; +extern uint32_t _bt_data_start; +extern uint32_t _bt_data_end; extern uint32_t _bt_controller_data_start; -#endif +extern uint32_t _bt_controller_data_end; /* Local Function Declaration ********************************************************************* @@ -900,9 +906,48 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end) return ret; } +typedef struct { + intptr_t start; + intptr_t end; + const char* name; +} bt_area_t; + +static esp_err_t esp_bt_mem_release_area(const bt_area_t *area) +{ + esp_err_t ret = ESP_OK; + intptr_t mem_start = area->start; + intptr_t mem_end = area->end; + if (mem_start != mem_end) { + ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start); + ret = try_heap_caps_add_region(mem_start, mem_end); + } + return ret; +} + +#ifndef CONFIG_BT_RELEASE_IRAM +static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2) +{ + esp_err_t ret = ESP_OK; + + if(area1->end == area2->start) { + bt_area_t merged_area = { + .start = area1->start, + .end = area2->end, + .name = area1->name + }; + ret = esp_bt_mem_release_area(&merged_area); + } else { + esp_bt_mem_release_area(area1); + ret = esp_bt_mem_release_area(area2); + } + + return ret; +} +#endif + esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) { - intptr_t mem_start, mem_end; + esp_err_t ret = ESP_OK; #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 @@ -911,26 +956,58 @@ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) * 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); + #error "ESP_SYSTEM_PMP_IDRAM_SPLIT should be disabled to allow BT to be released" #endif // CONFIG_BT_RELEASE_IRAM && CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT - if (mode & ESP_BT_MODE_BLE) { + if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return ESP_ERR_INVALID_STATE; + } + + if ((mode & ESP_BT_MODE_BLE) == 0) { + return ret; + } + #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; + bt_area_t merged_region = { + .start = (intptr_t)MAP_IRAM_TO_DRAM((intptr_t)&_iram_bt_text_start), + .end = (intptr_t)&_bss_bt_end, + .name = "BT Text, BSS and Data" + }; + ret = esp_bt_mem_release_area(&merged_region); #else - mem_start = (intptr_t)&_bt_controller_data_start; - mem_end = (intptr_t)&_bt_bss_end; -#endif // CONFIG_BT_RELEASE_IRAM - if (mem_start != mem_end) { - ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Release BLE [0x%08x] - [0x%08x], len %d", mem_start, - mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + bt_area_t bss = { + .start = (intptr_t)&_bt_bss_start, + .end = (intptr_t)&_bt_bss_end, + .name = "BT BSS", + }; + bt_area_t cont_bss = { + .start = (intptr_t)&_bt_controller_bss_start, + .end = (intptr_t)&_bt_controller_bss_end, + .name = "BT Controller BSS", + }; + bt_area_t data = { + .start = (intptr_t)&_bt_data_start, + .end = (intptr_t)&_bt_data_end, + .name = "BT Data", + }; + bt_area_t cont_data = { + .start = (intptr_t)&_bt_controller_data_start, + .end = (intptr_t)&_bt_controller_data_end, + .name = "BT Controller Data" + }; + + /* Start by freeing Bluetooth BSS section */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&bss, &cont_bss); } - return ESP_OK; + /* Do the same thing with the Bluetooth data section */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&data, &cont_data); + } +#endif + + return ret; } diff --git a/components/bt/controller/esp32c3/bt.c b/components/bt/controller/esp32c3/bt.c index 8f94c1e875ad..a9e839b444e6 100644 --- a/components/bt/controller/esp32c3/bt.c +++ b/components/bt/controller/esp32c3/bt.c @@ -263,16 +263,12 @@ extern void btdm_cca_feature_enable(void); 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 _nimble_bss_start; -extern uint32_t _nimble_bss_end; +extern uint32_t _bt_controller_bss_start; +extern uint32_t _bt_controller_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 uint32_t _nimble_data_start; -extern uint32_t _nimble_data_end; +extern uint32_t _bt_controller_data_start; +extern uint32_t _bt_controller_data_end; /* Local Function Declare ********************************************************************* @@ -984,145 +980,175 @@ static void btdm_controller_mem_init(void) btdm_controller_rom_data_init(); } -esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode) +/** + * Release two memory areas to the heap. If both areas are consecutive, they will be released as + * a single area. + */ +typedef struct { + intptr_t start; + intptr_t end; + const char* name; +} bt_area_t; + +static esp_err_t esp_bt_mem_release_area(const bt_area_t *area) { - intptr_t mem_start=(intptr_t) NULL, mem_end=(intptr_t) NULL; + esp_err_t ret = ESP_OK; + intptr_t mem_start = area->start; + intptr_t mem_end = area->end; + if (mem_start != mem_end) { + ESP_LOGD(BT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start); + ret = try_heap_caps_add_region(mem_start, mem_end); + } + return ret; +} + +static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2) +{ + esp_err_t ret = ESP_OK; + + if (area1->end == area2->start) { + bt_area_t merged_area = { + .start = area1->start, + .end = area2->end, + .name = area1->name + }; + ret = esp_bt_mem_release_area(&merged_area); + } else { + esp_bt_mem_release_area(area1); + ret = esp_bt_mem_release_area(area2); + } + + return ret; +} + +esp_err_t esp_bt_controller_rom_mem_release(esp_bt_mode_t mode) +{ + esp_err_t ret = ESP_OK; + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { return ESP_ERR_INVALID_STATE; } - if (mode & ESP_BT_MODE_BLE) { - /* if the addresses of rom btdm .data and .bss are consecutive, - they are registered in the system heap as a piece of memory - */ - if(ets_rom_layout_p->data_end_btdm == ets_rom_layout_p->bss_start_btdm) { - mem_start = (intptr_t)ets_rom_layout_p->data_start_btdm; - mem_end = (intptr_t)ets_rom_layout_p->bss_end_btdm; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release rom btdm [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - } else { - mem_start = (intptr_t)ets_rom_layout_p->bss_start_btdm; - mem_end = (intptr_t)ets_rom_layout_p->bss_end_btdm; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release rom btdm BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + bt_area_t rom_btdm_data = { + .start = (intptr_t) ets_rom_layout_p->data_start_btdm, + .end = (intptr_t) ets_rom_layout_p->data_end_btdm, + .name = "ROM btdm data", + }; + bt_area_t rom_btdm_bss = { + .start = (intptr_t)ets_rom_layout_p->bss_start_btdm, + .end = (intptr_t)ets_rom_layout_p->bss_end_btdm, + .name = "ROM btdm BSS", + }; + bt_area_t rom_btdm_inter_data = { + .start = (intptr_t) ets_rom_layout_p->data_start_interface_btdm, + .end = (intptr_t) ets_rom_layout_p->data_end_interface_btdm, + .name = "ROM interface btdm data", + }; + bt_area_t rom_btdm_inter_bss = { + .start = (intptr_t)ets_rom_layout_p->bss_start_interface_btdm, + .end = (intptr_t)ets_rom_layout_p->bss_end_interface_btdm, + .name = "ROM interface btdm BSS", + }; - mem_start = (intptr_t)ets_rom_layout_p->data_start_btdm; - mem_end = (intptr_t)ets_rom_layout_p->data_end_btdm; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release rom btdm Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + ret = ESP_ERR_INVALID_STATE; + } + + if (mode & ESP_BT_MODE_BLE) { + /* Free BTDM memory used by the ROM */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&rom_btdm_data, &rom_btdm_bss); } - /* if the addresses of rom interface btdm .data and .bss are consecutive, - they are registered in the system heap as a piece of memory - */ - if(ets_rom_layout_p->data_end_interface_btdm == ets_rom_layout_p->bss_start_interface_btdm) { - mem_start = (intptr_t)ets_rom_layout_p->data_start_interface_btdm; - mem_end = (intptr_t)ets_rom_layout_p->bss_end_interface_btdm; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release rom interface btdm [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - } else { - mem_start = (intptr_t)ets_rom_layout_p->data_start_interface_btdm; - mem_end = (intptr_t)ets_rom_layout_p->data_end_interface_btdm; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release rom interface btdm Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - mem_start = (intptr_t)ets_rom_layout_p->bss_start_interface_btdm; - mem_end = (intptr_t)ets_rom_layout_p->bss_end_interface_btdm; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release rom interface btdm BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&rom_btdm_inter_data, &rom_btdm_inter_bss); } + } + + return ret; +} + +esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode) +{ + esp_err_t ret = ESP_OK; + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return ESP_ERR_INVALID_STATE; } - return ESP_OK; + + bt_area_t cont_bss = { + .start = (intptr_t)&_bt_controller_bss_start, + .end = (intptr_t)&_bt_controller_bss_end, + .name = "BT Controller BSS", + }; + + bt_area_t cont_data = { + .start = (intptr_t)&_bt_controller_data_start, + .end = (intptr_t)&_bt_controller_data_end, + .name = "BT Controller Data" + }; + + if (mode & ESP_BT_MODE_BLE) { + /* free data and BSS section for libbtdm_app.a */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&cont_data, &cont_bss); + } + /* free data and BSS section for Bluetooth controller ROM code */ + if (ret == ESP_OK) { + ret = esp_bt_controller_rom_mem_release(mode); + } + } + + return ret; } esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) { - int ret; - intptr_t mem_start, mem_end; + esp_err_t ret = ESP_OK; - ret = esp_bt_controller_mem_release(mode); - if (ret != ESP_OK) { - return ret; + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return ESP_ERR_INVALID_STATE; } - if (mode & ESP_BT_MODE_BLE) { - /* if the addresses of btdm .bss and bt .bss are consecutive, - they are registered in the system heap as a piece of memory - */ - if(_bt_bss_end == _btdm_bss_start) { - mem_start = (intptr_t)&_bt_bss_start; - mem_end = (intptr_t)&_btdm_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - } else { - mem_start = (intptr_t)&_bt_bss_start; - mem_end = (intptr_t)&_bt_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release BT BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + bt_area_t bss = { + .start = (intptr_t)&_bt_bss_start, + .end = (intptr_t)&_bt_bss_end, + .name = "BT BSS", + }; + bt_area_t cont_bss = { + .start = (intptr_t)&_bt_controller_bss_start, + .end = (intptr_t)&_bt_controller_bss_end, + .name = "BT Controller BSS", + }; + bt_area_t data = { + .start = (intptr_t)&_bt_data_start, + .end = (intptr_t)&_bt_data_end, + .name = "BT Data", + }; + bt_area_t cont_data = { + .start = (intptr_t)&_bt_controller_data_start, + .end = (intptr_t)&_bt_controller_data_end, + .name = "BT Controller Data" + }; - mem_start = (intptr_t)&_btdm_bss_start; - mem_end = (intptr_t)&_btdm_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release BTDM BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + if (mode & ESP_BT_MODE_BLE) { + /* Start by freeing Bluetooth BSS section */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&bss, &cont_bss); } - /* if the addresses of btdm .data and bt .data are consecutive, - they are registered in the system heap as a piece of memory - */ - if(_bt_data_end == _btdm_data_start) { - mem_start = (intptr_t)&_bt_data_start; - mem_end = (intptr_t)&_btdm_data_end; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - } else { - mem_start = (intptr_t)&_bt_data_start; - mem_end = (intptr_t)&_bt_data_end; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release BT Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - mem_start = (intptr_t)&_btdm_data_start; - mem_end = (intptr_t)&_btdm_data_end; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release BTDM Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + /* Do the same thing with the Bluetooth data section */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&data, &cont_data); } - mem_start = (intptr_t)&_nimble_bss_start; - mem_end = (intptr_t)&_nimble_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release NimBLE BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - 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(BT_LOG_TAG, "Release NimBLE Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + /* free data and BSS section for Bluetooth controller ROM code */ + if (ret == ESP_OK) { + ret = esp_bt_controller_rom_mem_release(mode); } } - return ESP_OK; + + return ret; } static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end) diff --git a/components/bt/controller/esp32c6/bt.c b/components/bt/controller/esp32c6/bt.c index a9f9a3ba5b62..b00e135399fe 100644 --- a/components/bt/controller/esp32c6/bt.c +++ b/components/bt/controller/esp32c6/bt.c @@ -1003,70 +1003,86 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end) return ret; } + +typedef struct { + intptr_t start; + intptr_t end; + const char* name; +} bt_area_t; + +static esp_err_t esp_bt_mem_release_area(const bt_area_t *area) +{ + esp_err_t ret = ESP_OK; + intptr_t mem_start = area->start; + intptr_t mem_end = area->end; + if (mem_start != mem_end) { + ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start); + ret = try_heap_caps_add_region(mem_start, mem_end); + } + return ret; +} + +static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2) +{ + esp_err_t ret = ESP_OK; + + if (area1->end == area2->start) { + bt_area_t merged_area = { + .start = area1->start, + .end = area2->end, + .name = area1->name + }; + ret = esp_bt_mem_release_area(&merged_area); + } else { + esp_bt_mem_release_area(area1); + ret = esp_bt_mem_release_area(area2); + } + + return ret; +} + esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) { - intptr_t mem_start, mem_end; + esp_err_t ret = ESP_OK; - if (mode & ESP_BT_MODE_BLE) { - /* If the addresses of btdm .bss and bt .bss are consecutive, - * they are registered in the system heap as a piece of memory - */ - if(_bt_bss_end == _bt_controller_bss_start) { - mem_start = (intptr_t)&_bt_bss_start; - mem_end = (intptr_t)&_bt_controller_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release BSS [0x%08x] - [0x%08x], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - } else { - mem_start = (intptr_t)&_bt_bss_start; - mem_end = (intptr_t)&_bt_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release BT BSS [0x%08x] - [0x%08x], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return ESP_ERR_INVALID_STATE; + } - mem_start = (intptr_t)&_bt_controller_bss_start; - mem_end = (intptr_t)&_bt_controller_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release Controller BSS [0x%08x] - [0x%08x], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + bt_area_t bss = { + .start = (intptr_t)&_bt_bss_start, + .end = (intptr_t)&_bt_bss_end, + .name = "BT BSS", + }; + bt_area_t cont_bss = { + .start = (intptr_t)&_bt_controller_bss_start, + .end = (intptr_t)&_bt_controller_bss_end, + .name = "BT Controller BSS", + }; + bt_area_t data = { + .start = (intptr_t)&_bt_data_start, + .end = (intptr_t)&_bt_data_end, + .name = "BT Data", + }; + bt_area_t cont_data = { + .start = (intptr_t)&_bt_controller_data_start, + .end = (intptr_t)&_bt_controller_data_end, + .name = "BT Controller Data" + }; + + if (mode & ESP_BT_MODE_BLE) { + /* Start by freeing Bluetooth BSS section */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&bss, &cont_bss); } - /* If the addresses of btdm .data and bt .data are consecutive, - * they are registered in the system heap as a piece of memory - */ - if(_bt_data_end == _bt_controller_data_start) { - mem_start = (intptr_t)&_bt_data_start; - mem_end = (intptr_t)&_bt_controller_data_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release data [0x%08x] - [0x%08x], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - } else { - 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], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - mem_start = (intptr_t)&_bt_controller_data_start; - mem_end = (intptr_t)&_bt_controller_data_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release Controller Data [0x%08x] - [0x%08x], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + /* Do the same thing with the Bluetooth data section */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&data, &cont_data); } } - return ESP_OK; + return ret; } diff --git a/components/bt/controller/esp32h2/bt.c b/components/bt/controller/esp32h2/bt.c index aecc3b2ab844..b4557e815362 100644 --- a/components/bt/controller/esp32h2/bt.c +++ b/components/bt/controller/esp32h2/bt.c @@ -976,70 +976,86 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end) return ret; } + +typedef struct { + intptr_t start; + intptr_t end; + const char* name; +} bt_area_t; + +static esp_err_t esp_bt_mem_release_area(const bt_area_t *area) +{ + esp_err_t ret = ESP_OK; + intptr_t mem_start = area->start; + intptr_t mem_end = area->end; + if (mem_start != mem_end) { + ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start); + ret = try_heap_caps_add_region(mem_start, mem_end); + } + return ret; +} + +static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2) +{ + esp_err_t ret = ESP_OK; + + if (area1->end == area2->start) { + bt_area_t merged_area = { + .start = area1->start, + .end = area2->end, + .name = area1->name + }; + ret = esp_bt_mem_release_area(&merged_area); + } else { + esp_bt_mem_release_area(area1); + ret = esp_bt_mem_release_area(area2); + } + + return ret; +} + esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) { - intptr_t mem_start, mem_end; + esp_err_t ret = ESP_OK; + + if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return ESP_ERR_INVALID_STATE; + } + + bt_area_t bss = { + .start = (intptr_t)&_bt_bss_start, + .end = (intptr_t)&_bt_bss_end, + .name = "BT BSS", + }; + bt_area_t cont_bss = { + .start = (intptr_t)&_bt_controller_bss_start, + .end = (intptr_t)&_bt_controller_bss_end, + .name = "BT Controller BSS", + }; + bt_area_t data = { + .start = (intptr_t)&_bt_data_start, + .end = (intptr_t)&_bt_data_end, + .name = "BT Data", + }; + bt_area_t cont_data = { + .start = (intptr_t)&_bt_controller_data_start, + .end = (intptr_t)&_bt_controller_data_end, + .name = "BT Controller Data" + }; if (mode & ESP_BT_MODE_BLE) { - /* If the addresses of btdm .bss and bt .bss are consecutive, - * they are registered in the system heap as a piece of memory - */ - if(_bt_bss_end == _bt_controller_bss_start) { - mem_start = (intptr_t)&_bt_bss_start; - mem_end = (intptr_t)&_bt_controller_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release BSS [0x%08x] - [0x%08x], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - } else { - mem_start = (intptr_t)&_bt_bss_start; - mem_end = (intptr_t)&_bt_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release BT BSS [0x%08x] - [0x%08x], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - - mem_start = (intptr_t)&_bt_controller_bss_start; - mem_end = (intptr_t)&_bt_controller_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release Controller BSS [0x%08x] - [0x%08x], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + /* Start by freeing Bluetooth BSS section */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&bss, &cont_bss); } - /* If the addresses of btdm .data and bt .data are consecutive, - * they are registered in the system heap as a piece of memory - */ - if(_bt_data_end == _bt_controller_data_start) { - mem_start = (intptr_t)&_bt_data_start; - mem_end = (intptr_t)&_bt_controller_data_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release data [0x%08x] - [0x%08x], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - } else { - 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], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - - mem_start = (intptr_t)&_bt_controller_data_start; - mem_end = (intptr_t)&_bt_controller_data_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release Controller Data [0x%08x] - [0x%08x], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + + /* Do the same thing with the Bluetooth data section */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&data, &cont_data); } } - return ESP_OK; + return ret; } diff --git a/components/bt/linker.lf b/components/bt/linker.lf deleted file mode 100644 index debff10af3ee..000000000000 --- a/components/bt/linker.lf +++ /dev/null @@ -1,57 +0,0 @@ -[sections:bt_bss] -entries: - .bss+ - -[sections:bt_common] -entries: - COMMON - -[scheme:bt_start_end] -entries: - bt_bss -> dram0_bss - bt_common -> dram0_bss - data -> dram0_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: - if ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y: - * (extram_bss) - else: - * (bt_start_end); - bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_bss), - bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_common), - data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_data) - -[mapping:btdm] -archive: libbtdm_app.a -entries: - * (bt_start_end); - bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(btdm_bss), - bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(btdm_common), - data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(btdm_data) - -[mapping:bt_controller] -archive: libble_app.a -entries: - * (bt_start_end); - bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_bss), - bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_common), - data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_data) - -[mapping:nimble] -archive: libnimble.a -entries: - * (bt_start_end); - bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(nimble_bss), - bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(nimble_common), - data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(nimble_data) diff --git a/components/bt/linker_common.lf b/components/bt/linker_common.lf new file mode 100644 index 000000000000..501acd950542 --- /dev/null +++ b/components/bt/linker_common.lf @@ -0,0 +1,42 @@ +[sections:bt_bss] +entries: + .bss+ + +[sections:bt_common] +entries: + COMMON + +[scheme:bt_default] +entries: + bt_bss -> dram0_bss + bt_common -> dram0_bss + data -> dram0_data + +[scheme:bt_extram_bss] +entries: + bt_bss -> extern_ram + bt_common -> extern_ram + data -> dram0_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: + if ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y: + * (bt_extram_bss); + bt_bss -> extern_ram ALIGN(4) ALIGN(4, post) SURROUND(bt_bss), + bt_common -> extern_ram ALIGN(4) ALIGN(4, post) SURROUND(bt_common), + data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_data) + else: + * (bt_default); + bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_bss), + bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_common), + data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_data) diff --git a/components/bt/linker.lf.esp32c2 b/components/bt/linker_esp32c2.lf similarity index 66% rename from components/bt/linker.lf.esp32c2 rename to components/bt/linker_esp32c2.lf index 40d8a5630330..7178420a00a0 100644 --- a/components/bt/linker.lf.esp32c2 +++ b/components/bt/linker_esp32c2.lf @@ -1,4 +1,4 @@ -[sections:bt_text] +[sections:bt_iram_text] entries: .iram1+ @@ -17,9 +17,9 @@ entries: entries: COMMON -[scheme:bt_start_end] +[scheme:bt_default] entries: - bt_text -> iram0_bt_text + bt_iram_text -> iram0_bt_text bt_bss -> dram0_bt_bss bt_common -> dram0_bt_bss bt_data -> dram0_bt_data @@ -36,25 +36,15 @@ entries: [mapping:bt] archive: libbt.a entries: - * (bt_start_end); + * (bt_default); 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] +[mapping:ble_app] archive: libble_app.a entries: - * (bt_start_end); + * (bt_default); 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) diff --git a/components/bt/linker_esp_ble_controller.lf b/components/bt/linker_esp_ble_controller.lf new file mode 100644 index 000000000000..fe8598112bed --- /dev/null +++ b/components/bt/linker_esp_ble_controller.lf @@ -0,0 +1,7 @@ +[mapping:ble_app] +archive: libble_app.a +entries: + * (bt_default); + bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_bss), + bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_common), + data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_data) diff --git a/components/bt/linker_rw_bt_controller.lf b/components/bt/linker_rw_bt_controller.lf new file mode 100644 index 000000000000..083d6e90b799 --- /dev/null +++ b/components/bt/linker_rw_bt_controller.lf @@ -0,0 +1,7 @@ +[mapping:btdm] +archive: libbtdm_app.a +entries: + * (bt_default); + bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_bss), + bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_common), + data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_data) diff --git a/components/bt/test_apps/.build-test-rules.yml b/components/bt/test_apps/.build-test-rules.yml index f96777d2dabc..9b434736336d 100644 --- a/components/bt/test_apps/.build-test-rules.yml +++ b/components/bt/test_apps/.build-test-rules.yml @@ -1,8 +1,17 @@ # Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps -components/bt/test_apps: +components/bt/test_apps/basic_unit_test: disable: - if: IDF_TARGET not in ["esp32", "esp32c3"] reason: Sufficient to run the tests on one chip of each architecture depends_components: - bt + +components/bt/test_apps/memory_release: + disable: + - if: IDF_TARGET not in ["esp32", "esp32c2"] + - if: CONFIG_NAME == "iram" and IDF_TARGET != "esp32c2" + - if: CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1 + reason: Sufficient to run the tests on one chip of each architecture + depends_components: + - bt diff --git a/components/bt/test_apps/CMakeLists.txt b/components/bt/test_apps/basic_unit_test/CMakeLists.txt similarity index 100% rename from components/bt/test_apps/CMakeLists.txt rename to components/bt/test_apps/basic_unit_test/CMakeLists.txt diff --git a/components/bt/test_apps/README.md b/components/bt/test_apps/basic_unit_test/README.md similarity index 100% rename from components/bt/test_apps/README.md rename to components/bt/test_apps/basic_unit_test/README.md diff --git a/components/bt/test_apps/main/CMakeLists.txt b/components/bt/test_apps/basic_unit_test/main/CMakeLists.txt similarity index 100% rename from components/bt/test_apps/main/CMakeLists.txt rename to components/bt/test_apps/basic_unit_test/main/CMakeLists.txt diff --git a/components/bt/test_apps/main/test_bt_common.c b/components/bt/test_apps/basic_unit_test/main/test_bt_common.c similarity index 100% rename from components/bt/test_apps/main/test_bt_common.c rename to components/bt/test_apps/basic_unit_test/main/test_bt_common.c diff --git a/components/bt/test_apps/main/test_bt_main.c b/components/bt/test_apps/basic_unit_test/main/test_bt_main.c similarity index 100% rename from components/bt/test_apps/main/test_bt_main.c rename to components/bt/test_apps/basic_unit_test/main/test_bt_main.c diff --git a/components/bt/test_apps/main/test_smp.c b/components/bt/test_apps/basic_unit_test/main/test_smp.c similarity index 100% rename from components/bt/test_apps/main/test_smp.c rename to components/bt/test_apps/basic_unit_test/main/test_smp.c diff --git a/components/bt/test_apps/pytest_bt.py b/components/bt/test_apps/basic_unit_test/pytest_basic_unit_test.py similarity index 77% rename from components/bt/test_apps/pytest_bt.py rename to components/bt/test_apps/basic_unit_test/pytest_basic_unit_test.py index 74b0a76afc77..de3d235bb52e 100644 --- a/components/bt/test_apps/pytest_bt.py +++ b/components/bt/test_apps/basic_unit_test/pytest_basic_unit_test.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut diff --git a/components/bt/test_apps/sdkconfig.defaults b/components/bt/test_apps/basic_unit_test/sdkconfig.defaults similarity index 61% rename from components/bt/test_apps/sdkconfig.defaults rename to components/bt/test_apps/basic_unit_test/sdkconfig.defaults index 5847dd3c63f5..dc2d7ca08b55 100644 --- a/components/bt/test_apps/sdkconfig.defaults +++ b/components/bt/test_apps/basic_unit_test/sdkconfig.defaults @@ -1,3 +1,2 @@ CONFIG_BT_ENABLED=y -CONFIG_UNITY_FREERTOS_STACK_SIZE=12288 CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=n diff --git a/components/bt/test_apps/memory_release/CMakeLists.txt b/components/bt/test_apps/memory_release/CMakeLists.txt new file mode 100644 index 000000000000..f3d75bb43586 --- /dev/null +++ b/components/bt/test_apps/memory_release/CMakeLists.txt @@ -0,0 +1,5 @@ +# This is the project CMakeLists.txt file for the test subproject +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(test_bt_memory_release) diff --git a/components/bt/test_apps/memory_release/README.md b/components/bt/test_apps/memory_release/README.md new file mode 100644 index 000000000000..2975ce8f21cb --- /dev/null +++ b/components/bt/test_apps/memory_release/README.md @@ -0,0 +1,4 @@ +| Supported Targets | ESP32 | ESP32-C2 | +| ----------------- | ----- | -------- | + +This test app is used to test esp_bt_memory_release function diff --git a/components/bt/test_apps/memory_release/main/CMakeLists.txt b/components/bt/test_apps/memory_release/main/CMakeLists.txt new file mode 100644 index 000000000000..660eb5875dd2 --- /dev/null +++ b/components/bt/test_apps/memory_release/main/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "test_app_main.c" + INCLUDE_DIRS "." + PRIV_REQUIRES bt nvs_flash) diff --git a/components/bt/test_apps/memory_release/main/test_app_main.c b/components/bt/test_apps/memory_release/main/test_app_main.c new file mode 100644 index 000000000000..562d1d97ddd6 --- /dev/null +++ b/components/bt/test_apps/memory_release/main/test_app_main.c @@ -0,0 +1,131 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include + +#include "esp_log.h" +#include "nvs_flash.h" + +#include "multi_heap.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include "esp_bt.h" +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" +#include "host/ble_hs.h" +#include "host/util/util.h" +#include "services/gap/ble_svc_gap.h" + +#define FAIL() do { printf("FAILURE\n"); return; } while(0) + +extern uint8_t _bt_bss_start; +extern uint8_t _bt_bss_end; +extern uint8_t _bt_controller_bss_start; +extern uint8_t _bt_controller_bss_end; + +extern void ble_store_config_init(void); + +static const char *tag = "MEM_RELEASE_APP"; + +static void nimble_host_on_reset(int reason) +{ + ESP_LOGI(tag, "Resetting state; reason=%d", reason); +} + +static void nimble_host_on_sync(void) +{ + ESP_LOGI(tag, "NimBLE host synchronized"); +} + +static void nimble_host_task_fn(void *param) +{ + ESP_LOGI(tag, "BLE Host Task Started"); + /* This function will return only when nimble_port_stop() is executed */ + nimble_port_run(); + + nimble_port_freertos_deinit(); +} + +static void bt_stack_init(void) +{ + esp_err_t ret = nimble_port_init(); + ESP_ERROR_CHECK(ret); + + /* Initialize the NimBLE host configuration. */ + ble_hs_cfg.reset_cb = nimble_host_on_reset; + ble_hs_cfg.sync_cb = nimble_host_on_sync; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + /* Set the default device name. */ + int rc = ble_svc_gap_device_name_set(tag); + assert(rc == 0); + + /* XXX Need to have template for store */ + ble_store_config_init(); + + nimble_port_freertos_init(nimble_host_task_fn); +} + +static void bt_stack_deinit(void) +{ + int rc = nimble_port_stop(); + assert(rc == 0); + + nimble_port_deinit(); + ESP_LOGI(tag, "BLE Host Task Stopped"); +} + +void app_main(void) +{ + esp_err_t ret = ESP_OK; + + /* Initialize NVS — it is used to store PHY calibration data */ + ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + + /* initialize and then deinitialize bluetooth stack */ + bt_stack_init(); + + vTaskDelay(pdMS_TO_TICKS(200)); + + bt_stack_deinit(); + + /* Get the size of heap located in external RAM */ + const uint32_t free_before = heap_caps_get_free_size(MALLOC_CAP_DEFAULT); + ESP_LOGI(tag, "Free size in external RAM heap: %"PRIu32, free_before); + + /* Make sure at least one of the Bluetooth BSS section that can be used as a heap */ + const uint32_t heap_size = sizeof(multi_heap_info_t); + const uint32_t bt_bss_size = &_bt_bss_end - &_bt_bss_start; + const uint32_t bt_ctrl_bss_size = &_bt_controller_bss_end - &_bt_controller_bss_start; + + ESP_LOGI(tag, "bt_bss_size %"PRIu32", bt_ctrl_bss_size %"PRIu32, bt_bss_size, bt_ctrl_bss_size); + if (bt_bss_size < heap_size && bt_ctrl_bss_size < heap_size) + { + ESP_LOGW(tag, "Bluetooth BSS sections are too small!"); + FAIL(); + } + + /* Release the BSS sections to use them as heap */ + ret = esp_bt_mem_release(ESP_BT_MODE_BTDM); + ESP_ERROR_CHECK(ret); + + /* Check that we have more available memory in the external RAM heap */ + const uint32_t free_after = heap_caps_get_free_size(MALLOC_CAP_DEFAULT); + ESP_LOGI(tag, "Free size in external RAM after releasing: %"PRIu32, free_after); + if (free_after <= free_before) { + FAIL(); + } + ESP_LOGI(tag, "Free heap size increased by %"PRIu32" bytes", free_after - free_before); + + ESP_LOGI(tag, "SUCCESS"); +} diff --git a/components/bt/test_apps/memory_release/pytest_memory_release.py b/components/bt/test_apps/memory_release/pytest_memory_release.py new file mode 100644 index 000000000000..dbefc908a63c --- /dev/null +++ b/components/bt/test_apps/memory_release/pytest_memory_release.py @@ -0,0 +1,15 @@ +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 +import pytest +from pytest_embedded import Dut + + +@pytest.mark.parametrize('config', [ + pytest.param('default', marks=[pytest.mark.esp32, pytest.mark.esp32c2, pytest.mark.generic]), + pytest.param('iram', marks=[pytest.mark.esp32c2, pytest.mark.generic]), + pytest.param('psram', marks=[pytest.mark.esp32, pytest.mark.psram]), +], indirect=True) +def test_bt_memory_release(dut: Dut) -> None: + dut.expect_exact('BLE Host Task Started', timeout=6) + dut.expect_exact('BLE Host Task Stopped', timeout=8) + dut.expect_exact('SUCCESS', timeout=10) diff --git a/components/bt/test_apps/memory_release/sdkconfig.ci.iram b/components/bt/test_apps/memory_release/sdkconfig.ci.iram new file mode 100644 index 000000000000..36e7ceb92a90 --- /dev/null +++ b/components/bt/test_apps/memory_release/sdkconfig.ci.iram @@ -0,0 +1,2 @@ +CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT=n +CONFIG_BT_RELEASE_IRAM=y diff --git a/components/bt/test_apps/memory_release/sdkconfig.ci.psram b/components/bt/test_apps/memory_release/sdkconfig.ci.psram new file mode 100644 index 000000000000..4090a49eafab --- /dev/null +++ b/components/bt/test_apps/memory_release/sdkconfig.ci.psram @@ -0,0 +1,2 @@ +CONFIG_SPIRAM=y +CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y diff --git a/components/bt/test_apps/memory_release/sdkconfig.defaults b/components/bt/test_apps/memory_release/sdkconfig.defaults new file mode 100644 index 000000000000..a22d8109d7d5 --- /dev/null +++ b/components/bt/test_apps/memory_release/sdkconfig.defaults @@ -0,0 +1,2 @@ +CONFIG_BT_ENABLED=y +CONFIG_BT_NIMBLE_ENABLED=y