The previous LwIPLock for RP2040+Ethernet only called
ethernet_arch_lwip_begin/end, taking the async_context lock but never
bumping arduino-pico's __inLWIP counter. The W5500 GPIO IRQ path
(LwipIntfDev::_irq) checks __inLWIP to decide whether to defer packet
processing; with __inLWIP == 0 it would proceed to run _lwipCallback
immediately from IRQ context even while the main thread held the
async_context lock, re-entering lwIP and corrupting pbuf chains.
The corruption surfaced later as the pbuf_cat assertion
"p->tot_len == p->len (of last pbuf in chain)" panicking the device
on wiznet-w5500-evb-pico boards configured with an interrupt pin.
Mirror arduino-pico's LWIPMutex (cores/rp2040/lwip_wrap.h) exactly:
bump __inLWIP, take the lock, and on release re-unmask any GPIO IRQs
that were deferred while we held it (__needsIRQEN). We can't write
`using LwIPLock = LWIPMutex;` in core/helpers.h because pulling
lwip_wrap.h there transitively poisons many translation units with
lwIP types in an order that breaks err_t resolution, so the body is
inlined in the rp2040 helpers.cpp where the include is scoped.
The X-macro file requires ENTITY_TYPE_ and ENTITY_CONTROLLER_TYPE_
macros to be defined before inclusion. The generated esphome.h includes
all .h files bare, which causes compilation errors.
Neither PlatformIO nor ESP-IDF/CMake copy .inc files to the build
directory. Rename to .h so it's recognized by both build systems.
Exempt from pragma-once lint since this file is intentionally included
multiple times with different macro definitions.
clang-tidy flags macro arguments that aren't parenthesized, but
wrapping template type arguments in parentheses would break C++ syntax.
Add NOLINTBEGIN/END around the remaining macro blocks.
PlatformIO only copies files with extensions listed in
SOURCE_FILE_EXTENSIONS to the build directory. Add .inc so that
X-macro include files (entity_types.inc) are available during
compilation.
Introduce entity_types.inc X-macro and entity_includes.h shared header
to eliminate ~1000 lines of repetitive #ifdef/entity-type blocks across
core files.
entity_types.inc defines each entity type once with two macros:
- ENTITY_TYPE_ for non-controller entities (button, infrared)
- ENTITY_CONTROLLER_TYPE_ for entities with controller callbacks
Each consumer includes the file with appropriate macro definitions.
Sites wanting all entities delegate ENTITY_CONTROLLER_TYPE_ to
ENTITY_TYPE_. Sites wanting only controller entities define
ENTITY_TYPE_ as empty.
entity_includes.h consolidates the conditional entity header includes
shared by application.h, controller.h, and controller_registry.h.
Also makes ComponentIterator::on_media_player pure virtual for
consistency (trivial override added to web_server::ListEntitiesIterator).
Add a new message-level option (inline_encode) that causes the code
generator to inline sub-message encoding directly into the parent's
encode/calculate_size methods instead of going through the
encode_sub_message function pointer indirection.
When set on a sub-message type, the generator:
- Inlines field encoding directly (no function pointer, no backpatch overhead)
- Inlines size calculation (no separate method call)
- Skips generating standalone encode/calculate_size methods
- Validates at generation time that max encoded size < 128 bytes
Applied to BluetoothLERawAdvertisement which is encoded 12 times per
BLE advertisement batch in a hot loop.
- uint32_to_str_(): raw pointer, internal use
- uint32_to_str(): template with compile-time buffer size check
- frac_to_str_(): raw pointer, internal use
- small_pow10(): simplify to ternary chain