DUTCTL

Run a command on a device that is connected to a dutagent. Use it to power the DUT on and off, flash firmware, or work with the serial console.

The step sends one command to the agent and waits for it to finish. The agent receives command and args unchanged, so the step is equivalent to this CLI call:

dutctl -s <agent> <device> <command> <args...>
AttributeTypeRequiredDefaultDescription
cmdconstYesdutctlCommand Name
namestringYesName to uniquely identify the teststep. This name will show up in reports, logs and the WebUI
optionsOptionsObjectNoAdditional command options. The default timeout is 5m.
parametersDUTCTLOptionsYesOptions passed into the dutctl cmd

Quick start

A step that flashes the firmware under test:

- cmd: dutctl
  name: Flash firmware
  parameters:
    agent: "[[attributes.Agent]]"
    device: "[[attributes.Device]]"
    command: flash
    args: [write, "[[input.Binary]]"]
  options:
    timeout: 10m

Agent and Device are attributes of the DUT (see DUT Configuration). The command name flash and its arguments come from the agent’s configuration (see Commands). For a complete pre-stage and post-stage, see Connecting Hardware with dutctl.

DUTCTL Options

AttributeTypeRequiredDefaultDescription
agentstringYesAddress of the dutagent as host:port, for example lab-pi.local:2024. http:// is added if no scheme is given. There is no default port, so always include it. Usually "[[attributes.Agent]]".
devicestringYesName of the device on that agent. Usually "[[attributes.Device]]".
commandstringYesCommand to run on the device. Any command the agent defines for the device (see Commands).
args[]stringNoArguments for the command. Each list item is one argument; items are not split at spaces. Omit args for commands without arguments.

Quote values such as "on" and "off" as in the examples. FirmwareCI reads them as text either way, but some YAML tools and editors treat them as booleans.

Commands

The dutagent’s configuration, not FirmwareCI, defines which commands a device offers and which arguments they take. The names power, flash, and serial in the examples are common, but they only work if the agent defines them. The dutctl documentation describes the agent configuration and its modules, and the dutctl CLI lists the commands of a device.

Serial Console

The arguments of a serial command go to the dutctl serial module. Its README describes the script syntax. This step waits up to four minutes for the login prompt:

- cmd: dutctl
  name: Wait for the login prompt
  parameters:
    agent: "[[attributes.Agent]]"
    device: "[[attributes.Device]]"
    command: serial
    args: ["-t", "4m", "--", "expect", "login:"]
  options:
    timeout: 5m

In a FirmwareCI step, keep in mind:

  • Give the script a time limit shorter than the step’s options.timeout (default 5m). If options.timeout runs out first, the step fails.
  • The step does not forward any input to the console. Everything the console should receive has to be part of the script.

Files

Some commands move files between the job and the agent. File paths in args are paths in the job, not on the agent.

  • A file the agent asks for, for example the image for flash write, is sent from the job. [[input.Binary]] can be used directly.
  • A file the agent sends back, for example from flash read, is saved in the job. Use an absolute path in a directory that exists, such as /tmp/flash-dump.bin, so that later steps of the same job can use it.

Reservation and Locking

When the DUT uses reservation-system: dutctl, FirmwareCI locks the device on the agent before the job starts and unlocks it after the post-stage. The lock does not block the job’s own dutctl steps. FirmwareCI holds the lock as <job-id>@firmwareci, so manual dutctl commands against the device are refused until the job is done.

The lock only covers the Agent and Device of the reserved DUT. A step that points at another agent or device is not protected and fails if someone else holds a lock on that device. See Reservation and Manual Locks.

When the Step Fails

The step passes when the agent finishes the command without an error. It is not retried. Any error the agent reports (an unknown device or command, a lock held by someone else, or a failed command) ends the step, and the step log shows the agent’s message. The step itself reports these errors:

Error containsCause
agent must not be empty, device must not be empty, command must not be emptyThe parameter is missing, or the attribute it is templated from is empty.
unavailableThe job cannot reach the agent. Check the address and port in Agent, and that the agent is running.
context was canceled during dutctl RPCoptions.timeout was reached.

Note: args are written to the step log as they are, including values from [[secrets.*]]. Anyone who can see the job can read them, so do not pass passwords in args, for example as input in a serial script.

DUTCTL Examples

Power the board off, wait, and power it on again:

- cmd: dutctl
  name: Power off
  parameters:
    agent: "[[attributes.Agent]]"
    device: "[[attributes.Device]]"
    command: power
    args: ["off"]

- cmd: sleep
  name: Let the board discharge
  parameters:
    duration: 10s

- cmd: dutctl
  name: Power on
  parameters:
    agent: "[[attributes.Agent]]"
    device: "[[attributes.Device]]"
    command: power
    args: ["on"]

Read the flash back into the job:

- cmd: dutctl
  name: Read back the flash
  parameters:
    agent: "[[attributes.Agent]]"
    device: "[[attributes.Device]]"
    command: flash
    args: [read, /tmp/flash-dump.bin]
  options:
    timeout: 10m