embeddedCI documentation

Troubleshooting & FAQ

The failures people hit most often with a BenchPod, and how to clear them.

Flashing fails with “Can't change session's transport”

Info : only one transport option; autoselect 'jtag'
Error: Can't change session's transport after the initial selection was made

Your OpenOCD is too old. Flashing drives OpenOCD's SWD adapter, and the stock packages (apt install openocd, brew install open-ocd) are 0.12.0, whose adapter is JTAG-only. Install an OpenOCD master snapshot — the easiest is xPack OpenOCD (npm install -g @xpack-dev-tools/openocd). Verify it can do SWD:

openocd -c "adapter driver remote_bitbang" -c "transport list" -c "exit"
# must list:  jtag  swd     (if it only lists 'jtag', it's too old)

The CLI's flash uses OpenOCD'scmsis_dap_tcp backend instead, which also needs a post-0.12.0 build; the CLI checks for it up front and tells you if it's missing.

My tests skip instead of running

That's by design. The benchpod fixture skips when no connection is configured, so a suite stays green on runners without hardware. Pass --benchpod-connection=... (an IP, a serial port, or embeddedci:<device>) or set BENCHPOD_CONNECTION to actually exercise the pod.

Flash can't reach the target (connect-under-reset)

If the read fails on connect, NRST is the usual culprit — a floating or mis-wired reset line blocks connect-under-reset. If your firmware doesn't remap the SWD pins, NRST isn't required: retry the flash with nreset=None. The SDK's flash(..., check=False) returns a result you can inspect (result.target_unreachable) to fall back automatically.

Flashing is flaky or intermittent

  • Lower the adapter speed — long or noisy SWD wiring doesn't clock reliably at the default.
  • Keep SWCLK/SWDIO leads short, and make sure grounds are solid between pod and DUT.
  • Confirm the target is actually powered (use the eFuse target_power, not just bench power).

The serial link drops mid-capture

The pod handles one connection at a time — you can't send a command while the UART proxy owns the link. That's why the API schedules a power-on pod-side and then opens the capture, so the boot output lands in an already-listening window. Use power_on(efuse, delay=...) + open_uart(...), or the one-shot power_cycle_and_capture(...) — see Catching Boot Regressions.

Cloud: “could not mint a token”

The embeddedci:<device> connection authenticates with a GitHub OIDC token. The error names the cause — one of:

  • Not running inside a GitHub Action — the cloud destination only works in CI.
  • Missing id-token: write — add it to the job's permissions.
  • Token request failed — a transient GitHub/network issue; retry.

Also confirm the repo is trusted and allowed to drive that device — see Security & trusted repos.

FAQ

Which boards are supported?

Anything OpenOCD can flash over SWD. The target= argument is a normal OpenOCD config (target/stm32f4x.cfg, target/stm32h7x.cfg, target/nrf52.cfg, …), so changing chips is a one-line change.

Wifi, serial, or cloud — which connection do I use?

A pod on your LAN: its IP. A pod on your desk over USB: a serial path or serial. A pod somewhere else, from CI: embeddedci:<device-name>. The same test runs against all three. See the connection strings.

Does my whole suite need hardware?

No — mark hardware tests with @pytest.mark.hardware; without a connection they skip, so fast software tests still run everywhere.