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 f3823273c63..aa30829b840 100644 --- a/components/bt/common/ble_log/src/ble_log_lbm.c +++ b/components/bt/common/ble_log/src/ble_log_lbm.c @@ -182,7 +182,9 @@ BLE_LOG_STATIC void ble_log_lbm_reset_stats(void) __atomic_store_n(&lbm->trans_inflight, 0, __ATOMIC_RELAXED); __atomic_store_n(&lbm->trans_inflight_peak, 0, __ATOMIC_RELAXED); } +#if CONFIG_BLE_LOG_PRPH_UART_DMA ble_log_prph_reset_util_counters(); +#endif } BLE_LOG_IRAM_ATTR BLE_LOG_STATIC @@ -309,6 +311,17 @@ failed: /* -------------------------- */ /* INTERNAL INTERFACE */ /* -------------------------- */ +/* CRITICAL: + * Recycle a transport back to its LBM pool after the send completes or fails. + * Leaves trans->pos untouched on purpose: a failed send keeps its buffered data + * so the next flush re-queues it (flush re-sends any trans with pos != 0) */ +BLE_LOG_IRAM_ATTR void ble_log_lbm_recycle_trans(ble_log_prph_trans_t *trans) +{ + 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); +} + bool ble_log_lbm_init(void) { /* Avoid double init */ 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 e256c214217..3c4e21505eb 100644 --- a/components/bt/common/ble_log/src/ble_log_rt.c +++ b/components/bt/common/ble_log/src/ble_log_rt.c @@ -166,10 +166,8 @@ void ble_log_rt_deinit(void) if (rt_queue_handle) { ble_log_prph_trans_t *trans = NULL; while (xQueueReceive(rt_queue_handle, &trans, 0) == pdTRUE) { - ble_log_lbm_t *lbm = (ble_log_lbm_t *)trans->owner; trans->pos = 0; - __atomic_fetch_sub(&lbm->trans_inflight, 1, __ATOMIC_RELAXED); - __atomic_store_n(&trans->prph_owned, false, __ATOMIC_RELEASE); + ble_log_lbm_recycle_trans(trans); } vQueueDelete(rt_queue_handle); rt_queue_handle = NULL; diff --git a/components/bt/common/ble_log/src/internal_include/ble_log_lbm.h b/components/bt/common/ble_log/src/internal_include/ble_log_lbm.h index e63e6ff3a6e..9a2778281ae 100644 --- a/components/bt/common/ble_log/src/internal_include/ble_log_lbm.h +++ b/components/bt/common/ble_log/src/internal_include/ble_log_lbm.h @@ -257,6 +257,7 @@ _Static_assert(BLE_LOG_TRANS_BUF_CNT <= 255, bool ble_log_lbm_init(void); void ble_log_lbm_deinit(void); void ble_log_lbm_enable(bool enable); +void ble_log_lbm_recycle_trans(ble_log_prph_trans_t *trans); bool ble_log_write_internal(const uint8_t *addr, size_t len); void ble_log_write_final_stat(void); void ble_log_write_enh_stat(void); diff --git a/components/bt/common/ble_log/src/internal_include/ble_log_util.h b/components/bt/common/ble_log/src/internal_include/ble_log_util.h index a3699fe41dd..e1335dda5f5 100644 --- a/components/bt/common/ble_log/src/internal_include/ble_log_util.h +++ b/components/bt/common/ble_log/src/internal_include/ble_log_util.h @@ -48,6 +48,9 @@ #define BLE_LOG_MEM_CAP (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA) #define BLE_LOG_MALLOC(size) heap_caps_malloc(size, BLE_LOG_MEM_CAP) #define BLE_LOG_FREE(ptr) heap_caps_free(ptr) +/* GDMA burst alignment: weighted arbitration requires buffers aligned to burst size (32B) */ +#define BLE_LOG_BUF_ALIGN_BYTES (32U) +#define BLE_LOG_ALIGNED_MALLOC(size) heap_caps_aligned_alloc(BLE_LOG_BUF_ALIGN_BYTES, size, BLE_LOG_MEM_CAP) #define BLE_LOG_MEMCPY(dst, src, len) memcpy(dst, src, len) #define BLE_LOG_MEMSET(ptr, value, len) memset(ptr, value, len) @@ -103,6 +106,7 @@ void mocked_memcpy(void *dst, const void *src, size_t len); void mocked_memset(void *ptr, int value, size_t len); #define BLE_LOG_MALLOC(size) mocked_malloc(size) #define BLE_LOG_FREE(ptr) mocked_free(ptr) +#define BLE_LOG_ALIGNED_MALLOC(size) mocked_malloc(size) #define BLE_LOG_MEMCPY(dst, src, len) mocked_memcpy(dst, src, len) #define BLE_LOG_MEMSET(ptr, value, len) mocked_memset(ptr, value, len) 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 838aec67a54..e00c3b0f1fe 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 @@ -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 */ @@ -88,9 +88,5 @@ void ble_log_prph_trans_deinit(ble_log_prph_trans_t **trans) void ble_log_prph_send_trans(ble_log_prph_trans_t *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); + ble_log_lbm_recycle_trans(trans); } - -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 f3f8c33c64a..e1a7167a7ea 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 @@ -44,9 +44,7 @@ BLE_LOG_SPI_MASTER_DMA_CB_ATTR BLE_LOG_STATIC void spi_master_dma_tx_done_cb(spi /* Recycle transport */ ble_log_prph_trans_t *trans = (ble_log_prph_trans_t *)(spi_trans->user); 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); + ble_log_lbm_recycle_trans(trans); } BLE_LOG_SPI_MASTER_DMA_CB_ATTR BLE_LOG_STATIC void spi_master_dma_pre_tx_cb(spi_transaction_t *spi_trans) @@ -141,7 +139,7 @@ bool ble_log_prph_trans_init(ble_log_prph_trans_t **trans, size_t trans_size) (*trans)->ctx = (void *)spi_trans_ctx; /* Initialize log buffer */ - (*trans)->buf = (uint8_t *)BLE_LOG_MALLOC(trans_size); + (*trans)->buf = (uint8_t *)BLE_LOG_ALIGNED_MALLOC(trans_size); if (!(*trans)->buf) { goto exit; } @@ -204,10 +202,6 @@ BLE_LOG_IRAM_ATTR void ble_log_prph_send_trans(ble_log_prph_trans_t *trans) spi_trans->length = (tx_len << 3); spi_trans->rxlength = 0; if (spi_device_queue_trans(dev_handle, spi_trans, 0) != ESP_OK) { - 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_lbm_recycle_trans(trans); } } - -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 10479ede883..de52fb58c21 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 @@ -24,7 +24,10 @@ /* MACRO */ #define BLE_LOG_UART_MAX_TRANSFER_SIZE (10240) #define BLE_LOG_UART_RX_BUF_SIZE (256) -#define BLE_LOG_UART_DMA_BURST_SIZE (32) +/* ponytail: data burst disabled — UHCI enforces burst-size alignment (addr+len) on + * uhci_transmit() once GDMA weighted arbitration is enabled, and UART log bandwidth + * is baud-rate limited anyway, so burst buys nothing here */ +#define BLE_LOG_UART_DMA_BURST_SIZE (0) #if BLE_LOG_PRPH_UART_DMA_REDIR #define BLE_LOG_UART_REDIR_BUF_SIZE (512) #define BLE_LOG_UART_REDIR_FLUSH_PERIOD_US (1000 * 1000) @@ -57,9 +60,7 @@ 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; - 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_lbm_recycle_trans(trans); return true; } @@ -276,9 +277,7 @@ 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) { - 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_lbm_recycle_trans(trans); } }