For boards such as Waveshare's ESP32-P4-WIFI6-POE-ETH: WiFi through the board's ESP32-C6 on SDIO (esp-hosted), Ethernet on the P4's RMII MAC with an IP101. Not tested on a device: no P4 board was at hand. - platformio.ini: env esp32p4 (esp32-p4_r3, chip v3.01+) and esp32p4es (esp32-p4, the esp32p4_es libraries, chips before v2.0). An image runs on one of the two only, so each has its own release files, chip models "p4" and "p4es". Both keep the OTA slot: at level 2 they leave about 128 KB of it. - Ethernet clock mode: stored as eth_clock_id_t in the ESP32's numbering and translated by name, like the PHY id. The P4's eth_clock_mode_t is the IDF's emac_rmii_clock_mode_t, whose 0 is a deprecated default; only clock in (GPIO 50) translates there. - P4 Ethernet defaults: the Waveshare wiring (IP101 as TLK110, address 1, MDC 31, MDIO 52, reset 51), board type 8. The ESP32's put MDIO on an SDIO pin. - Settings take pins up to GPIO 54, the P4's last, instead of 48. - Radio defaults: SPI 32/33/27, CSN 46 (the framework's Waveshare variant), TX 2, RX 3. - Web UI: a Waveshare ESP32-P4-ETH preset, the P4's clock mode, pin lists up to GPIO 54 without the pins the C6 link, Ethernet, USB and UART0 use. - CI builds and releases both, with their ELFs; bootloader at 0x2000. - ADR 0003: amended. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4.5 KiB
Firmware builds on pioarduino (Arduino 3.x, ESP-IDF 5.5), pinned to one release
We moved every firmware env from espressif32 @ 6.13.0 (Arduino 2.0.17 on ESP-IDF 4.4.7) to pioarduino's 55.03.312 (Arduino 3.3.12 on ESP-IDF 5.5). IDF 4.4 no longer gets security fixes for Wi-Fi, lwIP and mbedTLS, and the planned RMT radio needs IDF 5's RMT driver. The official PlatformIO platform never shipped Arduino 3.x, so pioarduino, a community fork, is the only way to get it in PlatformIO. We pin one release URL rather than stable, so a framework upgrade is always its own PR with its own size check and hardware test.
Considered Options
- Stay on IDF 4.4. Rejected: no more security fixes, and no new RMT driver.
- Rebuild the IDF libraries with
custom_sdkconfigto leave out PPP, NAT and provisioning (about 20 KB the firmware never uses). Deferred: it makes builds much slower, and log level 2 already makes the ESP32 build fit. - Grow the app slots in the partition table. Rejected: an OTA update can't change the partition table, so every existing device would need a USB flash.
Consequences
-
Firmware size. The ESP32 image grows from 1,382,640 bytes (v3.0.14) to 1,555,472 at
CORE_DEBUG_LEVEL=2, leaving 17 KB of the 1.5 MB OTA slot. At level 3 it doesn't fit, so release envs build at level 2 (warnings and errors) and debug envs stay at 3. PlatformIO's "Flash:" figure counts ELF sections, not the image, and reads about 45 KB low, so CI checksfirmware.binagainst the app partition and fails under 8 KB free (.github/size_check.py). -
No more C3 builds. Its image grows by 214 KB to 1,651,216 bytes, 76.5 KB over the OTA slot even at level 2. C3 boards stay on the 3.0.x releases.
Amended by ADR 0006 (4.0.0). The C3 builds again. Without the old API (ports 8080 and 8081), its image is 1,498,512 bytes at level 2 and leaves 72.6 KB of the OTA slot. It runs on chip revision v0.3 or later only: the framework's C3 libraries are built with
CONFIG_ESP32C3_REV_MIN_3. Its default radio pins moved off GPIO 12-17, which hold the SPI flash. -
The C5 is updated over USB. New in 4.0.0. At level 2 its image left 3.4 KB of the OTA slot, under CI's 8 KB, so like the C6 it is released as a debug build with one 3 MB app slot (
esp32_huge_app.csv), which no OTA can write. The framework's C5 libraries run on chip revision v1.0 or later only (CONFIG_ESP32C5_REV_MIN_FULL=100). Its WiFi has 5 GHz too, so the passive scans for the configured network (src/ESPNetwork.cpp, 300 ms a channel) cover about 38 channels instead of 13: about 11 s instead of 4 s, depending on the country's channels. -
The P4 has two builds. New in 4.0.0, for boards such as Waveshare's ESP32-P4-WIFI6-POE-ETH. The framework's P4 libraries run on chip revision v3.01 or later only (
CONFIG_ESP32P4_REV_MIN_FULL=301), itsesp32p4_eslibraries on revisions before v2.0, soesp32p4(chip modelp4) andesp32p4es(p4es) each get their own release files. Both keep the OTA slot: at level 2 their images leave about 128 KB. WiFi goes through the board's ESP32-C6 on SDIO (esp-hosted, the framework's pins 14-19 and reset 54), so the C6 has to run a matching esp-hosted slave firmware, which Waveshare's boards ship with. -
Ethernet PHY ids are ours. Arduino 3.x renumbered
eth_phy_type_t(ETH_PHY_GENERICis 0). NVS, backups and the web UI keep the Arduino 2.x numbers aseth_phy_id_t(src/EthPhy.h), translated by name when Ethernet starts. Never cast a stored id to the framework enum. The RMII clock mode is kept the same way, aseth_clock_id_tin the ESP32's numbering: the P4'seth_clock_mode_tis the IDF'semac_rmii_clock_mode_t, whose 0 is a deprecated default. On the P4 only clock in (GPIO 50) translates, sinceETH.begin()keeps the clock on that pin. -
Ethernet only on the original ESP32 and the P4. Arduino 3.x has the RMII MAC API only where
CONFIG_ETH_USE_ESP32_EMACis set. S3, C3, C5 and C6 build without Ethernet. -
Updates roll back until proven. We override the core's
verifyRollbackLater()hook to return true, andloop()marks the new firmware valid once it has run 60 s and the network is up. A reset before then boots the previous firmware. The LittleFS image an update wrote stays, so the old firmware runs with the new web UI. -
Tooling. pioarduino needs its own Core fork (
pip install pioarduino, the pioarduino IDE extension in VS Code), which it installs into~/.platformio/penvin place of PlatformIO Core.