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
parent
81b71206a6
commit
ce199326a1
|
|
@ -85,13 +85,19 @@ class XT211Uart final : public uart::ESP8266UartComponent {
|
||||||
class XT211Uart final : public uart::IDFUARTComponent {
|
class XT211Uart final : public uart::IDFUARTComponent {
|
||||||
public:
|
public:
|
||||||
XT211Uart(uart::IDFUARTComponent &uart)
|
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
|
// Reconfigure baudrate
|
||||||
void update_baudrate(uint32_t baudrate) {
|
void update_baudrate(uint32_t baudrate) {
|
||||||
xSemaphoreTake(ilock_, portMAX_DELAY);
|
auto &lock = uart_.*(&XT211Uart::lock_);
|
||||||
uart_set_baudrate(iuart_num_, baudrate);
|
if (lock != nullptr) {
|
||||||
xSemaphoreGive(ilock_);
|
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); }
|
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;
|
size_t length_to_read = len;
|
||||||
if (!this->check_read_timeout_quick_(len))
|
if (!this->check_read_timeout_quick_(len))
|
||||||
return false;
|
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_) {
|
if (this->has_peek_) {
|
||||||
length_to_read--;
|
length_to_read--;
|
||||||
*data = this->peek_byte_;
|
*data = this->peek_byte_;
|
||||||
data++;
|
data++;
|
||||||
this->has_peek_ = false;
|
this->has_peek_ = false;
|
||||||
}
|
}
|
||||||
if (length_to_read > 0)
|
if (length_to_read > 0) {
|
||||||
uart_read_bytes(this->iuart_num_, data, length_to_read, 20 / portTICK_PERIOD_MS);
|
// If no valid hardware UART, fall back to base read_array (e.g., BLE-backed UART)
|
||||||
xSemaphoreGive(this->ilock_);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uart::IDFUARTComponent &uart_;
|
uart::IDFUARTComponent &uart_;
|
||||||
uart_port_t iuart_num_;
|
uart_port_t iuart_num_;
|
||||||
SemaphoreHandle_t &ilock_;
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue