Skip to content

revka hardware & peripheral

Discover USB boards, register peripherals, and flash firmware from the CLI.

Revka can drive physical microcontrollers and single-board computers as agent tools. Two CLI command groups manage that hardware:

  • revka hardware — read-only discovery and identification of USB-connected boards (Pico, Arduino, ESP32, Nucleo), plus probe-rs chip introspection.
  • revka peripheral — register boards in config.toml, flash Revka firmware, and set up the more involved boards (Arduino Uno Q bridge, STM32 Nucleo).

Use these commands when you connect a new board, need to flash firmware before the agent can talk to it, or want to confirm which device sits on which serial port. Once a board is registered, the agent calls it through tools like gpio_write / gpio_read over a JSON-over-serial protocol.

For the deeper hardware story — per-board reference, GPIO tools, flashing, and the Aardvark adapter — see the Hardware quickstart and Supported boards reference. To attach a board for a single session without editing config, use the --peripheral flag documented in revka agent.

Terminal window
revka hardware discover # enumerate connected USB boards
revka hardware introspect /dev/ttyACM0 # identify the device at a path
revka hardware introspect COM3 # Windows path
revka hardware info # chip info via probe-rs (default chip)
revka hardware info --chip STM32F401RETx # chip info for a specific target
SubcommandArgument / flagMeaning
discoverScan all USB serial ports, match VID/PID against the built-in board registry, and assign session aliases.
introspect<path> (required)Read detailed USB info for one device path and correlate it with the registry to report board name and architecture.
info--chip <NAME>Read chip name, architecture, and memory map over USB/SWD with probe-rs. No firmware on the target required. Default chip: STM32F401RETx.

revka hardware discover scans every USB serial port, matches each device’s USB vendor/product ID against a built-in registry, and assigns a stable session alias such as pico0, arduino0, esp0, nucleo0, or device0. Devices with an unrecognized VID are probed with a short firmware-ping handshake; only boards that answer with Revka firmware are registered, and others are skipped silently.

Terminal window
revka hardware discover
USB devices:
2e8a:000a (unknown) — Board in FS mode
2341:0043 arduino-uno (unknown arch) —
Known boards: nucleo-f401re, nucleo-f411re, arduino-uno, arduino-mega, cp2102

The same scan runs automatically when the daemon starts, so discovered boards are registered and their tools loaded without a separate command. Aliases are stable for the life of a session and reset on daemon restart.

BoardUSB VIDAlias prefix
Raspberry Pi Pico0x2E8Apico0, pico1, …
Arduino0x2341arduino0
ESP32 (CP2102)0x10C4esp0
STM32 Nucleo0x0483nucleo0
Total Phase Aardvark0x2B76device0, device1, …

When you already know a device path, revka hardware introspect <path> opens it, reads its USB details, and matches them to the registry to print the board name, architecture, and memory map.

Terminal window
revka hardware introspect /dev/ttyACM0
Device at /dev/ttyACM0:
VID:PID 0483:374b
Board nucleo-f401re
Architecture ARM Cortex-M4
Memory map Build with --features probe for live memory map via USB

revka hardware info connects to an STM32 Nucleo over USB through the on-board ST-Link and reads the chip identity and memory map directly via SWD — no firmware needs to be on the target. This is useful for factory programming and chip identification.

Terminal window
cargo build --release --features hardware,probe
revka hardware info --chip nucleo-f401re
Connecting to nucleo-f401re via USB (ST-Link)...
Chip: STM32F401RETx
Architecture: Armv7em
Memory map:
RAM: 0x20000000 - 0x2001FFFF (128 KB)
Flash: 0x08000000 - 0x0807FFFF (512 KB)
Info read via USB (SWD) — no firmware on target needed.

revka peripheral registers boards so the agent can use them, and flashes Revka firmware to the boards that need it. Registered peripherals become available to the agent as tools in the agent loop.

Terminal window
revka peripheral list # list configured boards
revka peripheral add nucleo-f401re /dev/ttyACM0 # register a serial board
revka peripheral add rpi-gpio native # register native GPIO (RPi)
revka peripheral add esp32 /dev/ttyUSB0
revka peripheral add arduino-uno COM3
revka peripheral flash # flash Arduino (Revka firmware)
revka peripheral flash --port /dev/cu.usbmodem12345
revka peripheral flash -p COM3
revka peripheral setup-uno-q # deploy Uno Q bridge app
revka peripheral setup-uno-q --host 192.168.0.48
revka peripheral flash-nucleo # build + flash Nucleo firmware
SubcommandArgument / flagMeaning
listList the peripherals currently configured under [peripherals].
add<board> <path>Register a board in config.toml. path is a serial device path, or native for on-board GPIO.
flash-p / --port <SERIAL_PORT>Flash Revka firmware to an Arduino Uno with arduino-cli. Port defaults to the first arduino-uno in config.
setup-uno-q--host <IP>Deploy the GPIO bridge app to an Arduino Uno Q. Omit --host when running on the Uno Q itself.
flash-nucleoBuild the Embassy firmware and flash a Nucleo-F401RE via probe-rs over ST-Link.

revka peripheral add <board> <path> writes a board entry into ~/.revka/config.toml. Use it for boards that were not auto-discovered — for example a board plugged in after the daemon started, or one with an unrecognized VID.

Terminal window
revka peripheral add nucleo-f401re /dev/ttyACM0
revka peripheral list

The equivalent manual config.toml entry:

[peripherals]
enabled = true
[[peripherals.boards]]
board = "nucleo-f401re"
transport = "serial"
path = "/dev/ttyACM0"
baud = 115200
FieldTypeDefaultMeaning
boardstringBoard identifier, e.g. nucleo-f401re, arduino-uno, esp32, rpi-gpio, arduino-uno-q.
transportstringserialserial (USB/serial), native (local GPIO, e.g. Raspberry Pi), or bridge (Arduino Uno Q bridge app).
pathstringDevice path for serial; omit for native.
baudinteger115200Serial baud rate.

revka peripheral flash flashes Revka firmware to an Arduino Uno using arduino-cli. It installs arduino-cli (via Homebrew on macOS) if missing, installs the AVR core, compiles the embedded firmware sketch, and uploads it. The firmware enables the capabilities, gpio_read, and gpio_write commands over serial.

Terminal window
revka peripheral flash --port /dev/cu.usbmodem14301
# or, if an arduino-uno board is already in config.toml:
revka peripheral flash
  • On macOS, arduino-cli is auto-installed via Homebrew when absent. On Linux, the command prints install instructions and exits with an error if arduino-cli is not found.
  • The --port value is validated: ports starting with - or containing shell metacharacters are rejected.
  • After flashing, register the board with revka peripheral add arduino-uno <path> so the GPIO tools load.

revka peripheral flash-nucleo builds the Embassy Rust firmware for the Nucleo-F401RE and flashes it through probe-rs over the board’s built-in ST-Link — no separate debug probe is needed. After flashing, the board answers the Revka serial JSON protocol over its ST-Link virtual COM port.

Terminal window
revka peripheral flash-nucleo

The manual equivalent:

Terminal window
cd firmware/nucleo
cargo build --release --target thumbv7em-none-eabihf
probe-rs run --chip STM32F401RETx target/thumbv7em-none-eabihf/release/nucleo

The Arduino Uno Q pairs a Linux side with an MCU. revka peripheral setup-uno-q deploys the bridge app — a Python + MCU socket server — to the board, which listens on TCP port 9999 and exposes gpio_read / gpio_write from the Linux side to the MCU’s GPIO.

Terminal window
# From your Mac, targeting the Uno Q over the network:
revka peripheral setup-uno-q --host 192.168.0.48
# From the Uno Q itself (SSH'd in), targeting localhost:
revka peripheral setup-uno-q

After setup, register the board with the bridge transport:

[[peripherals.boards]]
board = "arduino-uno-q"
transport = "bridge"

With this configuration the standard gpio_read and gpio_write tools are transparently backed by the bridge TCP socket (127.0.0.1:9999) instead of a serial port — the agent uses the same tool names. The bridge must be running for the tools to work.

Board (board value)TransportFirmware / driverHow to flash / set up
nucleo-f401re / nucleo-f411reserialEmbassy (Rust)revka peripheral flash-nucleo (probe-rs over ST-Link)
arduino-unoserialAVR sketchrevka peripheral flash (arduino-cli)
arduino-uno-qbridgeLinux + MCU bridge apprevka peripheral setup-uno-q
esp32serialESP-IDF / Embassyflashed externally; register with add
rpi-gpionativerppal / sysfs (peripheral-rpi)auto-detected; or add rpi-gpio native
Raspberry Pi PicoserialMicroPython (UF2)pico_flash agent tool (BOOTSEL + mpremote)
Total Phase AardvarkI2C/SPI/GPIO USB adapterauto-detected at startup

For the full per-board reference — VID/PID, LED pins, memory maps, and required feature flags — see Supported boards reference. For flashing details across all boards, see Flashing firmware. The Raspberry Pi Pico is flashed by the agent’s pico_flash tool rather than a CLI subcommand; see the Hardware quickstart. The Aardvark adapter is auto-detected and exposes I2C/SPI/GPIO tools — see Aardvark I2C/SPI/GPIO & datasheets.

All tethered serial boards (Pico, Arduino, ESP32, Nucleo) speak one wire format: newline-delimited JSON. Each request is a single JSON line terminated by \n, and the device replies with a single JSON line. This is the firmware contract shared by the host and every board’s firmware.

Host → device (ZcCommand):

{"cmd":"gpio_write","params":{"pin":25,"value":1}}

Device → host (ZcResponse):

{"ok":true,"data":{"pin":25,"value":1,"state":"HIGH"}}
FieldDirectionTypeMeaning
cmdrequeststringCommand name, e.g. gpio_write, gpio_read, ping, capabilities.
paramsrequestobjectCommand parameters; schema depends on cmd. Defaults to {}.
okresponsebooleanWhether the command succeeded.
dataresponseobjectResponse payload; schema depends on the command.
errorresponsestringHuman-readable error message, present only when ok is false.

A parameterless command such as ping or capabilities carries an empty params object. On first connection the serial transport sends a ping and expects a Revka-firmware response within roughly 300 ms; this handshake is how unknown-VID devices are accepted or rejected during discovery.

The agent does not hand-write this JSON — it calls tools like gpio_write(pin=25, value=1) or gpio_read(pin=25), and Revka serializes the wire frame. When exactly one GPIO-capable board is connected the device argument is optional; with multiple boards the agent must name the alias, e.g. gpio_write(device="pico0", pin=25, value=1). For the full GPIO tool set — including the native Raspberry Pi gpio_rpi_* tools and the Aardvark bitmask GPIO — see GPIO tools.