Skip to main content

Scripting with CAN Bus Debugger

The CAN Bus Debugger supports custom user-written scripts. Scripts are created in Berry Script Language and loaded onto the device's SD card. The device exposes an API for performing CAN bus operations, accessing the SD card file system, and more.

WARNING

Performing actions with this tool may completely halt a CAN bus. Do not perform any actions on a CAN bus until the system is deemed safe to do so.

Creating Scripts

Scripts are written in Berry Script Language. If you're not familiar with Berry, a good starting point is: Berry Introduction (in 20 minutes or less). The device runs Berry at commit 23c6576 from the main branch. The table below shows support for the built-in Berry modules.

Berry ModuleSupported
Strings
JSON
Math
Time
File System
OS
Global
Sys
Debug
Garbage Collector
Solidify
Introspect
Strict

CAN Debugger API

In addition to Berry's default functionality, the CAN Bus Debugger exposes an API for performing CAN bus operations.

The types used in the documentation below are described further in Chapter 2 of the Berry documentation.

Classes

Available classes:

  • CANFrame

CANFrame


Description

Contains all the information required to create and read CAN frames.

Getters
  • getID(): Gets the CAN ID of the frame.
    • Parameter: None.
    • Returns: (integer) The frame ID.
  • getIDE(): Gets the IDE flag state of the frame.
    • Parameter: None.
    • Returns: (boolean) true if the IDE flag is set, else false.
  • getRTR(): Gets the RTR flag state of the frame.
    • Parameter: None.
    • Returns: (boolean) true if the RTR flag is set, else false.
  • getData(): Gets the data field of the frame. Use the size() function to get the data length.
    • Parameter: None.
    • Returns: (bytes) The data as a byte array.
Setters
  • setID(): Sets the frame ID. Ensure you also set the appropriate IDE flag value.
    • Parameter: (integer) The ID of the frame.
    • Returns: nil.
  • setIDE(): Sets the IDE flag state of the frame.
    • Parameter: (boolean) true to set, false to clear.
    • Returns: nil.
  • setRTR(): Sets the RTR flag state of the frame.
    • Parameter: (boolean) true to set, false to clear.
    • Returns: nil.
  • setData(): Sets the data field of the frame.
    • Parameter: (byte array) The data to set.
    • Returns: nil on bad parameter, false on invalid byte array size, true on success.

CAN Functions

Available CAN functions:

cbd_start_can(...)


Description

Starts the device's CAN with the desired baud rate and sample point. If the CAN was previously running, it must be stopped before calling this function.

This function does not guarantee the exact baud rate and sample point will be used, but will use timing as close as possible given the CAN base clock of 80 MHz and device constraints. For exact timing, use cbd_start_can_with_timing and consider the CAN Bit Timing Calculator.

Syntax
cbd_start_can(baud_rate, sample_point, enable_terminator, enable_one_shot, enable_listen_only)
Parameters
NameTypeDescription
baud_rateintegerThe desired CAN baud rate.
sample_pointrealThe desired CAN sample point.
enable_terminatorbooleantrue to enable the device terminator, false to disable.
enable_one_shotbooleantrue to enable one-shot mode, false to disable.
enable_listen_onlybooleantrue to enable listen-only mode, false to disable.
Returns
ValueDescription
nilOne or more parameters are invalid.
falseBit timing calculation failed, or the CAN is already running.
trueCAN started successfully.

cbd_start_can_with_timing(...)


Description

Starts the device's CAN with the provided bit timing. If the CAN was previously running, it must be stopped before calling this function.

In addition to the parameter constraints below, the following restrictions apply:

  • tseg1 + tseg2 must be >= 3 and <= 384
  • tseg2 <= tseg1
  • sjw <= tseg2

The CAN Bus Debugger uses a base clock of 80 MHz. To help calculate parameters, use the CAN Bit Timing Calculator.

Syntax
cbd_start_can_with_timing(prescaler, tseg1, tseg2, sjw, enable_terminator, enable_one_shot, enable_listen_only)
Parameters
NameTypeDescription
prescalerintegerThe bit timing prescaler value. Valid range: 1–512.
tseg1integerBit timing segment 1. Valid range: 1–256.
tseg2integerBit timing segment 2. Valid range: 2–128.
sjwintegerSync jump width. Valid range: 1–128.
enable_terminatorbooleantrue to enable the device terminator, false to disable.
enable_one_shotbooleantrue to enable one-shot mode, false to disable.
enable_listen_onlybooleantrue to enable listen-only mode, false to disable.
Returns
ValueDescription
nilOne or more parameters are invalid.
falseBit timing calculation failed, or the CAN is already running.
trueCAN started successfully.

cbd_stop_can()


Description

Stops the CAN bus on the device.

Syntax
cbd_stop_can()
Parameters

None.

Returns
ValueDescription
nilAlways.

cbd_tx_frame(...)


Description

Queues a frame for transmission on the CAN bus. The device can hold up to 256 frames in the transmit FIFO.

Ensure CAN is started first with cbd_start_can or cbd_start_can_with_timing. Frames are not queued if CAN is started in listen-only mode.

Syntax
cbd_tx_frame(frame)
Parameters
NameTypeDescription
frameCANFrameThe frame to transmit.
Returns
ValueDescription
falseThe transmit queue is full, or the device is in an invalid state.
trueThe frame was queued successfully.

cbd_rx_frame()


Description

Pops the next frame from the device's receive FIFO. The device can hold up to 256 frames in the FIFO. If the FIFO is full, incoming frames are dropped until space becomes available. On higher-speed buses, consider using the cbd_rx_filter family of functions.

Ensure CAN is started first with cbd_start_can or cbd_start_can_with_timing.

Syntax
cbd_rx_frame()
Parameters

None.

Returns
ValueDescription
nilNo frames are available in the FIFO.
CANFrameThe next frame from the receive FIFO.

cbd_rx_clear()


Description

Empties the device's receive FIFO. If the FIFO is full, incoming frames are dropped until space becomes available. Use this function to clear the backlog.

Syntax
cbd_rx_clear()
Parameters

None.

Returns
ValueDescription
nilAlways.

cbd_rx_filter_start_buffer_mode(...)


Description

Starts the CAN receive filter in buffer mode. The buffer holds a maximum of 32 frames and operates independently of the standard receive FIFO. Once the buffer is full, additional matching frames are dropped.

Retrieve frames from the buffer with cbd_rx_filter_get_frame, check the frame count with cbd_rx_filter_get_frame_count, and clear the buffer with cbd_rx_filter_clear.

Only one filter mode can be active at a time. Calling this function or cbd_rx_filter_start_slot_mode while a filter is active will restart the filter with the new settings.

This function can be called before starting the CAN.

Syntax
cbd_rx_filter_start_buffer_mode(frame_id)
Parameters
NameTypeDescription
frame_idintegerThe ID of the frame to capture.
Returns
ValueDescription
nilOne or more parameters are invalid.
falseFailed to create the filter.
trueFilter created successfully.

cbd_rx_filter_start_slot_mode(...)


Description

Starts the CAN receive filter in slot mode. The filter accepts a list of up to 32 frame IDs and stores the most recently received frame for each ID. When a new matching frame arrives, it replaces the previous one. This filter operates independently of the standard receive FIFO.

Retrieve frames with cbd_rx_filter_get_frame, where the index maps to the position of the corresponding ID in the list passed to this function. For example, if the ID at index 2 was 0x21FA, call cbd_rx_filter_get_frame(2) to retrieve the latest frame with that ID. Check how many slots have been filled with cbd_rx_filter_get_frame_count, and clear all slots with cbd_rx_filter_clear.

Only one filter mode can be active at a time. Calling this function or cbd_rx_filter_start_buffer_mode while a filter is active will restart the filter with the new settings.

This function can be called before starting the CAN.

Syntax
cbd_rx_filter_start_slot_mode(frame_ids[])
Parameters
NameTypeDescription
frame_ids[]list[int]The list of frame IDs to capture. Maximum 32 entries.
Returns
ValueDescription
nilOne or more parameters are invalid.
falseFailed to create the filter.
trueFilter created successfully.

cbd_rx_filter_stop()


Description

Stops the active CAN receive filter. The slots and buffer are not cleared, so cbd_rx_filter_get_frame can still be used to retrieve frames captured before the filter was stopped.

Syntax
cbd_rx_filter_stop()
Parameters

None.

Returns
ValueDescription
nilAlways.

cbd_rx_filter_get_frame(...)


Description

Gets a frame from the active CAN receive filter. Behavior differs by mode.

In buffer mode, the index is the position of the frame in the buffer. Index 0 is the first frame captured and index 31 is the last. Use cbd_rx_filter_get_frame_count to check the current fill level.

In slot mode, the index maps to the position of the corresponding ID in the list passed to cbd_rx_filter_start_slot_mode. For example, if the ID at index 2 was 0x21FA, calling this function with index 2 returns the most recent frame with that ID.

Syntax
cbd_rx_filter_get_frame(index)
Parameters
NameTypeDescription
indexintegerThe index of the frame to retrieve from the filter.
Returns
ValueDescription
nilNo frame is available at the given index.
CANFrameThe frame at the given index.

cbd_rx_filter_get_frame_count()


Description

Returns the frame count for the currently configured CAN receive filter.

In buffer mode, this is the number of frames captured in the buffer. In slot mode, this is the number of slots that have received at least one matching frame.

Syntax
cbd_rx_filter_get_frame_count()
Parameters

None.

Returns
ValueDescription
integerThe number of captured frames in the filter.

cbd_rx_filter_clear()


Description

Clears all frames from the currently configured CAN receive filter.

Syntax
cbd_rx_filter_clear()
Parameters

None.

Returns
ValueDescription
nilAlways.

Utility Functions

sleep(...)


Description

Pauses the script for the given number of milliseconds.

The minimum resolution is 2ms. The function guarantees the script sleeps for at least the requested duration, rounded up to the nearest 2ms. For example, a sleep of 501ms will sleep for at least 502ms.

Syntax
sleep(time)
Parameters
NameTypeDescription
timeintegerThe number of milliseconds to sleep.
Returns
ValueDescription
nilAlways.

Description

Prints a message to the on-device console.

The message is printed on a new line.

Syntax
print_to_screen(message)
Parameters
NameTypeDescription
messagestringThe message to print (511 chars max).
Returns
ValueDescription
nilAlways.

Description

Prints a message to the on-device console.

The message is printed without a leading new line.

Syntax
print_to_screen_raw(message)
Parameters
NameTypeDescription
messagestringThe message to print (511 chars max).
Returns
ValueDescription
nilAlways.

user_prompt(...)


Description

Displays a dialog on the device with the given message and two buttons. The script pauses until the user selects an option.

Syntax
user_prompt(message, left_btn_text, right_btn_text)
Parameters
NameTypeDescription
messagestringThe message to display in the dialog (255 chars max).
left_btn_textstringThe label for the left button (9 chars max).
right_btn_textstringThe label for the right button (9 chars max).
Returns
ValueDescription
0The left button was selected.
1The right button was selected.
nilInvalid arguments or internal error.

user_message(...)


Description

Displays a dialog on the device with the given message and an OK button. The script pauses until the user selects OK.

Syntax
user_message(message, btn_text)
Parameters
NameTypeDescription
messagestringThe message to display in the dialog (255 chars max).
Returns
ValueDescription
trueThe dialog was shown successfully.
nilInvalid arguments or internal error.

Loading Scripts onto the Device

Place scripts in the /scripts folder on the SD card. To access the SD card, either remove it from the device and connect it directly to a PC, or connect the device to a PC via USB while CAN is not in use (preferably from the main menu).

Running Scripts

From the main menu, navigate to the Apps menu and select the Scripts app. The device displays a list of all *.berry scripts found in the /scripts folder on the SD card. Use the up/down buttons to navigate and press ✔ to select a script.


After selecting a script, the Script Runner screen is displayed. Use the Start button to run the script and the Terminate button to stop it. Any errors will be printed to the console.