mirror of
https://github.com/esphome/esphome.git
synced 2026-09-15 09:08:41 +00:00
Inline RP2040 wakeable_delay using function-local static + lambda callback
This commit is contained in:
+1
-39
@@ -31,50 +31,12 @@ void IRAM_ATTR wake_loop_any_context() { wake_loop_impl_(); }
|
||||
|
||||
#endif // USE_ESP8266
|
||||
|
||||
// === RP2040 — wakeable_delay (wake functions are inline in wake.h) ===
|
||||
// === RP2040 — g_main_loop_woke definition (wake functions + wakeable_delay are inline in wake.h) ===
|
||||
#ifdef USE_RP2040
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
volatile bool g_main_loop_woke = false;
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
static volatile bool s_delay_expired = false;
|
||||
|
||||
static int64_t alarm_callback_(alarm_id_t id, void *user_data) {
|
||||
(void) id;
|
||||
(void) user_data;
|
||||
s_delay_expired = true;
|
||||
__sev(); // Wake from __wfe() — timeout expired.
|
||||
return 0; // One-shot
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
void wakeable_delay(uint32_t ms) {
|
||||
if (ms == 0) {
|
||||
yield();
|
||||
return;
|
||||
}
|
||||
// If a wake was already signalled, consume it and return immediately
|
||||
if (g_main_loop_woke) {
|
||||
g_main_loop_woke = false;
|
||||
return;
|
||||
}
|
||||
s_delay_expired = false;
|
||||
alarm_id_t alarm = add_alarm_in_ms(ms, alarm_callback_, nullptr, true);
|
||||
if (alarm <= 0) {
|
||||
delay(ms);
|
||||
return;
|
||||
}
|
||||
// Sleep until woken by either the timer alarm or wake_loop_any_context()/wake_loop_threadsafe()
|
||||
while (!g_main_loop_woke && !s_delay_expired) {
|
||||
__wfe();
|
||||
}
|
||||
if (!s_delay_expired)
|
||||
cancel_alarm(alarm);
|
||||
g_main_loop_woke = false;
|
||||
}
|
||||
} // namespace internal
|
||||
|
||||
#endif // USE_RP2040
|
||||
|
||||
// === Host (UDP loopback socket) ===
|
||||
|
||||
+30
-2
@@ -26,6 +26,7 @@
|
||||
#include <coredecls.h>
|
||||
#elif defined(USE_RP2040)
|
||||
#include <hardware/sync.h>
|
||||
#include <pico/time.h>
|
||||
#endif
|
||||
|
||||
namespace esphome {
|
||||
@@ -111,8 +112,35 @@ inline void wake_loop_threadsafe() {
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
/// Delay that can be woken early. Uses hardware timer + __wfe()/__sev(). Defined in wake.cpp.
|
||||
void wakeable_delay(uint32_t ms);
|
||||
inline void wakeable_delay(uint32_t ms) {
|
||||
// Function-local statics — safe because this is only called from the main loop.
|
||||
static volatile bool s_delay_expired = false;
|
||||
if (ms == 0) {
|
||||
yield();
|
||||
return;
|
||||
}
|
||||
if (g_main_loop_woke) {
|
||||
g_main_loop_woke = false;
|
||||
return;
|
||||
}
|
||||
s_delay_expired = false;
|
||||
auto alarm_cb = [](alarm_id_t, void *) -> int64_t {
|
||||
s_delay_expired = true;
|
||||
__sev();
|
||||
return 0;
|
||||
};
|
||||
alarm_id_t alarm = add_alarm_in_ms(ms, alarm_cb, nullptr, true);
|
||||
if (alarm <= 0) {
|
||||
delay(ms);
|
||||
return;
|
||||
}
|
||||
while (!g_main_loop_woke && !s_delay_expired) {
|
||||
__wfe();
|
||||
}
|
||||
if (!s_delay_expired)
|
||||
cancel_alarm(alarm);
|
||||
g_main_loop_woke = false;
|
||||
}
|
||||
} // namespace internal
|
||||
|
||||
// === Host (UDP loopback socket) ===
|
||||
|
||||
Reference in New Issue
Block a user