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.
uart_fix
Tomer27cz 2026-01-23 21:04:55 +01:00
parent 81b71206a6
commit ce199326a1
1 changed files with 32 additions and 9 deletions

View File

@ -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);
auto &lock = uart_.*(&XT211Uart::lock_);
if (lock != nullptr) {
xSemaphoreTake(lock, portMAX_DELAY);
uart_set_baudrate(iuart_num_, baudrate);
xSemaphoreGive(ilock_);
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)
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);
xSemaphoreGive(this->ilock_);
}
}
if (locked) {
xSemaphoreGive(lock);
}
return true;
}
uart::IDFUARTComponent &uart_;
uart_port_t iuart_num_;
SemaphoreHandle_t &ilock_;
};
#endif