From 61261b4a592fa449a1e820a6392c4696fbc3d49a Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 30 Apr 2026 12:33:22 -0500 Subject: [PATCH] [libretiny] Move HAL bodies into components/libretiny/hal.cpp + inline trivial dispatches (#16113) --- esphome/components/libretiny/core.cpp | 53 +-------------------------- esphome/components/libretiny/hal.cpp | 53 +++++++++++++++++++++++++++ esphome/core/hal/hal_libretiny.h | 18 +++++++-- 3 files changed, 69 insertions(+), 55 deletions(-) create mode 100644 esphome/components/libretiny/hal.cpp diff --git a/esphome/components/libretiny/core.cpp b/esphome/components/libretiny/core.cpp index f46abe3b81..8686a41e64 100644 --- a/esphome/components/libretiny/core.cpp +++ b/esphome/components/libretiny/core.cpp @@ -1,55 +1,6 @@ #ifdef USE_LIBRETINY -#include "core.h" -#include "esphome/core/defines.h" -#include "esphome/core/hal.h" -#include "esphome/core/helpers.h" -#include "preferences.h" - -#include -#include - -void setup(); -void loop(); - -namespace esphome { - -// yield(), delay(), micros(), millis(), millis_64() inlined in hal.h. -void IRAM_ATTR HOT delayMicroseconds(uint32_t us) { ::delayMicroseconds(us); } - -void arch_init() { - libretiny::setup_preferences(); - lt_wdt_enable(10000L); -#ifdef USE_BK72XX - // BK72xx SDK creates the main Arduino task at priority 3, which is lower than - // all WiFi (4-5), LwIP (4), and TCP/IP (7) tasks. This causes ~100ms loop - // stalls whenever WiFi background processing runs, because the main task - // cannot resume until every higher-priority task finishes. - // - // By contrast, RTL87xx creates the main task at osPriorityRealtime (highest). - // - // Raise to priority 6: above WiFi/LwIP tasks (4-5) so they don't preempt the - // main loop, but below the TCP/IP thread (7) so packet processing keeps priority. - // This is safe because ESPHome yields voluntarily via wakeable_delay() and - // the Arduino mainTask yield() after each loop() iteration. - static constexpr UBaseType_t MAIN_TASK_PRIORITY = 6; - static_assert(MAIN_TASK_PRIORITY < configMAX_PRIORITIES, "MAIN_TASK_PRIORITY must be less than configMAX_PRIORITIES"); - vTaskPrioritySet(nullptr, MAIN_TASK_PRIORITY); -#endif -#if LT_GPIO_RECOVER - lt_gpio_recover(); -#endif -} - -void arch_restart() { - lt_reboot(); - while (1) { - } -} -void HOT arch_feed_wdt() { lt_wdt_feed(); } -uint32_t arch_get_cpu_cycle_count() { return lt_cpu_get_cycle_count(); } -uint32_t arch_get_cpu_freq_hz() { return lt_cpu_get_freq(); } - -} // namespace esphome +// HAL functions live in hal.cpp. core.cpp is intentionally empty for +// libretiny — there is no extra component bootstrap to keep here. #endif // USE_LIBRETINY diff --git a/esphome/components/libretiny/hal.cpp b/esphome/components/libretiny/hal.cpp new file mode 100644 index 0000000000..e6dbb7296c --- /dev/null +++ b/esphome/components/libretiny/hal.cpp @@ -0,0 +1,53 @@ +#ifdef USE_LIBRETINY + +#include "core.h" +#include "esphome/core/hal.h" +#include "preferences.h" + +#include +#include + +// Empty libretiny namespace block to satisfy ci-custom's lint_namespace check. +// HAL functions live in namespace esphome (root) — they are not part of the +// libretiny component's API. +namespace esphome::libretiny {} // namespace esphome::libretiny + +namespace esphome { + +// yield(), delay(), micros(), millis(), millis_64(), delayMicroseconds(), +// arch_feed_wdt(), arch_get_cpu_cycle_count(), arch_get_cpu_freq_hz() +// inlined in core/hal/hal_libretiny.h. + +void arch_init() { + libretiny::setup_preferences(); + lt_wdt_enable(10000L); +#ifdef USE_BK72XX + // BK72xx SDK creates the main Arduino task at priority 3, which is lower than + // all WiFi (4-5), LwIP (4), and TCP/IP (7) tasks. This causes ~100ms loop + // stalls whenever WiFi background processing runs, because the main task + // cannot resume until every higher-priority task finishes. + // + // By contrast, RTL87xx creates the main task at osPriorityRealtime (highest). + // + // Raise to priority 6: above WiFi/LwIP tasks (4-5) so they don't preempt the + // main loop, but below the TCP/IP thread (7) so packet processing keeps priority. + // This is safe because ESPHome yields voluntarily via wakeable_delay() and + // the Arduino mainTask yield() after each loop() iteration. + static constexpr UBaseType_t MAIN_TASK_PRIORITY = 6; + static_assert(MAIN_TASK_PRIORITY < configMAX_PRIORITIES, "MAIN_TASK_PRIORITY must be less than configMAX_PRIORITIES"); + vTaskPrioritySet(nullptr, MAIN_TASK_PRIORITY); +#endif +#if LT_GPIO_RECOVER + lt_gpio_recover(); +#endif +} + +void arch_restart() { + lt_reboot(); + while (1) { + } +} + +} // namespace esphome + +#endif // USE_LIBRETINY diff --git a/esphome/core/hal/hal_libretiny.h b/esphome/core/hal/hal_libretiny.h index ecfe830fe3..db0fc11bfb 100644 --- a/esphome/core/hal/hal_libretiny.h +++ b/esphome/core/hal/hal_libretiny.h @@ -51,8 +51,16 @@ extern "C" void yield(void); extern "C" void delay(unsigned long ms); extern "C" unsigned long micros(void); extern "C" unsigned long millis(void); +extern "C" void delayMicroseconds(unsigned int us); // NOLINTEND(google-runtime-int,readability-identifier-naming,readability-redundant-declaration) +// Forward decls from libretiny's family for the inline arch_* +// wrappers below. Pulling the full header would drag in the rest of the +// LibreTiny C API. +extern "C" void lt_wdt_feed(void); +extern "C" uint32_t lt_cpu_get_cycle_count(void); +extern "C" uint32_t lt_cpu_get_freq(void); + namespace esphome { /// Returns true when executing inside an interrupt handler. @@ -88,11 +96,13 @@ __attribute__((always_inline)) inline uint32_t millis() { return static_cast