From ce199326a184aa4953a35ff3ef0e16088b6591f7 Mon Sep 17 00:00:00 2001 From: Tomer27cz Date: Fri, 23 Jan 2026 21:04:55 +0100 Subject: [PATCH] Improve UART locking and fallback read logic Refactored XT211Uart to handle cases where the lock is not initialized, preventing null dereference. Added fallback to base read_array for non-hardware UARTs in read_array_quick_, improving compatibility with BLE-backed UARTs. --- components/xt211/xt211_uart.h | 41 +++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/components/xt211/xt211_uart.h b/components/xt211/xt211_uart.h index 591cb8c..f1c2ab8 100644 --- a/components/xt211/xt211_uart.h +++ b/components/xt211/xt211_uart.h @@ -85,13 +85,19 @@ class XT211Uart final : public uart::ESP8266UartComponent { class XT211Uart final : public uart::IDFUARTComponent { public: XT211Uart(uart::IDFUARTComponent &uart) - : uart_(uart), iuart_num_(uart.*(&XT211Uart::uart_num_)), ilock_(uart.*(&XT211Uart::lock_)) {} + : uart_(uart), iuart_num_(uart.*(&XT211Uart::uart_num_)) {} // Reconfigure baudrate void update_baudrate(uint32_t baudrate) { - xSemaphoreTake(ilock_, portMAX_DELAY); - uart_set_baudrate(iuart_num_, baudrate); - xSemaphoreGive(ilock_); + auto &lock = uart_.*(&XT211Uart::lock_); + if (lock != nullptr) { + xSemaphoreTake(lock, portMAX_DELAY); + uart_set_baudrate(iuart_num_, baudrate); + xSemaphoreGive(lock); + } else { + // Lock not initialized yet, just set baudrate without locking + uart_set_baudrate(iuart_num_, baudrate); + } } bool read_one_byte(uint8_t *data) { return read_array_quick_(data, 1); } @@ -115,23 +121,40 @@ class XT211Uart final : public uart::IDFUARTComponent { size_t length_to_read = len; if (!this->check_read_timeout_quick_(len)) return false; - xSemaphoreTake(this->ilock_, portMAX_DELAY); + + auto &lock = uart_.*(&XT211Uart::lock_); + bool locked = false; + if (lock != nullptr) { + xSemaphoreTake(lock, portMAX_DELAY); + locked = true; + } + if (this->has_peek_) { length_to_read--; *data = this->peek_byte_; data++; this->has_peek_ = false; } - if (length_to_read > 0) - uart_read_bytes(this->iuart_num_, data, length_to_read, 20 / portTICK_PERIOD_MS); - xSemaphoreGive(this->ilock_); + if (length_to_read > 0) { + // If no valid hardware UART, fall back to base read_array (e.g., BLE-backed UART) + if (this->iuart_num_ < UART_NUM_0 || this->iuart_num_ >= UART_NUM_MAX) { + if (!uart_.read_array(data, length_to_read)) { + return false; + } + } else { + uart_read_bytes(this->iuart_num_, data, length_to_read, 20 / portTICK_PERIOD_MS); + } + } + + if (locked) { + xSemaphoreGive(lock); + } return true; } uart::IDFUARTComponent &uart_; uart_port_t iuart_num_; - SemaphoreHandle_t &ilock_; }; #endif