Skip to main content
The rig TOML is the single source of truth for hardware configuration. It maps logical names to real hardware, specifies backends, and controls timeouts. Test code never contains hardware details — they all live here.

Full example

[rig] — root section

string
required
Rig identifier. Used in the cloud dashboard, agent hello message, and as the TOML filename convention. Letters, numbers, hyphens (e.g. bench_01, orin-bench-prod).
string
required
Hardware platform name. Informational only — used in dashboard display. Examples: orin_nx, s32g, rcar_s4, virtual, custom.
string
required
TOML schema version. Always "1.0" for current releases.
string
required
Top-level backend hint. "virtual" enables virtual backends for all interfaces. "hardware" requires each interface to specify its own backend.

[rig.can.<name>] — CAN interfaces

Each [rig.can.<name>] section defines one CAN interface. The <name> key (e.g. powertrain, chassis) is used in rig.can routing — it is never referenced from test code.
string
required
OS interface name (e.g. can0, can1, PCAN_USBBUS1).
integer
required
Nominal bitrate in bits/second. Common values: 125000, 250000, 500000, 1000000.
boolean
default:"false"
Enable CAN-FD mode. Set to true for CAN-FD buses. Requires an FD-capable adapter and backend.
string
required
Backend driver. Options: virtual, socketcan, peak. See Backends.

Multiple CAN interfaces

You can define as many CAN interfaces as your rig has:

[rig.ethernet.<name>] — Ethernet interfaces

Used for DoIP and SOME/IP communication.
string
required
OS interface name (e.g. eth0, eth1).
string
required
Local IP address to bind to. For DoIP targets on a dedicated link: 169.254.0.1 (link-local).
string
required
SOME/IP backend. Options: python-someip, vsomeip. See Backends.
string
required
DoIP backend. Options: python-doip, virtual. See Backends.

[rig.power.<name>] — Power rails

string
required
Power backend. Options: virtual_power, gpio_relay, bench_psu. See Backends.
string
default:"\"off\""
Initial power state when the rig connects. "on" or "off".
integer
GPIO pin number for gpio_relay backend.
string
Serial port for bench_psu backend (e.g. /dev/ttyUSB0).
string
Instrument model for bench_psu backend (e.g. keysight_e3631a).

[rig.gpio] — GPIO pins

GPIO pins are declared as inline tables under [rig.gpio]:
Each pin entry accepts:
integer
required
GPIO pin number (BCM numbering on Raspberry Pi; board-specific elsewhere).
string
required
"in" or "out".
boolean
default:"false"
Initial state for output pins. Ignored for input pins.
string
default:"\"virtual_gpio\""
GPIO backend. Options: virtual_gpio, linux_gpio. See Backends.

[rig.ecus.<name>] — ECU definitions

Each ECU has a logical address and a transport. The framework uses this to route UDS commands and manage power lifecycle.
string
required
Human-readable ECU name (e.g. Engine_ECU, Orin_NX). Shown in dashboard and reports.
integer
required
UDS logical address (hex notation allowed: 0x0001).
string
required
Transport for UDS. "doip" or "can_isotp".
string
Key of the [rig.ethernet.<name>] interface to use for DoIP. Required when transport = "doip".
string
Key of the [rig.can.<name>] interface to use for ISO-TP. Required when transport = "can_isotp".
string
Key of a [rig.power.<name>] rail. If set, rig.ecu.power_on() and rig.ecu.power_off() control this rail.
float
default:"5.0"
Seconds to wait for the ECU to become responsive after power-on. Platform-specific values belong here — never in test code (Rule R6). Example: virtual ECU 0.1, Nvidia Orin 8.0.

[rig.udp.<name>] — UDP interfaces

Raw UDP interfaces for AV/robotics payloads. Currently virtual-only (virtual_udp stub); a real UDP transport ships in a later phase.
string
required
OS interface name (e.g. eth0).
string
required
Local IP address to bind.
integer
default:"0"
Local port to bind. 0 = ephemeral.
string
default:"\"virtual_udp\""
UDP backend. Options: virtual_udp, or a custom module path. See Backends.

[rig.uds] — UDS diagnostic channel

A standalone UDS diagnostic channel. Currently virtual-only (virtual_uds stub). UDS over DoIP is already handled by [rig.ethernet] + [rig.ecus] — this section is not needed for that.
string
default:"\"virtual_uds\""
UDS backend. Options: virtual_uds, or a custom module path. See Backends.
float
default:"2.0"
Default request timeout in seconds. Must be greater than 0.

[rig.custom.<name>] — Custom protocol interfaces

Simulate a proprietary protocol by pairing a codec (the protocol grammar) with a transport. The codec must pass the round-trip verification harness before the rig loads it. Accessed in tests via rig.bus.
string
required
Transport: a registry name (virtual_datagram, virtual_stream, virtual_spi, virtual_i2c) or a custom "module.path:ClassName".
string
required
Path to the protocol spec — a declarative wire-format YAML, or a .dbc for the built-in DBC codec.
string
default:"\"declarative\""
Codec that interprets definitions: declarative, dbc, or a custom "module.path:ClassName".
string
default:"\"datagram\""
Transport shape: datagram or stream.
object
default:"{}"
Free-form table passed to the transport’s connect().
Custom protocols (the declarative wire-format YAML, AI spec import, and the verification harness) are covered in depth in Custom Protocols.

[rig.definitions] — DBC files

string
Path to the CAN DBC file. Relative to the directory containing the TOML file.
string
Path to the Ethernet (SOME/IP) DBC/descriptor file.
The key names can_dbc and eth_dbc are also used by crucihil analyze to infer the interface type of each signal corpus. Use these exact key names.

[rig.cloud] — Cloud connection (optional)

string
HTTP(S) base URL of the CruciHiL control plane.
string
One-time token used for agent self-registration on first boot. The agent exchanges this for a permanent API key and stores it in ~/.crucihil/credentials.toml. Once registered, this field is no longer needed.

Virtual rig (no hardware)

The virtual rig uses in-process simulated backends for all interfaces. Use it for CI and local development.

Configuration validation

CruciHiL validates the TOML with Pydantic at rig initialization — before any test runs. Schema errors produce a ConfigurationError that marks the run as BLOCKED (not FAIL). This means a config typo never appears as a firmware regression. You can validate a TOML without running any tests:
No error means the config is valid.

See also