Skip to content

DroneCAN Shell ​

The DroneCAN Shell is a NuttShell (NSH) console running on a DroneCAN peripheral node (a CAN node running PX4 firmware), which you access over the CAN bus via the uavcan.protocol.AccessCommandShell service. It is intended for peripheral nodes that only have a CAN connection and no accessible serial debug port.

TIP

This gives you a shell on the peripheral node, not on the flight controller. To access the flight controller, use the MAVLink Shell or the System Console — see System Console vs. Shells for how they compare. If the node does not boot, the DroneCAN Shell is not available: use the node's System Console instead, if it has an accessible debug port.

Preconditions ​

PX4 firmware must be built with CONFIG_UAVCANNODE_COMMAND_SHELL enabled. This option is part of the uavcannode driver (CONFIG_DRIVERS_UAVCANNODE), so it is only available in DroneCAN peripheral-node firmware (such as ark_can-gps), not on flight controllers. It is not enabled by default on any board.

Opening the Shell ​

dronecan_shell.py ​

Access the shell from a terminal using the dronecan_shell.py script.

Requirements ​

  • A computer running Linux or macOS. The script uses termios for terminal handling, so it does not run on Windows.

  • A USB-CAN adapter that supports SLCAN, connected to the same CAN bus as the node.

  • The dronecan and pyserial Python packages:

    sh
    pip3 install --user dronecan pyserial

Command ​

sh
./Tools/dronecan_shell.py <device> [--node-id NODE_ID] [--baudrate BAUDRATE] [--bitrate BITRATE] [--allocator]
ArgumentDefaultDescription
devicerequiredSerial port of the SLCAN adapter, e.g. /dev/ttyACM0
--node-id100DroneCAN node ID used by the script itself
--baudrate115200Serial baudrate to the adapter
--bitrate1000000CAN bus bitrate
--allocatordisabledAct as a dynamic node ID allocator

The script listens on the bus for 5 seconds, lists the nodes it finds, and asks for the ID of the one to connect to. The list includes every node on the bus, such as the flight controller and ESCs, but only PX4 peripheral nodes built with CONFIG_UAVCANNODE_COMMAND_SHELL provide a shell.

If you select a node that does not provide a shell, the script prints the node <id>: Ctrl-C interrupts, Ctrl-D goes back banner and then nothing else. No nsh> prompt appears and no error is reported, because the node silently ignores the shell requests. Press Ctrl+D to return to the node list.

In the shell, Ctrl+C resets the shell (it starts a new NSH session rather than interrupting the running command), and Ctrl+D returns to the node list. Arrow keys, command history and tab completion are not supported (arrow keys insert stray characters such as [A into the line).

Scenarios ​

Flight controller connected to the bus, already allocating dynamic node IDs:

sh
./Tools/dronecan_shell.py /dev/ttyACM0

No other allocator on the bus, so the script must allocate an ID for the target node:

sh
./Tools/dronecan_shell.py /dev/ttyACM0 --allocator

WARNING

Don't use --allocator if the flight controller or any other node is already allocating IDs on the same bus. Two allocators racing can assign conflicting IDs.

Using the DroneCAN Shell ​

For information see: PX4 Consoles/Shells > Using Consoles/Shells.

Limitations ​

  • Only one shell session per node: a request from another client node closes the current shell and starts a new one.
  • The output buffer is just the pipe's current buffer, not a persistent per-command output store.
  • FLAG_CLEAR_OUTPUT_BUFFERS, FLAG_READ_STDERR, FLAG_READ_STDOUT, FLAG_RUNNING, FLAG_HAS_PENDING_STDERR are not implemented.
  • last_exit_status is not reported (always 0).
  • There is no separate stderr stream: stderr is redirected to stdout.