diff --git a/components/bt/common/ble_log/src/ble_log.c b/components/bt/common/ble_log/src/ble_log.c index 97659886b3..ed0625688f 100644 --- a/components/bt/common/ble_log/src/ble_log.c +++ b/components/bt/common/ble_log/src/ble_log.c @@ -46,7 +46,7 @@ bool ble_log_init(void) } /* Initialize BLE Log peripheral interface */ - if (!ble_log_prph_init(BLE_LOG_LBM_CNT)) { + if (!ble_log_prph_init(BLE_LOG_TRANS_TOTAL_CNT)) { goto exit; } diff --git a/components/bt/common/ble_log/src/ble_log_lbm.c b/components/bt/common/ble_log/src/ble_log_lbm.c index 5112c2474a..a57fe01532 100644 --- a/components/bt/common/ble_log/src/ble_log_lbm.c +++ b/components/bt/common/ble_log/src/ble_log_lbm.c @@ -203,11 +203,12 @@ bool ble_log_lbm_init(void) ble_log_lbm_t *lbm; for (int i = 0; i < BLE_LOG_LBM_COMMON_CNT; i++) { lbm = &(lbm_ctx->lbm_common_pool[i]); - for (int j = 0; j < BLE_LOG_TRANS_PING_PONG_BUF_CNT; j++) { + for (int j = 0; j < BLE_LOG_TRANS_BUF_CNT; j++) { if (!ble_log_prph_trans_init(&(lbm->trans[j]), - CONFIG_BLE_LOG_LBM_TRANS_SIZE)) { + BLE_LOG_TRANS_SIZE)) { goto exit; } + lbm->trans[j]->owner = (void *)lbm; } } @@ -225,11 +226,12 @@ bool ble_log_lbm_init(void) #if CONFIG_BLE_LOG_LL_ENABLED for (int i = 0; i < BLE_LOG_LBM_LL_MAX; i++) { lbm = &(lbm_ctx->lbm_ll_pool[i]); - for (int j = 0; j < BLE_LOG_TRANS_PING_PONG_BUF_CNT; j++) { + for (int j = 0; j < BLE_LOG_TRANS_BUF_CNT; j++) { if (!ble_log_prph_trans_init(&(lbm->trans[j]), - CONFIG_BLE_LOG_LBM_LL_TRANS_SIZE)) { + BLE_LOG_TRANS_LL_SIZE)) { goto exit; } + lbm->trans[j]->owner = (void *)lbm; } } @@ -286,7 +288,7 @@ void ble_log_lbm_deinit(void) ble_log_lbm_t *lbm; for (int i = 0; i < BLE_LOG_LBM_CNT; i++) { lbm = &(lbm_ctx->lbm_pool[i]); - for (int j = 0; j < BLE_LOG_TRANS_PING_PONG_BUF_CNT; j++) { + for (int j = 0; j < BLE_LOG_TRANS_BUF_CNT; j++) { ble_log_prph_trans_deinit(&(lbm->trans[j])); } } @@ -302,9 +304,9 @@ ble_log_prph_trans_t **ble_log_lbm_get_trans(ble_log_lbm_t *lbm, size_t log_len) { /* Check if available buffer can contain incoming log */ ble_log_prph_trans_t **trans; - for (int i = 0; i < BLE_LOG_TRANS_PING_PONG_BUF_CNT; i++) { + for (int i = 0; i < BLE_LOG_TRANS_BUF_CNT; i++) { trans = &(lbm->trans[lbm->trans_idx]); - if (!(*trans)->prph_owned) { + if (!__atomic_load_n(&(*trans)->prph_owned, __ATOMIC_ACQUIRE)) { /* Return if there's enough free space in current transport */ if (BLE_LOG_TRANS_FREE_SPACE((*trans)) >= (log_len + BLE_LOG_FRAME_OVERHEAD)) { return trans; @@ -317,10 +319,10 @@ ble_log_prph_trans_t **ble_log_lbm_get_trans(ble_log_lbm_t *lbm, size_t log_len) } /* Current transport unavailable, switch to the other */ - lbm->trans_idx = !lbm->trans_idx; + lbm->trans_idx = (lbm->trans_idx + 1) & (BLE_LOG_TRANS_BUF_CNT - 1); } - /* Both ping-pong buffers are unavailable */ + /* All buffers are unavailable */ return NULL; } @@ -414,16 +416,70 @@ BLE_LOG_IRAM_ATTR void ble_log_lbm_stream_flush(ble_log_lbm_t *lbm, ble_log_src_t src_code) { int trans_idx = lbm->trans_idx; - for (int i = 0; i < BLE_LOG_TRANS_PING_PONG_BUF_CNT; i++) { + for (int i = 0; i < BLE_LOG_TRANS_BUF_CNT; i++) { ble_log_prph_trans_t **trans = &(lbm->trans[trans_idx]); - if (!(*trans)->prph_owned && (*trans)->pos > BLE_LOG_FRAME_HEAD_LEN) { + if (!__atomic_load_n(&(*trans)->prph_owned, __ATOMIC_ACQUIRE) && + (*trans)->pos > BLE_LOG_FRAME_HEAD_LEN) { ble_log_lbm_stream_seal(trans, src_code); } - trans_idx = (trans_idx + 1) % BLE_LOG_TRANS_PING_PONG_BUF_CNT; + trans_idx = (trans_idx + 1) & (BLE_LOG_TRANS_BUF_CNT - 1); } } #endif /* BLE_LOG_UART_REDIR_ENABLED */ +BLE_LOG_STATIC void ble_log_emit_buf_util(ble_log_lbm_t *lbm, uint8_t lbm_id) +{ + ble_log_buf_util_t util = { + .int_src_code = BLE_LOG_INT_SRC_BUF_UTIL, + .lbm_id = lbm_id, + .trans_cnt = BLE_LOG_TRANS_BUF_CNT, + .inflight_peak = (uint8_t)__atomic_exchange_n( + &lbm->trans_inflight_peak, 0, __ATOMIC_RELAXED), + }; + ble_log_write_hex(BLE_LOG_SRC_INTERNAL, + (const uint8_t *)&util, sizeof(ble_log_buf_util_t)); +} + +void ble_log_write_buf_util(void) +{ + BLE_LOG_REF_COUNT_ACQUIRE(&lbm_ref_count); + if (!lbm_enabled) { + goto deref; + } + + ble_log_emit_buf_util(&lbm_ctx->spin_task, + BLE_LOG_BUF_UTIL_MAKE_ID(BLE_LOG_BUF_UTIL_POOL_COMMON_TASK, 0)); + for (int i = 0; i < BLE_LOG_LBM_ATOMIC_TASK_CNT; i++) { + ble_log_emit_buf_util(&lbm_ctx->atomic_pool_task[i], + BLE_LOG_BUF_UTIL_MAKE_ID(BLE_LOG_BUF_UTIL_POOL_COMMON_TASK, 1 + i)); + } + + ble_log_emit_buf_util(&lbm_ctx->spin_isr, + BLE_LOG_BUF_UTIL_MAKE_ID(BLE_LOG_BUF_UTIL_POOL_COMMON_ISR, 0)); + for (int i = 0; i < BLE_LOG_LBM_ATOMIC_ISR_CNT; i++) { + ble_log_emit_buf_util(&lbm_ctx->atomic_pool_isr[i], + BLE_LOG_BUF_UTIL_MAKE_ID(BLE_LOG_BUF_UTIL_POOL_COMMON_ISR, 1 + i)); + } + +#if CONFIG_BLE_LOG_LL_ENABLED + ble_log_emit_buf_util(&lbm_ctx->lbm_ll_task, + BLE_LOG_BUF_UTIL_MAKE_ID(BLE_LOG_BUF_UTIL_POOL_LL, 0)); + ble_log_emit_buf_util(&lbm_ctx->lbm_ll_hci, + BLE_LOG_BUF_UTIL_MAKE_ID(BLE_LOG_BUF_UTIL_POOL_LL, 1)); +#endif + +#if BLE_LOG_UART_REDIR_ENABLED + ble_log_lbm_t *redir_lbm = ble_log_prph_get_redir_lbm(); + if (redir_lbm) { + ble_log_emit_buf_util(redir_lbm, + BLE_LOG_BUF_UTIL_MAKE_ID(BLE_LOG_BUF_UTIL_POOL_REDIR, 0)); + } +#endif + +deref: + BLE_LOG_REF_COUNT_RELEASE(&lbm_ref_count); +} + /* ------------------------ */ /* PUBLIC INTERFACE */ /* ------------------------ */ @@ -445,6 +501,7 @@ void ble_log_flush(void) /* Write enhanced statistics before module disable */ ble_log_write_enh_stat(); + ble_log_write_buf_util(); /* Write BLE Log flush log */ ble_log_info_t ble_log_info = { @@ -470,12 +527,13 @@ void ble_log_flush(void) for (int i = 0; i < BLE_LOG_LBM_CNT; i++) { lbm = &(lbm_ctx->lbm_pool[i]); int trans_idx = lbm->trans_idx; - for (int j = 0; j < BLE_LOG_TRANS_PING_PONG_BUF_CNT; j++) { + for (int j = 0; j < BLE_LOG_TRANS_BUF_CNT; j++) { trans = &(lbm->trans[trans_idx]); - if (!(*trans)->prph_owned && (*trans)->pos) { + if (!__atomic_load_n(&(*trans)->prph_owned, __ATOMIC_ACQUIRE) && + (*trans)->pos) { ble_log_rt_queue_trans(trans); } - trans_idx = !trans_idx; + trans_idx = (trans_idx + 1) & (BLE_LOG_TRANS_BUF_CNT - 1); } } @@ -486,9 +544,9 @@ void ble_log_flush(void) in_progress = false; for (int i = 0; i < BLE_LOG_LBM_CNT; i++) { lbm = &(lbm_ctx->lbm_pool[i]); - for (int j = 0; j < BLE_LOG_TRANS_PING_PONG_BUF_CNT; j++) { + for (int j = 0; j < BLE_LOG_TRANS_BUF_CNT; j++) { trans = &(lbm->trans[j]); - in_progress |= (*trans)->prph_owned; + in_progress |= __atomic_load_n(&(*trans)->prph_owned, __ATOMIC_ACQUIRE); } } if (in_progress) { @@ -502,6 +560,13 @@ void ble_log_flush(void) BLE_LOG_MEMSET(stat_mgr_ctx[i], 0, sizeof(ble_log_stat_mgr_t)); } + for (int i = 0; i < BLE_LOG_LBM_CNT; i++) { + lbm = &(lbm_ctx->lbm_pool[i]); + __atomic_store_n(&lbm->trans_inflight, 0, __ATOMIC_RELAXED); + __atomic_store_n(&lbm->trans_inflight_peak, 0, __ATOMIC_RELAXED); + } + ble_log_prph_reset_util_counters(); + /* Resume enable status */ lbm_enabled = lbm_enabled_copy; @@ -633,7 +698,7 @@ void ble_log_dump_to_console(void) for (int i = 0; i < BLE_LOG_LBM_CNT; i++) { lbm = &(lbm_ctx->lbm_pool[i]); trans_idx = lbm->trans_idx; - for (int j = 0; j < BLE_LOG_TRANS_PING_PONG_BUF_CNT; j++) { + for (int j = 0; j < BLE_LOG_TRANS_BUF_CNT; j++) { trans = lbm->trans[trans_idx]; BLE_LOG_FEED_WDT(); @@ -643,7 +708,7 @@ void ble_log_dump_to_console(void) BLE_LOG_FEED_WDT(); } } - trans_idx = !trans_idx; + trans_idx = (trans_idx + 1) & (BLE_LOG_TRANS_BUF_CNT - 1); } } BLE_LOG_CONSOLE("\n:BLE_LOG_DUMP_END]\n\n"); diff --git a/components/bt/common/ble_log/src/ble_log_rt.c b/components/bt/common/ble_log/src/ble_log_rt.c index 8b680d0bac..c055dcd0fc 100644 --- a/components/bt/common/ble_log/src/ble_log_rt.c +++ b/components/bt/common/ble_log/src/ble_log_rt.c @@ -70,6 +70,7 @@ BLE_LOG_IRAM_ATTR BLE_LOG_STATIC void ble_log_rt_task(void *pvParameters) #endif /* CONFIG_BLE_LOG_TS_TRIGGER_TASK_EVENT */ ble_log_write_enh_stat(); + ble_log_write_buf_util(); } } @@ -100,7 +101,7 @@ bool ble_log_rt_init(void) /* CRITICAL: * Queue must be initialized before creating task */ - rt_queue_handle = xQueueCreate(BLE_LOG_LBM_CNT, sizeof(ble_log_prph_trans_t *)); + rt_queue_handle = xQueueCreate(BLE_LOG_TRANS_TOTAL_CNT, sizeof(ble_log_prph_trans_t *)); if (!rt_queue_handle) { goto exit; } @@ -170,9 +171,22 @@ void ble_log_rt_deinit(void) BLE_LOG_IRAM_ATTR void ble_log_rt_queue_trans(ble_log_prph_trans_t **trans) { - (*trans)->prph_owned = true; + __atomic_store_n(&(*trans)->prph_owned, true, __ATOMIC_RELAXED); + + ble_log_lbm_t *lbm = (ble_log_lbm_t *)(*trans)->owner; + uint32_t inflight = __atomic_add_fetch(&lbm->trans_inflight, 1, __ATOMIC_RELAXED); + uint32_t peak = __atomic_load_n(&lbm->trans_inflight_peak, __ATOMIC_RELAXED); + while (inflight > peak) { + if (__atomic_compare_exchange_n(&lbm->trans_inflight_peak, &peak, inflight, + true, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) { + break; + } + } + if (BLE_LOG_IN_ISR()) { - xQueueSendFromISR(rt_queue_handle, trans, NULL); + BaseType_t woken = pdFALSE; + xQueueSendFromISR(rt_queue_handle, trans, &woken); + portYIELD_FROM_ISR(woken); } else { xQueueSend(rt_queue_handle, trans, portMAX_DELAY); } diff --git a/components/bt/common/ble_log/src/prph/ble_log_prph_dummy.c b/components/bt/common/ble_log/src/prph/ble_log_prph_dummy.c index 4fd9c48a7f..838aec67a5 100644 --- a/components/bt/common/ble_log/src/prph/ble_log_prph_dummy.c +++ b/components/bt/common/ble_log/src/prph/ble_log_prph_dummy.c @@ -9,6 +9,7 @@ /* INCLUDE */ #include "ble_log_prph_dummy.h" +#include "ble_log_lbm.h" /* INTERFACE */ bool ble_log_prph_init(size_t trans_cnt) @@ -80,7 +81,16 @@ void ble_log_prph_trans_deinit(ble_log_prph_trans_t **trans) *trans = NULL; } +/* Dummy transport has no DMA/hardware -- recycle the buffer immediately + * so that ble_log_lbm_get_trans() can reuse it and ble_log_flush() does + * not hang waiting for prph_owned to clear. Real peripherals (UART DMA, + * SPI DMA) do the same work inside their asynchronous tx_done callbacks. */ void ble_log_prph_send_trans(ble_log_prph_trans_t *trans) { - (void)trans; + trans->pos = 0; + ble_log_lbm_t *lbm = (ble_log_lbm_t *)trans->owner; + __atomic_fetch_sub(&lbm->trans_inflight, 1, __ATOMIC_RELAXED); + __atomic_store_n(&trans->prph_owned, false, __ATOMIC_RELEASE); } + +void ble_log_prph_reset_util_counters(void) {} diff --git a/components/bt/common/ble_log/src/prph/ble_log_prph_spi_master_dma.c b/components/bt/common/ble_log/src/prph/ble_log_prph_spi_master_dma.c index 41cbfd1721..41f7975938 100644 --- a/components/bt/common/ble_log/src/prph/ble_log_prph_spi_master_dma.c +++ b/components/bt/common/ble_log/src/prph/ble_log_prph_spi_master_dma.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +9,7 @@ /* INCLUDE */ #include "ble_log_prph_spi_master_dma.h" +#include "ble_log_lbm.h" #include "esp_timer.h" @@ -35,7 +36,9 @@ BLE_LOG_IRAM_ATTR BLE_LOG_STATIC void spi_master_dma_tx_done_cb(spi_transaction_ /* Recycle transport */ ble_log_prph_trans_t *trans = (ble_log_prph_trans_t *)(spi_trans->user); trans->pos = 0; - trans->prph_owned = false; + ble_log_lbm_t *lbm = (ble_log_lbm_t *)trans->owner; + __atomic_fetch_sub(&lbm->trans_inflight, 1, __ATOMIC_RELAXED); + __atomic_store_n(&trans->prph_owned, false, __ATOMIC_RELEASE); } BLE_LOG_IRAM_ATTR BLE_LOG_STATIC void spi_master_dma_pre_tx_cb(spi_transaction_t *spi_trans) @@ -179,6 +182,10 @@ BLE_LOG_IRAM_ATTR void ble_log_prph_send_trans(ble_log_prph_trans_t *trans) spi_trans->length = (trans->pos << 3); spi_trans->rxlength = 0; if (spi_device_queue_trans(dev_handle, spi_trans, 0) != ESP_OK) { - trans->prph_owned = false; + ble_log_lbm_t *lbm = (ble_log_lbm_t *)trans->owner; + __atomic_fetch_sub(&lbm->trans_inflight, 1, __ATOMIC_RELAXED); + __atomic_store_n(&trans->prph_owned, false, __ATOMIC_RELEASE); } } + +void ble_log_prph_reset_util_counters(void) {} diff --git a/components/bt/common/ble_log/src/prph/ble_log_prph_uart_dma.c b/components/bt/common/ble_log/src/prph/ble_log_prph_uart_dma.c index 4b55975820..73c9792fab 100644 --- a/components/bt/common/ble_log/src/prph/ble_log_prph_uart_dma.c +++ b/components/bt/common/ble_log/src/prph/ble_log_prph_uart_dma.c @@ -10,11 +10,11 @@ /* INCLUDE */ #include "ble_log_prph_uart_dma.h" - -#if BLE_LOG_PRPH_UART_DMA_REDIR #include "ble_log.h" #include "ble_log_lbm.h" +#if BLE_LOG_PRPH_UART_DMA_REDIR + #include "esp_timer.h" #include "driver/uart.h" #include "driver/uart_vfs.h" @@ -56,7 +56,9 @@ BLE_LOG_IRAM_ATTR BLE_LOG_STATIC bool uart_dma_tx_done_cb( ); ble_log_prph_trans_t *trans = uart_trans_ctx->trans; trans->pos = 0; - trans->prph_owned = false; + ble_log_lbm_t *lbm = (ble_log_lbm_t *)trans->owner; + __atomic_fetch_sub(&lbm->trans_inflight, 1, __ATOMIC_RELAXED); + __atomic_store_n(&trans->prph_owned, false, __ATOMIC_RELEASE); return true; } @@ -128,11 +130,12 @@ bool ble_log_prph_init(size_t trans_cnt) redir_lbm->lock_type = BLE_LOG_LBM_LOCK_MUTEX; /* Transport initialization */ - for (int i = 0; i < BLE_LOG_TRANS_PING_PONG_BUF_CNT; i++) { + for (int i = 0; i < BLE_LOG_TRANS_BUF_CNT; i++) { if (!ble_log_prph_trans_init(&(redir_lbm->trans[i]), BLE_LOG_UART_REDIR_BUF_SIZE)) { goto exit; } + redir_lbm->trans[i]->owner = (void *)redir_lbm; } /* Mutex initialization */ @@ -197,7 +200,7 @@ void ble_log_prph_deinit(void) } /* Release transport */ - for (int i = 0; i < BLE_LOG_TRANS_PING_PONG_BUF_CNT; i++) { + for (int i = 0; i < BLE_LOG_TRANS_BUF_CNT; i++) { ble_log_prph_trans_deinit(&(redir_lbm->trans[i])); } @@ -271,7 +274,9 @@ void ble_log_prph_trans_deinit(ble_log_prph_trans_t **trans) BLE_LOG_IRAM_ATTR void ble_log_prph_send_trans(ble_log_prph_trans_t *trans) { if (uhci_transmit(dev_handle, trans->buf, trans->pos) != ESP_OK) { - trans->prph_owned = false; + ble_log_lbm_t *lbm = (ble_log_lbm_t *)trans->owner; + __atomic_fetch_sub(&lbm->trans_inflight, 1, __ATOMIC_RELAXED); + __atomic_store_n(&trans->prph_owned, false, __ATOMIC_RELEASE); } } @@ -316,4 +321,19 @@ int __wrap_uart_write_bytes_with_break(uart_port_t uart_num, const void *src, si return __wrap_uart_write_bytes(uart_num, src, size); } } + +ble_log_lbm_t *ble_log_prph_get_redir_lbm(void) +{ + return redir_lbm; +} #endif /* BLE_LOG_PRPH_UART_DMA_REDIR */ + +void ble_log_prph_reset_util_counters(void) +{ +#if BLE_LOG_PRPH_UART_DMA_REDIR + if (redir_lbm) { + __atomic_store_n(&redir_lbm->trans_inflight, 0, __ATOMIC_RELAXED); + __atomic_store_n(&redir_lbm->trans_inflight_peak, 0, __ATOMIC_RELAXED); + } +#endif +}