From a06844d9b17e1b45e4cac11e293d5bee4d735621 Mon Sep 17 00:00:00 2001 From: Wang Mengyang Date: Wed, 20 Mar 2024 14:45:09 +0800 Subject: [PATCH 1/4] fix(bt): Fix missing linker symbol when ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY enabled 1. Closes https://github.com/espressif/esp-idf/issues/10427 2. add two linker script to unify linker script symbols for BT libraries 3. The memory release functions have also been simplified --- components/bt/CMakeLists.txt | 13 +- components/bt/controller/esp32/bt.c | 68 +++-- components/bt/controller/esp32c2/bt.c | 108 ++++++-- components/bt/controller/esp32c3/bt.c | 234 ++++++++---------- components/bt/controller/esp32c6/bt.c | 128 +++++----- components/bt/controller/esp32h2/bt.c | 126 +++++----- components/bt/linker.lf | 57 ----- components/bt/linker_common.lf | 36 +++ ...er.lf.esp32c2 => linker_common_esp32c2.lf} | 18 -- components/bt/linker_esp_ble_controller.lf | 7 + components/bt/linker_rw_bt_controller.lf | 7 + 11 files changed, 439 insertions(+), 363 deletions(-) delete mode 100644 components/bt/linker.lf create mode 100644 components/bt/linker_common.lf rename components/bt/{linker.lf.esp32c2 => linker_common_esp32c2.lf} (53%) create mode 100644 components/bt/linker_esp_ble_controller.lf create mode 100644 components/bt/linker_rw_bt_controller.lf diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index 5241178673..1d80d615c6 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -72,32 +72,37 @@ 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_common_esp32c2.lf") + list(APPEND ldscripts "linker_esp_ble_controller.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 +825,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 10604e9d98..b2e3b281f4 100644 --- a/components/bt/controller/esp32/bt.c +++ b/components/bt/controller/esp32/bt.c @@ -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); @@ -1281,6 +1277,25 @@ 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(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; +} + esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode) { bool update = true; @@ -1333,19 +1348,20 @@ esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode) } 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" + }; + esp_bt_mem_release_area(&cont_bss); + esp_bt_mem_release_area(&cont_data); } + return ESP_OK; } @@ -1373,16 +1389,16 @@ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) 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; + mem_start = (intptr_t)&_bt_controller_bss_start; + mem_end = (intptr_t)&_bt_controller_bss_end; if (mem_start != mem_end) { - ESP_LOGD(BTDM_LOG_TAG, "Release NimBLE BSS [0x%08x] - [0x%08x]", mem_start, mem_end); + ESP_LOGD(BTDM_LOG_TAG, "Release Controller 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; + mem_start = (intptr_t)&_bt_controller_data_start; + mem_end = (intptr_t)&_bt_controller_data_end; if (mem_start != mem_end) { - ESP_LOGD(BTDM_LOG_TAG, "Release NimBLE Data [0x%08x] - [0x%08x]", mem_start, mem_end); + ESP_LOGD(BTDM_LOG_TAG, "Release Controller Data [0x%08x] - [0x%08x]", mem_start, mem_end); ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); } } diff --git a/components/bt/controller/esp32c2/bt.c b/components/bt/controller/esp32c2/bt.c index ae699b380f..454387610d 100644 --- a/components/bt/controller/esp32c2/bt.c +++ b/components/bt/controller/esp32c2/bt.c @@ -168,11 +168,17 @@ 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 -extern uint32_t _bt_bss_end; -extern uint32_t _bt_controller_data_start; #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; +extern uint32_t _bt_controller_data_end; + /* Local Function Declaration ********************************************************************* */ @@ -900,9 +906,46 @@ 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 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 @@ -915,22 +958,51 @@ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) assert(0); #endif // CONFIG_BT_RELEASE_IRAM && CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT - if (mode & ESP_BT_MODE_BLE) { -#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; -#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)); - } + if ((mode & ESP_BT_MODE_BLE) == 0) { + return ret; } - return ESP_OK; +#if CONFIG_BT_RELEASE_IRAM + 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 + 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); + } + + /* 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 8f94c1e875..550bd6fd93 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,131 @@ static void btdm_controller_mem_init(void) btdm_controller_rom_data_init(); } +/** + * 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_areas(const bt_area_t* area1, const bt_area_t* area2) +{ + esp_err_t ret = ESP_OK; + intptr_t mem_start = 0; + intptr_t mem_end = 0; + + if(area1->end == area2->start) { + mem_start = area1->start; + mem_end = area2->end; + if (mem_start != mem_end) { + ESP_LOGD(BT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area1->name, mem_start, mem_end, mem_end - mem_start); + ret = try_heap_caps_add_region(mem_start, mem_end); + } + } else { + mem_start = area1->start; + mem_end = area1->end; + if (mem_start != mem_end) { + ESP_LOGD(BT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area1->name, mem_start, mem_end, mem_end - mem_start); + ret = try_heap_caps_add_region(mem_start, mem_end); + } + + mem_start = area2->start; + mem_end = area2->end; + if (ret == ESP_OK && mem_start != mem_end) { + ESP_LOGD(BT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area2->name, mem_start, mem_end, mem_end - mem_start); + ret = try_heap_caps_add_region(mem_start, mem_end); + } + } + + return ret; +} + + esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode) { - intptr_t mem_start=(intptr_t) NULL, mem_end=(intptr_t) NULL; + esp_err_t ret = ESP_OK; + 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", + }; + + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { - return ESP_ERR_INVALID_STATE; + ret = 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)); - } - - 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 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)); - } + /* Free BTDM memory used by the ROM */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&rom_btdm_data, &rom_btdm_bss); } + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&rom_btdm_inter_data, &rom_btdm_inter_bss); + } } - return ESP_OK; + + 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; + 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" + }; ret = esp_bt_controller_mem_release(mode); - if (ret != ESP_OK) { - return ret; - } 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)); - } - - 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 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)); - } + /* 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(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)); + /* 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; } 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 a9f9a3ba5b..cd5ece61ec 100644 --- a/components/bt/controller/esp32c6/bt.c +++ b/components/bt/controller/esp32c6/bt.c @@ -1003,70 +1003,84 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end) return ret; } -esp_err_t esp_bt_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_areas(const bt_area_t* area1, const bt_area_t* area2) { - intptr_t mem_start, mem_end; + esp_err_t ret = ESP_OK; + intptr_t mem_start = 0; + intptr_t mem_end = 0; - 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)); - } + if(area1->end == area2->start) { + mem_start = area1->start; + mem_end = area2->end; + if (mem_start != mem_end) { + ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area1->name, mem_start, mem_end, mem_end - mem_start); + ret = try_heap_caps_add_region(mem_start, mem_end); + } + } else { + mem_start = area1->start; + mem_end = area1->end; + if (mem_start != mem_end) { + ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area1->name, mem_start, mem_end, mem_end - mem_start); + ret = try_heap_caps_add_region(mem_start, mem_end); } - /* 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)); - } + mem_start = area2->start; + mem_end = area2->end; + if (ret == ESP_OK && mem_start != mem_end) { + ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area2->name, mem_start, mem_end, mem_end - mem_start); + ret = try_heap_caps_add_region(mem_start, mem_end); } } - return ESP_OK; + return ret; +} + + +esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) +{ + esp_err_t ret = ESP_OK; + 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); + } + + /* Do the same thing with the Bluetooth data section */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&data, &cont_data); + } + } + + return ret; } diff --git a/components/bt/controller/esp32h2/bt.c b/components/bt/controller/esp32h2/bt.c index aecc3b2ab8..5ec52e5b46 100644 --- a/components/bt/controller/esp32h2/bt.c +++ b/components/bt/controller/esp32h2/bt.c @@ -976,70 +976,82 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end) return ret; } -esp_err_t esp_bt_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_areas(const bt_area_t* area1, const bt_area_t* area2) { - intptr_t mem_start, mem_end; + esp_err_t ret = ESP_OK; + intptr_t mem_start = 0; + intptr_t mem_end = 0; - 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)); - } + if(area1->end == area2->start) { + mem_start = area1->start; + mem_end = area2->end; + if (mem_start != mem_end) { + ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area1->name, mem_start, mem_end, mem_end - mem_start); + ret = try_heap_caps_add_region(mem_start, mem_end); + } + } else { + mem_start = area1->start; + mem_end = area1->end; + if (mem_start != mem_end) { + ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area1->name, mem_start, mem_end, mem_end - mem_start); + ret = try_heap_caps_add_region(mem_start, mem_end); } - /* 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)); - } + mem_start = area2->start; + mem_end = area2->end; + if (ret == ESP_OK && mem_start != mem_end) { + ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area2->name, mem_start, mem_end, mem_end - mem_start); + ret = try_heap_caps_add_region(mem_start, mem_end); } } - return ESP_OK; + return ret; +} + +esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) +{ + esp_err_t ret = ESP_OK; + 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); + } + + /* Do the same thing with the Bluetooth data section */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&data, &cont_data); + } + } + + return ret; } diff --git a/components/bt/linker.lf b/components/bt/linker.lf deleted file mode 100644 index debff10af3..0000000000 --- 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 0000000000..af38b5af11 --- /dev/null +++ b/components/bt/linker_common.lf @@ -0,0 +1,36 @@ +[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 + +[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: + * (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) diff --git a/components/bt/linker.lf.esp32c2 b/components/bt/linker_common_esp32c2.lf similarity index 53% rename from components/bt/linker.lf.esp32c2 rename to components/bt/linker_common_esp32c2.lf index 40d8a56303..2fb68d6850 100644 --- a/components/bt/linker.lf.esp32c2 +++ b/components/bt/linker_common_esp32c2.lf @@ -40,21 +40,3 @@ entries: 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) diff --git a/components/bt/linker_esp_ble_controller.lf b/components/bt/linker_esp_ble_controller.lf new file mode 100644 index 0000000000..e5b8590988 --- /dev/null +++ b/components/bt/linker_esp_ble_controller.lf @@ -0,0 +1,7 @@ +[mapping:ble_app] +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) diff --git a/components/bt/linker_rw_bt_controller.lf b/components/bt/linker_rw_bt_controller.lf new file mode 100644 index 0000000000..3b19bdbe24 --- /dev/null +++ b/components/bt/linker_rw_bt_controller.lf @@ -0,0 +1,7 @@ +[mapping:btdm] +archive: libbtdm_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) From bb6cf16177c93b3e608770e288e9d738d4764ac1 Mon Sep 17 00:00:00 2001 From: Wang Mengyang Date: Wed, 20 Mar 2024 19:27:43 +0800 Subject: [PATCH 2/4] change(bt): Rename linker script file names and symbol names 1. rename linker files 2. support memory release in case that ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY is enabled 3. improve the implementation of memory release --- components/bt/CMakeLists.txt | 4 +- components/bt/controller/esp32/bt.c | 115 ++++++++++++------ components/bt/controller/esp32c2/bt.c | 13 +- components/bt/controller/esp32c3/bt.c | 100 ++++++++++----- components/bt/controller/esp32c6/bt.c | 52 ++++---- components/bt/controller/esp32h2/bt.c | 50 ++++---- components/bt/linker_common.lf | 16 ++- ...er_common_esp32c2.lf => linker_esp32c2.lf} | 16 ++- components/bt/linker_esp_ble_controller.lf | 2 +- components/bt/linker_rw_bt_controller.lf | 2 +- 10 files changed, 240 insertions(+), 130 deletions(-) rename components/bt/{linker_common_esp32c2.lf => linker_esp32c2.lf} (62%) diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index 1d80d615c6..6a87a3e177 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -67,7 +67,6 @@ if(CONFIG_IDF_DOC_BUILD) ${nimble_hci_include_dirs}) endif() - if(CONFIG_BT_ENABLED) set(srcs "") @@ -90,8 +89,7 @@ if(CONFIG_BT_ENABLED) elseif(CONFIG_IDF_TARGET_ESP32C2) list(APPEND srcs "controller/esp32c2/bt.c") - set(ldscripts "linker_common_esp32c2.lf") - list(APPEND ldscripts "linker_esp_ble_controller.lf") + set(ldscripts "linker_esp32c2.lf") elseif(CONFIG_IDF_TARGET_ESP32C6) list(APPEND srcs "controller/esp32c6/bt.c") diff --git a/components/bt/controller/esp32/bt.c b/components/bt/controller/esp32/bt.c index b2e3b281f4..f2489b837a 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 */ @@ -756,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. @@ -1296,7 +1296,26 @@ static esp_err_t esp_bt_mem_release_area(const bt_area_t *area) return ret; } -esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode) +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; @@ -1347,6 +1366,17 @@ 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) { bt_area_t cont_bss = { .start = (intptr_t)&_bt_controller_bss_start, @@ -1358,51 +1388,64 @@ esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode) .end = (intptr_t)&_bt_controller_data_end, .name = "BT Controller Data" }; - esp_bt_mem_release_area(&cont_bss); - esp_bt_mem_release_area(&cont_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)&_bt_controller_bss_start; - mem_end = (intptr_t)&_bt_controller_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(BTDM_LOG_TAG, "Release Controller 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_controller_data_start; - mem_end = (intptr_t)&_bt_controller_data_end; - if (mem_start != mem_end) { - ESP_LOGD(BTDM_LOG_TAG, "Release Controller 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 @@ -1711,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); @@ -1874,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 454387610d..b89e953599 100644 --- a/components/bt/controller/esp32c2/bt.c +++ b/components/bt/controller/esp32c2/bt.c @@ -924,6 +924,7 @@ static esp_err_t esp_bt_mem_release_area(const bt_area_t *area) 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; @@ -942,6 +943,7 @@ static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_ return ret; } +#endif esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) { @@ -954,18 +956,21 @@ 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 (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 bt_area_t merged_region = { - .start = (intptr_t)MAP_IRAM_TO_DRAM((intptr_t)&_iram_bt_text_start); - .end = (intptr_t)&_bss_bt_end; + .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); diff --git a/components/bt/controller/esp32c3/bt.c b/components/bt/controller/esp32c3/bt.c index 550bd6fd93..a9e839b444 100644 --- a/components/bt/controller/esp32c3/bt.c +++ b/components/bt/controller/esp32c3/bt.c @@ -990,42 +990,45 @@ typedef struct { const char* name; } bt_area_t; -static esp_err_t esp_bt_mem_release_areas(const bt_area_t* area1, const bt_area_t* area2) +static esp_err_t esp_bt_mem_release_area(const bt_area_t *area) { esp_err_t ret = ESP_OK; - intptr_t mem_start = 0; - intptr_t mem_end = 0; + 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; +} - if(area1->end == area2->start) { - mem_start = area1->start; - mem_end = area2->end; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area1->name, mem_start, mem_end, mem_end - mem_start); - ret = try_heap_caps_add_region(mem_start, mem_end); - } +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 { - mem_start = area1->start; - mem_end = area1->end; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area1->name, mem_start, mem_end, mem_end - mem_start); - ret = try_heap_caps_add_region(mem_start, mem_end); - } - - mem_start = area2->start; - mem_end = area2->end; - if (ret == ESP_OK && mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area2->name, mem_start, mem_end, mem_end - mem_start); - ret = try_heap_caps_add_region(mem_start, mem_end); - } + esp_bt_mem_release_area(area1); + ret = esp_bt_mem_release_area(area2); } return ret; } - -esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode) +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; + } + 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, @@ -1047,7 +1050,6 @@ esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode) .name = "ROM interface btdm BSS", }; - if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { ret = ESP_ERR_INVALID_STATE; } @@ -1066,9 +1068,48 @@ esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode) 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; + } + + 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) { esp_err_t ret = ESP_OK; + + 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, @@ -1090,8 +1131,6 @@ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) .name = "BT Controller Data" }; - ret = esp_bt_controller_mem_release(mode); - if (mode & ESP_BT_MODE_BLE) { /* Start by freeing Bluetooth BSS section */ if (ret == ESP_OK) { @@ -1102,6 +1141,11 @@ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) if (ret == ESP_OK) { ret = esp_bt_mem_release_areas(&data, &cont_data); } + + /* free data and BSS section for Bluetooth controller ROM code */ + if (ret == ESP_OK) { + ret = esp_bt_controller_rom_mem_release(mode); + } } return ret; diff --git a/components/bt/controller/esp32c6/bt.c b/components/bt/controller/esp32c6/bt.c index cd5ece61ec..b00e135399 100644 --- a/components/bt/controller/esp32c6/bt.c +++ b/components/bt/controller/esp32c6/bt.c @@ -1010,43 +1010,45 @@ typedef struct { const char* name; } bt_area_t; - -static esp_err_t esp_bt_mem_release_areas(const bt_area_t* area1, const bt_area_t* area2) +static esp_err_t esp_bt_mem_release_area(const bt_area_t *area) { esp_err_t ret = ESP_OK; - intptr_t mem_start = 0; - intptr_t mem_end = 0; + 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; +} - if(area1->end == area2->start) { - mem_start = area1->start; - mem_end = area2->end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area1->name, mem_start, mem_end, mem_end - mem_start); - ret = try_heap_caps_add_region(mem_start, mem_end); - } +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 { - mem_start = area1->start; - mem_end = area1->end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area1->name, mem_start, mem_end, mem_end - mem_start); - ret = try_heap_caps_add_region(mem_start, mem_end); - } - - mem_start = area2->start; - mem_end = area2->end; - if (ret == ESP_OK && mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area2->name, mem_start, mem_end, mem_end - mem_start); - ret = try_heap_caps_add_region(mem_start, mem_end); - } + 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) { 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, diff --git a/components/bt/controller/esp32h2/bt.c b/components/bt/controller/esp32h2/bt.c index 5ec52e5b46..b4557e8153 100644 --- a/components/bt/controller/esp32h2/bt.c +++ b/components/bt/controller/esp32h2/bt.c @@ -983,33 +983,32 @@ typedef struct { const char* name; } bt_area_t; -static esp_err_t esp_bt_mem_release_areas(const bt_area_t* area1, const bt_area_t* area2) +static esp_err_t esp_bt_mem_release_area(const bt_area_t *area) { esp_err_t ret = ESP_OK; - intptr_t mem_start = 0; - intptr_t mem_end = 0; + 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; +} - if(area1->end == area2->start) { - mem_start = area1->start; - mem_end = area2->end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area1->name, mem_start, mem_end, mem_end - mem_start); - ret = try_heap_caps_add_region(mem_start, mem_end); - } +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 { - mem_start = area1->start; - mem_end = area1->end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area1->name, mem_start, mem_end, mem_end - mem_start); - ret = try_heap_caps_add_region(mem_start, mem_end); - } - - mem_start = area2->start; - mem_end = area2->end; - if (ret == ESP_OK && mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area2->name, mem_start, mem_end, mem_end - mem_start); - ret = try_heap_caps_add_region(mem_start, mem_end); - } + esp_bt_mem_release_area(area1); + ret = esp_bt_mem_release_area(area2); } return ret; @@ -1018,6 +1017,11 @@ static esp_err_t esp_bt_mem_release_areas(const bt_area_t* area1, const bt_area_ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) { 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, diff --git a/components/bt/linker_common.lf b/components/bt/linker_common.lf index af38b5af11..501acd9505 100644 --- a/components/bt/linker_common.lf +++ b/components/bt/linker_common.lf @@ -6,7 +6,7 @@ entries: entries: COMMON -[scheme:bt_start_end] +[scheme:bt_default] entries: bt_bss -> dram0_bss bt_common -> dram0_bss @@ -30,7 +30,13 @@ entries: [mapping:bt] archive: libbt.a entries: - * (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) + 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_common_esp32c2.lf b/components/bt/linker_esp32c2.lf similarity index 62% rename from components/bt/linker_common_esp32c2.lf rename to components/bt/linker_esp32c2.lf index 2fb68d6850..7178420a00 100644 --- a/components/bt/linker_common_esp32c2.lf +++ 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,7 +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) + +[mapping:ble_app] +archive: libble_app.a +entries: + * (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 index e5b8590988..fe8598112b 100644 --- a/components/bt/linker_esp_ble_controller.lf +++ b/components/bt/linker_esp_ble_controller.lf @@ -1,7 +1,7 @@ [mapping:ble_app] archive: libble_app.a entries: - * (bt_start_end); + * (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 index 3b19bdbe24..083d6e90b7 100644 --- a/components/bt/linker_rw_bt_controller.lf +++ b/components/bt/linker_rw_bt_controller.lf @@ -1,7 +1,7 @@ [mapping:btdm] archive: libbtdm_app.a entries: - * (bt_start_end); + * (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) From c136089f4e0b27d9f034175579379e8f208ac869 Mon Sep 17 00:00:00 2001 From: Wang Mengyang Date: Fri, 29 Mar 2024 12:30:45 +0800 Subject: [PATCH 3/4] change(bt): Modify test_app directory layout - Existing test app is put in a new subdirectory "basic_unit_test" --- components/bt/test_apps/.build-test-rules.yml | 2 +- components/bt/test_apps/{ => basic_unit_test}/CMakeLists.txt | 0 components/bt/test_apps/{ => basic_unit_test}/README.md | 0 .../bt/test_apps/{ => basic_unit_test}/main/CMakeLists.txt | 0 .../bt/test_apps/{ => basic_unit_test}/main/test_bt_common.c | 0 .../bt/test_apps/{ => basic_unit_test}/main/test_bt_main.c | 0 components/bt/test_apps/{ => basic_unit_test}/main/test_smp.c | 0 .../pytest_basic_unit_test.py} | 3 +-- .../bt/test_apps/{ => basic_unit_test}/sdkconfig.defaults | 1 - 9 files changed, 2 insertions(+), 4 deletions(-) rename components/bt/test_apps/{ => basic_unit_test}/CMakeLists.txt (100%) rename components/bt/test_apps/{ => basic_unit_test}/README.md (100%) rename components/bt/test_apps/{ => basic_unit_test}/main/CMakeLists.txt (100%) rename components/bt/test_apps/{ => basic_unit_test}/main/test_bt_common.c (100%) rename components/bt/test_apps/{ => basic_unit_test}/main/test_bt_main.c (100%) rename components/bt/test_apps/{ => basic_unit_test}/main/test_smp.c (100%) rename components/bt/test_apps/{pytest_bt.py => basic_unit_test/pytest_basic_unit_test.py} (77%) rename components/bt/test_apps/{ => basic_unit_test}/sdkconfig.defaults (61%) diff --git a/components/bt/test_apps/.build-test-rules.yml b/components/bt/test_apps/.build-test-rules.yml index f96777d2da..72899ce198 100644 --- a/components/bt/test_apps/.build-test-rules.yml +++ b/components/bt/test_apps/.build-test-rules.yml @@ -1,6 +1,6 @@ # 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 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 74b0a76afc..de3d235bb5 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 5847dd3c63..dc2d7ca08b 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 From 4d7f9c5d88b477ed8673e5f9aff402c0e0e60c00 Mon Sep 17 00:00:00 2001 From: Wang Mengyang Date: Fri, 29 Mar 2024 12:46:04 +0800 Subject: [PATCH 4/4] change(bt): Add a test for release bt .bss and .data memory to heap 1. use nimble host, initialize and then deinitialize bt stack in the test 2. support tests for different SoC targets and multiple configuration options --- components/bt/test_apps/.build-test-rules.yml | 9 ++ .../test_apps/memory_release/CMakeLists.txt | 5 + .../bt/test_apps/memory_release/README.md | 4 + .../memory_release/main/CMakeLists.txt | 3 + .../memory_release/main/test_app_main.c | 131 ++++++++++++++++++ .../memory_release/pytest_memory_release.py | 15 ++ .../memory_release/sdkconfig.ci.iram | 2 + .../memory_release/sdkconfig.ci.psram | 2 + .../memory_release/sdkconfig.defaults | 2 + 9 files changed, 173 insertions(+) create mode 100644 components/bt/test_apps/memory_release/CMakeLists.txt create mode 100644 components/bt/test_apps/memory_release/README.md create mode 100644 components/bt/test_apps/memory_release/main/CMakeLists.txt create mode 100644 components/bt/test_apps/memory_release/main/test_app_main.c create mode 100644 components/bt/test_apps/memory_release/pytest_memory_release.py create mode 100644 components/bt/test_apps/memory_release/sdkconfig.ci.iram create mode 100644 components/bt/test_apps/memory_release/sdkconfig.ci.psram create mode 100644 components/bt/test_apps/memory_release/sdkconfig.defaults diff --git a/components/bt/test_apps/.build-test-rules.yml b/components/bt/test_apps/.build-test-rules.yml index 72899ce198..9b43473633 100644 --- a/components/bt/test_apps/.build-test-rules.yml +++ b/components/bt/test_apps/.build-test-rules.yml @@ -6,3 +6,12 @@ components/bt/test_apps/basic_unit_test: 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/memory_release/CMakeLists.txt b/components/bt/test_apps/memory_release/CMakeLists.txt new file mode 100644 index 0000000000..f3d75bb435 --- /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 0000000000..2975ce8f21 --- /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 0000000000..660eb5875d --- /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 0000000000..562d1d97dd --- /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 0000000000..dbefc908a6 --- /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 0000000000..36e7ceb92a --- /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 0000000000..4090a49eaf --- /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 0000000000..a22d8109d7 --- /dev/null +++ b/components/bt/test_apps/memory_release/sdkconfig.defaults @@ -0,0 +1,2 @@ +CONFIG_BT_ENABLED=y +CONFIG_BT_NIMBLE_ENABLED=y