diff --git a/components/bt/common/include/bt_common.h b/components/bt/common/include/bt_common.h index 098082f647..372ea68e7e 100644 --- a/components/bt/common/include/bt_common.h +++ b/components/bt/common/include/bt_common.h @@ -61,6 +61,12 @@ #define HEAP_MEMORY_DEBUG FALSE #endif +#if UC_BT_BLUEDROID_MEM_STATS +#define HEAP_MEMORY_STATS TRUE +#else +#define HEAP_MEMORY_STATS FALSE +#endif + #if UC_BT_BLUEDROID_THREAD_DEBUG #define OSI_THREAD_DEBUG TRUE #else diff --git a/components/bt/common/include/bt_user_config.h b/components/bt/common/include/bt_user_config.h index 7712c90462..b9dd69d8cb 100644 --- a/components/bt/common/include/bt_user_config.h +++ b/components/bt/common/include/bt_user_config.h @@ -107,6 +107,12 @@ #define UC_BT_BLUEDROID_MEM_DEBUG FALSE #endif +#ifdef CONFIG_BT_BLUEDROID_MEM_STATS +#define UC_BT_BLUEDROID_MEM_STATS TRUE +#else +#define UC_BT_BLUEDROID_MEM_STATS FALSE +#endif + #ifdef CONFIG_BT_BLUEDROID_THREAD_DEBUG #define UC_BT_BLUEDROID_THREAD_DEBUG TRUE #else diff --git a/components/bt/common/osi/allocator.c b/components/bt/common/osi/allocator.c index 91ec942eb5..68a5bdb3a4 100644 --- a/components/bt/common/osi/allocator.c +++ b/components/bt/common/osi/allocator.c @@ -20,6 +20,12 @@ #include "bt_common.h" #include "osi/allocator.h" +#if HEAP_MEMORY_STATS +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#endif extern void *pvPortZalloc(size_t size); extern void vPortFree(void *pv); @@ -198,6 +204,28 @@ uint32_t osi_mem_dbg_get_max_size_section(uint8_t index) } #endif +#if HEAP_MEMORY_STATS +static size_t s_mem_used_size = 0; +static SemaphoreHandle_t s_mem_mutex = NULL; + +int osi_mem_init(void) +{ + s_mem_mutex = xSemaphoreCreateMutex(); + if (s_mem_mutex == NULL) { + return -1; + } + return 0; +} + +void osi_mem_deinit(void) +{ + if (s_mem_mutex) { + vSemaphoreDelete(s_mem_mutex); + s_mem_mutex = NULL; + } +} +#endif + char *osi_strdup(const char *str) { size_t size = strlen(str) + 1; // + 1 for the null terminator @@ -224,6 +252,15 @@ void *osi_malloc_func(size_t size) #endif } +#if HEAP_MEMORY_STATS + if (s_mem_mutex != NULL && p != NULL) { + size_t alloc_size = heap_caps_get_allocated_size(p); + xSemaphoreTake(s_mem_mutex, portMAX_DELAY); + s_mem_used_size += alloc_size; + xSemaphoreGive(s_mem_mutex); + } +#endif + return p; } @@ -240,10 +277,45 @@ void *osi_calloc_func(size_t size) #endif } +#if HEAP_MEMORY_STATS + if (s_mem_mutex != NULL && p != NULL) { + size_t alloc_size = heap_caps_get_allocated_size(p); + xSemaphoreTake(s_mem_mutex, portMAX_DELAY); + s_mem_used_size += alloc_size; + xSemaphoreGive(s_mem_mutex); + } +#endif + return p; } void osi_free_func(void *ptr) { - osi_free(ptr); +#if HEAP_MEMORY_DEBUG + osi_mem_dbg_clean(ptr, __func__, __LINE__); +#endif + +#if HEAP_MEMORY_STATS + if (s_mem_mutex != NULL && ptr != NULL) { + size_t free_size = heap_caps_get_allocated_size(ptr); + xSemaphoreTake(s_mem_mutex, portMAX_DELAY); + if (s_mem_used_size >= free_size) { + s_mem_used_size -= free_size; + } else { + OSI_TRACE_ERROR("The size of malloc and free not match: alloc_size=%u free_size=%u", + s_mem_used_size, free_size); + } + xSemaphoreGive(s_mem_mutex); + } +#endif + + free(ptr); } + +#if HEAP_MEMORY_STATS +// Get the size of memory allocated by Bluedroid but not yet freed +uint32_t esp_host_used_heap_size_get(void) +{ + return s_mem_used_size; +} +#endif diff --git a/components/bt/common/osi/include/osi/allocator.h b/components/bt/common/osi/include/osi/allocator.h index 071892ffaf..caba42f3ea 100644 --- a/components/bt/common/osi/include/osi/allocator.h +++ b/components/bt/common/osi/include/osi/allocator.h @@ -24,6 +24,10 @@ #include "bt_common.h" #include "esp_heap_caps.h" +#if HEAP_MEMORY_STATS +int osi_mem_init(void); +void osi_mem_deinit(void); +#endif char *osi_strdup(const char *str); void *osi_malloc_func(size_t size); @@ -109,7 +113,7 @@ do { \ // Memory alloc function with print and assertion when fails #define osi_malloc(size) osi_malloc_func((size)) #define osi_calloc(size) osi_calloc_func((size)) -#define osi_free(p) free((p)) +#define osi_free(p) osi_free_func((p)) #endif /* HEAP_MEMORY_DEBUG */ diff --git a/components/bt/common/osi/pkt_queue.c b/components/bt/common/osi/pkt_queue.c index 81abd1f043..7db2ff3580 100644 --- a/components/bt/common/osi/pkt_queue.c +++ b/components/bt/common/osi/pkt_queue.c @@ -19,7 +19,7 @@ struct pkt_queue { struct pkt_queue *pkt_queue_create(void) { - struct pkt_queue *queue = calloc(1, sizeof(struct pkt_queue)); + struct pkt_queue *queue = osi_calloc(sizeof(struct pkt_queue)); if (queue == NULL) { return NULL; } diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 1ddcc693cf..e3fca2216e 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -357,6 +357,14 @@ menu "Bluedroid debug option" help Bluedroid memory debug + config BT_BLUEDROID_MEM_STATS + bool "Bluedroid memory statistics" + depends on BT_BLUEDROID_ENABLED + depends on !BT_BLUEDROID_MEM_DEBUG + default n + help + Enable Bluedroid memory usage statistics + config BT_BLUEDROID_THREAD_DEBUG bool "Bluedroid thread debug" depends on BT_BLUEDROID_ENABLED diff --git a/components/bt/host/bluedroid/api/esp_bt_main.c b/components/bt/host/bluedroid/api/esp_bt_main.c index 420ea826b8..cf488dd184 100644 --- a/components/bt/host/bluedroid/api/esp_bt_main.c +++ b/components/bt/host/bluedroid/api/esp_bt_main.c @@ -138,6 +138,13 @@ esp_err_t esp_bluedroid_init_with_cfg(esp_bluedroid_config_t *cfg) osi_mem_dbg_init(); #endif +#if HEAP_MEMORY_STATS + if (osi_mem_init() != 0) { + LOG_ERROR("Bluedroid Initialize Fail"); + return ESP_FAIL; + } +#endif + ret = bluedroid_config_init(cfg); if (ret != BT_STATUS_SUCCESS) { LOG_ERROR("Bluedroid stack initialize fail, ret:%d", ret); @@ -228,6 +235,10 @@ esp_err_t esp_bluedroid_deinit(void) bt_hci_log_deinit(); #endif // (BT_HCI_LOG_INCLUDED == TRUE) +#if HEAP_MEMORY_STATS + osi_mem_deinit(); +#endif + s_bt_host_state = ESP_BLUEDROID_STATUS_UNINITIALIZED; return ESP_OK; } diff --git a/components/bt/host/bluedroid/hci/hci_hal_h4.c b/components/bt/host/bluedroid/hci/hci_hal_h4.c index ef30a04992..c6c78a46b3 100644 --- a/components/bt/host/bluedroid/hci/hci_hal_h4.c +++ b/components/bt/host/bluedroid/hci/hci_hal_h4.c @@ -666,7 +666,7 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len) } #endif pkt_size = BT_PKT_LINKED_HDR_SIZE + BT_HDR_SIZE + len; - #if HEAP_MEMORY_DEBUG + #if (HEAP_MEMORY_DEBUG || HEAP_MEMORY_STATS) linked_pkt = (pkt_linked_item_t *) osi_calloc(pkt_size); #else linked_pkt = (pkt_linked_item_t *) osi_calloc_base(pkt_size);