diff --git a/components/bt/common/Kconfig.in b/components/bt/common/Kconfig.in index fcd6ec8496..4bcfaa79ce 100644 --- a/components/bt/common/Kconfig.in +++ b/components/bt/common/Kconfig.in @@ -255,3 +255,9 @@ config BT_BLE_LOG_UHCI_OUT_UART_IO_NUM_TX default 0 help IO number for UART TX port + +config BT_LE_USED_MEM_STATISTICS_ENABLED + bool "Enable used memory statistics" + default n + help + Used in internal tests only. Enable used memory statistics. diff --git a/components/bt/controller/esp32c2/bt.c b/components/bt/controller/esp32c2/bt.c index 120083000b..409c2f6741 100644 --- a/components/bt/controller/esp32c2/bt.c +++ b/components/bt/controller/esp32c2/bt.c @@ -575,7 +575,7 @@ struct ext_funcs_t ext_funcs_ro = { ._esp_intr_alloc = esp_intr_alloc_wrapper, ._esp_intr_free = esp_intr_free_wrapper, ._malloc = bt_osi_mem_malloc_internal, - ._free = bt_osi_mem_free, + ._free = bt_osi_mem_free_internal, ._task_create = task_create_wrapper, ._task_delete = task_delete_wrapper, ._osi_assert = osi_assert_wrapper, diff --git a/components/bt/controller/esp32c5/bt.c b/components/bt/controller/esp32c5/bt.c index 93c983b5b9..c9961afeca 100644 --- a/components/bt/controller/esp32c5/bt.c +++ b/components/bt/controller/esp32c5/bt.c @@ -537,7 +537,7 @@ struct ext_funcs_t ext_funcs_ro = { ._esp_intr_alloc = esp_intr_alloc_wrapper, ._esp_intr_free = esp_intr_free_wrapper, ._malloc = bt_osi_mem_malloc_internal, - ._free = bt_osi_mem_free, + ._free = bt_osi_mem_free_internal, ._task_create = task_create_wrapper, ._task_delete = task_delete_wrapper, ._osi_assert = osi_assert_wrapper, diff --git a/components/bt/controller/esp32c6/bt.c b/components/bt/controller/esp32c6/bt.c index 351474d6dc..b26d3cbf08 100644 --- a/components/bt/controller/esp32c6/bt.c +++ b/components/bt/controller/esp32c6/bt.c @@ -553,7 +553,7 @@ struct ext_funcs_t ext_funcs_ro = { ._esp_intr_alloc = esp_intr_alloc_wrapper, ._esp_intr_free = esp_intr_free_wrapper, ._malloc = bt_osi_mem_malloc_internal, - ._free = bt_osi_mem_free, + ._free = bt_osi_mem_free_internal, ._task_create = task_create_wrapper, ._task_delete = task_delete_wrapper, ._osi_assert = osi_assert_wrapper, diff --git a/components/bt/controller/esp32h2/bt.c b/components/bt/controller/esp32h2/bt.c index 8533a1aa99..b23c018d8d 100644 --- a/components/bt/controller/esp32h2/bt.c +++ b/components/bt/controller/esp32h2/bt.c @@ -545,7 +545,7 @@ struct ext_funcs_t ext_funcs_ro = { ._esp_intr_alloc = esp_intr_alloc_wrapper, ._esp_intr_free = esp_intr_free_wrapper, ._malloc = bt_osi_mem_malloc_internal, - ._free = bt_osi_mem_free, + ._free = bt_osi_mem_free_internal, ._task_create = task_create_wrapper, ._task_delete = task_delete_wrapper, ._osi_assert = osi_assert_wrapper, diff --git a/components/bt/porting/include/bt_osi_mem.h b/components/bt/porting/include/bt_osi_mem.h index cf5f60956e..a97165d707 100644 --- a/components/bt/porting/include/bt_osi_mem.h +++ b/components/bt/porting/include/bt_osi_mem.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +20,12 @@ void *bt_osi_mem_calloc_internal(size_t n, size_t size); void bt_osi_mem_free(void *ptr); +void bt_osi_mem_free_internal(void *ptr); #if CONFIG_BT_LE_MEM_CHECK_ENABLED void bt_osi_mem_count_limit_set(uint16_t count_limit); #endif // CONFIG_BT_LE_MEM_CHECK_ENABLED + +#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED +size_t bt_osi_mem_internal_used_size_get(void); +size_t bt_osi_mem_used_size_get(void); +#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED diff --git a/components/bt/porting/mem/bt_osi_mem.c b/components/bt/porting/mem/bt_osi_mem.c index cbedf8c96d..306ec8290e 100644 --- a/components/bt/porting/mem/bt_osi_mem.c +++ b/components/bt/porting/mem/bt_osi_mem.c @@ -11,6 +11,10 @@ #include static uint8_t log_count; +#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED +static size_t controller_mem_used_size = 0; +static size_t host_mem_used_size = 0; +#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED #if CONFIG_BT_LE_MEM_CHECK_ENABLED static uint16_t mem_count_limit = 0; static uint16_t curr_mem_count; @@ -35,24 +39,37 @@ IRAM_ATTR void *bt_osi_mem_malloc(size_t size) } assert(mem != NULL); } +#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED + if(mem) { + host_mem_used_size += heap_caps_get_allocated_size(mem); + } +#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED return mem; } IRAM_ATTR void *bt_osi_mem_calloc(size_t n, size_t size) { + void *mem = NULL; #ifdef CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL - return heap_caps_calloc(n, size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); + mem = heap_caps_calloc(n, size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); #elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL - return heap_caps_calloc(n, size, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT); + mem = heap_caps_calloc(n, size, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT); #elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_IRAM_8BIT - return heap_caps_calloc_prefer(n, size, 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); + mem = heap_caps_calloc_prefer(n, size, 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); #else - return calloc(n, size); + mem = calloc(n, size); #endif +#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED + if(mem) { + host_mem_used_size += heap_caps_get_allocated_size(mem); + } +#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED + return mem; } IRAM_ATTR void *bt_osi_mem_malloc_internal(size_t size) { + void *mem_ptr; #if CONFIG_BT_LE_MEM_CHECK_ENABLED if (mem_count_limit) { if (curr_mem_count > mem_count_limit) { @@ -61,11 +78,18 @@ IRAM_ATTR void *bt_osi_mem_malloc_internal(size_t size) curr_mem_count ++; } #endif // CONFIG_BT_LE_MEM_CHECK_ENABLED - return heap_caps_malloc(size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT|MALLOC_CAP_DMA); + mem_ptr = heap_caps_malloc(size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT|MALLOC_CAP_DMA); +#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED + if (mem_ptr) { + controller_mem_used_size += heap_caps_get_allocated_size(mem_ptr); + } +#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED + return mem_ptr; } IRAM_ATTR void *bt_osi_mem_calloc_internal(size_t n, size_t size) { + void *mem_ptr; #if CONFIG_BT_LE_MEM_CHECK_ENABLED if (mem_count_limit) { if (curr_mem_count > mem_count_limit) { @@ -74,11 +98,36 @@ IRAM_ATTR void *bt_osi_mem_calloc_internal(size_t n, size_t size) curr_mem_count ++; } #endif // CONFIG_BT_LE_MEM_CHECK_ENABLED - return heap_caps_calloc(n, size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT|MALLOC_CAP_DMA); + mem_ptr = heap_caps_calloc(n, size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT|MALLOC_CAP_DMA); +#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED + if (mem_ptr) { + controller_mem_used_size += heap_caps_get_allocated_size(mem_ptr); + } +#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED + return mem_ptr; +} + +IRAM_ATTR void bt_osi_mem_free_internal(void *ptr) +{ +#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED + if (ptr) { + size_t alloc_size = heap_caps_get_allocated_size(ptr); + // assert(controller_mem_used_size >= alloc_size); + controller_mem_used_size -= alloc_size; + } +#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED + heap_caps_free(ptr); } IRAM_ATTR void bt_osi_mem_free(void *ptr) { +#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED + if (ptr) { + size_t alloc_size = heap_caps_get_allocated_size(ptr); + // assert(host_mem_used_size >= alloc_size); + host_mem_used_size -= alloc_size; + } +#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED heap_caps_free(ptr); } @@ -89,3 +138,29 @@ void bt_osi_mem_count_limit_set(uint16_t count_limit) curr_mem_count = 0; } #endif // CONFIG_BT_LE_MEM_CHECK_ENABLED + +#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED +size_t +bt_osi_mem_internal_used_size_get(void) +{ + return controller_mem_used_size; +} + +size_t +bt_osi_mem_used_size_get(void) +{ + return host_mem_used_size; +} + +uint32_t esp_ble_controller_used_heap_size_get(void) +{ + return bt_osi_mem_internal_used_size_get(); +} + +#if CONFIG_BT_NIMBLE_ENABLED +uint32_t esp_host_used_heap_size_get(void) +{ + return bt_osi_mem_used_size_get(); +} +#endif // CONFIG_BT_NIMBLE_ENABLED +#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED diff --git a/components/bt/porting/npl/freertos/src/npl_os_freertos.c b/components/bt/porting/npl/freertos/src/npl_os_freertos.c index 73f425262f..4103e62042 100644 --- a/components/bt/porting/npl/freertos/src/npl_os_freertos.c +++ b/components/bt/porting/npl/freertos/src/npl_os_freertos.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -116,7 +116,7 @@ IRAM_ATTR npl_freertos_event_deinit(struct ble_npl_event *ev) #if OS_MEM_ALLOC os_memblock_put(&ble_freertos_ev_pool,ev->event); #else - bt_osi_mem_free(ev->event); + bt_osi_mem_free_internal(ev->event); #endif ev->event = NULL; } @@ -170,7 +170,7 @@ npl_freertos_eventq_deinit(struct ble_npl_eventq *evq) #if OS_MEM_ALLOC os_memblock_put(&ble_freertos_evq_pool,eventq); #else - bt_osi_mem_free((void *)eventq); + bt_osi_mem_free_internal((void *)eventq); #endif evq->eventq = NULL; } @@ -391,7 +391,7 @@ npl_freertos_mutex_deinit(struct ble_npl_mutex *mu) #if OS_MEM_ALLOC os_memblock_put(&ble_freertos_mutex_pool,mutex); #else - bt_osi_mem_free((void *)mutex); + bt_osi_mem_free_internal((void *)mutex); #endif mu->mutex = NULL; @@ -528,7 +528,7 @@ npl_freertos_sem_deinit(struct ble_npl_sem *sem) #if OS_MEM_ALLOC os_memblock_put(&ble_freertos_sem_pool,semaphore); #else - bt_osi_mem_free((void *)semaphore); + bt_osi_mem_free_internal((void *)semaphore); #endif sem->sem = NULL; @@ -707,7 +707,7 @@ npl_freertos_callout_init(struct ble_npl_callout *co, struct ble_npl_eventq *evq if (esp_timer_create(&create_args, &callout->handle) != ESP_OK) { ble_npl_event_deinit(&callout->ev); - bt_osi_mem_free((void *)callout); + bt_osi_mem_free_internal((void *)callout); co->co = NULL; return -1; } @@ -716,7 +716,7 @@ npl_freertos_callout_init(struct ble_npl_callout *co, struct ble_npl_eventq *evq if (!callout->handle) { ble_npl_event_deinit(&callout->ev); - bt_osi_mem_free((void *)callout); + bt_osi_mem_free_internal((void *)callout); co->co = NULL; return -1; } @@ -764,7 +764,7 @@ npl_freertos_callout_deinit(struct ble_npl_callout *co) #if OS_MEM_ALLOC os_memblock_put(&ble_freertos_co_pool,callout); #else - bt_osi_mem_free((void *)callout); + bt_osi_mem_free_internal((void *)callout); #endif // OS_MEM_ALLOC co->co = NULL; memset(co, 0, sizeof(struct ble_npl_callout)); @@ -1203,27 +1203,27 @@ int npl_freertos_mempool_init(void) return 0; _error: if (ble_freertos_ev_buf) { - bt_osi_mem_free(ble_freertos_ev_buf); + bt_osi_mem_free_internal(ble_freertos_ev_buf); ble_freertos_ev_buf = NULL; } if (ble_freertos_evq_buf) { - bt_osi_mem_free(ble_freertos_evq_buf); + bt_osi_mem_free_internal(ble_freertos_evq_buf); ble_freertos_evq_buf = NULL; } if (ble_freertos_co_buf) { - bt_osi_mem_free(ble_freertos_co_buf); + bt_osi_mem_free_internal(ble_freertos_co_buf); ble_freertos_co_buf = NULL; } if (ble_freertos_sem_buf) { - bt_osi_mem_free(ble_freertos_sem_buf); + bt_osi_mem_free_internal(ble_freertos_sem_buf); ble_freertos_sem_buf = NULL; } if (ble_freertos_mutex_buf) { - bt_osi_mem_free(ble_freertos_mutex_buf); + bt_osi_mem_free_internal(ble_freertos_mutex_buf); ble_freertos_mutex_buf = NULL; } return -1; @@ -1232,23 +1232,23 @@ _error: void npl_freertos_mempool_deinit(void) { if (ble_freertos_ev_buf) { - bt_osi_mem_free(ble_freertos_ev_buf); + bt_osi_mem_free_internal(ble_freertos_ev_buf); ble_freertos_ev_buf = NULL; } if (ble_freertos_evq_buf) { - bt_osi_mem_free(ble_freertos_evq_buf); + bt_osi_mem_free_internal(ble_freertos_evq_buf); ble_freertos_evq_buf = NULL; } if (ble_freertos_co_buf) { - bt_osi_mem_free(ble_freertos_co_buf); + bt_osi_mem_free_internal(ble_freertos_co_buf); ble_freertos_co_buf = NULL; } if (ble_freertos_sem_buf) { - bt_osi_mem_free(ble_freertos_sem_buf); + bt_osi_mem_free_internal(ble_freertos_sem_buf); ble_freertos_sem_buf = NULL; } if (ble_freertos_mutex_buf) { - bt_osi_mem_free(ble_freertos_mutex_buf); + bt_osi_mem_free_internal(ble_freertos_mutex_buf); ble_freertos_mutex_buf = NULL; } } @@ -1256,7 +1256,7 @@ void npl_freertos_mempool_deinit(void) void npl_freertos_funcs_deinit(void) { if (npl_funcs) { - bt_osi_mem_free(npl_funcs); + bt_osi_mem_free_internal(npl_funcs); } npl_funcs = NULL; }