diff --git a/esphome/components/libretiny/patch_linker.py.script b/esphome/components/libretiny/patch_linker.py.script index 56a42db0ee0..b62ec1a5fb2 100644 --- a/esphome/components/libretiny/patch_linker.py.script +++ b/esphome/components/libretiny/patch_linker.py.script @@ -6,9 +6,10 @@ import re # BK72xx linker templates declare the SRAM region as "(rw!x)" — read/write but # not executable. That prevents the linker from emitting functions we mark -# IRAM_ATTR (defined as section(".data") on BK72xx in esphome/core/hal.h) into -# the .data output section, which is the only section the SDK startup code -# copies from flash into SRAM before main() runs. +# IRAM_ATTR (defined as section(".data.iram_text") on BK72xx in +# esphome/core/hal.h; folded into .data by the linker's "*(.data.*)" glob) +# into the .data output section, which is the only section the SDK startup +# code copies from flash into SRAM before main() runs. # # LibreTiny's own Wi-Fi driver already runs code from SRAM at runtime, so the # BK72xx MMU permits execution from that region; the "!x" is a stale hint in diff --git a/esphome/core/hal.h b/esphome/core/hal.h index 4009950ea04..aa36a1f03dd 100644 --- a/esphome/core/hal.h +++ b/esphome/core/hal.h @@ -28,15 +28,18 @@ // varies per family, based on what each linker script already supports: // - RTL8710B (AmebaZ): ".image2.ram.text" output section exists. // - RTL8720C (AmebaZ2): "*(.sram.text*)" is already consumed. -// - BK72xx / LN882H: stock linker script has no RAM text section, so we -// piggyback on ".data" — the SDK startup code copies .data from flash into -// SRAM before main() runs, so the function body ends up in executable RAM. +// - BK72xx / LN882H: the stock linker script has no RAM text section, so we +// use ".data.iram_text" which the linker's "*(.data.*)" glob folds into +// the .data output section. The SDK startup code copies .data from flash +// into SRAM before main() runs, so the function body ends up in executable +// RAM. Using ".data.*" instead of plain ".data" keeps the assembler happy +// (no section-attribute collision) while still landing in the right place. #if defined(USE_LIBRETINY_VARIANT_RTL8710B) #define IRAM_ATTR __attribute__((noinline, section(".image2.ram.text"))) #elif defined(USE_LIBRETINY_VARIANT_RTL8720C) #define IRAM_ATTR __attribute__((noinline, section(".sram.text"))) #else -#define IRAM_ATTR __attribute__((noinline, section(".data"))) +#define IRAM_ATTR __attribute__((noinline, section(".data.iram_text"))) #endif #define PROGMEM diff --git a/esphome/core/wake.h b/esphome/core/wake.h index f0a2d34b502..5733ee65f6c 100644 --- a/esphome/core/wake.h +++ b/esphome/core/wake.h @@ -34,7 +34,13 @@ __attribute__((always_inline)) inline void wake_main_task_any_context() { if (in_isr_context()) { BaseType_t px_higher_priority_task_woken = pdFALSE; esphome_main_task_notify_from_isr(&px_higher_priority_task_woken); +#ifdef portYIELD_FROM_ISR portYIELD_FROM_ISR(px_higher_priority_task_woken); +#else + // ARM9 FreeRTOS port (BK72xx) does not define portYIELD_FROM_ISR; the IRQ + // exit sequence performs the context switch if one was requested. + (void) px_higher_priority_task_woken; +#endif } else { esphome_main_task_notify(); }