mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +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)
|
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);
|
BLE_LOG_REF_COUNT_ACQUIRE(&lbm_ref_count);
|
||||||
if (!lbm_inited) {
|
if (!lbm_inited) {
|
||||||
goto deref;
|
goto deref;
|
||||||
@@ -535,7 +543,7 @@ void ble_log_flush(void)
|
|||||||
bool lbm_enabled_copy = lbm_enabled;
|
bool lbm_enabled_copy = lbm_enabled;
|
||||||
lbm_enabled = false;
|
lbm_enabled = false;
|
||||||
uint32_t time_waited = 0;
|
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));
|
vTaskDelay(pdMS_TO_TICKS(1));
|
||||||
BLE_LOG_ASSERT(time_waited++ < 1000);
|
BLE_LOG_ASSERT(time_waited++ < 1000);
|
||||||
}
|
}
|
||||||
@@ -593,6 +601,7 @@ void ble_log_flush(void)
|
|||||||
|
|
||||||
deref:
|
deref:
|
||||||
BLE_LOG_REF_COUNT_RELEASE(&lbm_ref_count);
|
BLE_LOG_REF_COUNT_RELEASE(&lbm_ref_count);
|
||||||
|
__atomic_clear(&flush_in_progress, __ATOMIC_RELEASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
BLE_LOG_IRAM_ATTR
|
BLE_LOG_IRAM_ATTR
|
||||||
|
|||||||
@@ -97,12 +97,11 @@ void ble_log_prph_deinit(void)
|
|||||||
{
|
{
|
||||||
prph_inited = false;
|
prph_inited = false;
|
||||||
if (dev_handle) {
|
if (dev_handle) {
|
||||||
/* Drain all queued transactions */
|
|
||||||
if (spi_device_acquire_bus(dev_handle, portMAX_DELAY) == ESP_OK) {
|
if (spi_device_acquire_bus(dev_handle, portMAX_DELAY) == ESP_OK) {
|
||||||
spi_device_release_bus(dev_handle);
|
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 */
|
/* Note: We don't care if the bus has been inited or not */
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "esp_timer.h"
|
#include "esp_timer.h"
|
||||||
#include "driver/uart.h"
|
#include "driver/uart.h"
|
||||||
#include "driver/uart_vfs.h"
|
#include "driver/uart_vfs.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
#endif /* BLE_LOG_PRPH_UART_DMA_REDIR */
|
#endif /* BLE_LOG_PRPH_UART_DMA_REDIR */
|
||||||
|
|
||||||
/* MACRO */
|
/* MACRO */
|
||||||
@@ -146,8 +147,9 @@ bool ble_log_prph_init(size_t trans_cnt)
|
|||||||
|
|
||||||
/* Initialize UART driver for redirection */
|
/* Initialize UART driver for redirection */
|
||||||
if (!uart_is_driver_installed(UART_NUM_0)) {
|
if (!uart_is_driver_installed(UART_NUM_0)) {
|
||||||
uart_driver_install(UART_NUM_0, BLE_LOG_UART_RX_BUF_SIZE, 0, 0, NULL, 0);
|
if (uart_driver_install(UART_NUM_0, BLE_LOG_UART_RX_BUF_SIZE, 0, 0, NULL, 0) == ESP_OK) {
|
||||||
uart_driver_inited = true;
|
uart_driver_inited = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
uart_vfs_dev_use_driver(UART_NUM_0);
|
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
|
BLE_LOG_IRAM_ATTR BLE_LOG_STATIC
|
||||||
void ble_log_redir_uart_tx_chars(const char *src, size_t len)
|
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);
|
xSemaphoreTake(redir_lbm->mutex, portMAX_DELAY);
|
||||||
ble_log_lbm_stream_write(redir_lbm, BLE_LOG_SRC_REDIR,
|
ble_log_lbm_stream_write(redir_lbm, BLE_LOG_SRC_REDIR,
|
||||||
(const uint8_t *)src, len);
|
(const uint8_t *)src, len);
|
||||||
|
|||||||
Reference in New Issue
Block a user