mirror of
https://github.com/esphome/esphome.git
synced 2026-09-03 19:46:02 +00:00
[esphome.ota] Fold OTA wake hook into wake.h
All wake_* state lives in one place now. wake.h gains a C-compatible section at the top (the inline esphome_wake_ota_component_any_context() + its two extern 'volatile bool *' globals) guarded outside any C++ namespace, with the existing C++ platform wake primitives moved behind an outer #ifdef __cplusplus. lwip_fast_select.c includes wake.h directly for the inline; .cpp files continue to see the C++ side as before. Deletes the ephemeral esphome/core/ota_wake_hook.h — same code, better home.
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
#include "esphome/core/wake.h"
|
||||
#include "esphome/core/log.h"
|
||||
#ifdef USE_OTA
|
||||
#include "esphome/core/ota_wake_hook.h"
|
||||
#include "esphome/core/wake.h" // inline esphome_wake_ota_component_any_context() lives here
|
||||
#endif
|
||||
|
||||
#ifdef USE_ESP8266
|
||||
@@ -861,8 +861,8 @@ err_t LWIPRawListenImpl::accept_fn_(struct tcp_pcb *newpcb, err_t err) {
|
||||
// Mark the OTA component loop to be re-enabled if it disabled itself while idle.
|
||||
// This MUST happen before wake_loop_any_context() below — otherwise the main loop
|
||||
// could wake, run a full iteration, and finish before we set the pending-enable
|
||||
// flags, losing the wake event. Inline hook (ota_wake_hook.h) — two volatile stores,
|
||||
// no function call. Safe from RP2040's low-priority user IRQ context.
|
||||
// flags, losing the wake event. Inline hook (wake.h) — two volatile stores, no
|
||||
// function call. Safe from RP2040's low-priority user IRQ context.
|
||||
esphome_wake_ota_component_any_context();
|
||||
#endif
|
||||
// Wake the main loop immediately so it can accept the new connection.
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
#include "esphome/core/build_info_data.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/progmem.h"
|
||||
#ifdef USE_OTA
|
||||
#include "esphome/core/ota_wake_hook.h"
|
||||
#endif
|
||||
#include "esphome/core/wake.h"
|
||||
#include <cstring>
|
||||
|
||||
#ifdef USE_ESP8266
|
||||
@@ -452,16 +450,19 @@ void Application::enable_pending_loops_() {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_OTA
|
||||
// Storage for the inline OTA wake hook (see esphome/core/ota_wake_hook.h). Set in
|
||||
// Application::set_ota_wake_component() and read from the lwip fast-select callback on
|
||||
// every NETCONN_EVT_RCVPLUS. Kept as raw C globals so the .c file can inline the wake
|
||||
// body (two volatile stores) without a function-call round trip into application.cpp.
|
||||
// Storage for the inline OTA wake hook (see esphome/core/wake.h). Set in
|
||||
// Application::set_ota_wake_component() and read from the lwip fast-select callback
|
||||
// on every NETCONN_EVT_RCVPLUS. Kept as raw C globals so the .c file can inline the
|
||||
// wake body (two volatile stores) without a function-call round trip. Defined
|
||||
// unconditionally so wake.h's inline compiles the same whether or not OTA is in the
|
||||
// build — when OTA is absent nothing ever calls set_ota_wake_component() and the
|
||||
// pointers stay nullptr, collapsing the inline to a single null check.
|
||||
extern "C" {
|
||||
volatile bool *esphome_ota_pending_enable_loop_ptr = nullptr;
|
||||
volatile bool *esphome_ota_has_pending_requests_ptr = nullptr;
|
||||
}
|
||||
|
||||
#ifdef USE_OTA
|
||||
void Application::set_ota_wake_component(Component *component) {
|
||||
// Application is a friend of Component — can take the address of its protected
|
||||
// pending_enable_loop_ field. The C-side inline hook writes through that pointer when
|
||||
|
||||
@@ -561,12 +561,12 @@ class Application {
|
||||
|
||||
#ifdef USE_OTA
|
||||
/// Register the OTA component so socket-wake paths can enable its loop when a new
|
||||
/// connection arrives on the listening socket. Captures the address of the component's
|
||||
/// pending_enable_loop_ flag and the Application has_pending_enable_loop_requests_ flag
|
||||
/// into extern C globals consumed by the inline wake hook in ota_wake_hook.h. Defined
|
||||
/// out-of-line in application.cpp so application.h doesn't need to pull in the hook
|
||||
/// header. OTA calls this once from setup(); the component itself then self-disables
|
||||
/// its loop on its first idle tick.
|
||||
/// connection arrives on the listening socket. Captures the addresses of the component's
|
||||
/// pending_enable_loop_ flag and Application's has_pending_enable_loop_requests_ flag
|
||||
/// into extern-C globals consumed by the inline wake hook in wake.h. Defined out-of-line
|
||||
/// in application.cpp so application.h doesn't need to pull in wake.h. OTA calls this
|
||||
/// once from setup(); the component itself then self-disables its loop on its first
|
||||
/// idle tick.
|
||||
void set_ota_wake_component(Component *component);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
#include "esphome/core/lwip_fast_select.h"
|
||||
#include "esphome/core/main_task.h"
|
||||
#ifdef ESPHOME_USE_OTA
|
||||
#include "esphome/core/ota_wake_hook.h"
|
||||
#include "esphome/core/wake.h" // inline esphome_wake_ota_component_any_context() lives here
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// Inline OTA wake hook, called from lwip_fast_select.c on every NETCONN_EVT_RCVPLUS so a
|
||||
// disabled OTA loop can be re-enabled when a monitored socket signals activity.
|
||||
//
|
||||
// Defined as a static inline here (rather than an out-of-line extern "C" shim into
|
||||
// application.cpp) so the fast-select callback pays zero function-call overhead per
|
||||
// socket event: the two volatile stores below are cheaper inlined than dispatched.
|
||||
//
|
||||
// The two pointers are set once in Application::set_ota_wake_component() to the addresses
|
||||
// of Component::pending_enable_loop_ and Application::has_pending_enable_loop_requests_.
|
||||
// Accessing those C++ members by raw address is safe: Application is a friend of Component
|
||||
// (granting access at registration time), and volatile writes through a bool* see the same
|
||||
// storage the C++ side reads.
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Address of the registered OTA component's pending_enable_loop_ flag. NULL until
|
||||
// Application::set_ota_wake_component() is called. When non-NULL, the has-pending
|
||||
// pointer below is also non-NULL, so a single null check covers both.
|
||||
extern volatile bool *esphome_ota_pending_enable_loop_ptr;
|
||||
// Address of Application::has_pending_enable_loop_requests_. Set in tandem with the
|
||||
// pending_enable pointer above.
|
||||
extern volatile bool *esphome_ota_has_pending_requests_ptr;
|
||||
|
||||
// Mark the registered OTA component pending loop-enable. Safe to call from LwIP TCP/IP
|
||||
// task context and raw-TCP IRQ context — only writes to volatile bools, no locks.
|
||||
// Callers must invoke this BEFORE waking the main task, so the flags are visible to the
|
||||
// main loop's next iteration.
|
||||
static inline void esphome_wake_ota_component_any_context(void) {
|
||||
volatile bool *pending_enable = esphome_ota_pending_enable_loop_ptr;
|
||||
if (pending_enable != NULL) {
|
||||
*pending_enable = true;
|
||||
*esphome_ota_has_pending_requests_ptr = true;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -3,6 +3,63 @@
|
||||
/// @file wake.h
|
||||
/// Platform-specific main loop wake primitives.
|
||||
/// Always available on all platforms — no opt-in needed.
|
||||
///
|
||||
/// This file has two sections:
|
||||
/// 1. A C-compatible section at the top (the inline OTA wake hook) that .c files
|
||||
/// like lwip_fast_select.c can include. Uses only <stdbool.h>/<stddef.h>.
|
||||
/// 2. A C++ section (everything after #ifdef __cplusplus below) with the existing
|
||||
/// platform wake primitives and wakeable_delay() implementations.
|
||||
|
||||
// ============================================================================
|
||||
// C-compatible section: inline OTA wake hook
|
||||
// ============================================================================
|
||||
//
|
||||
// Called from lwip_fast_select.c (and lwip_raw_tcp_impl.cpp / host select) on every
|
||||
// NETCONN_EVT_RCVPLUS so a disabled OTA loop can be re-enabled when a monitored
|
||||
// socket signals activity. Static inline (not an extern-C trampoline) so the .c
|
||||
// callback pays zero function-call overhead — just a pointer load, null check, and
|
||||
// two volatile bool stores inlined into the callback body.
|
||||
//
|
||||
// The two pointers are captured once in Application::set_ota_wake_component(): they
|
||||
// point at Component::pending_enable_loop_ and Application::has_pending_enable_loop_requests_.
|
||||
// When OTA is not compiled into the build, nothing calls set_ota_wake_component(),
|
||||
// the pointers stay NULL, and the inline collapses to a single null check.
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Address of the registered OTA component's pending_enable_loop_ flag, captured at
|
||||
// registration time. NULL when no OTA component has registered (including when OTA
|
||||
// is not compiled in at all).
|
||||
extern volatile bool *esphome_ota_pending_enable_loop_ptr;
|
||||
// Address of Application::has_pending_enable_loop_requests_. Set in tandem with the
|
||||
// pending_enable pointer above — single null check covers both.
|
||||
extern volatile bool *esphome_ota_has_pending_requests_ptr;
|
||||
|
||||
// Mark the registered OTA component pending loop-enable. Safe from the LwIP TCP/IP
|
||||
// task and raw-TCP IRQ context — only volatile stores, no locks. Callers MUST invoke
|
||||
// this BEFORE waking the main task, so the flags are visible on the next iteration.
|
||||
static inline void esphome_wake_ota_component_any_context(void) {
|
||||
volatile bool *pending_enable = esphome_ota_pending_enable_loop_ptr;
|
||||
if (pending_enable != NULL) {
|
||||
*pending_enable = true;
|
||||
*esphome_ota_has_pending_requests_ptr = true;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
// ============================================================================
|
||||
// C++ section: platform wake primitives
|
||||
// ============================================================================
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "esphome/core/defines.h"
|
||||
#include "esphome/core/hal.h"
|
||||
@@ -124,3 +181,5 @@ inline void wakeable_delay(uint32_t ms) {
|
||||
#endif
|
||||
|
||||
} // namespace esphome
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
Reference in New Issue
Block a user