[esp8266] Inline delayMicroseconds/arch_feed_wdt/progmem_read_* in hal_esp8266.h

These wrappers were one-line forwarders to platform primitives:

  delayMicroseconds(us)   -> delay_microseconds_safe(us)
  arch_feed_wdt()         -> system_soft_wdt_feed()
  progmem_read_byte(p)    -> pgm_read_byte(p)
  progmem_read_ptr(p)     -> pgm_read_ptr(p) cast
  progmem_read_uint16(p)  -> pgm_read_word(p)

Mark them __attribute__((always_inline)) inline in hal_esp8266.h so the
wrapper call/return is eliminated at every call site, and remove the
out-of-line definitions from components/esp8266/core.cpp.

The IRAM_ATTR previously on delayMicroseconds() was decorative — its
body calls delay_microseconds_safe() which lives in flash, so an IRAM
ISR caller already jumped from SRAM into flash. Inlining is no worse
than the prior code (same reasoning as the libretiny IRAM_ATTR note in
the parent commit's PR description).

The dispatcher hal.h now gates its delayMicroseconds/arch_feed_wdt
declarations behind #ifndef USE_ESP8266 so clang-tidy does not flag
them as redundant on top of the inline definitions.
This commit is contained in:
J. Nick Koston
2026-04-29 05:37:48 -05:00
parent 83252df908
commit 0f128d2f15
3 changed files with 30 additions and 17 deletions
+1 -12
View File
@@ -84,7 +84,7 @@ void HOT delay(uint32_t ms) {
optimistic_yield(1000);
}
}
void IRAM_ATTR HOT delayMicroseconds(uint32_t us) { delay_microseconds_safe(us); }
// delayMicroseconds(), arch_feed_wdt(), and progmem_read_*() are inlined in hal/hal_esp8266.h.
void arch_restart() {
system_restart();
// restart() doesn't always end execution
@@ -93,17 +93,6 @@ void arch_restart() {
}
}
void arch_init() {}
void HOT arch_feed_wdt() { system_soft_wdt_feed(); }
uint8_t progmem_read_byte(const uint8_t *addr) {
return pgm_read_byte(addr); // NOLINT
}
const char *progmem_read_ptr(const char *const *addr) {
return reinterpret_cast<const char *>(pgm_read_ptr(addr)); // NOLINT
}
uint16_t progmem_read_uint16(const uint16_t *addr) {
return pgm_read_word(addr); // NOLINT
}
uint32_t IRAM_ATTR HOT arch_get_cpu_cycle_count() { return esp_get_cycle_count(); }
uint32_t arch_get_cpu_freq_hz() { return F_CPU; }
+5 -1
View File
@@ -30,10 +30,14 @@
namespace esphome {
// ESP8266 inlines delayMicroseconds() and arch_feed_wdt() in hal/hal_esp8266.h;
// every other platform keeps them out-of-line in components/<platform>/core.cpp.
#ifndef USE_ESP8266
void delayMicroseconds(uint32_t us); // NOLINT(readability-identifier-naming)
void arch_feed_wdt();
#endif
void __attribute__((noreturn)) arch_restart();
void arch_init();
void arch_feed_wdt();
uint32_t arch_get_cpu_cycle_count();
uint32_t arch_get_cpu_freq_hz();
+24 -4
View File
@@ -4,6 +4,7 @@
#include <c_types.h>
#include <cstdint>
#include <pgmspace.h>
#include "esphome/core/time_64.h"
@@ -19,8 +20,15 @@ extern "C" unsigned long micros(void);
extern "C" unsigned long millis(void);
// NOLINTEND(google-runtime-int,readability-identifier-naming,readability-redundant-declaration)
// Forward decl from <user_interface.h> for arch_feed_wdt() inline below.
extern "C" void system_soft_wdt_feed(void);
namespace esphome {
// Forward decl from helpers.h so this header stays cheap.
// NOLINTNEXTLINE(readability-redundant-declaration)
void delay_microseconds_safe(uint32_t us);
/// Returns true when executing inside an interrupt handler.
/// ESP8266 has no reliable single-register ISR detection: PS.INTLEVEL is
/// non-zero both in a real ISR and when user code masks interrupts. The
@@ -34,10 +42,22 @@ void delay(uint32_t ms);
uint32_t millis();
__attribute__((always_inline)) inline uint64_t millis_64() { return Millis64Impl::compute(millis()); }
// ESP8266: pgm_read_* does real flash reads on Harvard architecture
uint8_t progmem_read_byte(const uint8_t *addr);
const char *progmem_read_ptr(const char *const *addr);
uint16_t progmem_read_uint16(const uint16_t *addr);
// ESP8266: pgm_read_* does aligned 32-bit flash reads on Harvard architecture.
// Inline-forward to the platform macros so the wrappers themselves don't
// occupy IRAM/flash on every call site.
__attribute__((always_inline)) inline uint8_t progmem_read_byte(const uint8_t *addr) {
return pgm_read_byte(addr); // NOLINT
}
__attribute__((always_inline)) inline const char *progmem_read_ptr(const char *const *addr) {
return reinterpret_cast<const char *>(pgm_read_ptr(addr)); // NOLINT
}
__attribute__((always_inline)) inline uint16_t progmem_read_uint16(const uint16_t *addr) {
return pgm_read_word(addr); // NOLINT
}
// NOLINTNEXTLINE(readability-identifier-naming)
__attribute__((always_inline)) inline void delayMicroseconds(uint32_t us) { delay_microseconds_safe(us); }
__attribute__((always_inline)) inline void arch_feed_wdt() { system_soft_wdt_feed(); }
} // namespace esphome