Wire Application::wake_loop_any_context() to socket::socket_wake()
on ESP8266. This allows any component calling wake_loop_any_context()
from an ISR or callback to immediately wake the main loop from
esp_delay() sleep, instead of waiting up to 16ms for the timeout.
Changes:
- Add IRAM_ATTR to socket_wake() so it's safe to call from ISR context
- Add ESP8266 wake_loop_any_context() backed by socket::socket_wake()
- Extend enable_loop_soon_any_context() to wake the loop on ESP8266
LibreTiny lacks IRAM_ATTR support needed for ISR-safe paths,
and BK72xx doesn't support the mrs ipsr instruction in Thumb mode.
The existing fast select functionality on LibreTiny is unaffected.
API protobuf messages are never deleted through base class pointers —
they are always stack-allocated and passed by reference. The virtual
destructor occupies 2 vtable slots (complete + deleting destructor)
on 32-bit platforms using the Itanium ABI, costing 8 bytes per vtable.
With 122 message classes, removing the virtual destructor saves
~976 bytes of flash. Each vtable shrinks from 24 bytes to 16 bytes.
Wire Application::wake_loop_any_context() to socket::socket_wake()
on ESP8266. This allows any component calling wake_loop_any_context()
from an ISR or callback to immediately wake the main loop from
esp_delay() sleep, instead of waiting up to 16ms for the timeout.
Changes:
- Add IRAM_ATTR to socket_wake() so it's safe to call from ISR context
- Add ESP8266 wake_loop_any_context() backed by socket::socket_wake()
- Extend enable_loop_soon_any_context() to wake the loop on ESP8266
Wire Application::wake_loop_any_context() to socket::socket_wake()
on ESP8266. This allows any component calling wake_loop_any_context()
from an ISR or callback to immediately wake the main loop from
esp_delay() sleep, instead of waiting up to 16ms for the timeout.
Changes:
- Add IRAM_ATTR to socket_wake() so it's safe to call from ISR context
- Add ESP8266 wake_loop_any_context() backed by socket::socket_wake()
- Extend enable_loop_soon_any_context() to wake the loop on ESP8266
LibreTiny's FreeRTOS port does not provide portYIELD_FROM_ISR.
On ARM Cortex-M, FreeRTOS internally sets the PendSV bit when
vTaskNotifyGiveFromISR wakes a higher-priority task, so the
context switch happens automatically when the ISR returns.
Wire Application::wake_loop_any_context() to socket::socket_wake()
on ESP8266. This allows any component calling wake_loop_any_context()
from an ISR or callback to immediately wake the main loop from
esp_delay() sleep, instead of waiting up to 16ms for the timeout.
Changes:
- Add IRAM_ATTR to socket_wake() so it's safe to call from ISR context
- Add ESP8266 wake_loop_any_context() backed by socket::socket_wake()
- Extend enable_loop_soon_any_context() to wake the loop on ESP8266
Now that the ISR callback mechanism (from #14382) costs essentially
zero — just a function pointer registration, no task or queue — enable
wake-on-RX by default for all ESP32 UART instances.
This reduces RX buffer overflow risk by waking the main loop
immediately when data arrives instead of waiting for the ~16ms
select timeout.
Remove the opt-in request_wake_loop_on_rx() API since all ESP32
UART instances now get this automatically.
The fast select code paths and wake_loop_any_context() require
USE_SOCKET_SELECT_SUPPORT. Gate USE_LWIP_FAST_SELECT on not using
lwip_tcp implementation which does not provide select() support.
- Update ISR safety comment: point 3 now reflects that
wake_loop_any_context() is called (ISR-safe)
- Initialize ipsr = 0 as safety net before inline asm
- Update ISR safety comment: point 3 now reflects that
wake_loop_any_context() is called (ISR-safe)
- Initialize ipsr = 0 as safety net before inline asm
- Replace __get_IPSR() with inline asm to avoid CMSIS header dependency
on LibreTiny chip families that may not declare it (e.g. beken-72xx)
- Pass local variable to wake_from_isr and call portYIELD_FROM_ISR for
immediate context switch instead of passing NULL
- Update comment in component.cpp to mention both ESP32 and LibreTiny
platform-specific context detection
- Switch USE_LWIP_FAST_SELECT from cg.add_define to cg.add_build_flag
so it is visible in .c translation units, aligning guards across all
source files
Replace acosf(y/distance) + sign flip with atan2f(-x, y) which
computes the angle from the Y axis directly. This eliminates the
division by distance, the acosf call, the sign branch, and the
calculate_angle helper function entirely.
atan2f also handles all quadrants correctly by definition, avoiding
the edge-case guard that silently returned 0 when y was negative.
Merge the two separate count_targets_in_zone_ calls (one for still,
one for moving) into a single pass that counts both simultaneously.
This halves the number of iterations through the target list per zone
(from 6 calls to 3 for 3 zones).
Replace per-frame string comparison with Deduplicator<uint8_t> on
the direction enum value. The previous code called get_state() and
compared std::string against const char* on every frame for each
target (~75 times/sec). The new approach does a single uint8_t
comparison and only looks up the direction string and publishes
when the direction actually changes.
Also use MAX_TARGETS instead of hardcoded 3 for direction_text_sensors_
array size for consistency with all other sensor arrays.