Merge branch 'logger_perf_8266' into integration

This commit is contained in:
J. Nick Koston
2026-01-18 20:36:32 -10:00

View File

@@ -2,10 +2,31 @@
#include "logger.h"
#include "esphome/core/log.h"
// Direct UART register access for optimized write path
// Arduino's Serial.write() has significant overhead:
// - pgm_read_byte() for every character (unnecessary for RAM buffers)
// - optimistic_yield() after every character (massive scheduler overhead)
// - Per-character FIFO checks (could batch)
// Direct register writes with batching are 10-50x faster for CPU-side work.
#include <esp8266_peri.h> // USF, USS, USTXC register macros
namespace esphome::logger {
static const char *const TAG = "logger";
// UART TX FIFO size is 128 bytes, use 0x7F as threshold
static constexpr uint8_t UART_TX_FIFO_THRESHOLD = 0x7F;
// Yield timeout in microseconds - matches Arduino's uart_write behavior
static constexpr uint32_t YIELD_TIMEOUT_US = 10000UL;
// Determine UART number at compile time
#if defined(USE_ESP8266_LOGGER_SERIAL)
static const uint8_t LOGGER_UART_NUM = 0;
#elif defined(USE_ESP8266_LOGGER_SERIAL1)
static const uint8_t LOGGER_UART_NUM = 1;
#endif
void Logger::pre_setup() {
#if defined(USE_ESP8266_LOGGER_SERIAL)
this->hw_serial_ = &Serial;
@@ -29,8 +50,30 @@ void Logger::pre_setup() {
}
void HOT Logger::write_msg_(const char *msg, size_t len) {
// Single write with newline already in buffer (added by caller)
this->hw_serial_->write(msg, len);
#if defined(USE_ESP8266_LOGGER_SERIAL) || defined(USE_ESP8266_LOGGER_SERIAL1)
// Direct FIFO writes with batching - much faster than Arduino's per-character approach
// Arduino's uart_write() calls optimistic_yield() after EVERY character,
// but we can burst up to 127 bytes at once and only yield when FIFO is actually full.
while (len > 0) {
// Check current FIFO level (USTXC field at bits 16-23)
uint8_t fifo_cnt = (USS(LOGGER_UART_NUM) >> USTXC) & 0xFF;
if (fifo_cnt >= UART_TX_FIFO_THRESHOLD) {
// FIFO full - yield once and retry
optimistic_yield(YIELD_TIMEOUT_US);
continue;
}
// Burst write to FIFO - no function calls, no PROGMEM overhead
size_t fifo_free = UART_TX_FIFO_THRESHOLD - fifo_cnt;
size_t to_write = len < fifo_free ? len : fifo_free;
len -= to_write;
while (to_write--) {
USF(LOGGER_UART_NUM) = *msg++;
}
}
#endif
}
const LogString *Logger::get_uart_selection_() {