mirror of
https://github.com/esphome/esphome.git
synced 2026-07-10 17:05:36 +00:00
[esp8266] Replace delay() with yield loop to allow GC of original millis
Arduino's ::delay() is implemented in core_esp8266_wiring.cpp alongside millis(). Because __delay calls millis() within the same compilation unit, --wrap=millis can't intercept that intra-object reference, which prevents the linker from garbage-collecting the original millis body (~80 bytes of IRAM). Replace esphome::delay() with a simple yield loop that uses our fast millis() accumulator. This has the same behavior as Arduino's delay: feeds the watchdog and processes SDK tasks via yield(), keeping WiFi alive. With __delay unreferenced, the linker can now GC both __delay and the original millis function.
This commit is contained in:
@@ -54,7 +54,17 @@ static uint32_t IRAM_ATTR HOT millis_accumulator() {
|
||||
}
|
||||
uint32_t IRAM_ATTR HOT millis() { return millis_accumulator(); }
|
||||
uint64_t millis_64() { return Millis64Impl::compute(millis()); }
|
||||
void HOT delay(uint32_t ms) { ::delay(ms); }
|
||||
// Avoid calling ::delay() which pulls in __delay from core_esp8266_wiring.cpp.
|
||||
// __delay has an intra-object call to the original millis() that --wrap=millis
|
||||
// can't intercept, preventing the linker from garbage-collecting the expensive
|
||||
// original millis body (~80 bytes IRAM). This yield loop achieves the same
|
||||
// behavior: feeds the watchdog, processes SDK tasks, keeps WiFi alive.
|
||||
void HOT delay(uint32_t ms) {
|
||||
uint32_t start = millis();
|
||||
while (millis() - start < ms) {
|
||||
yield();
|
||||
}
|
||||
}
|
||||
uint32_t IRAM_ATTR HOT micros() { return ::micros(); }
|
||||
void IRAM_ATTR HOT delayMicroseconds(uint32_t us) { delay_microseconds_safe(us); }
|
||||
void arch_restart() {
|
||||
|
||||
Reference in New Issue
Block a user