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 9b1dd64c92c..7bed717b2c9 100644 --- a/components/bt/common/ble_log/src/ble_log_lbm.c +++ b/components/bt/common/ble_log/src/ble_log_lbm.c @@ -515,6 +515,14 @@ bool ble_log_enable(bool enable) void ble_log_flush(void) { + /* Prevent concurrent flush — two concurrent callers would deadlock on + * the ref_count spin-wait (both hold a ref, both wait for ref_count <= 1). + * Second caller returns immediately instead of deadlocking. */ + static volatile bool flush_in_progress = false; + if (__atomic_test_and_set(&flush_in_progress, __ATOMIC_ACQUIRE)) { + return; + } + BLE_LOG_REF_COUNT_ACQUIRE(&lbm_ref_count); if (!lbm_inited) { goto deref; @@ -535,7 +543,7 @@ void ble_log_flush(void) bool lbm_enabled_copy = lbm_enabled; lbm_enabled = false; uint32_t time_waited = 0; - while (lbm_ref_count > 1) { + while (__atomic_load_n(&lbm_ref_count, __ATOMIC_ACQUIRE) > 1) { vTaskDelay(pdMS_TO_TICKS(1)); BLE_LOG_ASSERT(time_waited++ < 1000); } @@ -593,6 +601,7 @@ void ble_log_flush(void) deref: BLE_LOG_REF_COUNT_RELEASE(&lbm_ref_count); + __atomic_clear(&flush_in_progress, __ATOMIC_RELEASE); } BLE_LOG_IRAM_ATTR 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 41f7975938c..293f70b2c63 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 @@ -97,12 +97,11 @@ void ble_log_prph_deinit(void) { prph_inited = false; if (dev_handle) { - /* Drain all queued transactions */ if (spi_device_acquire_bus(dev_handle, portMAX_DELAY) == ESP_OK) { spi_device_release_bus(dev_handle); - spi_bus_remove_device(dev_handle); - dev_handle = NULL; } + spi_bus_remove_device(dev_handle); + dev_handle = NULL; } /* Note: We don't care if the bus has been inited or not */ 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 73c9792fabe..f21ff5f291c 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 @@ -18,6 +18,7 @@ #include "esp_timer.h" #include "driver/uart.h" #include "driver/uart_vfs.h" +#include "freertos/task.h" #endif /* BLE_LOG_PRPH_UART_DMA_REDIR */ /* MACRO */ @@ -146,8 +147,9 @@ bool ble_log_prph_init(size_t trans_cnt) /* Initialize UART driver for redirection */ if (!uart_is_driver_installed(UART_NUM_0)) { - uart_driver_install(UART_NUM_0, BLE_LOG_UART_RX_BUF_SIZE, 0, 0, NULL, 0); - uart_driver_inited = true; + if (uart_driver_install(UART_NUM_0, BLE_LOG_UART_RX_BUF_SIZE, 0, 0, NULL, 0) == ESP_OK) { + uart_driver_inited = true; + } } uart_vfs_dev_use_driver(UART_NUM_0); @@ -285,6 +287,9 @@ BLE_LOG_IRAM_ATTR void ble_log_prph_send_trans(ble_log_prph_trans_t *trans) BLE_LOG_IRAM_ATTR BLE_LOG_STATIC void ble_log_redir_uart_tx_chars(const char *src, size_t len) { + if (BLE_LOG_IN_ISR() || xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED) { + return; + } xSemaphoreTake(redir_lbm->mutex, portMAX_DELAY); ble_log_lbm_stream_write(redir_lbm, BLE_LOG_SRC_REDIR, (const uint8_t *)src, len);