From 08c09fbe367a85e765e6675615ee3545807f0dc0 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 10 Apr 2026 16:20:03 -1000 Subject: [PATCH] [esphome.ota] TEMP: add shim call counter to pinpoint C->C++ wake break --- esphome/components/esphome/ota/ota_esphome.cpp | 12 ++++++++---- esphome/core/application.cpp | 10 +++++++++- esphome/core/lwip_fast_select.h | 4 ++++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/esphome/components/esphome/ota/ota_esphome.cpp b/esphome/components/esphome/ota/ota_esphome.cpp index fb583e6d7a..3367696ddd 100644 --- a/esphome/components/esphome/ota/ota_esphome.cpp +++ b/esphome/components/esphome/ota/ota_esphome.cpp @@ -118,19 +118,23 @@ void ESPHomeOTAComponent::loop() { const uint32_t wake_count = App.ota_wake_count_debug(); #ifdef USE_LWIP_FAST_SELECT const uint32_t total_rcvplus = esphome_fast_select_rcvplus_total_debug; + const uint32_t shim_count = esphome_ota_shim_call_count_debug; #else const uint32_t total_rcvplus = 0; + const uint32_t shim_count = 0; #endif const bool ready = this->server_->ready(); static uint32_t last_wake_count = 0; static uint32_t last_total_rcvplus = 0; + static uint32_t last_shim_count = 0; static bool last_ready = false; - if (wake_count != last_wake_count || total_rcvplus != last_total_rcvplus || ready != last_ready || - this->client_ != nullptr) { - ESP_LOGD(TAG, "loop tick: client=%p ready=%d wakes=%u total_rcvplus=%u", (void *) this->client_.get(), ready, - wake_count, total_rcvplus); + if (wake_count != last_wake_count || total_rcvplus != last_total_rcvplus || shim_count != last_shim_count || + ready != last_ready || this->client_ != nullptr) { + ESP_LOGD(TAG, "loop tick: client=%p ready=%d wakes=%u shim=%u total_rcvplus=%u", (void *) this->client_.get(), + ready, wake_count, shim_count, total_rcvplus); last_wake_count = wake_count; last_total_rcvplus = total_rcvplus; + last_shim_count = shim_count; last_ready = ready; } if (this->client_ == nullptr && !ready) { diff --git a/esphome/core/application.cpp b/esphome/core/application.cpp index 5fc794d1f6..46f8922bc6 100644 --- a/esphome/core/application.cpp +++ b/esphome/core/application.cpp @@ -450,11 +450,19 @@ void Application::enable_pending_loops_() { } #if defined(USE_OTA) && defined(USE_LWIP_FAST_SELECT) +// DEBUG: directly-incremented C counter so we can tell whether the shim is being called at all, +// independent of whether the App.wake_ota_component_any_context() call inside it is working. +extern "C" { +volatile uint32_t esphome_ota_shim_call_count_debug = 0; +} // Called from the LwIP TCP/IP task via esphome_socket_event_callback() on NETCONN_EVT_RCVPLUS, // BEFORE the callback calls xTaskNotifyGive() — the flag-set must happen before the wake, // otherwise the main task could wake, run a full iteration, and miss the pending-enable. // Only marks the OTA component as pending loop-enable; does not itself wake the main task. -extern "C" void esphome_wake_ota_component_any_context() { App.wake_ota_component_any_context(); } +extern "C" void esphome_wake_ota_component_any_context() { + esphome_ota_shim_call_count_debug++; + esphome::App.wake_ota_component_any_context(); +} #endif #ifdef USE_LWIP_FAST_SELECT diff --git a/esphome/core/lwip_fast_select.h b/esphome/core/lwip_fast_select.h index 6ed2704ef0..f152106f0e 100644 --- a/esphome/core/lwip_fast_select.h +++ b/esphome/core/lwip_fast_select.h @@ -56,6 +56,10 @@ void esphome_lwip_hook_socket(struct lwip_sock *sock); // DEBUG counter: total RCVPLUS events the wrapper callback observed across all monitored sockets. extern volatile uint32_t esphome_fast_select_rcvplus_total_debug; +// DEBUG counter: number of times esphome_wake_ota_component_any_context() C shim was entered. +// Independent of whether App.wake_ota_component_any_context() inside it actually ran. +extern volatile uint32_t esphome_ota_shim_call_count_debug; + /// Set or clear TCP_NODELAY on a socket's tcp_pcb directly. /// Must be called with the TCPIP core lock held (LwIPLock in C++). /// This bypasses lwip_setsockopt() overhead (socket lookups, switch cascade,