CANbus Driver
The Core Services of the Edge Compute Platform need to have been installed.
- ase-canbus-driver
These services can be deployed by adding the "App - ECP CANbus Driver" application from the Marketplace to your own space (see Marketplace).
![](../../images/edge_compute/edge-ops-marketplace-app-ecp-canbus-driver.png)
CANbus Protocol
CAN is short for 'controller area network'. Controller area network is an electronic communication bus defined by the ISO 11898 standards. Those standards define how communication happens, how wiring is configured and how messages are constructed, among other things. Collectively, this system is referred to as a CAN bus.
The CAN bus is a broadcast type of bus. This means that all nodes can 'hear' all transmissions. There is no way to send a message to just a specific node; all nodes will invariably pick up all traffic. The CAN hardware, however, provides local filtering so that each node may react only on the interesting messages.
CANbus messages are typically short binary messages (around 8 bytes) with "ID" and payload. Payload has proprietary encoding specific to particular devices. To decode it into human-readable format so-called DBC files are required.
More information is available on protocol is available here:
CANbus on Linux
Here is how install and test CANbus driver using Linux virtual device. In a nutshell the following commands can be used to enable virtual CANbus Linux interface:
# bring CANbus interface vcan0 up (one time) sudo modprobe vcan sudo ip link add dev vcan0 type vcan sudo ifconfig vcan0 up # read canbus messages from vcan0 candump vcan0 # send canbus messages to vcan0 cangen -v -I 7E8 -D 03411126FFFFFFFF -L 8 vcan0
The last string sends CANbus command with ID 7E8 and payload of 03411126FFFFFFFF (hexidecimal).
In case if real CANbus interface are present, when shall appear under names "can0" , "can1" etc.
More information is available here: https://elinux.org/Bringing_CAN_interface_up.
Here is the page explaining how to bring virtual and real CANbus interface on ubuntu boot. It uses systemd-networkd service, which is typical for ubuntu server: https://www.pragmaticlinux.com/2021/10/how-to-create-a-virtual-can-interface-on-linux/.
Decoding of CANbus Messages
CANbus messages could be decoded using public and proprietary DBC (databses) files. DBC file is a text file which can be edited with the text editor, however it has strict formatting rules (spaces, tabs etc) which should be followed.
Altair C++ driver dbcppp library to decode raw CANbus messages. The library and set of DBC files are available from available https://github.com/xR3b0rn/dbcppp.
To summarize, DBC file is a set of rules, indexed by CAN bus ID and payload. Each ID may correspond to one message, and each message can (and almost certainly) have multiple data payloads, which are called signals. E Each message and signal have their names defined in DBC file. To create proper Things description for Altair IoT Studio, users must know Message and **Signa**l name he or she interested in.
For instance DBC fragment used in this test looks like:
BO_ 2564485392 OBD2: 8 Vector__XXX
SG_ S1_PID_00_PIDsSupported_01_20 m0 : 31|32@0+ (1,0) [0|-1] "" Vector__XXX
SG_ S1_PID_01_MonitorStatus m1 : 31|32@0+ (1,0) [0|-1] "" Vector__XXX
SG_ S1_PID_02_FreezeDTC m2 : 31|16@0+ (1,0) [0|65535] "" Vector__XXX
Here is BO_ record indicates message record, and SG_ indicates signal record. Assuming user is interested in MonitorStatus, he or she needs to know also name of the message, which is in this case OBD2. Therefore complete telemetry property would be:
"CAN,OBD2,MonitorStatus" : {
}
C++ Driver
C++ driver deployment and handling is the same as for other (bacnet, toggled) edge drivers. The following are current limitations of the driver:
- This is listen only driver; it does not allow modification of any CANbus values on CANbus devices.
- CANbus protocol has no ability to discover devices, so there is no such options opposite to bacnet driver.
- CANbus interfaces shall be up before driver starts; they are automatically discovered by the driver at start up time. If new interfaces are added driver must be restarted.
- Common DBC files are included in the driver image; driver can use environment variable to scan sequence of locations for DBC files.
List of Environment Variables Accepted by the Driver
- AMQP_HOST - RabbitQ host IP or name
- AMQP_PROTOCOL - protocol, can be amqp or amqps (for secure)
- AMQP_PORT - port to use with RabbitMq, if no-standard
- AMQP_RETRY_INTERVAL retry interval for AMQP connections, ms
- API_USER - user name to use with RabbitMq API calls
- API_PASSWORD - password for API calls to RabbitMq server
- DEVICE_DRIVER_USER - device driver user name for RabbitMq
- DEVICE_DRIVER_PASSWORD - device driver password for RabbitMq
- TELEMETRY_USER telemetry user name for RabbitMq server
- TELEMETRY_PASSWORD telemetry user password for RabbitMq
- USE_APICALL (YES or NO) controls API call on driver start. If variable exists and set to NO driver won't attempt to instantiate things on startup, but it is possible to add Thing descriptions with addThing calls.
- DBC_STORAGE_PATH - location of DBC files. By default its /data directory. If no DBC files found, driver exits. Driver scans directories recursively to discover DBC files.
- LD_LIBRARY_PATH system variable to be defined to locate shared libraries libdbcppp.so and libxmlmm.so
Internals:
Driver uses /proc/net/can/rcvlist_all
file to discover CANbus
interfaces. This takes place when driver starts.
Thing Description (TD) for CANbus Driver
The simplest TD for CANbus driver can look like that:
{ "@type": [ "canbusdrivermain" ], "actions": {}, "description": "", "events": {}, "id": "<leave blank when creating a new thing>", "properties": { "CAN,OBD2,S1_PID_01_MonitorStatus": {} }, "title": "canbus-driver-test" }
@type
array. This array MUST have elementcanbusdriver
- this is the name of the driver's executable. Only in this case TD is recognized as CANbus."properties"
shall have keys in the format"CAN,MESSAGE_NAME,SIGNAL_NAME"
where CAN is pre-defined prefix used for all CANbus data, MESSAGE_NAME is message name from DBC file, and SIGNAL_NAME is signal name from DBC file as well.
Note that TD is not interface specific so one TD can be used to stream data obtained via different interfaces.