Skip to content

Add RP2350 support with USB OTA and hardware peripherals - #3241

Draft
floitsch wants to merge 8 commits into
masterfrom
floitsch/rp2350-support
Draft

floitsch wants to merge 8 commits into
masterfrom
floitsch/rp2350-support

Conversation

@floitsch

@floitsch floitsch commented Sep 20, 2026 •

Copy link
Copy Markdown
Member

Adds a Toit port for the WeAct RP2350B: the VM and GC, persistent containers and storage, wired peripherals, and USB firmware updates with validation and rollback.

Runtime and peripherals

  • Integrate the pinned Pico SDK fork and upstream FreeRTOS kernel. The compiler is not forked or pinned.
  • Use one event task for GPIO, UART, I2C, SPI, and USB input. Peripheral APIs take integer GP numbers.
  • Support GPIO/interrupts, ADC, PWM, UART with software RS485, and I2C/SPI controller and target operation. ADC shuts down after its last resource closes and reinitializes on reopen.
  • Support timed deep sleep, native-failure recovery, and a shared system.watchdog API on ESP32, EC618, and RP2350. Existing platform watchdog APIs remain available; the watchdog package update is toitware/toit-watchdog#17.
  • Register the TLS event source and support TLS session export through a small C adapter for mbedTLS's private C headers.
  • Remove the obsolete SweepingVisitor declaration left behind by the fast-sweep implementation; it caused the ARM linker to reference the removed add_free_list_region method.

Flashing and updates

toit tool firmware -e firmware.envelope flash --port SERIAL_PORT updates running firmware. flash --bootloader [--serial BOARD_SERIAL] performs initial installation or recovery through the USB ROM bootloader. Recovery images are generated from the current envelope, including installed containers, assets, and configuration.

The normal SDK bundles picotool, the native OTA uploader, and replaceable libusb with its source and notices. Flashing requires neither Python nor a mounted drive. The Debian package installs the PICOBOOT USB access rule automatically; archive installs document the one-time setup and the alternative of copying an extracted recovery UF2 onto the mounted ROM drive. Trial updates preserve the previous firmware until the application validates startup; recovery preserves slot B and the registry, with normal ROM version selection still applying.

Documentation covers supported usage, architecture, and reproducible tests. Bring-up transcripts and investigation diaries are not tracked. New first-party build helpers and hardware-test runners use Toit instead of Python.

Changing RP2350_PROGRAM now rebuilds the generated application snapshot, including when the selected source is older than the previous build.

Validation

  • Host image parser/boundary/fuzz, hash, picotool, envelope install/extract, retained-memory layout, and uploader PTY tests.
  • CLI regressions for envelope contents/configuration, ROM selectors, failed load/reboot handling, option validation, and installed SDK discovery for both flashing modes.
  • Linux SDK build/install/relocation and standalone flasher archive; MinGW build and runtime dependency inspection. Native watchdog implementations compile for ESP32, EC618, and RP2350; the watchdog package's six existing tests pass.
  • Physical mapped-wire tests, GPIO/ADC/PWM/UART, I2C and SPI controller/target operation, cancellation, process-exit cleanup, and simultaneous peripheral traffic with forced GCs.
  • Physical OTA validation/rollback, equal-version updates and downgrades, malformed/interrupted uploads, persistent container installation/uninstallation, native-failure recovery, and repeated deep-sleep wakeups.
  • Physical TLS session export and encrypted echo assertions over UART through the ESP32 relay, plus existing host TLS regressions.
  • Physical RS485 direction/drain, ADC last-close/reopen, shared watchdog rearm/feed/stop, and all four cases in the converted OTA rejection test.
  • Installed SDK CLI flashed a production envelope containing a validating application, assets, and configuration through both the bundled serial uploader and PICOBOOT tool, with no tool-path overrides. ROM flashing verified the written image and rebooted successfully. The board is left on confirmed v66, partition 0, with the serial port released.
  • Debian udev packaging checked in an isolated staging directory with debhelper 13.11.4; the installed rule matches the bundled upstream rule.
  • Application-switch regression verifies that selecting another program changes the built snapshot.

Limits

Physical coverage is for the WeAct RP2350B in Arm Secure mode. RP2040, RISC-V, external PSRAM, networking, and GPIO deep-sleep wakeup are not implemented. I2C scanning/address-only probes remain TODO; a GPIO implementation must reuse the bus's reserved pins and restore their peripheral function. SPI controllers support all modes; hardware targets support modes 1/3 and reject modes 0/2.

The classic ESP32 Jaguar I2C target can intermittently NACK long writes at 400 kHz. The merged ESP-IDF fixes are integrated separately by #3245; this PR does not change the ESP-IDF submodule.

macOS/MSVC builds and Windows/macOS physical flashing remain for CI or platform testing.

The implementation was removed by f456a34 (Fast sweep), but the remaining inline virtual method can still make ARM builds reference the undefined add_free_list_region method. The active collector uses OldSpace::sweep directly.

Verified with the same RP2350 Release build: restoring the declaration fails to link; removing it builds successfully.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant