From 0aca5ec3573bfb0825751ac3af1ceadc87d6c1b6 Mon Sep 17 00:00:00 2001 From: Wang Mengyang Date: Wed, 20 Mar 2024 14:45:09 +0800 Subject: [PATCH 1/5] 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 | 15 +- 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, 440 insertions(+), 364 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 e97332b631..e7b7b9682f 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -75,36 +75,41 @@ 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") elseif(CONFIG_IDF_TARGET_ESP32C5) list(APPEND srcs "controller/esp32c5/bt.c") - + list(APPEND ldscripts "linker_esp_ble_controller.lf") endif() list(APPEND include_dirs ${target_specific_include_dirs}) - endif() # Common @@ -827,7 +832,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 esp_driver_uart vfs esp_ringbuf - 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 403e0acd91..13b461879d 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 4309aa3e73..a5dfd6aa88 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 ********************************************************************* */ @@ -891,9 +897,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 @@ -906,22 +949,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 191ea8c52c..81dabd759d 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 ********************************************************************* @@ -983,145 +979,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 1197bf7f40..32d15a45ee 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 b36cc28fa5..7b575a9cd8 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 1d9559cc9dfc2d329eab446f82aca67b72a4eafa Mon Sep 17 00:00:00 2001 From: Wang Mengyang Date: Wed, 20 Mar 2024 19:27:43 +0800 Subject: [PATCH 2/5] 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 e7b7b9682f..d005c340c0 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -70,7 +70,6 @@ if(CONFIG_IDF_DOC_BUILD) ${nimble_hci_include_dirs}) endif() - if(CONFIG_BT_ENABLED) set(srcs "") @@ -93,8 +92,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 13b461879d..3e0335c756 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 a5dfd6aa88..7cd5db609e 100644 --- a/components/bt/controller/esp32c2/bt.c +++ b/components/bt/controller/esp32c2/bt.c @@ -915,6 +915,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; @@ -933,6 +934,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) { @@ -945,18 +947,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 81dabd759d..03ceee341f 100644 --- a/components/bt/controller/esp32c3/bt.c +++ b/components/bt/controller/esp32c3/bt.c @@ -989,42 +989,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, @@ -1046,7 +1049,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; } @@ -1065,9 +1067,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, @@ -1089,8 +1130,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) { @@ -1101,6 +1140,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 32d15a45ee..40578218a4 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 7b575a9cd8..d781aade86 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 95a249e3f6d23d59252f3a8cabe59925fee8958c Mon Sep 17 00:00:00 2001 From: Wang Mengyang Date: Fri, 29 Mar 2024 12:30:45 +0800 Subject: [PATCH 3/5] 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 745922ac72b8a74c2c2ddc03073f85e72bc73712 Mon Sep 17 00:00:00 2001 From: Wang Mengyang Date: Fri, 29 Mar 2024 12:46:04 +0800 Subject: [PATCH 4/5] 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 From d69767fcb87e5456e0a36af1f7ed1d32c1ef9975 Mon Sep 17 00:00:00 2001 From: Wang Mengyang Date: Tue, 9 Apr 2024 09:18:04 +0800 Subject: [PATCH 5/5] change(bt): Follow the same implementation of esp_bt_mem_release on ESP32-C5 --- components/bt/controller/esp32c5/bt.c | 126 +++++++++++++++----------- 1 file changed, 71 insertions(+), 55 deletions(-) diff --git a/components/bt/controller/esp32c5/bt.c b/components/bt/controller/esp32c5/bt.c index e49254b21a..7e13c7124c 100644 --- a/components/bt/controller/esp32c5/bt.c +++ b/components/bt/controller/esp32c5/bt.c @@ -986,70 +986,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; }