mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
fix(ble_log): fix crash and resource issues in peripheral drivers
- Handle scheduler-suspended and ISR context in UART redirect path to prevent xSemaphoreTake crash during light sleep (C1) - Check uart_driver_install return value before setting inited flag (M1) - Always clean up SPI device handle in deinit even if acquire_bus fails (M4)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user