[esphome.ota] Drop unnecessary IRAM_ATTR from wake hook

The wake hook is called only from:
  - esphome_socket_event_callback (lwip fast select, LwIP TCP/IP task context)
  - LWIPRawListenImpl::accept_fn_ (raw TCP accept callback)
  - Application::yield_with_select_ (host select fallback, main thread)

None of those contexts require IRAM-resident code. The LwIP fast-select
event callback itself is not IRAM_ATTR; the raw-TCP accept callback runs
from a low-priority user IRQ on RP2040 where IRAM_ATTR is a no-op anyway
(it's an ESP32-specific section attribute for code that must run while
flash cache is disabled). This is not a real ISR path the way
enable_loop_soon_any_context() is (which is called from GPIO ISRs and
genuinely does need IRAM).

Removing IRAM_ATTR frees scarce IRAM on ESP32.
This commit is contained in:
J. Nick Koston
2026-04-10 14:47:52 -10:00
parent af8fd1d060
commit 92f93e128f
2 changed files with 9 additions and 8 deletions
+1 -1
View File
@@ -453,7 +453,7 @@ void Application::enable_pending_loops_() {
// Called from the LwIP TCP/IP task via esphome_socket_event_callback() on NETCONN_EVT_RCVPLUS.
// Only marks the OTA component as pending loop-enable; the fast-select callback itself has
// already woken the main task via xTaskNotifyGive().
extern "C" void IRAM_ATTR esphome_wake_ota_component_any_context() { App.wake_ota_component_any_context(); }
extern "C" void esphome_wake_ota_component_any_context() { App.wake_ota_component_any_context(); }
#endif
#ifdef USE_LWIP_FAST_SELECT
+8 -7
View File
@@ -564,13 +564,14 @@ class Application {
/// a new connection arrives on the listening socket. OTA disables its own
/// loop while idle to avoid per-tick dispatch overhead.
void set_ota_wake_component(Component *component) { this->ota_wake_component_ = component; }
/// Mark the registered OTA component (if any) for loop re-enable from any
/// context. Intentionally does NOT call wake_loop_any_context() — every
/// caller (lwip fast-select callback, raw-tcp accept callback, host
/// select() return path) has already woken the main loop, so a second wake
/// here would be redundant. Application is a friend of Component, so we
/// set the pending-enable flags directly.
void IRAM_ATTR wake_ota_component_any_context() {
/// Mark the registered OTA component (if any) for loop re-enable. Intentionally
/// does NOT call wake_loop_any_context() — every caller (lwip fast-select
/// callback, raw-tcp accept callback, host select() return path) has already
/// woken the main loop, so a second wake here would be redundant. Application
/// is a friend of Component, so we set the pending-enable flags directly.
/// Not IRAM_ATTR: all callers run in task / user-IRQ context, not a real ISR,
/// and the LwIP event callbacks that invoke this are not IRAM-resident either.
void wake_ota_component_any_context() {
if (this->ota_wake_component_ != nullptr) {
this->ota_wake_component_->pending_enable_loop_ = true;
this->has_pending_enable_loop_requests_ = true;