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)