CLI reference

benchpod is the command-line tool for driving a pod by hand. It talks to the device over its TCP/JSON API (port 8080) or its USB console — GPIO, signal generation, measurement, capture, Wi-Fi config, and SWD flashing. For automated tests, use the pytest library instead; the CLI is for interactive bring-up and one-off operations.

Install

On macOS and Linux, install from the Homebrew tap:

brew install --cask embeddedci-com/tap/benchpod
benchpod --version

brew upgrade --cask benchpod picks up later releases. The macOS binary isn't Apple-notarized, so the cask strips the quarantine flag on install — otherwise Gatekeeper would block the unsigned binary.

Pre-built binaries for macOS, Linux and Windows (amd64 + arm64) are also attached to every GitHub release. On Windows, download the …_Windows_x86_64.zip archive and extract benchpod.exe.

# Or grab the latest binary and put it on your PATH.
# The releases/latest/download URL always points at the newest release.

# macOS (Apple Silicon) example:
curl -fsSL -o benchpod.tar.gz \
  https://github.com/embeddedci-com/benchpod-cli/releases/latest/download/benchpod_Darwin_arm64.tar.gz
tar -xzf benchpod.tar.gz benchpod
sudo mv benchpod /usr/local/bin/

If you fetch the archive with a browser (rather than curl/Homebrew), clear the quarantine flag once with xattr -d com.apple.quarantine ./benchpod, or run it from the terminal. Flashing also needs OpenOCD — see Flashing below.

Finding a pod

benchpod discover answers two questions at once: can a pod be found, and does it work? It probes every USB port for a bench-pod console and browses the LAN over mDNS, then calls the API of each pod it found on the network — so the report says whether the pod actually answers commands and whether it is registered with the cloud, rather than only that something replied to a broadcast. A pod reachable both ways is reported once, with the two entries matched up.

It also reports whether each pod is already registered to an account, on both transports — the USB half reads it off the pod's own console, so the answer comes even from a pod with no network yet. That is what tells you whether a pod you were handed still needs benchpod login and benchpod register, or arrived already claimed and needs nothing. Firmware too old to report it says nothing rather than guessing.

Because it probes USB, it finds a pod that has no network at all — which is the state a pod ships in. When nothing is found, the output lists the ports it probed and the likely causes (charge-only cable, no firmware, mDNS blocked). --save stores the address as the default connection when exactly one pod is found, preferring the network address; --no-usb / --no-network restrict the search, and --wait / --probe-timeout tune how long each half gets.

Connection

The global --connection flag is the single place that says where and how to reach the pod; the transport is inferred from its value.

--connection valueTransport
192.168.1.5[:8080]TCP/JSON API over the network — wired Ethernet or Wi-Fi alike
/dev/tty…, COM3USB console, explicit device path
usbUSB console, auto-detected by probing the ports
(omitted)the default saved by benchpod set-connection

Every flag is also settable via a BENCHPOD_* environment variable (e.g. BENCHPOD_CONNECTION=usb), with precedence flag > env > saved default.

Commands

# Find every pod on this machine and this LAN, and check each one works:
benchpod discover
benchpod discover --save     # save it as the default when exactly one is found

# Save a default connection so later commands can omit --connection:
benchpod set-connection 192.168.1.5
benchpod set-connection usb

# Reachability / state:
benchpod ping
benchpod status
# Digital IO and signals:
benchpod set-gpio PIN STATE
benchpod step-gpio
benchpod generate ...     # DAC waveform
benchpod measure ...      # ADC read
benchpod capture ...      # scope capture
benchpod stream ...       # continuous capture
benchpod test ...

# Network (always over the pod's USB console):
benchpod set-wifi
benchpod show-network     # the pod's IP (wired lease included), SSID, state, RSSI
benchpod clear-wifi

# Firmware:
benchpod flash ...        # SWD via OpenOCD's CMSIS-DAP backend
benchpod bootsel          # USB console only

# Cloud auth (optional):
benchpod login [--server-url https://www.embeddedci.com]
benchpod register ...
benchpod deregister ...

Run benchpod <command> -h for the flags of any subcommand.

Flashing (CMSIS-DAP)

flash always drives host-side OpenOCD — the pod holds no flash intelligence and OpenOCD's exit code is the verdict. The pod runs a CMSIS-DAP processor locally and OpenOCD's cmsis-dap TCP backend ships whole DAP transfers, so a flash is one round-trip per DAP command instead of thousands of per-bit round-trips — fast even over the network. It works over the network and over USB, and needs a recent OpenOCD with the cmsis_dap_tcp backend (post-0.12.0; e.g. brew install --HEAD open-ocd). The CLI checks for the backend up front and fails with clear advice if it's missing.

Cloud auth

Direct firmware commands are unauthenticated and send no tokens — they assume a trusted local network.benchpod login (device-login flow) and benchpod register authenticate with embeddedci-server for cloud features such as driving a named device or registering a new pod. See Security & trusted repos for the model.

  • benchpod register --connection <pod-ip> — claim a pod into your org, then name it on the BenchPod page.
  • benchpod login — authenticate the CLI for cloud operations.
  • benchpod deregister --connection <pod-ip> — detach a pod from your org. The device is disabled, not deleted: its captures, waveforms and wiring are kept, and registering the same pod again restores them. Registering it for another account starts that account with a fresh device.