Merge branch 'bugfix/bt_bss_in_extram_v5.0' into 'release/v5.0'

fix(bt): Fix missing linker symbol when ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY enabled(backport v5.0)

See merge request espressif/esp-idf!30377
This commit is contained in:
Jiang Jiang Jian
2024-05-13 11:03:07 +08:00
9 changed files with 478 additions and 270 deletions

View File

@ -2,30 +2,34 @@ if(CONFIG_BT_ENABLED)
set(srcs "") set(srcs "")
set(include_dirs "") set(include_dirs "")
set(ldfragments "linker.lf") set(ldscripts "linker_common.lf")
if(CONFIG_IDF_TARGET_ESP32) if(CONFIG_IDF_TARGET_ESP32)
list(APPEND srcs "controller/esp32/bt.c" list(APPEND srcs "controller/esp32/bt.c"
"controller/esp32/hli_api.c" "controller/esp32/hli_api.c"
"controller/esp32/hli_vectors.S") "controller/esp32/hli_vectors.S")
list(APPEND include_dirs include/esp32/include) list(APPEND include_dirs include/esp32/include)
list(APPEND ldscripts "linker_rw_bt_controller.lf")
elseif(CONFIG_IDF_TARGET_ESP32C3) elseif(CONFIG_IDF_TARGET_ESP32C3)
list(APPEND srcs "controller/esp32c3/bt.c") list(APPEND srcs "controller/esp32c3/bt.c")
list(APPEND include_dirs include/esp32c3/include) list(APPEND include_dirs include/esp32c3/include)
list(APPEND ldscripts "linker_rw_bt_controller.lf")
elseif(CONFIG_IDF_TARGET_ESP32S3) elseif(CONFIG_IDF_TARGET_ESP32S3)
list(APPEND srcs "controller/esp32c3/bt.c") list(APPEND srcs "controller/esp32c3/bt.c")
list(APPEND include_dirs include/esp32c3/include) list(APPEND include_dirs include/esp32c3/include)
list(APPEND ldscripts "linker_rw_bt_controller.lf")
elseif(CONFIG_IDF_TARGET_ESP32H2) elseif(CONFIG_IDF_TARGET_ESP32H2)
list(APPEND srcs "controller/esp32h2/bt.c") list(APPEND srcs "controller/esp32h2/bt.c")
list(APPEND include_dirs include/esp32h2/include) list(APPEND include_dirs include/esp32h2/include)
list(APPEND ldscripts "linker_esp_ble_controller.lf")
elseif(CONFIG_IDF_TARGET_ESP32C2) elseif(CONFIG_IDF_TARGET_ESP32C2)
set(ldfragments "linker.lf.esp32c2")
list(APPEND srcs "controller/esp32c2/bt.c") list(APPEND srcs "controller/esp32c2/bt.c")
list(APPEND include_dirs include/esp32c2/include) list(APPEND include_dirs include/esp32c2/include)
set(ldscripts "linker_esp32c2.lf")
endif() endif()
@ -688,7 +692,7 @@ idf_component_register(SRCS "${srcs}"
PRIV_INCLUDE_DIRS "${priv_include_dirs}" PRIV_INCLUDE_DIRS "${priv_include_dirs}"
REQUIRES esp_timer esp_wifi REQUIRES esp_timer esp_wifi
PRIV_REQUIRES nvs_flash soc esp_pm esp_phy mbedtls driver vfs PRIV_REQUIRES nvs_flash soc esp_pm esp_phy mbedtls driver vfs
LDFRAGMENTS "${ldfragments}") LDFRAGMENTS "${ldscripts}")
if(CONFIG_BT_ENABLED) if(CONFIG_BT_ENABLED)
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-implicit-fallthrough -Wno-unused-const-variable) target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-implicit-fallthrough -Wno-unused-const-variable)

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -248,16 +248,12 @@ extern uint32_t _data_end_btdm_rom;
extern uint32_t _bt_bss_start; extern uint32_t _bt_bss_start;
extern uint32_t _bt_bss_end; extern uint32_t _bt_bss_end;
extern uint32_t _nimble_bss_start; extern uint32_t _bt_controller_bss_start;
extern uint32_t _nimble_bss_end; extern uint32_t _bt_controller_bss_end;
extern uint32_t _btdm_bss_start;
extern uint32_t _btdm_bss_end;
extern uint32_t _bt_data_start; extern uint32_t _bt_data_start;
extern uint32_t _bt_data_end; extern uint32_t _bt_data_end;
extern uint32_t _nimble_data_start; extern uint32_t _bt_controller_data_start;
extern uint32_t _nimble_data_end; extern uint32_t _bt_controller_data_end;
extern uint32_t _btdm_data_start;
extern uint32_t _btdm_data_end;
extern void config_bt_funcs_reset(void); extern void config_bt_funcs_reset(void);
extern void config_ble_funcs_reset(void); extern void config_ble_funcs_reset(void);
@ -805,7 +801,7 @@ static int32_t queue_send_hlevel_wrapper(void *queue, void *item, uint32_t block
* @param item The message which will be send * @param item The message which will be send
* @param hptw need do task yield or not * @param hptw need do task yield or not
* @return send success 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. * 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. * It only required tp send success when the queue is empty all the time.
* So, this function meets the requirement. * So, this function meets the requirement.
@ -1337,7 +1333,45 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end)
return ret; return ret;
} }
esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode) typedef struct {
intptr_t start;
intptr_t end;
const char* name;
} bt_area_t;
static esp_err_t esp_bt_mem_release_area(const bt_area_t *area)
{
esp_err_t ret = ESP_OK;
intptr_t mem_start = area->start;
intptr_t mem_end = area->end;
if (mem_start != mem_end) {
ESP_LOGD(BTDM_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start);
ret = try_heap_caps_add_region(mem_start, mem_end);
}
return ret;
}
static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2)
{
esp_err_t ret = ESP_OK;
if (area1->end == area2->start) {
bt_area_t merged_area = {
.start = area1->start,
.end = area2->end,
.name = area1->name
};
ret = esp_bt_mem_release_area(&merged_area);
} else {
esp_bt_mem_release_area(area1);
ret = esp_bt_mem_release_area(area2);
}
return ret;
}
static esp_err_t esp_bt_controller_rom_mem_release(esp_bt_mode_t mode)
{ {
bool update = true; bool update = true;
intptr_t mem_start=(intptr_t) NULL, mem_end=(intptr_t) NULL; intptr_t mem_start=(intptr_t) NULL, mem_end=(intptr_t) NULL;
@ -1388,61 +1422,86 @@ 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));
}
}
return ESP_OK; 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,
.end = (intptr_t)&_bt_controller_bss_end,
.name = "BT Controller BSS",
};
bt_area_t cont_data = {
.start = (intptr_t)&_bt_controller_data_start,
.end = (intptr_t)&_bt_controller_data_end,
.name = "BT Controller Data"
};
ret = esp_bt_mem_release_areas(&cont_data, &cont_bss);
}
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 esp_bt_mem_release(esp_bt_mode_t mode)
{ {
int ret; esp_err_t ret = ESP_OK;
intptr_t mem_start, mem_end;
ret = esp_bt_controller_mem_release(mode); if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
if (ret != ESP_OK) { return ESP_ERR_INVALID_STATE;
return ret;
} }
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) { if (mode == ESP_BT_MODE_BTDM) {
mem_start = (intptr_t)&_bt_bss_start; /* Start by freeing Bluetooth BSS section */
mem_end = (intptr_t)&_bt_bss_end; if (ret == ESP_OK) {
if (mem_start != mem_end) { ret = esp_bt_mem_release_areas(&bss, &cont_bss);
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));
} }
mem_start = (intptr_t)&_nimble_bss_start; /* Do the same thing with the Bluetooth data section */
mem_end = (intptr_t)&_nimble_bss_end; if (ret == ESP_OK) {
if (mem_start != mem_end) { ret = esp_bt_mem_release_areas(&data, &cont_data);
ESP_LOGD(BTDM_LOG_TAG, "Release NimBLE BSS [0x%08x] - [0x%08x]", mem_start, mem_end);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
mem_start = (intptr_t)&_nimble_data_start;
mem_end = (intptr_t)&_nimble_data_end;
if (mem_start != mem_end) {
ESP_LOGD(BTDM_LOG_TAG, "Release NimBLE Data [0x%08x] - [0x%08x]", mem_start, mem_end);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
} }
} }
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 #if CONFIG_BTDM_CTRL_HLI
@ -1751,7 +1810,7 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode)
sdk_config_set_bt_pll_track_enable(true); sdk_config_set_bt_pll_track_enable(true);
// inititalize bluetooth baseband // initialize bluetooth baseband
btdm_check_and_init_bb(); btdm_check_and_init_bb();
ret = btdm_controller_enable(mode); ret = btdm_controller_enable(mode);
@ -1914,7 +1973,7 @@ esp_err_t esp_ble_scan_dupilcate_list_flush(void)
/** /**
* This function re-write controller's function, * 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. * After coredump fixing this issue, just delete this function.
*/ */

View File

@ -169,11 +169,17 @@ extern const char *r_ble_controller_get_rom_compile_version(void);
#if CONFIG_BT_RELEASE_IRAM #if CONFIG_BT_RELEASE_IRAM
extern uint32_t _iram_bt_text_start; extern uint32_t _iram_bt_text_start;
extern uint32_t _bss_bt_end; extern uint32_t _bss_bt_end;
#else
extern uint32_t _bt_bss_end;
extern uint32_t _bt_controller_data_start;
#endif #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 /* Local Function Declaration
********************************************************************* *********************************************************************
*/ */
@ -902,9 +908,48 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end)
return ret; return ret;
} }
typedef struct {
intptr_t start;
intptr_t end;
const char* name;
} bt_area_t;
static esp_err_t esp_bt_mem_release_area(const bt_area_t *area)
{
esp_err_t ret = ESP_OK;
intptr_t mem_start = area->start;
intptr_t mem_end = area->end;
if (mem_start != mem_end) {
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start);
ret = try_heap_caps_add_region(mem_start, mem_end);
}
return ret;
}
#ifndef CONFIG_BT_RELEASE_IRAM
static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2)
{
esp_err_t ret = ESP_OK;
if(area1->end == area2->start) {
bt_area_t merged_area = {
.start = area1->start,
.end = area2->end,
.name = area1->name
};
ret = esp_bt_mem_release_area(&merged_area);
} else {
esp_bt_mem_release_area(area1);
ret = esp_bt_mem_release_area(area2);
}
return ret;
}
#endif
esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) 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 #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 /* Release Bluetooth text section and merge Bluetooth data, bss & text into a large free heap
@ -913,26 +958,58 @@ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode)
* memory into 3 different regions (IRAM, BLE-IRAM, DRAM). So `ESP_SYSTEM_PMP_IDRAM_SPLIT` needs * memory into 3 different regions (IRAM, BLE-IRAM, DRAM). So `ESP_SYSTEM_PMP_IDRAM_SPLIT` needs
* to be disabled. * to be disabled.
*/ */
ESP_LOGE(NIMBLE_PORT_LOG_TAG, "`ESP_SYSTEM_PMP_IDRAM_SPLIT` should be disabled!"); #error "ESP_SYSTEM_PMP_IDRAM_SPLIT should be disabled to allow BT to be released"
assert(0);
#endif // CONFIG_BT_RELEASE_IRAM && CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT #endif // CONFIG_BT_RELEASE_IRAM && CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT
if (mode & ESP_BT_MODE_BLE) { if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
#if CONFIG_BT_RELEASE_IRAM return ESP_ERR_INVALID_STATE;
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));
}
} }
return ESP_OK; 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,
.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;
} }

View File

@ -266,16 +266,12 @@ extern void btdm_cca_feature_enable(void);
extern uint32_t _bt_bss_start; extern uint32_t _bt_bss_start;
extern uint32_t _bt_bss_end; extern uint32_t _bt_bss_end;
extern uint32_t _btdm_bss_start; extern uint32_t _bt_controller_bss_start;
extern uint32_t _btdm_bss_end; extern uint32_t _bt_controller_bss_end;
extern uint32_t _nimble_bss_start;
extern uint32_t _nimble_bss_end;
extern uint32_t _bt_data_start; extern uint32_t _bt_data_start;
extern uint32_t _bt_data_end; extern uint32_t _bt_data_end;
extern uint32_t _btdm_data_start; extern uint32_t _bt_controller_data_start;
extern uint32_t _btdm_data_end; extern uint32_t _bt_controller_data_end;
extern uint32_t _nimble_data_start;
extern uint32_t _nimble_data_end;
/* Local Function Declare /* Local Function Declare
********************************************************************* *********************************************************************
@ -1014,145 +1010,175 @@ static void btdm_controller_mem_init(void)
btdm_controller_rom_data_init(); btdm_controller_rom_data_init();
} }
esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode) /**
* Release two memory areas to the heap. If both areas are consecutive, they will be released as
* a single area.
*/
typedef struct {
intptr_t start;
intptr_t end;
const char* name;
} bt_area_t;
static esp_err_t esp_bt_mem_release_area(const bt_area_t *area)
{ {
intptr_t mem_start=(intptr_t) NULL, mem_end=(intptr_t) NULL; esp_err_t ret = ESP_OK;
intptr_t mem_start = area->start;
intptr_t mem_end = area->end;
if (mem_start != mem_end) {
ESP_LOGD(BT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start);
ret = try_heap_caps_add_region(mem_start, mem_end);
}
return ret;
}
static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2)
{
esp_err_t ret = ESP_OK;
if (area1->end == area2->start) {
bt_area_t merged_area = {
.start = area1->start,
.end = area2->end,
.name = area1->name
};
ret = esp_bt_mem_release_area(&merged_area);
} else {
esp_bt_mem_release_area(area1);
ret = esp_bt_mem_release_area(area2);
}
return ret;
}
esp_err_t esp_bt_controller_rom_mem_release(esp_bt_mode_t mode)
{
esp_err_t ret = ESP_OK;
if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
return ESP_ERR_INVALID_STATE; return ESP_ERR_INVALID_STATE;
} }
if (mode & ESP_BT_MODE_BLE) { bt_area_t rom_btdm_data = {
/* if the addresses of rom btdm .data and .bss are consecutive, .start = (intptr_t) ets_rom_layout_p->data_start_btdm,
they are registered in the system heap as a piece of memory .end = (intptr_t) ets_rom_layout_p->data_end_btdm,
*/ .name = "ROM btdm data",
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; bt_area_t rom_btdm_bss = {
mem_end = (intptr_t)ets_rom_layout_p->bss_end_btdm; .start = (intptr_t)ets_rom_layout_p->bss_start_btdm,
if (mem_start != mem_end) { .end = (intptr_t)ets_rom_layout_p->bss_end_btdm,
ESP_LOGD(BT_LOG_TAG, "Release rom btdm [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); .name = "ROM btdm BSS",
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); };
} bt_area_t rom_btdm_inter_data = {
} else { .start = (intptr_t) ets_rom_layout_p->data_start_interface_btdm,
mem_start = (intptr_t)ets_rom_layout_p->bss_start_btdm; .end = (intptr_t) ets_rom_layout_p->data_end_interface_btdm,
mem_end = (intptr_t)ets_rom_layout_p->bss_end_btdm; .name = "ROM interface btdm data",
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); bt_area_t rom_btdm_inter_bss = {
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); .start = (intptr_t)ets_rom_layout_p->bss_start_interface_btdm,
} .end = (intptr_t)ets_rom_layout_p->bss_end_interface_btdm,
.name = "ROM interface btdm BSS",
mem_start = (intptr_t)ets_rom_layout_p->data_start_btdm; };
mem_end = (intptr_t)ets_rom_layout_p->data_end_btdm;
if (mem_start != mem_end) {
ESP_LOGD(BT_LOG_TAG, "Release rom btdm Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
}
/* if the addresses of rom interface btdm .data and .bss are consecutive,
they are registered in the system heap as a piece of memory
*/
if(ets_rom_layout_p->data_end_interface_btdm == ets_rom_layout_p->bss_start_interface_btdm) {
mem_start = (intptr_t)ets_rom_layout_p->data_start_interface_btdm;
mem_end = (intptr_t)ets_rom_layout_p->bss_end_interface_btdm;
if (mem_start != mem_end) {
ESP_LOGD(BT_LOG_TAG, "Release rom interface btdm [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
} else {
mem_start = (intptr_t)ets_rom_layout_p->data_start_interface_btdm;
mem_end = (intptr_t)ets_rom_layout_p->data_end_interface_btdm;
if (mem_start != mem_end) {
ESP_LOGD(BT_LOG_TAG, "Release rom interface btdm Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
mem_start = (intptr_t)ets_rom_layout_p->bss_start_interface_btdm;
mem_end = (intptr_t)ets_rom_layout_p->bss_end_interface_btdm;
if (mem_start != mem_end) {
ESP_LOGD(BT_LOG_TAG, "Release rom interface btdm BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
}
if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
ret = ESP_ERR_INVALID_STATE;
} }
return ESP_OK;
if (mode & ESP_BT_MODE_BLE) {
/* Free BTDM memory used by the ROM */
if (ret == ESP_OK) {
ret = esp_bt_mem_release_areas(&rom_btdm_data, &rom_btdm_bss);
}
if (ret == ESP_OK) {
ret = esp_bt_mem_release_areas(&rom_btdm_inter_data, &rom_btdm_inter_bss);
}
}
return ret;
}
esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode)
{
esp_err_t ret = ESP_OK;
if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
return ESP_ERR_INVALID_STATE;
}
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 esp_bt_mem_release(esp_bt_mode_t mode)
{ {
int ret; esp_err_t ret = ESP_OK;
intptr_t mem_start, mem_end;
ret = esp_bt_controller_mem_release(mode); if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
if (ret != ESP_OK) { return ESP_ERR_INVALID_STATE;
return ret;
} }
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 (mode & ESP_BT_MODE_BLE) {
/* if the addresses of btdm .bss and bt .bss are consecutive, /* Start by freeing Bluetooth BSS section */
they are registered in the system heap as a piece of memory if (ret == ESP_OK) {
*/ ret = esp_bt_mem_release_areas(&bss, &cont_bss);
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));
}
} }
mem_start = (intptr_t)&_nimble_bss_start; /* Do the same thing with the Bluetooth data section */
mem_end = (intptr_t)&_nimble_bss_end; if (ret == ESP_OK) {
if (mem_start != mem_end) { ret = esp_bt_mem_release_areas(&data, &cont_data);
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; /* free data and BSS section for Bluetooth controller ROM code */
if (mem_start != mem_end) { if (ret == ESP_OK) {
ESP_LOGD(BT_LOG_TAG, "Release NimBLE Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); ret = esp_bt_controller_rom_mem_release(mode);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
} }
} }
return ESP_OK;
return ret;
} }
static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end) static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end)

View File

@ -142,12 +142,12 @@ extern int ble_txpwr_get(esp_ble_enhanced_power_type_t power_type, uint16_t hand
extern int ble_get_npl_element_info(esp_bt_controller_config_t *cfg, ble_npl_count_info_t * npl_info); extern int ble_get_npl_element_info(esp_bt_controller_config_t *cfg, ble_npl_count_info_t * npl_info);
extern uint32_t _bt_bss_start; extern uint32_t _bt_bss_start;
extern uint32_t _bt_bss_end; extern uint32_t _bt_bss_end;
extern uint32_t _nimble_bss_start; extern uint32_t _bt_controller_bss_start;
extern uint32_t _nimble_bss_end; extern uint32_t _bt_controller_bss_end;
extern uint32_t _nimble_data_start;
extern uint32_t _nimble_data_end;
extern uint32_t _bt_data_start; extern uint32_t _bt_data_start;
extern uint32_t _bt_data_end; extern uint32_t _bt_data_end;
extern uint32_t _bt_controller_data_start;
extern uint32_t _bt_controller_data_end;
/* Local Function Declaration /* Local Function Declaration
********************************************************************* *********************************************************************
@ -806,41 +806,86 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end)
return ret; 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) 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 (mode & ESP_BT_MODE_BLE) {
mem_start = (intptr_t)&_bt_bss_start; /* Start by freeing Bluetooth BSS section */
mem_end = (intptr_t)&_bt_bss_end; if (ret == ESP_OK) {
if (mem_start != mem_end) { ret = esp_bt_mem_release_areas(&bss, &cont_bss);
ESP_LOGD(NIMBLE_PORT_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; /* Do the same thing with the Bluetooth data section */
mem_end = (intptr_t)&_bt_data_end; if (ret == ESP_OK) {
if (mem_start != mem_end) { ret = esp_bt_mem_release_areas(&data, &cont_data);
ESP_LOGD(NIMBLE_PORT_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));
}
mem_start = (intptr_t)&_nimble_bss_start;
mem_end = (intptr_t)&_nimble_bss_end;
if (mem_start != mem_end) {
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release NimBLE BSS [0x%08x] - [0x%08x]", mem_start, mem_end);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
}
mem_start = (intptr_t)&_nimble_data_start;
mem_end = (intptr_t)&_nimble_data_end;
if (mem_start != mem_end) {
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release NimBLE Data [0x%08x] - [0x%08x]", mem_start, mem_end);
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
} }
} }
return ESP_OK; return ret;
} }

View File

@ -6,12 +6,18 @@ entries:
entries: entries:
COMMON COMMON
[scheme:bt_start_end] [scheme:bt_default]
entries: entries:
bt_bss -> dram0_bss bt_bss -> dram0_bss
bt_common -> dram0_bss bt_common -> dram0_bss
data -> dram0_data 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 # For the following fragments, order matters for
# 'ALIGN(4) ALIGN(4, post) SURROUND(sym)', which generates: # 'ALIGN(4) ALIGN(4, post) SURROUND(sym)', which generates:
# #
@ -25,25 +31,12 @@ entries:
archive: libbt.a archive: libbt.a
entries: entries:
if ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y: if ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y:
* (extram_bss) * (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: else:
* (bt_start_end); * (bt_default);
bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_bss), bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_bss),
bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_common), bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_common),
data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_data) 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: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)

View File

@ -1,4 +1,4 @@
[sections:bt_text] [sections:bt_iram_text]
entries: entries:
.iram1+ .iram1+
@ -17,9 +17,9 @@ entries:
entries: entries:
COMMON COMMON
[scheme:bt_start_end] [scheme:bt_default]
entries: entries:
bt_text -> iram0_bt_text bt_iram_text -> iram0_bt_text
bt_bss -> dram0_bt_bss bt_bss -> dram0_bt_bss
bt_common -> dram0_bt_bss bt_common -> dram0_bt_bss
bt_data -> dram0_bt_data bt_data -> dram0_bt_data
@ -36,25 +36,15 @@ entries:
[mapping:bt] [mapping:bt]
archive: libbt.a archive: libbt.a
entries: entries:
* (bt_start_end); * (bt_default);
bt_bss -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_bss), 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_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) 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] [mapping:ble_app]
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 archive: libble_app.a
entries: entries:
* (bt_start_end); * (bt_default);
bt_bss -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_bss), 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_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) bt_data -> dram0_bt_data ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_data)

View File

@ -0,0 +1,7 @@
[mapping:ble_app]
archive: libble_app.a
entries:
* (bt_default);
bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_bss),
bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_common),
data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_data)

View File

@ -0,0 +1,7 @@
[mapping:btdm]
archive: libbtdm_app.a
entries:
* (bt_default);
bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_bss),
bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_common),
data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_data)