[libretiny] Fix LN882x boot crash with the logger or a uart on UART0 (#20162)

This commit is contained in:
J. Nick Koston
2026-10-05 14:53:47 +13:00
committed by GitHub
parent 8b9d51cf93
commit 6f2d2a2001
6 changed files with 63 additions and 3 deletions
+22 -2
View File
@@ -1,6 +1,26 @@
#ifdef USE_LIBRETINY
// HAL functions live in hal.cpp. core.cpp is intentionally empty for
// libretiny — there is no extra component bootstrap to keep here.
// HAL functions live in hal.cpp; this file only holds the serial port
// workaround below.
#include "core.h"
#ifdef USE_LN882X
#include <sdk_private.h>
// The SDK's open port handles (components/serial/serial.c); not in its header.
extern "C" Serial_t *serial_handles[SER_PORT_NUM];
namespace esphome::libretiny {
void ensure_serial_handle(uint8_t port) {
if (port >= SER_PORT_NUM || serial_handles[port] != nullptr)
return;
// serial_init() zeroes and opens it; the port stays open for good.
serial_handles[port] = new Serial_t();
}
} // namespace esphome::libretiny
#endif // USE_LN882X
#endif // USE_LIBRETINY
+16 -1
View File
@@ -4,6 +4,21 @@
#include <Arduino.h>
namespace esphome::libretiny {} // namespace esphome::libretiny
namespace esphome::libretiny {
#ifdef USE_LN882X
/// Give a hardware UART its SDK handle before its Serial begin()s.
///
/// LibreTiny's LN882H Serial passes the SDK's per port handle to
/// serial_init(), which fills it in, but only the default log port (UART1)
/// has one at boot. Any other port hands it NULL and the chip faults before
/// setup, so a logger or uart on UART0 never boots. Drop this once LibreTiny
/// gives each port storage of its own.
void ensure_serial_handle(uint8_t port);
#else
inline void ensure_serial_handle(uint8_t /*port*/) {}
#endif
} // namespace esphome::libretiny
#endif // USE_LIBRETINY
@@ -1,6 +1,8 @@
#ifdef USE_LIBRETINY
#include "logger.h"
#include "esphome/components/libretiny/core.h"
namespace esphome::logger {
static const char *const TAG = "logger";
@@ -11,18 +13,21 @@ void Logger::pre_setup() {
#if LT_HW_UART0
case UART_SELECTION_UART0:
this->hw_serial_ = &Serial0;
libretiny::ensure_serial_handle(0);
Serial0.begin(this->baud_rate_);
break;
#endif
#if LT_HW_UART1
case UART_SELECTION_UART1:
this->hw_serial_ = &Serial1;
libretiny::ensure_serial_handle(1);
Serial1.begin(this->baud_rate_);
break;
#endif
#if LT_HW_UART2
case UART_SELECTION_UART2:
this->hw_serial_ = &Serial2;
libretiny::ensure_serial_handle(2);
Serial2.begin(this->baud_rate_);
break;
#endif
@@ -6,6 +6,8 @@
#include "esphome/core/log.h"
#include "uart_component_libretiny.h"
#include "esphome/components/libretiny/core.h"
#ifdef USE_LOGGER
#include "esphome/components/logger/logger.h"
#endif
@@ -118,6 +120,8 @@ void LibreTinyUARTComponent::setup() {
#endif
}
if (this->hardware_idx_ >= 0)
libretiny::ensure_serial_handle(this->hardware_idx_);
this->serial_->begin(this->baud_rate_, get_config());
}
@@ -0,0 +1,2 @@
logger:
hardware_uart: UART0
@@ -0,0 +1,14 @@
uart:
- id: uart_id
tx_pin: PA2
rx_pin: PA3
baud_rate: 9600
data_bits: 8
parity: NONE
stop_bits: 1
switch:
- platform: uart
name: "UART Switch"
uart_id: uart_id
data: [0x01, 0x02, 0x03]