Skip to content

build: move to pioarduino 55.03.312 (Arduino 3.3.12, ESP-IDF 5.5) - #71

Merged
cjkas merged 7 commits into
feat/eth-framework-independentfrom
feat/idf55
Oct 21, 2026
Merged

cjkas merged 7 commits into
feat/eth-framework-independentfrom
feat/idf55

Conversation

@cjkas

@cjkas cjkas commented Oct 19, 2026

Copy link
Copy Markdown
Owner

Summary

This is part 2 of the IDF 5.5 migration. It is stacked on #70, so merge that first. The decision and its trade-offs are in ADR 0003.

 [esp32]
-platform = espressif32 @ 6.13.0                       ; Arduino 2.0.17 / IDF 4.4.7
+platform = …/pioarduino/…/55.03.312/…zip              ; Arduino 3.3.12 / IDF 5.5, pinned
 envs
   esp32dev     CORE_DEBUG_LEVEL 3 -> 2                 ; needed to fit the 1.5 MB OTA slot
   esp32devdbg  3
-  esp32c3                                             ; image no longer fits its OTA slot
   esp32s3      3 -> 2
   esp32c6      own libs/platform -> shared [esp32]    ; still debug + huge_app

How an updated firmware gets confirmed. The core's verifyRollbackLater() hook is overridden:

boot after OTA     state PENDING_VERIFY, the core skips verification
loop()             once uptime >= 60 s and net.connected(): esp_ota_mark_app_valid_cancel_rollback()
reset before that  the bootloader boots the previous firmware

Other changes:

  • esp_task_wdt_reconfigure() replaces esp_task_wdt_init(). On 3.x the core starts the watchdog before setup(), so init failed and the C6 build kept the 5 s default.
  • ETH.begin() uses the 3.x argument order, and the Arduino 2.x #if branches are removed.
  • CI installs pioarduino (Core 6.2) and runs .github/size_check.py, which compares firmware.bin with the app partition in partitions.bin. It fails with less than 8 KB free.
  • Docs: ADR 0003, a Building section in the README, AGENTS.md, and a GitOTA certificate note in SECURITY_PLAN.md.

Evidence

Why the size check exists. PlatformIO's Flash: line counts ELF sections, not the image that has to fit:

Env PlatformIO "Flash:" firmware.bin App slot Free
esp32dev 1,508,932 (95.9%) 1,555,488 1,572,864 17.0 KB ✅
esp32c3 1,551,001 (98.6%) ✅ 1,651,216 1,572,864 −76.5 KB
esp32s3 1,427,901 1,473,696 3,342,336 1,824.8 KB ✅
esp32c6 (huge_app) 1,664,334 1,800,416 3,145,728 1,313.8 KB ✅
esp32devdbg (huge_app) 1,632,808 1,695,056 3,145,728 1,416.7 KB ✅

For comparison, v3.0.14 on IDF 4.4: ESP32 1,382,640, C3 1,437,440.

  • pio test -e native with pioarduino Core: 415/415 passed, including the new otaProven tests.
  • The firmware.elf symbols show the hooks are linked:
    • T verifyRollbackLater: our strong override.
    • W verifyOta: the core's weak default, never called.
    • T __wrap_log_printf and T __wrap_log_printfv: the log lock still sits under the ESP Insights wrap.

Not yet tested on hardware, and needed before the 3.1.0 pre-release:

  • OTA from v3.0.14 to this build on an ESP32
  • Forced rollback: reset within 60 s of the first boot
  • USB flash of the onboard image
  • CC1101 send and receive
  • 24 h memStatus heap and loop health
  • Ethernet board (volunteer)
  • C6 radio (volunteer)

Merge Danger

Door: two-way

Reverting the commit puts the build back on 6.13.0. A device that has installed and confirmed an IDF 5.5 firmware can still go back to 3.0.x through a normal OTA, because the partition table, NVS and backup formats are unchanged. The tooling change does reach every contributor: pioarduino replaces PlatformIO Core in ~/.platformio/penv.

Blast Radius: release

  • C3 users get no new releases. GitOTA on a C3 board will show an error for 3.1.0 because the release has no ino.esp32c3.bin.
  • Logs: release builds lose the info and debug lines (about 220 call sites). Warnings and errors stay.
  • Existing bug, not fixed here: GitOTA's LittleFS step requests SomfyController.littlefs.bin, but releases publish littlefs.esp32*.bin. An online update installs the new firmware and keeps the old web UI. After a rollback, the old firmware also runs with whatever UI is on the device.

🤖 Generated with Claude Code

cjkas and others added 5 commits October 19, 2026 22:05
IDF 4.4 gets no more security fixes, and the planned RMT radio needs
IDF 5's RMT driver.  See docs/adr/0003-pioarduino-idf55.md.

- Every env on one pinned pioarduino release.  C6 drops its own
  library list and flags but stays a debug build on huge_app.
- Release envs build at CORE_DEBUG_LEVEL=2 so the ESP32 image fits its
  1.5 MB OTA slot (17 KB free); debug envs stay at 3.
- Drop the C3: its image is 76.5 KB over the OTA slot on IDF 5.5.
- CI installs pioarduino's Core and checks firmware.bin against the app
  partition, failing under 8 KB free.  PlatformIO's "Flash:" figure
  reads ~45 KB low and passed a C3 image that doesn't fit.
- esp_task_wdt_reconfigure(): on 3.x the core already starts the watchdog
  and esp_task_wdt_init() fails, so the C6 build kept the 5 s default.
- An updated firmware is kept only once it has run 60 s with the
  network up; a reset before then rolls back to the previous one.
- ETH.begin() takes the 3.x argument order; Arduino 2.x branches gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Releases publish SomfyController.littlefs.<chip>.bin, but the updater asked
for SomfyController.littlefs.bin. The download 404'd and the device rebooted
into the new firmware with the old web UI.

Also: hasFS now matches per-chip images, C6 picks its own firmware file, and
recoverFilesystem() points at cjkas instead of rstrouse.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review follow-up for #72.

- releaseAssetName() takes ConfigSettings::chipModel ("", "s3", "c3", "c6"),
  so GitOTA no longer keeps its own chip switch. C3 keeps its name for when
  the build comes back.
- hasFS is set only when this board's own LittleFS image is in the release.
  isFsAsset() is gone; it also matched the old unsuffixed littlefs.bin, which
  the updater no longer asks for.
- releaseAssetName() returns void: no caller checked the result and every
  name fits currentFile.
- Both manual-upload hints name this board's file.
- KNOWN_ISSUES: the "Main" install can't work, the repo holds no .bin files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copied from the registry package lsatan/SmartRC-CC1101-Driver-Lib@2.5.7
(upstream unmaintained since 2021) so it can be fixed for Arduino 3.x in
the next commit. This commit is the untouched copy, so that diff shows
every change. Licence: LICENSE.txt ("permission to modify and publish").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Arduino 3.x tracks which peripheral owns each pin and logs when a pin the
SPI bus owns is used through digitalRead()/digitalWrite(). The vendored
SmartRC-CC1101 driver does both:

- Every register access waits for CHIP_RDYn with digitalRead(MISO): one
  "IO 19 is not set as GPIO" warning per access, about one every 4 s from
  the RSSI read in decodeFrame(). It now reads the pad with gpio_get_level(),
  which returns the same level without the ownership check.
- Init() set SCK and MOSI with digitalWrite() after SpiStart(), which the core
  refused with an error each boot. The writes are gone; the bus idles them.

The MISO wait also had no bound, so a missing or dead module hung the caller.
It now gives up after 10 ms.

No native test: the driver only builds for the ESP32. To check on hardware:
the serial log should have no "is not set as GPIO" lines, and frames should
still decode with an RSSI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cjkas added 2 commits October 21, 2026 12:46
fix: download the per-chip LittleFS image in online updates
fix: stop the CC1101 driver's "IO is not set as GPIO" log spam
@cjkas
cjkas merged commit 4dbef4f into feat/eth-framework-independent Oct 21, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant