Replace write_() call with direct char stores for the 4-byte
ANSI reset sequence ("\033[0m"). This eliminates function call
overhead (entry/retw, bounds check, memcpy setup) on every log
message and avoids a rodata string reference that consumes RAM
on ESP8266.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
On IDF 5.x, the ESP-IDF headers use CONFIG_ETH_SPI_ETHERNET_W5500 and
CONFIG_ETH_SPI_ETHERNET_DM9051 to conditionally expose the W5500/DM9051
types. Static analysis (clang-tidy) needs both the new USE_ETHERNET_*
defines and the old CONFIG_* defines to resolve all symbols.
On IDF 5.x these headers don't exist as standalone files — they are
included internally via esp_eth.h. On IDF 6.0 they moved to registry
components and need explicit includes.
LAN867x is unchanged (external component since IDF 5.3).
pioarduino only patches esp_eth_phy_new_jl1101() into IDF 5.4.2-5.x,
not IDF 6.0. Update guards in both the .c driver and .h declaration
to also compile when IDF >= 6.0.
Guard logic: compile custom driver when JL1101 configured AND
(IDF >= 6.0 OR IDF < 5.4.2 OR not PlatformIO)
- Exclude esp_eth_phy_jl1101.c when JL1101 is not configured
- Exclude on IDF 5.4.2-5.x where pioarduino has it builtin
- Keep custom driver for IDF < 5.4.2 and IDF 6.0+ (pioarduino may
not have patched JL1101 into their IDF 6.0 fork yet)
- Always use esp_eth_phy_new_jl1101() in C++ (no generic fallback)
- Namespace ethernet type in CORE.data[KEY_ETHERNET]
Only exclude esp_eth_phy_jl1101.c at the Python level on IDF >= 6.0.
On IDF 5.4.2+ with PlatformIO, the file's own preprocessor guard
(checking the C-level PLATFORMIO define) compiles it to empty.
- Add explicit includes for per-chip PHY/MAC headers (required on IDF 6.0
where they are no longer pulled in via esp_eth.h, also works on IDF 5.x)
- Exclude esp_eth_phy_jl1101.c from compilation on IDF >= 6.0 (uses
generic PHY) and IDF >= 5.4.2 with PlatformIO (uses builtin driver)
ESP-IDF 6.0 moved individual ethernet PHY and SPI MAC/PHY drivers out
of the builtin esp_eth component into the Espressif Component Registry.
Changes:
- Add USE_ETHERNET_W5500/DM9051 defines, replacing CONFIG_ETH_SPI_ETHERNET_*
Kconfig options that were removed in IDF 6.0
- Conditionally pull registry components (lan87xx, rtl8201, dp83848,
ip101, ksz80xx, w5500, dm9051) via add_idf_component() on IDF >= 6.0
- Skip CONFIG_ETH_SPI_ETHERNET_{TYPE} sdkconfig on IDF >= 6.0
- Fix emac_rmii_clock_gpio_t cast using decltype (enum removed in IDF 6.0)
- Use esp_eth_phy_new_generic() for OPENETH and JL1101 on IDF >= 6.0
- Fix JL1101 to work on IDF 5.4.2+ with PlatformIO (was previously
falling through to mark_failed due to overly restrictive guard)
- Exclude custom JL1101 driver on IDF >= 6.0
- Add registry components to idf_component.yml for static analysis
- Update defines.h for static analysis
All changes maintain backward compatibility with IDF 5.x.
Mark 12 leaf classes (no subclasses) as final to enable
compiler devirtualization of virtual calls, reducing code
size and improving performance on embedded targets.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Eliminates virtual dispatch from ESPPreferenceBackend and ESPPreferences.
Only one implementation of each exists per platform build, so the
polymorphic design was unnecessary overhead — same pattern as OTA (#14473)
and socket (#14398) devirtualizations.
Each platform's backend class is now a standalone final class in its own
header (preference_backend.h). The preferences manager class is extracted
to the platform's preferences.h with a PreferencesMixin CRTP base for
shared template helpers. core/preference_backend.h provides the
PreferenceBackend alias, ESPPreferenceObject, and DECLARE_PREFERENCE_ALIASES
macro. core/preferences.h is a thin wrapper including the active platform.
ESPPreferenceBackend and ESPPreferences become backward-compatible type
aliases to the concrete types. Zero caller changes required.
Don't set started_ = true in setup(). Let the link polling in
loop() set it when the W5500 PHY link is actually up. Previously,
setting it immediately caused a spurious state transition because
the W5500 needs time after begin() before the link is ready.
Don't set started_ = true in setup(). Let the link polling in
loop() set it when the W5500 PHY link is actually up. Previously,
setting it immediately caused a spurious state transition because
the W5500 needs time after begin() before the link is ready.
localIP() reads netif->ip_addr which can be mutated by DHCP
callbacks from IRQ context. Lock for consistency since this is
called from API responses, not just hot-loop polling.
- Throttle linkStatus()/connected() polling to 500ms intervals to
avoid excessive SPI transactions on every loop iteration
- Guard USE_ETHERNET/USE_ETHERNET_SPI in RP2040 defines.h block
with #ifndef to prevent macro redefinition warnings
Explain why linkStatus() and connected() are called without
LwIPLock — linkStatus() only reads the W5500 PHY via SPI, and
connected() does a single atomic 32-bit read of netif->ip_addr.
- Copy dns_getserver() values (not pointers) under LwIPLock in
dump_connect_params_() to avoid dereferencing stale pointers
- Read netif ip_addr/netmask/gw under LwIPLock to prevent races
with DHCP callbacks from IRQ context
- Remove duplicate connect_begin_ assignment in start_connect_()
- Remove duplicate status_set_warning() call in start_connect_()
Add a separate no-argument status_set_warning() that delegates to the
LogString* overload, matching the existing status_set_error() pattern.
This allows the linker to garbage-collect the const char* overload in
firmware that only uses no-arg or LOG_STR() calls.
Migrate static string literal callers to LOG_STR() so the const char*
overload can be eliminated in most builds.