Why RPBridge¶
Linux developers regularly need access to low-speed peripheral buses on workstations, laptops and SBCs that do not expose them natively. The alternatives on the market are either
- closed-source vendor dongles with bespoke APIs, requiring their own library + daemon on every machine,
- single-bus adapters (CP2102 for UART, FT232H for one bus, MCP2221 for I²C or GPIO…),
- expensive industrial bridges that package everything but lock users into proprietary drivers.
RPBridge unifies seven bus classes on one open-source device. Each
one appears as a standard Linux subsystem entry — /dev/i2c-N,
/dev/spidevN.M, /dev/gpiochipN, /dev/ttyACM*, can0 — which
means every existing tool, script, and service keeps working
unmodified:
i2c-tools(i2cdetect,i2cget,i2cset,i2ctransfer)libgpiod 2.x(gpioset,gpioget,gpiomon) and anything linkinglibgpiodcan-utils(cansend,candump,cangen,cansequence) + any SocketCAN-based software (Wireshark CAN dissector, SavvyCAN, python-can)flashromandspidev_teston SPI flash chipsiio_info/iio_readdevfor the ADC — and throughlibiio, Grafana and friends- any terminal that talks to
/dev/ttyACM*(PuTTY, minicom, picocom, tio, Arduino IDE)
Why RP2354B¶
- 2× Cortex-M33 @ 150 MHz with FPU and DSP, 520 KB SRAM.
- 12 PIO state machines across 3 PIO blocks — enough to run CAN 2.0B in software (via can2040) while still leaving room for PIO-based UARTs, 1-Wire, WS2812, and custom applets.
- 2 MB stacked QSPI flash integrated in the QFN-80 package — one less external IC on the board.
- USB 2.0 Full-Speed (12 Mbit/s) native. We lose high-speed bandwidth relative to chips with HS PHYs, but USB-FS is enough to share seven low-speed buses with headroom.
- Excellent tooling (pico-sdk, picotool, TinyUSB) and a well-supported open ecosystem.
Why Rust in userspace, C in the kernel¶
For the kernel driver: plain C against the Linux kernel's stable
in-kernel ABI. The driver was first attempted in Rust-for-Linux —
the R4L API is still stabilising (between 6.18 and 7.0 the
kernel::usb::Driver trait, KString, #[vtable] mechanics and
the probe lifecycle all moved). Out-of-tree R4L modules pay this
drift cost on every major kernel release. C compiles unchanged
across years, which matters more for an out-of-tree module that has
to land on whatever Linux Ubuntu ships today than the marginal
maintenance benefit of "one language top-to-bottom" did.
For userspace: memory safety, a first-class async ecosystem
(nusb, tokio), a crate-per-binding model that makes FFI bindings
to Python and .NET straightforward, and a build system that cross-
compiles to ARM SBCs without surprises.
See ADR-0003 #Amendment for the full reasoning behind the C pivot.