mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'bugfix/bt_bss_in_extram_v5.2' into 'release/v5.2'
fix(bt): Fix missing linker symbol when ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY enabled(backport v5.2) See merge request espressif/esp-idf!30378
This commit is contained in:
commit
dc3e9531c0
@ -67,37 +67,40 @@ if(CONFIG_IDF_DOC_BUILD)
|
||||
${nimble_hci_include_dirs})
|
||||
endif()
|
||||
|
||||
|
||||
if(CONFIG_BT_ENABLED)
|
||||
|
||||
set(srcs "")
|
||||
set(include_dirs "")
|
||||
set(ldfragments "linker.lf")
|
||||
set(ldscripts "linker_common.lf")
|
||||
if(CONFIG_BT_CONTROLLER_ENABLED)
|
||||
if(CONFIG_IDF_TARGET_ESP32)
|
||||
list(APPEND srcs "controller/esp32/bt.c"
|
||||
"controller/esp32/hli_api.c"
|
||||
"controller/esp32/hli_vectors.S")
|
||||
list(APPEND ldscripts "linker_rw_bt_controller.lf")
|
||||
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C3)
|
||||
list(APPEND srcs "controller/esp32c3/bt.c")
|
||||
list(APPEND ldscripts "linker_rw_bt_controller.lf")
|
||||
|
||||
elseif(CONFIG_IDF_TARGET_ESP32S3)
|
||||
list(APPEND srcs "controller/esp32c3/bt.c")
|
||||
list(APPEND ldscripts "linker_rw_bt_controller.lf")
|
||||
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C2)
|
||||
set(ldfragments "linker.lf.esp32c2")
|
||||
list(APPEND srcs "controller/esp32c2/bt.c")
|
||||
set(ldscripts "linker_esp32c2.lf")
|
||||
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C6)
|
||||
list(APPEND srcs "controller/esp32c6/bt.c")
|
||||
list(APPEND ldscripts "linker_esp_ble_controller.lf")
|
||||
|
||||
elseif(CONFIG_IDF_TARGET_ESP32H2)
|
||||
list(APPEND srcs "controller/esp32h2/bt.c")
|
||||
list(APPEND ldscripts "linker_esp_ble_controller.lf")
|
||||
endif()
|
||||
|
||||
list(APPEND include_dirs ${target_specific_include_dirs})
|
||||
|
||||
endif()
|
||||
|
||||
# Common
|
||||
@ -820,7 +823,7 @@ idf_component_register(SRCS "${srcs}"
|
||||
PRIV_INCLUDE_DIRS "${priv_include_dirs}"
|
||||
REQUIRES esp_timer esp_wifi
|
||||
PRIV_REQUIRES nvs_flash soc esp_pm esp_phy esp_coex mbedtls driver vfs
|
||||
LDFRAGMENTS "${ldfragments}")
|
||||
LDFRAGMENTS "${ldscripts}")
|
||||
|
||||
if(CONFIG_BT_ENABLED)
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-implicit-fallthrough -Wno-unused-const-variable)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -233,16 +233,12 @@ extern uint32_t _data_end_btdm_rom;
|
||||
|
||||
extern uint32_t _bt_bss_start;
|
||||
extern uint32_t _bt_bss_end;
|
||||
extern uint32_t _nimble_bss_start;
|
||||
extern uint32_t _nimble_bss_end;
|
||||
extern uint32_t _btdm_bss_start;
|
||||
extern uint32_t _btdm_bss_end;
|
||||
extern uint32_t _bt_controller_bss_start;
|
||||
extern uint32_t _bt_controller_bss_end;
|
||||
extern uint32_t _bt_data_start;
|
||||
extern uint32_t _bt_data_end;
|
||||
extern uint32_t _nimble_data_start;
|
||||
extern uint32_t _nimble_data_end;
|
||||
extern uint32_t _btdm_data_start;
|
||||
extern uint32_t _btdm_data_end;
|
||||
extern uint32_t _bt_controller_data_start;
|
||||
extern uint32_t _bt_controller_data_end;
|
||||
|
||||
extern void config_bt_funcs_reset(void);
|
||||
extern void config_ble_funcs_reset(void);
|
||||
@ -760,7 +756,7 @@ static int32_t queue_send_hlevel_wrapper(void *queue, void *item, uint32_t block
|
||||
* @param item The message which will be send
|
||||
* @param hptw need do task yield or not
|
||||
* @return send success or not
|
||||
* There is an issue here: When the queue is full, it may reture true but it send fail to the queue, sometimes.
|
||||
* There is an issue here: When the queue is full, it may return true but it send fail to the queue, sometimes.
|
||||
* But in Bluetooth controller's isr, We don't care about the return value.
|
||||
* It only required tp send success when the queue is empty all the time.
|
||||
* So, this function meets the requirement.
|
||||
@ -1281,7 +1277,45 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end)
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode)
|
||||
typedef struct {
|
||||
intptr_t start;
|
||||
intptr_t end;
|
||||
const char* name;
|
||||
} bt_area_t;
|
||||
|
||||
|
||||
static esp_err_t esp_bt_mem_release_area(const bt_area_t *area)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
intptr_t mem_start = area->start;
|
||||
intptr_t mem_end = area->end;
|
||||
if (mem_start != mem_end) {
|
||||
ESP_LOGD(BTDM_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start);
|
||||
ret = try_heap_caps_add_region(mem_start, mem_end);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
if (area1->end == area2->start) {
|
||||
bt_area_t merged_area = {
|
||||
.start = area1->start,
|
||||
.end = area2->end,
|
||||
.name = area1->name
|
||||
};
|
||||
ret = esp_bt_mem_release_area(&merged_area);
|
||||
} else {
|
||||
esp_bt_mem_release_area(area1);
|
||||
ret = esp_bt_mem_release_area(area2);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_err_t esp_bt_controller_rom_mem_release(esp_bt_mode_t mode)
|
||||
{
|
||||
bool update = true;
|
||||
intptr_t mem_start=(intptr_t) NULL, mem_end=(intptr_t) NULL;
|
||||
@ -1332,61 +1366,86 @@ esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode)
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int ret;
|
||||
intptr_t mem_start, mem_end;
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
ret = esp_bt_controller_mem_release(mode);
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
bt_area_t bss = {
|
||||
.start = (intptr_t)&_bt_bss_start,
|
||||
.end = (intptr_t)&_bt_bss_end,
|
||||
.name = "BT BSS",
|
||||
};
|
||||
bt_area_t cont_bss = {
|
||||
.start = (intptr_t)&_bt_controller_bss_start,
|
||||
.end = (intptr_t)&_bt_controller_bss_end,
|
||||
.name = "BT Controller BSS",
|
||||
};
|
||||
bt_area_t data = {
|
||||
.start = (intptr_t)&_bt_data_start,
|
||||
.end = (intptr_t)&_bt_data_end,
|
||||
.name = "BT Data",
|
||||
};
|
||||
bt_area_t cont_data = {
|
||||
.start = (intptr_t)&_bt_controller_data_start,
|
||||
.end = (intptr_t)&_bt_controller_data_end,
|
||||
.name = "BT Controller Data"
|
||||
};
|
||||
|
||||
if (mode == ESP_BT_MODE_BTDM) {
|
||||
mem_start = (intptr_t)&_bt_bss_start;
|
||||
mem_end = (intptr_t)&_bt_bss_end;
|
||||
if (mem_start != mem_end) {
|
||||
ESP_LOGD(BTDM_LOG_TAG, "Release BT BSS [0x%08x] - [0x%08x]", mem_start, mem_end);
|
||||
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
|
||||
}
|
||||
mem_start = (intptr_t)&_bt_data_start;
|
||||
mem_end = (intptr_t)&_bt_data_end;
|
||||
if (mem_start != mem_end) {
|
||||
ESP_LOGD(BTDM_LOG_TAG, "Release BT Data [0x%08x] - [0x%08x]", mem_start, mem_end);
|
||||
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
|
||||
/* Start by freeing Bluetooth BSS section */
|
||||
if (ret == ESP_OK) {
|
||||
ret = esp_bt_mem_release_areas(&bss, &cont_bss);
|
||||
}
|
||||
|
||||
mem_start = (intptr_t)&_nimble_bss_start;
|
||||
mem_end = (intptr_t)&_nimble_bss_end;
|
||||
if (mem_start != mem_end) {
|
||||
ESP_LOGD(BTDM_LOG_TAG, "Release NimBLE BSS [0x%08x] - [0x%08x]", mem_start, mem_end);
|
||||
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
|
||||
}
|
||||
mem_start = (intptr_t)&_nimble_data_start;
|
||||
mem_end = (intptr_t)&_nimble_data_end;
|
||||
if (mem_start != mem_end) {
|
||||
ESP_LOGD(BTDM_LOG_TAG, "Release NimBLE Data [0x%08x] - [0x%08x]", mem_start, mem_end);
|
||||
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
|
||||
/* Do the same thing with the Bluetooth data section */
|
||||
if (ret == ESP_OK) {
|
||||
ret = esp_bt_mem_release_areas(&data, &cont_data);
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
|
||||
/* free data and BSS section for Bluetooth controller ROM code */
|
||||
if (ret == ESP_OK) {
|
||||
ret = esp_bt_controller_rom_mem_release(mode);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if CONFIG_BTDM_CTRL_HLI
|
||||
@ -1695,7 +1754,7 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode)
|
||||
|
||||
sdk_config_set_bt_pll_track_enable(true);
|
||||
|
||||
// inititalize bluetooth baseband
|
||||
// initialize bluetooth baseband
|
||||
btdm_check_and_init_bb();
|
||||
|
||||
ret = btdm_controller_enable(mode);
|
||||
@ -1858,7 +1917,7 @@ esp_err_t esp_ble_scan_dupilcate_list_flush(void)
|
||||
|
||||
/**
|
||||
* This function re-write controller's function,
|
||||
* As coredump can not show paramerters in function which is in a .a file.
|
||||
* As coredump can not show parameters in function which is in a .a file.
|
||||
*
|
||||
* After coredump fixing this issue, just delete this function.
|
||||
*/
|
||||
|
@ -168,11 +168,17 @@ extern const char *r_ble_controller_get_rom_compile_version(void);
|
||||
#if CONFIG_BT_RELEASE_IRAM
|
||||
extern uint32_t _iram_bt_text_start;
|
||||
extern uint32_t _bss_bt_end;
|
||||
#else
|
||||
extern uint32_t _bt_bss_end;
|
||||
extern uint32_t _bt_controller_data_start;
|
||||
#endif
|
||||
|
||||
extern uint32_t _bt_bss_start;
|
||||
extern uint32_t _bt_bss_end;
|
||||
extern uint32_t _bt_controller_bss_start;
|
||||
extern uint32_t _bt_controller_bss_end;
|
||||
extern uint32_t _bt_data_start;
|
||||
extern uint32_t _bt_data_end;
|
||||
extern uint32_t _bt_controller_data_start;
|
||||
extern uint32_t _bt_controller_data_end;
|
||||
|
||||
/* Local Function Declaration
|
||||
*********************************************************************
|
||||
*/
|
||||
@ -900,9 +906,48 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end)
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
intptr_t start;
|
||||
intptr_t end;
|
||||
const char* name;
|
||||
} bt_area_t;
|
||||
|
||||
static esp_err_t esp_bt_mem_release_area(const bt_area_t *area)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
intptr_t mem_start = area->start;
|
||||
intptr_t mem_end = area->end;
|
||||
if (mem_start != mem_end) {
|
||||
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start);
|
||||
ret = try_heap_caps_add_region(mem_start, mem_end);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_BT_RELEASE_IRAM
|
||||
static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
if(area1->end == area2->start) {
|
||||
bt_area_t merged_area = {
|
||||
.start = area1->start,
|
||||
.end = area2->end,
|
||||
.name = area1->name
|
||||
};
|
||||
ret = esp_bt_mem_release_area(&merged_area);
|
||||
} else {
|
||||
esp_bt_mem_release_area(area1);
|
||||
ret = esp_bt_mem_release_area(area2);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_err_t esp_bt_mem_release(esp_bt_mode_t mode)
|
||||
{
|
||||
intptr_t mem_start, mem_end;
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
#if CONFIG_BT_RELEASE_IRAM && CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT
|
||||
/* Release Bluetooth text section and merge Bluetooth data, bss & text into a large free heap
|
||||
@ -911,26 +956,58 @@ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode)
|
||||
* memory into 3 different regions (IRAM, BLE-IRAM, DRAM). So `ESP_SYSTEM_PMP_IDRAM_SPLIT` needs
|
||||
* to be disabled.
|
||||
*/
|
||||
ESP_LOGE(NIMBLE_PORT_LOG_TAG, "`ESP_SYSTEM_PMP_IDRAM_SPLIT` should be disabled!");
|
||||
assert(0);
|
||||
#error "ESP_SYSTEM_PMP_IDRAM_SPLIT should be disabled to allow BT to be released"
|
||||
#endif // CONFIG_BT_RELEASE_IRAM && CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT
|
||||
|
||||
if (mode & ESP_BT_MODE_BLE) {
|
||||
#if 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 (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -263,16 +263,12 @@ extern void btdm_cca_feature_enable(void);
|
||||
|
||||
extern uint32_t _bt_bss_start;
|
||||
extern uint32_t _bt_bss_end;
|
||||
extern uint32_t _btdm_bss_start;
|
||||
extern uint32_t _btdm_bss_end;
|
||||
extern uint32_t _nimble_bss_start;
|
||||
extern uint32_t _nimble_bss_end;
|
||||
extern uint32_t _bt_controller_bss_start;
|
||||
extern uint32_t _bt_controller_bss_end;
|
||||
extern uint32_t _bt_data_start;
|
||||
extern uint32_t _bt_data_end;
|
||||
extern uint32_t _btdm_data_start;
|
||||
extern uint32_t _btdm_data_end;
|
||||
extern uint32_t _nimble_data_start;
|
||||
extern uint32_t _nimble_data_end;
|
||||
extern uint32_t _bt_controller_data_start;
|
||||
extern uint32_t _bt_controller_data_end;
|
||||
|
||||
/* Local Function Declare
|
||||
*********************************************************************
|
||||
@ -984,145 +980,175 @@ static void btdm_controller_mem_init(void)
|
||||
btdm_controller_rom_data_init();
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode)
|
||||
/**
|
||||
* Release two memory areas to the heap. If both areas are consecutive, they will be released as
|
||||
* a single area.
|
||||
*/
|
||||
typedef struct {
|
||||
intptr_t start;
|
||||
intptr_t end;
|
||||
const char* name;
|
||||
} bt_area_t;
|
||||
|
||||
static esp_err_t esp_bt_mem_release_area(const bt_area_t *area)
|
||||
{
|
||||
intptr_t mem_start=(intptr_t) NULL, mem_end=(intptr_t) NULL;
|
||||
esp_err_t ret = ESP_OK;
|
||||
intptr_t mem_start = area->start;
|
||||
intptr_t mem_end = area->end;
|
||||
if (mem_start != mem_end) {
|
||||
ESP_LOGD(BT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start);
|
||||
ret = try_heap_caps_add_region(mem_start, mem_end);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
if (area1->end == area2->start) {
|
||||
bt_area_t merged_area = {
|
||||
.start = area1->start,
|
||||
.end = area2->end,
|
||||
.name = area1->name
|
||||
};
|
||||
ret = esp_bt_mem_release_area(&merged_area);
|
||||
} else {
|
||||
esp_bt_mem_release_area(area1);
|
||||
ret = esp_bt_mem_release_area(area2);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_controller_rom_mem_release(esp_bt_mode_t mode)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (mode & ESP_BT_MODE_BLE) {
|
||||
/* if the addresses of rom btdm .data and .bss are consecutive,
|
||||
they are registered in the system heap as a piece of memory
|
||||
*/
|
||||
if(ets_rom_layout_p->data_end_btdm == ets_rom_layout_p->bss_start_btdm) {
|
||||
mem_start = (intptr_t)ets_rom_layout_p->data_start_btdm;
|
||||
mem_end = (intptr_t)ets_rom_layout_p->bss_end_btdm;
|
||||
if (mem_start != mem_end) {
|
||||
ESP_LOGD(BT_LOG_TAG, "Release rom btdm [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start);
|
||||
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
|
||||
}
|
||||
} else {
|
||||
mem_start = (intptr_t)ets_rom_layout_p->bss_start_btdm;
|
||||
mem_end = (intptr_t)ets_rom_layout_p->bss_end_btdm;
|
||||
if (mem_start != mem_end) {
|
||||
ESP_LOGD(BT_LOG_TAG, "Release rom btdm BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start);
|
||||
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
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) {
|
||||
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)
|
||||
{
|
||||
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_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));
|
||||
/* Do the same thing with the Bluetooth data section */
|
||||
if (ret == ESP_OK) {
|
||||
ret = esp_bt_mem_release_areas(&data, &cont_data);
|
||||
}
|
||||
mem_start = (intptr_t)&_nimble_data_start;
|
||||
mem_end = (intptr_t)&_nimble_data_end;
|
||||
if (mem_start != mem_end) {
|
||||
ESP_LOGD(BT_LOG_TAG, "Release NimBLE Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start);
|
||||
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
|
||||
|
||||
/* free data and BSS section for Bluetooth controller ROM code */
|
||||
if (ret == ESP_OK) {
|
||||
ret = esp_bt_controller_rom_mem_release(mode);
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end)
|
||||
|
@ -1003,70 +1003,86 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
intptr_t start;
|
||||
intptr_t end;
|
||||
const char* name;
|
||||
} bt_area_t;
|
||||
|
||||
static esp_err_t esp_bt_mem_release_area(const bt_area_t *area)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
intptr_t mem_start = area->start;
|
||||
intptr_t mem_end = area->end;
|
||||
if (mem_start != mem_end) {
|
||||
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start);
|
||||
ret = try_heap_caps_add_region(mem_start, mem_end);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
if (area1->end == area2->start) {
|
||||
bt_area_t merged_area = {
|
||||
.start = area1->start,
|
||||
.end = area2->end,
|
||||
.name = area1->name
|
||||
};
|
||||
ret = esp_bt_mem_release_area(&merged_area);
|
||||
} else {
|
||||
esp_bt_mem_release_area(area1);
|
||||
ret = esp_bt_mem_release_area(area2);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_mem_release(esp_bt_mode_t mode)
|
||||
{
|
||||
intptr_t mem_start, mem_end;
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
if (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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -976,70 +976,86 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
intptr_t start;
|
||||
intptr_t end;
|
||||
const char* name;
|
||||
} bt_area_t;
|
||||
|
||||
static esp_err_t esp_bt_mem_release_area(const bt_area_t *area)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
intptr_t mem_start = area->start;
|
||||
intptr_t mem_end = area->end;
|
||||
if (mem_start != mem_end) {
|
||||
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start);
|
||||
ret = try_heap_caps_add_region(mem_start, mem_end);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
if (area1->end == area2->start) {
|
||||
bt_area_t merged_area = {
|
||||
.start = area1->start,
|
||||
.end = area2->end,
|
||||
.name = area1->name
|
||||
};
|
||||
ret = esp_bt_mem_release_area(&merged_area);
|
||||
} else {
|
||||
esp_bt_mem_release_area(area1);
|
||||
ret = esp_bt_mem_release_area(area2);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_mem_release(esp_bt_mode_t mode)
|
||||
{
|
||||
intptr_t mem_start, mem_end;
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
bt_area_t bss = {
|
||||
.start = (intptr_t)&_bt_bss_start,
|
||||
.end = (intptr_t)&_bt_bss_end,
|
||||
.name = "BT BSS",
|
||||
};
|
||||
bt_area_t cont_bss = {
|
||||
.start = (intptr_t)&_bt_controller_bss_start,
|
||||
.end = (intptr_t)&_bt_controller_bss_end,
|
||||
.name = "BT Controller BSS",
|
||||
};
|
||||
bt_area_t data = {
|
||||
.start = (intptr_t)&_bt_data_start,
|
||||
.end = (intptr_t)&_bt_data_end,
|
||||
.name = "BT Data",
|
||||
};
|
||||
bt_area_t cont_data = {
|
||||
.start = (intptr_t)&_bt_controller_data_start,
|
||||
.end = (intptr_t)&_bt_controller_data_end,
|
||||
.name = "BT Controller Data"
|
||||
};
|
||||
|
||||
if (mode & ESP_BT_MODE_BLE) {
|
||||
/* If the addresses of btdm .bss and bt .bss are consecutive,
|
||||
* they are registered in the system heap as a piece of memory
|
||||
*/
|
||||
if(_bt_bss_end == _bt_controller_bss_start) {
|
||||
mem_start = (intptr_t)&_bt_bss_start;
|
||||
mem_end = (intptr_t)&_bt_controller_bss_end;
|
||||
if (mem_start != mem_end) {
|
||||
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release BSS [0x%08x] - [0x%08x], len %d",
|
||||
mem_start, mem_end, mem_end - mem_start);
|
||||
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
|
||||
}
|
||||
} else {
|
||||
mem_start = (intptr_t)&_bt_bss_start;
|
||||
mem_end = (intptr_t)&_bt_bss_end;
|
||||
if (mem_start != mem_end) {
|
||||
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release BT BSS [0x%08x] - [0x%08x], len %d",
|
||||
mem_start, mem_end, mem_end - mem_start);
|
||||
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
|
||||
}
|
||||
|
||||
mem_start = (intptr_t)&_bt_controller_bss_start;
|
||||
mem_end = (intptr_t)&_bt_controller_bss_end;
|
||||
if (mem_start != mem_end) {
|
||||
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release Controller BSS [0x%08x] - [0x%08x], len %d",
|
||||
mem_start, mem_end, mem_end - mem_start);
|
||||
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
|
||||
}
|
||||
/* Start by freeing Bluetooth BSS section */
|
||||
if (ret == ESP_OK) {
|
||||
ret = esp_bt_mem_release_areas(&bss, &cont_bss);
|
||||
}
|
||||
/* If the addresses of btdm .data and bt .data are consecutive,
|
||||
* they are registered in the system heap as a piece of memory
|
||||
*/
|
||||
if(_bt_data_end == _bt_controller_data_start) {
|
||||
mem_start = (intptr_t)&_bt_data_start;
|
||||
mem_end = (intptr_t)&_bt_controller_data_end;
|
||||
if (mem_start != mem_end) {
|
||||
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release data [0x%08x] - [0x%08x], len %d",
|
||||
mem_start, mem_end, mem_end - mem_start);
|
||||
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
|
||||
}
|
||||
} else {
|
||||
mem_start = (intptr_t)&_bt_data_start;
|
||||
mem_end = (intptr_t)&_bt_data_end;
|
||||
if (mem_start != mem_end) {
|
||||
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release BT Data [0x%08x] - [0x%08x], len %d",
|
||||
mem_start, mem_end, mem_end - mem_start);
|
||||
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
|
||||
}
|
||||
|
||||
mem_start = (intptr_t)&_bt_controller_data_start;
|
||||
mem_end = (intptr_t)&_bt_controller_data_end;
|
||||
if (mem_start != mem_end) {
|
||||
ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release Controller Data [0x%08x] - [0x%08x], len %d",
|
||||
mem_start, mem_end, mem_end - mem_start);
|
||||
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
|
||||
}
|
||||
/* Do the same thing with the Bluetooth data section */
|
||||
if (ret == ESP_OK) {
|
||||
ret = esp_bt_mem_release_areas(&data, &cont_data);
|
||||
}
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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)
|
42
components/bt/linker_common.lf
Normal file
42
components/bt/linker_common.lf
Normal file
@ -0,0 +1,42 @@
|
||||
[sections:bt_bss]
|
||||
entries:
|
||||
.bss+
|
||||
|
||||
[sections:bt_common]
|
||||
entries:
|
||||
COMMON
|
||||
|
||||
[scheme:bt_default]
|
||||
entries:
|
||||
bt_bss -> dram0_bss
|
||||
bt_common -> dram0_bss
|
||||
data -> dram0_data
|
||||
|
||||
[scheme:bt_extram_bss]
|
||||
entries:
|
||||
bt_bss -> extern_ram
|
||||
bt_common -> extern_ram
|
||||
data -> dram0_data
|
||||
|
||||
# For the following fragments, order matters for
|
||||
# 'ALIGN(4) ALIGN(4, post) SURROUND(sym)', which generates:
|
||||
#
|
||||
# . = ALIGN(4)
|
||||
# _sym_start
|
||||
# ...
|
||||
# . = ALIGN(4)
|
||||
# _sym_end
|
||||
|
||||
[mapping:bt]
|
||||
archive: libbt.a
|
||||
entries:
|
||||
if ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y:
|
||||
* (bt_extram_bss);
|
||||
bt_bss -> extern_ram ALIGN(4) ALIGN(4, post) SURROUND(bt_bss),
|
||||
bt_common -> extern_ram ALIGN(4) ALIGN(4, post) SURROUND(bt_common),
|
||||
data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_data)
|
||||
else:
|
||||
* (bt_default);
|
||||
bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_bss),
|
||||
bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_common),
|
||||
data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_data)
|
@ -1,4 +1,4 @@
|
||||
[sections:bt_text]
|
||||
[sections:bt_iram_text]
|
||||
entries:
|
||||
.iram1+
|
||||
|
||||
@ -17,9 +17,9 @@ entries:
|
||||
entries:
|
||||
COMMON
|
||||
|
||||
[scheme:bt_start_end]
|
||||
[scheme:bt_default]
|
||||
entries:
|
||||
bt_text -> iram0_bt_text
|
||||
bt_iram_text -> iram0_bt_text
|
||||
bt_bss -> dram0_bt_bss
|
||||
bt_common -> dram0_bt_bss
|
||||
bt_data -> dram0_bt_data
|
||||
@ -36,25 +36,15 @@ entries:
|
||||
[mapping:bt]
|
||||
archive: libbt.a
|
||||
entries:
|
||||
* (bt_start_end);
|
||||
* (bt_default);
|
||||
bt_bss -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_bss),
|
||||
bt_common -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_common),
|
||||
bt_data -> dram0_bt_data ALIGN(4) ALIGN(4, post) SURROUND(bt_data)
|
||||
if ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y:
|
||||
* (extram_bss)
|
||||
|
||||
[mapping:btdm]
|
||||
archive: libbtdm_app.a
|
||||
entries:
|
||||
* (bt_start_end);
|
||||
bt_bss -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(btdm_bss),
|
||||
bt_common -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(btdm_common),
|
||||
bt_data -> dram0_bt_data ALIGN(4) ALIGN(4, post) SURROUND(btdm_data)
|
||||
|
||||
[mapping:bt_controller]
|
||||
[mapping:ble_app]
|
||||
archive: libble_app.a
|
||||
entries:
|
||||
* (bt_start_end);
|
||||
* (bt_default);
|
||||
bt_bss -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_bss),
|
||||
bt_common -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_common),
|
||||
bt_data -> dram0_bt_data ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_data)
|
7
components/bt/linker_esp_ble_controller.lf
Normal file
7
components/bt/linker_esp_ble_controller.lf
Normal 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)
|
7
components/bt/linker_rw_bt_controller.lf
Normal file
7
components/bt/linker_rw_bt_controller.lf
Normal 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)
|
@ -1,8 +1,17 @@
|
||||
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
|
||||
|
||||
components/bt/test_apps:
|
||||
components/bt/test_apps/basic_unit_test:
|
||||
disable:
|
||||
- if: IDF_TARGET not in ["esp32", "esp32c3"]
|
||||
reason: Sufficient to run the tests on one chip of each architecture
|
||||
depends_components:
|
||||
- bt
|
||||
|
||||
components/bt/test_apps/memory_release:
|
||||
disable:
|
||||
- if: IDF_TARGET not in ["esp32", "esp32c2"]
|
||||
- if: CONFIG_NAME == "iram" and IDF_TARGET != "esp32c2"
|
||||
- if: CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1
|
||||
reason: Sufficient to run the tests on one chip of each architecture
|
||||
depends_components:
|
||||
- bt
|
||||
|
@ -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
|
||||
|
@ -1,3 +1,2 @@
|
||||
CONFIG_BT_ENABLED=y
|
||||
CONFIG_UNITY_FREERTOS_STACK_SIZE=12288
|
||||
CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=n
|
5
components/bt/test_apps/memory_release/CMakeLists.txt
Normal file
5
components/bt/test_apps/memory_release/CMakeLists.txt
Normal file
@ -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)
|
4
components/bt/test_apps/memory_release/README.md
Normal file
4
components/bt/test_apps/memory_release/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 |
|
||||
| ----------------- | ----- | -------- |
|
||||
|
||||
This test app is used to test esp_bt_memory_release function
|
@ -0,0 +1,3 @@
|
||||
idf_component_register(SRCS "test_app_main.c"
|
||||
INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES bt nvs_flash)
|
131
components/bt/test_apps/memory_release/main/test_app_main.c
Normal file
131
components/bt/test_apps/memory_release/main/test_app_main.c
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
|
||||
#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");
|
||||
}
|
@ -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)
|
2
components/bt/test_apps/memory_release/sdkconfig.ci.iram
Normal file
2
components/bt/test_apps/memory_release/sdkconfig.ci.iram
Normal file
@ -0,0 +1,2 @@
|
||||
CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT=n
|
||||
CONFIG_BT_RELEASE_IRAM=y
|
@ -0,0 +1,2 @@
|
||||
CONFIG_SPIRAM=y
|
||||
CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y
|
@ -0,0 +1,2 @@
|
||||
CONFIG_BT_ENABLED=y
|
||||
CONFIG_BT_NIMBLE_ENABLED=y
|
Loading…
Reference in New Issue
Block a user