[libretiny] Move HAL bodies into components/libretiny/hal.cpp + inline trivial dispatches

Per-platform follow-up to #15977.

Move out-of-line HAL bodies (delayMicroseconds, arch_init, arch_restart)
from components/libretiny/core.cpp into a new components/libretiny/hal.cpp.
core.cpp is now empty (no extra component bootstrap to keep) — left as a
stub for symmetry.

Inline the trivial one-liners directly in hal_libretiny.h with forward
decls for the LibreTiny C API:

  arch_feed_wdt()              -> lt_wdt_feed()
  arch_get_cpu_cycle_count()   -> lt_cpu_get_cycle_count()
  arch_get_cpu_freq_hz()       -> lt_cpu_get_freq()

arch_init stays out-of-line because of the libretiny::setup_preferences()
call (component-private header) plus the BK72xx priority-raise + GPIO
recovery logic.

delayMicroseconds() also stays out-of-line — Arduino's ::delayMicroseconds
signature is unsigned int and forward-declaring it across the C/C++
boundary in a hot header is fragile.
This commit is contained in:
J. Nick Koston
2026-04-29 06:01:11 -05:00
parent bb76ee76ec
commit 1ce6364892
3 changed files with 66 additions and 54 deletions
+2 -51
View File
@@ -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 <FreeRTOS.h>
#include <task.h>
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
+53
View File
@@ -0,0 +1,53 @@
#ifdef USE_LIBRETINY
#include "esphome/core/hal.h"
#include "preferences.h"
#include <FreeRTOS.h>
#include <task.h>
// 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(), arch_feed_wdt(),
// arch_get_cpu_cycle_count(), arch_get_cpu_freq_hz() inlined in
// core/hal/hal_libretiny.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) {
}
}
} // namespace esphome
#endif // USE_LIBRETINY
+11 -3
View File
@@ -53,6 +53,13 @@ extern "C" unsigned long micros(void);
extern "C" unsigned long millis(void);
// NOLINTEND(google-runtime-int,readability-identifier-naming,readability-redundant-declaration)
// Forward decls from libretiny's <lt_api.h> 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 +95,12 @@ __attribute__((always_inline)) inline uint32_t millis() { return static_cast<uin
#endif
__attribute__((always_inline)) inline uint64_t millis_64() { return Millis64Impl::compute(millis()); }
__attribute__((always_inline)) inline void arch_feed_wdt() { lt_wdt_feed(); }
__attribute__((always_inline)) inline uint32_t arch_get_cpu_cycle_count() { return lt_cpu_get_cycle_count(); }
__attribute__((always_inline)) inline uint32_t arch_get_cpu_freq_hz() { return lt_cpu_get_freq(); }
void delayMicroseconds(uint32_t us); // NOLINT(readability-identifier-naming)
void arch_feed_wdt();
uint32_t arch_get_cpu_cycle_count();
void arch_init();
uint32_t arch_get_cpu_freq_hz();
} // namespace esphome