Overview

The Karbon 'Command Line Interface' (CLI) is a simple, cross-platform, command line utility for interfacing with the onboard microcontroller. This document assumes some basic familiarity with using the command line on Windows, or the terminal on a linux system. The Karbon CLI supports four core commands for managing and interacting with the microcontroller.

Table 1. Commands
Command Functionality

config

Change and report all user configuration parameters, including automotive settings, power management, etc.

op

Run 'operations' on the microcontroller, including reporting firmware version, reading the input voltage, setting the output state of the DIO and LEDs, etc.

can

Send and receive can messages. Supports filtering and timing messages, sending extended and standard frames, and more.

update

Update the microcontroller’s firmware version. Binaries are available at OnLogic’s support portal.

The Karbon series microcontroller is managed through two virtual serial interfaces. During normal operation, this command line utility will automatically detect and attach to the correct interface. The tool additionally supports a fifth command raw, that allows manually specifying any available interface.

Interface Detection

Virtual serial interfaces are software interfaces supported by a USB protocol known as "CDC ACM". On Linux systems, the ports will enumerate as /dev/ttyACMx, while on Windows systems they will simply appear as COMx.

You can determine which ports belong to the microcontroller by running:

Table 2. Identify interfaces
Linux Windows
$ sudo ./karbon raw devices
> karbon.exe raw devices

On most Linux systems, this tool will need the correct permissions in order to access the microcontroller’s interfaces. To achieve this, either run the Karbon CLI as root, or add the current user the "dialout" group.

Table 3. Permissions
Method Command Example

Run the CLI as root

$ sudo ./karbon <COMMANDS>

Add user to dialout group

$ sudo adduser some_user dialout
Note
When adding a user to the dialout group, you may need to logout or reboot the system before it takes effect.

On Windows systems, administrative privileges are usually not required when accessing COM devices.

Command Reference

The Karbon command line utility ships with built-in help text. This can be used as a quick reference when running commands directly on the target machine. Help text can be printed for multiple levels of commands with the help flag:

Note
Commands in this reference will specified as karbon. For Linux systems, you may need to replace this with sudo ./karbon or ./karbon. For Windows operating systems, you should replace it with karbon.exe.
Help text
$ karbon --help
$ karbon <COMMAND> --help
$ karbon <COMMAND> <SUBCOMMAND> --help
Karbon 1.0.1
Run various commands and operations on a Karbon series microcontroller. Access permissions to serial devices are
required, so you may need to run this command with elevated privileges (e.g. `sudo karbon <SUBCOMMAND>`).

Run `karbon <SUBCOMMAND> --help` for detailed help about a command.

USAGE:
    karbon [OPTIONS] [SUBCOMMAND]

FLAGS:
    -h, --help
            Prints help information

    -V, --version
            Prints version information


OPTIONS:
        --gen-completions <gen-completions>
            Generate auto-completions for a given shell [possible values: bash, fish, zsh, powershell, elvish]


SUBCOMMANDS:
    can       Interface with and control the on-board can device
    config    Set or get a user configuration parameter
    help      Prints this message or the help of the given subcommand(s)
    op        Run a command or operation on the microcontroller
    raw       Run string commands directly against or listen to a specified serial interface
    update    Update to a new microcontroller firmware version

Config

The config subcommand handles changing and reporting all configurable system settings. Each parameter can be called directly:

Direct call
$ karbon config <PARAMETER>

Which will report the current value of the setting. Or with an argument, which will program the value of that setting:

Set call
$ karbon config <PARAMETER> <VALUE>

By default, any configuration changes will not be saved to the microcontroller’s flash memory. This means that the setting will not be persistent across hard (AC) reboots and power failures. To give a change persistency, use the save flag to write the configuration change to flash memory.

Save
$ karbon config -s <PARAMETER> <VALUE>
Important
When the save flag is not used configuration changes will not be persistent!

It’s also possible to change the current user configuration file whenever running this command. When the number flag is specified, the current configuration will be changed to the specified number, and then the command will be performed. This configuration will not be loaded after a hard-power cycle, unless you also run the set-as-default command.

Note
The configuration will not be changed back after the operation completes!
Change configuration
$ karbon config -n <1-4> <PARAMETER> <VALUE>

Configuration Parameters

Parameter Description

can-baudrate

The default baudrate of the CAN bus. The baudrate is specified in thousands, and should fall between 100 and 1000

Example
$ karbon config can-baudrate 500

can-mode

The operational mode the CAN bus. This parameter allows for selecting between interpreting CAN commands with the slcan and standard parsers. The standard parser supports this tool alongside Pykarbon, while the slcan parser supports a number of standard Linux tools, including can-utils. (See Using SLCAN)

Example
$ karbon config can-mode slcan

dio-power-switch

If the isolated digital IO will be used for remote power on. When enabled, the system can be powered on by toggling the state of any of the digital inputs. Once the system has powered on, the digital inputs may be used normally. For proper function, the DIO must remain powered while the system is off.

Example
$ karbon config dio-power-switch true

hard-off-timer

The number of seconds that ignition can remain off, or a low voltage state can occur, before the system is forced to power off. This shutdown event does not respect the operating system’s shutdown sequence.

Example
$ karbon config hard-off-timer 60

hdmi-cec

Enable or disable HDMI CEC (Consumer Electronics Control) functionality.

Example
$ karbon config hdmi-cec false

hotplug

Decides if display hotplug events will be reported to the processor. When disabled, all display inputs will set the display hotplug pin as if a display is connected at all times.

Example
$ karbon config hotplug true

ignition-sense

Enable power management features based on the state of the ignition pin. When this feature is disabled, all ignition events will be ignored, and will not effect the power state of the machine.

Example
$ karbon config ignition-sense true

low-power-mode

Enable or disable entering low power mode (ERP mode), after the system has been shutdown. On K700 systems, when both this feature and ignition-sense are enabled, the system will enter a 'very low power mode' and will only wake via ignition events.

Example
$ karbon config low-power-mode true

show

Displays the entire current user configuration.

Example
$ karbon config show

shutdown-timer

The number of seconds that ignition can remain off, or a low voltage state can occur, before the microcontroller will request that the operating system power down. To the operating system, this appears as if a user has pressed the front power button once.

Example
$ karbon config shutdown-timer 30

shutdown-voltage

The low voltage threshold of the system. If detected system voltage falls below this value for longer that the shutdown-timer, the system will power off to preserve battery health. Supports increments of .1 volts.

Example
$ karbon config shutdown-voltage 11.7

startup-timer

The number of seconds after ignition rises, before the microcontroller will power the system on.

Example
$ karbon config startup-timer 10

set-as-default

Set the currently selected configuration to be loaded at boot

Example
$ karbon config set-as-default

Op

The op subcommand handles requesting that the system perform certain 'operations'. It supports commands for setting or reading the state of the digital IO, reporting the system voltage, etc. Most commands will operate normally with the system 'as is', but both the digital IO and the CAN Bus require some external hardware.

External Hardware Setup

Both the K300 and the K700 have isolated Digital IO (DIO), which protects the system if a dangerous voltage is applied to the IO. Because of this feature, the DIO requires externally supplied voltage to operate. The supplied voltage should fall within the valid range for the given system.

Table 4. Valid voltages
System Range

K300

5-36 VDC

K700

5-48 VDC

The external voltage should be applied to VIN, and the external ground attached to GND:

KarbonDIOPinout
Figure 1. Karbon DIO Pinout

All four digital outputs are open collector and operate either as current sinks or high impedance, depending on the output state. The digital inputs are pulled up internally (npn), and will read as '1' when left floating.

The Karbon’s internal CAN device should be attached directly to a CAN Bus, but features no internal termination. Because of this, for proper operation, it may be required to implement an external termination resistor. This resistor should match the nominal impendence of the cable; typically 120Ω, which complies with ISO 11898.

The terminating resistor should bridge CAN_L and CAN_H, as depicted here:

KarbonCANPinout
Figure 2. Karbon CAN Termination

For more detailed information on external hardware setup, please refer to the system manual, or contact OnLogic Support.

Op Commands

Parameter Description

cal-voltage

Calibrate input voltage detection based on measured voltage. Voltage calibration is limited to +- 5%.

Important
Before running this function, measure the input voltage at the terminal: Applying the measured value will adjust the input voltage calculation to account for hardware tolerance.
Example
$ karbon op cal-voltage -r 19.5

can-autobaud

Attempts to automatically detect and set the baudrate of the CAN Bus. This functionality is achieved by polling for acknowledgments to messages with ID 0x7FF, and may not be suitable for use in all configurations.

Example
$ karbon op can-autobaud
Set Baudrate: 800k

can-message

Accepts id and data, formats them into a can message, and transmits it the CAN Bus. This function does not support the more sophisticated options that are exposed by the Can command, and only supports standard frames.

Example
$ karbon op can-message -i 123 -d 11223344

get-di

Reports the current logical state of a specific digital input.

Example
$ karbon op get-di 0
1

dio-state

Reports the current logical states of the digital inputs/outputs. This is represented by eight characters, each a '1' or a '0'.

The bit order is: I0 - I1 - I2 - I3 - O0 - O1 - O2 - O3, where I is input and O is output. For example, in the response 00001000 only digital output 1 is on. When the DIO has no inputs connected and all outputs disabled, the expected digital IO state is 11110000.

Example
$ karbon op dio-state
00001000

get-voltage

Reports the current input voltage, as measured by the microcontroller. If this voltage is below the value of shutdown-voltage the system will power off.

Example
$ karbon op get-voltage
Voltage: 23.80

kind

Reports the baseboard name

Example
$ karbon op kind
K700

set-do

Sets the state of a digital output as on or off. Outputs are numbered from 0 - 3. (See Karbon DIO Pinout)

Example
$ karbon op set-do 0 1

set-led

Sets the state of a numbered front LED to on or off. LEDs are numbered from 1 - 4.

Example
$ karbon op set-led 1 1

status

Reports system status information. Actual information reported will vary by system.

Example
$ karbon op status
Version: v3.1.2.1
40.18C / 18.51%
Voltage: 24.00
Thermal Trip: Clear
Power Fault: Clear

user-config

Sets the currently selected user configuration. The system supports up to four user configurations, each holding a copy of the Configuration Parameters. It is also possible to switch between configurations using the n flag alongside the config subcommand, or by cycling through configurations with the front settings switch.

Example
$ karbon op user-config -n 1

version

Reports the system firmware version and build date.

Example
$ karbon op version
<  v3.1.2.1  |  2020-07-06--14:00:46  >

Can

The can subcommand supports interfacing with and controlling the onboard CAN device. This includes sending and receiving CAN messages and setting the baudrate of the CAN Bus. This module requires the CAN device be configured standard operational mode. The mode of the CAN device is controlled by the can-mode configuration parameter.

The CAN device does not support internal termination, and should be externally terminated when connected to a CAN bus.

Using SLCAN

Karbon series computers also support processing CAN commands using an slcan compliant parser. To get up and running with slcan on a Karbon running Ubuntu, start by installing can-utils:

$ sudo apt install can-utils

Then detect and set up the Karbon, for example:

slcan_setup.sh
#! /bin/bash

# ASCII Command vs CAN Bitrate
# s0 --- s1 --- s2 --- s3 --- s4 --- s5 --- s6 --- s7 --- s8
# 10     20     50     100    125    250    500    800    1000  Kbits/s
BAUD=8

# Name of slcan device to attach
DEV=can0


# Detect correct port for device interfaces
TERM_PORT=$(ls -l /dev/serial/by-id/ | grep 1fc9_00a3 | sed 's/.*\///g' | awk '{if(NR==2) print $0}')
CANB_PORT=$(ls -l /dev/serial/by-id/ | grep 1fc9_00a3 | sed 's/.*\///g' | awk '{if(NR==1) print $0}')

# Start or stop the service
while getopts ":ks" opt; do
    case $opt in
        k)
            # Stop the SLCAN service and turn off the can device
            echo "Shutting down can interface..."
            sudo ifconfig $DEV down 2> /dev/null
            sudo pkill slcand

            sudo slcand -c /dev/"$CANB_PORT"
            sudo pkill slcand
            ;;
        s)
            # Open the can device, and start the slcan service.
            echo "Terminal interface on: $TERM_PORT"
            echo "CAN Bus  interface on: $CANB_PORT"

            # Set the mode to slcan
            echo -ne "set can-mode slcan" > /dev/$TERM_PORT

            echo "Attaching slcan device..."

            # Attach to the port with slcand
            sudo slcand -s$BAUD -o /dev/"$CANB_PORT" $DEV

            # Give interface time to come up
            sleep .25

            # Enable the inteface
            sudo ifconfig $DEV up
            sudo ifconfig $DEV txqueuelen 1000

            echo "Interface is set up."
            ;;
        \?)
            echo "Invalid option: -$OPTARG" >&2
            exit 1
            ;;
        :)
            echo "Option -$OPTARG requires an argument." >&2
            exit 1
            ;;
    esac
done

The system is now ready to send and receive can messages using can-utils:

$ cansend can0 123#11223344
$ candump can0

By default, the can subcommand will first check the operational mode before sending a command. Because this is slower than just sending or receiving can messages, and requires access to the terminal port, it can disabled with the --nocheck flag.

Don’t check can mode
$ karbon can -n <COMMAND>

Additionally all can operations support setting the baudrate before processing the command. This requires access to the terminal serial interface, and does not change the baudrate that will be loaded at system boot. If no baudrate is specified, the last transmitted baudrate will continue to be used.

Specify can baudrate
$ karbon can -b 500 <COMMAND>

The baudrate is specified in Kbits/s, and supports setting rates from 100-1000.

Can Commands

The Karbon CLI supports sending and receiving can messages with two commands: send and dump.

Send

The send command supports sending standard, extended, and remote frames. All messages require an id. Standard and extended frames also require data. Standard frames are sent by default, while extended and remote frames can be sent by using the corresponding flag.

Usage
$ karbon can send [FLAGS] [OPTIONS] <identifier> [data]
Table 5. Can send parameters
Argument Description Type

data

The data to be transmitted, represented as an up-to eight byte hex string. Passed data will be checked for validity before transmission. This argument is required, except when sending remote request frames (-r).

Example
$ karbon can send 123 1122334455667788

arg

identifier

The 'id' of the can frame. Should be specified as hex string from 1-7FF for standard frames, and 1-1FFFFFFF for extended frames.

Lower numbered frames will have priority during message arbitration, and by default, the id will be interpreted as a standard frame id.

Validity checking will be performed against the hex string and id range.

arg

extended

Send message in extended frame format. Supports larger id range.

Example
$ karbon can send -e 999 11223344

flag

length

Length of data to be transmitted. If not specified, the data length will be automatically determined.

Example
$ karbon can send -l 3 123 112233

opt

remote

Send a remote frame. When specified, data is not required.

Example
$ karbon can send -r 123

flag

Validity Checking

The send command’s id and data arguments are specified as strings, and parsed into hexadecimal. Because of this, validity checking is performed against the specified ID and data, before the command is passed on to the microcontroller. In psuedo-code the checks performed are as follows:

Identifier validity test
# ID tests
try:
    n = u32_from_base_16(identifier)
    if not extended and n > 0x7FF:
        return Error  # Invalid ID range
    else if extended and n > 0x1FFFFFFF:
        return Error  # Invalid ID range
    else:
        return Ok
except:
    # Invalid characters, or > 32 bits
    return Error
Data validity test
# Data tests
if length(data) is not even:
    return Error  # Bytes must be complete
else if length(data) > 16:
    return Error  # More than eight bytes

try:
    n = u64_from_base_16(data)
    return Ok
except:
    # Invalid characters, or > 64 bits
    return Error

Additionally, it is acceptable to specify id or data with a leading 0x, which will simply be trimmed before data validation is performed.

Dump

The dump command supports reporting all received CAN messages. Messages may be filtered by id, and the time between frames can be recorded.

By default, the messages will be formatted and printed to stdout, but the data can also be reported in csv format and/or saved to file.

For instance, to print all messages to the terminal along with their time delta, run:

$ karbon can dump -d

Or to log only messages with a matching id to messages.csv, run:

$ karbon can dump -d -c -f 123 7FF -- messages.csv
Usage
karbon can dump [FLAGS] [OPTIONS] [--] [output]
Table 6. Can dump parameters
Argument Description Type

csv

Format the output as a csv. Does not redirect output from stdout. Header will be included as id,len,data or as id,len,data,delta.

Example
$ karbon can dump -c
id,len,data
123,4,11223344

flag

delta

Log the time delta between frames. Times will be reported as floating point seconds; 1.001 is 1001 milliseconds.

Time delta is calculated at the host, and should not be considered a perfect representation of time between frames.

Example
$ karbon can dump -d
      id [l]             data            delta
     123 [4]         11223344         2.907689
     7FF [4]             ABCD         3.386151
     123 [4]         11223344         6.232194
00000999 [8] 1122334455667788         0.000519

flag

filter

A list of CAN frame identifiers to match received messages against. All other messages will be discarded.

Important
Extended IDs should be specified in their full form, including leading zeroes. E.g. 00000999 not 999.
Example
$ karbon can dump -f 123 1FFFFFFF 00000999 3AA

opt

output

The output location for printing CAN frames. Defaults to stdout when not specified.

arg

Update

The update subcommand simply handles updating the microcontroller’s firmware version. Update binaries are available from OnLogic’s support site.

To update the system’s firmware, download a binary update file and run karbon update <filename>.

Firmware update example
$ karbon update Karbon_v3.1.2.1.bin
Tip
If the system ever encounters an un-recoverable error (for instance, power-loss during an update), you can manually start the system in bootloader mode by attaching wall/AC power while depressing the pinhole settings button. If done correctly, the watchdog light will start blinking. The system should now boot normally, and the 'update' command will be available for firmware re-flashing.

Generate Shell Completions

This utility is capable of generating a bash completion script for the following shells: bash, fish, zsh, powershell, and elvish. Once a script has been generated and sourced, it will be possible to use TAB to auto-complete entered commands.

Shell completions only affect user experience, and are not required to run any microcontroller commands.

Bash completion example
$ karbon --gen-completions bash > karbon_completions.bash
$ source karbon_completions.bash

Changes

1.0.3

  • Fix port kind detection on certain Windows systems

  • Improve reading multi-line messages on Windows

  • Don’t print two empty lines when closing "can-dump"