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.
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 Module | Supported |
|---|---|
| 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.
GettersgetID(): 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)
trueif the IDE flag is set, elsefalse.
getRTR(): Gets the RTR flag state of the frame.- Parameter: None.
- Returns: (boolean)
trueif the RTR flag is set, elsefalse.
getData(): Gets the data field of the frame. Use thesize()function to get the data length.- Parameter: None.
- Returns: (bytes) The data as a byte array.
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)
trueto set,falseto clear. - Returns:
nil.
- Parameter: (boolean)
setRTR(): Sets the RTR flag state of the frame.- Parameter: (boolean)
trueto set,falseto clear. - Returns:
nil.
- Parameter: (boolean)
setData(): Sets the data field of the frame.- Parameter: (byte array) The data to set.
- Returns:
nilon bad parameter,falseon invalid byte array size,trueon success.
CAN Functions
Available CAN functions:
- cbd_start_can
- cbd_start_can_with_timing
- cbd_stop_can
- cbd_tx_frame
- cbd_rx_frame
- cbd_rx_clear
- cbd_rx_filter_start_buffer_mode
- cbd_rx_filter_start_slot_mode
- cbd_rx_filter_stop
- cbd_rx_filter_get_frame
- cbd_rx_filter_get_frame_count
- cbd_rx_filter_clear
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.
cbd_start_can(baud_rate, sample_point, enable_terminator, enable_one_shot, enable_listen_only)
| Name | Type | Description |
|---|---|---|
baud_rate | integer | The desired CAN baud rate. |
sample_point | real | The desired CAN sample point. |
enable_terminator | boolean | true to enable the device terminator, false to disable. |
enable_one_shot | boolean | true to enable one-shot mode, false to disable. |
enable_listen_only | boolean | true to enable listen-only mode, false to disable. |
| Value | Description |
|---|---|
nil | One or more parameters are invalid. |
false | Bit timing calculation failed, or the CAN is already running. |
true | CAN 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+tseg2must be >= 3 and <= 384tseg2<=tseg1sjw<=tseg2
The CAN Bus Debugger uses a base clock of 80 MHz. To help calculate parameters, use the CAN Bit Timing Calculator.
cbd_start_can_with_timing(prescaler, tseg1, tseg2, sjw, enable_terminator, enable_one_shot, enable_listen_only)
| Name | Type | Description |
|---|---|---|
prescaler | integer | The bit timing prescaler value. Valid range: 1–512. |
tseg1 | integer | Bit timing segment 1. Valid range: 1–256. |
tseg2 | integer | Bit timing segment 2. Valid range: 2–128. |
sjw | integer | Sync jump width. Valid range: 1–128. |
enable_terminator | boolean | true to enable the device terminator, false to disable. |
enable_one_shot | boolean | true to enable one-shot mode, false to disable. |
enable_listen_only | boolean | true to enable listen-only mode, false to disable. |
| Value | Description |
|---|---|
nil | One or more parameters are invalid. |
false | Bit timing calculation failed, or the CAN is already running. |
true | CAN started successfully. |
cbd_stop_can()
Description
Stops the CAN bus on the device.
cbd_stop_can()
None.
Returns| Value | Description |
|---|---|
nil | Always. |
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.
cbd_tx_frame(frame)
| Name | Type | Description |
|---|---|---|
frame | CANFrame | The frame to transmit. |
| Value | Description |
|---|---|
false | The transmit queue is full, or the device is in an invalid state. |
true | The 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.
cbd_rx_frame()
None.
Returns| Value | Description |
|---|---|
nil | No frames are available in the FIFO. |
CANFrame | The 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.
cbd_rx_clear()
None.
Returns| Value | Description |
|---|---|
nil | Always. |
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.
cbd_rx_filter_start_buffer_mode(frame_id)
| Name | Type | Description |
|---|---|---|
frame_id | integer | The ID of the frame to capture. |
| Value | Description |
|---|---|
nil | One or more parameters are invalid. |
false | Failed to create the filter. |
true | Filter 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.
cbd_rx_filter_start_slot_mode(frame_ids[])
| Name | Type | Description |
|---|---|---|
frame_ids[] | list[int] | The list of frame IDs to capture. Maximum 32 entries. |
| Value | Description |
|---|---|
nil | One or more parameters are invalid. |
false | Failed to create the filter. |
true | Filter 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.
cbd_rx_filter_stop()
None.
Returns| Value | Description |
|---|---|
nil | Always. |
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.
cbd_rx_filter_get_frame(index)
| Name | Type | Description |
|---|---|---|
index | integer | The index of the frame to retrieve from the filter. |
| Value | Description |
|---|---|
nil | No frame is available at the given index. |
CANFrame | The 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.
cbd_rx_filter_get_frame_count()
None.
Returns| Value | Description |
|---|---|
integer | The number of captured frames in the filter. |
cbd_rx_filter_clear()
Description
Clears all frames from the currently configured CAN receive filter.
cbd_rx_filter_clear()
None.
Returns| Value | Description |
|---|---|
nil | Always. |
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.
sleep(time)
| Name | Type | Description |
|---|---|---|
time | integer | The number of milliseconds to sleep. |
| Value | Description |
|---|---|
nil | Always. |
print_to_screen(...)
Description
Prints a message to the on-device console.
The message is printed on a new line.
print_to_screen(message)
| Name | Type | Description |
|---|---|---|
message | string | The message to print (511 chars max). |
| Value | Description |
|---|---|
nil | Always. |
print_to_screen_raw(...)
Description
Prints a message to the on-device console.
The message is printed without a leading new line.
print_to_screen_raw(message)
| Name | Type | Description |
|---|---|---|
message | string | The message to print (511 chars max). |
| Value | Description |
|---|---|
nil | Always. |
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.
user_prompt(message, left_btn_text, right_btn_text)
| Name | Type | Description |
|---|---|---|
message | string | The message to display in the dialog (255 chars max). |
left_btn_text | string | The label for the left button (9 chars max). |
right_btn_text | string | The label for the right button (9 chars max). |
| Value | Description |
|---|---|
0 | The left button was selected. |
1 | The right button was selected. |
nil | Invalid 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.
user_message(message, btn_text)
| Name | Type | Description |
|---|---|---|
message | string | The message to display in the dialog (255 chars max). |
| Value | Description |
|---|---|
true | The dialog was shown successfully. |
nil | Invalid 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.