The logger's uart_driver_install() was allocating a 10-item FreeRTOS
event queue but passing nullptr as the queue handle, meaning nothing
could ever read from it. Setting the queue size to 0 saves ~212 bytes
of heap.
Replace std::unique_ptr<Socket> with raw Socket* for listen sockets
that are created once in setup() and live for the program lifetime.
The unique_ptr move-assign generates dead code to destroy the previous
value (which is always nullptr in setup), including a virtual destructor
call through the vtable that the compiler cannot eliminate because
__uniq_ptr_impl::reset is not inlined.
Changes:
- Use .release() to extract raw pointer from socket factory return
- Add socket_failed_/server_failed_ helpers that combine error logging,
cleanup, and mark_failed into a single call
- Convert error messages to LOG_STR for flash storage on ESP8266
- Socket destructor already calls close(), so explicit close() before
delete is unnecessary
Saves 20 bytes on ESP32-IDF, 180 bytes on ESP8266.
Resolve conflict in defines.h - keep both new NRF52 defines
(USE_LOGGER_EARLY_MESSAGE, USE_LOGGER_WAIT_FOR_CDC from dev) and
existing defines (USE_LOGGER_UART_SELECTION_USB_CDC, USE_LOGGER_USB_CDC
from this branch).
Remove unnecessary template parameters from mark_matching_items_removed_locked_
since all callers use the same concrete type (std::vector<std::unique_ptr<SchedulerItem>>).
Eliminate has_cancelled_timeout_in_container_locked_ entirely by inlining its
logic into the only caller (is_retry_cancelled_locked_), which is deprecated
and will be removed in 2026.8.0.
Saves 32 bytes of flash.
Reduce CPU usage when USB components are idle by disabling the
component loop when there are no events or data to process. The
loop is re-enabled from USB task callbacks via
enable_loop_soon_any_context() when new events or data arrive.
- Extract process_usb_events_() from USBClient::loop() returning
bool so subclasses can combine with their own work checks for a
single disable_loop() decision
- Add enable_loop_soon_any_context() calls in client_event_cb and
USB data input callback
- Start with loop disabled in setup(), enabled by first event
- Reorder USBClient members by thread-safety context
- Reorder TransferStatus fields for optimal struct packing
- Fix missing early return after mark_failed() in setup()
Reduce CPU usage when USB components are idle by disabling the
component loop when there are no events or data to process. The
loop is re-enabled from USB task callbacks via
enable_loop_soon_any_context() when new events or data arrive.
- Extract process_usb_events_() from USBClient::loop() returning
bool so subclasses can combine with their own work checks for a
single disable_loop() decision
- Add enable_loop_soon_any_context() calls in client_event_cb and
USB data input callback
- Start with loop disabled in setup(), enabled by first event
- Reorder USBClient members by thread-safety context
- Reorder TransferStatus fields for optimal struct packing
- Fix missing early return after mark_failed() in setup()
The logger loop disable optimization was guarded by USE_LOGGER_USB_CDC,
which is a platform capability flag defined whenever the platform
supports USB CDC. This meant the optimization was disabled on all
ESP32-S2, S3, C3, C5, C6, C61, H2, and P4 variants regardless of
whether USB CDC was actually selected as the hardware UART.
Changed all guards to use USE_LOGGER_UART_SELECTION_USB_CDC which is
only defined when USB CDC is the selected hardware UART. Also changed
the guard logic from || to && so the loop only stays permanently active
when both Zephyr AND USB CDC is selected (the only case that needs
cdc_loop_() to poll port readiness).
Additionally set USE_LOGGER_UART_SELECTION_USB_CDC in the Zephyr
codepath when USB CDC is selected, and updated defines.h for static
analysis coverage.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>