From 4d7f9c5d88b477ed8673e5f9aff402c0e0e60c00 Mon Sep 17 00:00:00 2001 From: Wang Mengyang Date: Fri, 29 Mar 2024 12:46:04 +0800 Subject: [PATCH] change(bt): Add a test for release bt .bss and .data memory to heap 1. use nimble host, initialize and then deinitialize bt stack in the test 2. support tests for different SoC targets and multiple configuration options --- components/bt/test_apps/.build-test-rules.yml | 9 ++ .../test_apps/memory_release/CMakeLists.txt | 5 + .../bt/test_apps/memory_release/README.md | 4 + .../memory_release/main/CMakeLists.txt | 3 + .../memory_release/main/test_app_main.c | 131 ++++++++++++++++++ .../memory_release/pytest_memory_release.py | 15 ++ .../memory_release/sdkconfig.ci.iram | 2 + .../memory_release/sdkconfig.ci.psram | 2 + .../memory_release/sdkconfig.defaults | 2 + 9 files changed, 173 insertions(+) create mode 100644 components/bt/test_apps/memory_release/CMakeLists.txt create mode 100644 components/bt/test_apps/memory_release/README.md create mode 100644 components/bt/test_apps/memory_release/main/CMakeLists.txt create mode 100644 components/bt/test_apps/memory_release/main/test_app_main.c create mode 100644 components/bt/test_apps/memory_release/pytest_memory_release.py create mode 100644 components/bt/test_apps/memory_release/sdkconfig.ci.iram create mode 100644 components/bt/test_apps/memory_release/sdkconfig.ci.psram create mode 100644 components/bt/test_apps/memory_release/sdkconfig.defaults diff --git a/components/bt/test_apps/.build-test-rules.yml b/components/bt/test_apps/.build-test-rules.yml index 72899ce198..9b43473633 100644 --- a/components/bt/test_apps/.build-test-rules.yml +++ b/components/bt/test_apps/.build-test-rules.yml @@ -6,3 +6,12 @@ components/bt/test_apps/basic_unit_test: reason: Sufficient to run the tests on one chip of each architecture depends_components: - bt + +components/bt/test_apps/memory_release: + disable: + - if: IDF_TARGET not in ["esp32", "esp32c2"] + - if: CONFIG_NAME == "iram" and IDF_TARGET != "esp32c2" + - if: CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1 + reason: Sufficient to run the tests on one chip of each architecture + depends_components: + - bt diff --git a/components/bt/test_apps/memory_release/CMakeLists.txt b/components/bt/test_apps/memory_release/CMakeLists.txt new file mode 100644 index 0000000000..f3d75bb435 --- /dev/null +++ b/components/bt/test_apps/memory_release/CMakeLists.txt @@ -0,0 +1,5 @@ +# This is the project CMakeLists.txt file for the test subproject +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(test_bt_memory_release) diff --git a/components/bt/test_apps/memory_release/README.md b/components/bt/test_apps/memory_release/README.md new file mode 100644 index 0000000000..2975ce8f21 --- /dev/null +++ b/components/bt/test_apps/memory_release/README.md @@ -0,0 +1,4 @@ +| Supported Targets | ESP32 | ESP32-C2 | +| ----------------- | ----- | -------- | + +This test app is used to test esp_bt_memory_release function diff --git a/components/bt/test_apps/memory_release/main/CMakeLists.txt b/components/bt/test_apps/memory_release/main/CMakeLists.txt new file mode 100644 index 0000000000..660eb5875d --- /dev/null +++ b/components/bt/test_apps/memory_release/main/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "test_app_main.c" + INCLUDE_DIRS "." + PRIV_REQUIRES bt nvs_flash) diff --git a/components/bt/test_apps/memory_release/main/test_app_main.c b/components/bt/test_apps/memory_release/main/test_app_main.c new file mode 100644 index 0000000000..562d1d97dd --- /dev/null +++ b/components/bt/test_apps/memory_release/main/test_app_main.c @@ -0,0 +1,131 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include + +#include "esp_log.h" +#include "nvs_flash.h" + +#include "multi_heap.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include "esp_bt.h" +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" +#include "host/ble_hs.h" +#include "host/util/util.h" +#include "services/gap/ble_svc_gap.h" + +#define FAIL() do { printf("FAILURE\n"); return; } while(0) + +extern uint8_t _bt_bss_start; +extern uint8_t _bt_bss_end; +extern uint8_t _bt_controller_bss_start; +extern uint8_t _bt_controller_bss_end; + +extern void ble_store_config_init(void); + +static const char *tag = "MEM_RELEASE_APP"; + +static void nimble_host_on_reset(int reason) +{ + ESP_LOGI(tag, "Resetting state; reason=%d", reason); +} + +static void nimble_host_on_sync(void) +{ + ESP_LOGI(tag, "NimBLE host synchronized"); +} + +static void nimble_host_task_fn(void *param) +{ + ESP_LOGI(tag, "BLE Host Task Started"); + /* This function will return only when nimble_port_stop() is executed */ + nimble_port_run(); + + nimble_port_freertos_deinit(); +} + +static void bt_stack_init(void) +{ + esp_err_t ret = nimble_port_init(); + ESP_ERROR_CHECK(ret); + + /* Initialize the NimBLE host configuration. */ + ble_hs_cfg.reset_cb = nimble_host_on_reset; + ble_hs_cfg.sync_cb = nimble_host_on_sync; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + /* Set the default device name. */ + int rc = ble_svc_gap_device_name_set(tag); + assert(rc == 0); + + /* XXX Need to have template for store */ + ble_store_config_init(); + + nimble_port_freertos_init(nimble_host_task_fn); +} + +static void bt_stack_deinit(void) +{ + int rc = nimble_port_stop(); + assert(rc == 0); + + nimble_port_deinit(); + ESP_LOGI(tag, "BLE Host Task Stopped"); +} + +void app_main(void) +{ + esp_err_t ret = ESP_OK; + + /* Initialize NVS — it is used to store PHY calibration data */ + ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + + /* initialize and then deinitialize bluetooth stack */ + bt_stack_init(); + + vTaskDelay(pdMS_TO_TICKS(200)); + + bt_stack_deinit(); + + /* Get the size of heap located in external RAM */ + const uint32_t free_before = heap_caps_get_free_size(MALLOC_CAP_DEFAULT); + ESP_LOGI(tag, "Free size in external RAM heap: %"PRIu32, free_before); + + /* Make sure at least one of the Bluetooth BSS section that can be used as a heap */ + const uint32_t heap_size = sizeof(multi_heap_info_t); + const uint32_t bt_bss_size = &_bt_bss_end - &_bt_bss_start; + const uint32_t bt_ctrl_bss_size = &_bt_controller_bss_end - &_bt_controller_bss_start; + + ESP_LOGI(tag, "bt_bss_size %"PRIu32", bt_ctrl_bss_size %"PRIu32, bt_bss_size, bt_ctrl_bss_size); + if (bt_bss_size < heap_size && bt_ctrl_bss_size < heap_size) + { + ESP_LOGW(tag, "Bluetooth BSS sections are too small!"); + FAIL(); + } + + /* Release the BSS sections to use them as heap */ + ret = esp_bt_mem_release(ESP_BT_MODE_BTDM); + ESP_ERROR_CHECK(ret); + + /* Check that we have more available memory in the external RAM heap */ + const uint32_t free_after = heap_caps_get_free_size(MALLOC_CAP_DEFAULT); + ESP_LOGI(tag, "Free size in external RAM after releasing: %"PRIu32, free_after); + if (free_after <= free_before) { + FAIL(); + } + ESP_LOGI(tag, "Free heap size increased by %"PRIu32" bytes", free_after - free_before); + + ESP_LOGI(tag, "SUCCESS"); +} diff --git a/components/bt/test_apps/memory_release/pytest_memory_release.py b/components/bt/test_apps/memory_release/pytest_memory_release.py new file mode 100644 index 0000000000..dbefc908a6 --- /dev/null +++ b/components/bt/test_apps/memory_release/pytest_memory_release.py @@ -0,0 +1,15 @@ +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 +import pytest +from pytest_embedded import Dut + + +@pytest.mark.parametrize('config', [ + pytest.param('default', marks=[pytest.mark.esp32, pytest.mark.esp32c2, pytest.mark.generic]), + pytest.param('iram', marks=[pytest.mark.esp32c2, pytest.mark.generic]), + pytest.param('psram', marks=[pytest.mark.esp32, pytest.mark.psram]), +], indirect=True) +def test_bt_memory_release(dut: Dut) -> None: + dut.expect_exact('BLE Host Task Started', timeout=6) + dut.expect_exact('BLE Host Task Stopped', timeout=8) + dut.expect_exact('SUCCESS', timeout=10) diff --git a/components/bt/test_apps/memory_release/sdkconfig.ci.iram b/components/bt/test_apps/memory_release/sdkconfig.ci.iram new file mode 100644 index 0000000000..36e7ceb92a --- /dev/null +++ b/components/bt/test_apps/memory_release/sdkconfig.ci.iram @@ -0,0 +1,2 @@ +CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT=n +CONFIG_BT_RELEASE_IRAM=y diff --git a/components/bt/test_apps/memory_release/sdkconfig.ci.psram b/components/bt/test_apps/memory_release/sdkconfig.ci.psram new file mode 100644 index 0000000000..4090a49eaf --- /dev/null +++ b/components/bt/test_apps/memory_release/sdkconfig.ci.psram @@ -0,0 +1,2 @@ +CONFIG_SPIRAM=y +CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y diff --git a/components/bt/test_apps/memory_release/sdkconfig.defaults b/components/bt/test_apps/memory_release/sdkconfig.defaults new file mode 100644 index 0000000000..a22d8109d7 --- /dev/null +++ b/components/bt/test_apps/memory_release/sdkconfig.defaults @@ -0,0 +1,2 @@ +CONFIG_BT_ENABLED=y +CONFIG_BT_NIMBLE_ENABLED=y