First Steps using the candleLight

So you went and got yourself one of our fancy rocket-penguin branded CandleLight dongles or, being the die hard hacker you are, went and soldered one up in your toaster oven labeled "not food safe". What's next then? How do you use this thing? Let's answer these question by grabbing a Raspberry Pi and exploring some of the possibilities.

On our Pi we will be using the October 30th 2021 release of the "Raspberry Pi OS". Once the Pi is booted you should first of all log in and make sure that you have a working internet connection. Once that's done yo can go ahead and install the can-utils packet using apt. can-utils will come in handy for sending and receiving CAN message to/from the CAN bus:

pi@raspberrypi:~ $ sudo apt install can-utils
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following NEW packages will be installed:
  can-utils
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 118 kB of archives.
After this operation, 492 kB of additional disk space will be used.
Get:1 http://ftp.halifax.rwth-aachen.de/raspbian/raspbian bullseye/main armhf can-utils ar
Fetched 118 kB in 1s (161 kB/s)
Selecting previously unselected package can-utils.
(Reading database ... 40796 files and directories currently installed.)
Preparing to unpack .../can-utils_2020.11.0-1_armhf.deb ...
Unpacking can-utils (2020.11.0-1) ...
Setting up can-utils (2020.11.0-1) ...
Processing triggers for man-db (2.9.4-2) ...

If you did not yet connect the CandleLight you should see that the gs_usb driver, that's responsible for handling the CandleLight, has not been loaded. We would also not expect to see any CAN interfaces already present on the Pi. Let's confirm these assumpptions using a few commands on the commandline:

pi@raspberrypi:~ $ lsmod | grep gs_usb
pi@raspberrypi:~ $ ip addr show can0
Device "can0" does not exist.

We do however expect both of these things to change once we have connected the CandleLight to the Pi. Let's do so and have a look at the kernel log for confirmation:

pi@raspberrypi:~ $ journalctl -kn9
-- Journal begins at Sat 2021-10-30 12:29:41 BST, ends at Wed 2022-01-19 13:49:39 GMT. --
Jan 19 13:49:39 raspberrypi kernel: usb 1-1.1: new full-speed USB device number 4 using xh
Jan 19 13:49:39 raspberrypi kernel: usb 1-1.1: New USB device found, idVendor=1d50, idProd
Jan 19 13:49:39 raspberrypi kernel: usb 1-1.1: New USB device strings: Mfr=1, Product=2, S
Jan 19 13:49:39 raspberrypi kernel: usb 1-1.1: Product: candleLight USB to CAN adapter
Jan 19 13:49:39 raspberrypi kernel: usb 1-1.1: Manufacturer: bytewerk
Jan 19 13:49:39 raspberrypi kernel: usb 1-1.1: SerialNumber: 000000000002
Jan 19 13:49:39 raspberrypi kernel: CAN device driver interface
Jan 19 13:49:39 raspberrypi kernel: gs_usb 1-1.1:1.0: Configuring for 1 interfaces
Jan 19 13:49:39 raspberrypi kernel: usbcore: registered new interface driver gs_usb

We can see that the USB device was detected and the gs_usb driver was loaded. But do we also see a CAN interface?:

pi@raspberrypi:~ $ ip addr show can0
5: can0: <NOARP,ECHO> mtu 16 qdisc noop state DOWN group default qlen 10
    link/can

Yes we do!

candump

Now let's receive some CAN messages. To do so we are going to start the candump tool and let it decode the incoming messages. In order for it to receiv anything there has to be a sending node on the bus, in this case this is just another CandleLight plugged into my laptop:

pi@raspberrypi:~ $ candump any,0:0,#FFFFFFFF -extA
 (2022-01-19 13:51:50.144617)  can0  RX - -  002   [4]  04 00 00 00
 (2022-01-19 13:51:50.644835)  can0  RX - -  002   [5]  05 00 00 00 00
 (2022-01-19 13:51:51.145058)  can0  RX - -  002   [6]  06 00 00 00 00 00
 (2022-01-19 13:51:51.645290)  can0  RX - -  002   [7]  07 00 00 00 00 00 00
 (2022-01-19 13:51:52.145435)  can0  RX - -  002   [8]  08 00 00 00 00 00 00 00
 (2022-01-19 13:51:52.645477)  can0  RX - -  002   [1]  09
 (2022-01-19 13:51:53.145785)  can0  RX - -  002   [1]  0A
 (2022-01-19 13:51:53.645952)  can0  RX - -  002   [2]  0B 00
 (2022-01-19 13:51:54.146142)  can0  RX - -  002   [3]  0C 00 00
 (2022-01-19 13:51:54.646362)  can0  RX - -  002   [4]  0D 00 00 00
 (2022-01-19 13:51:55.146577)  can0  RX - -  002   [5]  0E 00 00 00 00
 (2022-01-19 13:51:55.646752)  can0  RX - -  002   [6]  0F 00 00 00 00 00
 (2022-01-19 13:51:56.146970)  can0  RX - -  002   [7]  10 00 00 00 00 00 00
 (2022-01-19 13:51:56.647190)  can0  RX - -  002   [8]  11 00 00 00 00 00 00 00
 (2022-01-19 13:51:57.147229)  can0  RX - -  002   [1]  12
 (2022-01-19 13:51:57.647433)  can0  RX - -  002   [1]  13
 (2022-01-19 13:51:58.147653)  can0  RX - -  002   [2]  14 00
 (2022-01-19 13:51:58.647844)  can0  RX - -  002   [3]  15 00 00
 (2022-01-19 13:51:59.147993)  can0  RX - -  002   [4]  16 00 00 00
 (2022-01-19 13:51:59.648122)  can0  RX - -  002   [5]  17 00 00 00 00
 (2022-01-19 13:52:00.148298)  can0  RX - -  002   [6]  18 00 00 00 00 00
^C

Once you have seen enough you can quit the capture using Ctrl+c.

cansend

Next, let's send some CAN messages, in order to have someone to receive these messages I've started the candump command on my laptop. To send messages instead of dumping them we can use cansend. When starting cansend without arguments it shows some examples how CAN messages are encoded on the command line:

pi@raspberrypi:~ $ cansend
cansend - send CAN-frames via CAN_RAW sockets.

Usage: cansend <device> <can_frame>.

<can_frame>:
 <can_id>#{data}          for 'classic' CAN 2.0 data frames
 <can_id>#R{len}          for 'classic' CAN 2.0 data frames
 <can_id>##<flags>{data}  for CAN FD frames

<can_id>:
 3 (SFF) or 8 (EFF) hex chars
{data}:
 0..8 (0..64 CAN FD) ASCII hex-values (optionally separated by '.')
{len}:
 an optional 0..8 value as RTR frames can contain a valid dlc field
<flags>:
 a single ASCII Hex value (0 .. F) which defines canfd_frame.flags

Examples:
  5A1#11.2233.44556677.88 / 123#DEADBEEF / 5AA# / 123##1 / 213##311223344 /
  1F334455#1122334455667788 / 123#R / 00000123#R3

Let's send the can message with data ff 01 00 00 00 00 00 22 (all values in hex) with CAN-ID 0x023 on our CandleLight:

pi@raspberrypi:~ $ cansend can0 023#ff.01.00.00.00.00.00.22

The command expects the data bytes without spaces, but you can use . for separation. The receiving side shows:

➜ (pts/40) frogger@hardanger:socketcan/linux-rpi (rpi-v5.16) candump any,0:0,#FFFFFFFF -ex
 (2022-01-19 14:52:31.979395)  can0  RX - -  023   [8]  FF 01 00 00 00 00 00 22

With the candump and cansend commands most of your CAN sending and dumping needs should be covered. But there is also a third command that comes in handy from time to time.

cangen

The cangen command is used to generate lots of CAN messages. If you start it like shown belog it will send CAN messages with an increasing counter (-Di) with increasing length (-Li), on CAN-ID 2 (-I2) with a gap of 500 ms in between each CAN frame (-g 500). If you try and send more messages than the bus or controller can handle cangen will retry after 10 ms (-g10):

pi@raspberrypi:~ $ cangen can0 -Di -Li -I2 -p10 -g 500

The receiver show this:

➜ (pts/40) frogger@hardanger:socketcan/linux-rpi (rpi-v5.16) candump any,0:0,#FFFFFFFF -ex
 (2022-01-19 14:52:45.159111)  can0  RX - -  002   [1]  00
 (2022-01-19 14:52:45.659342)  can0  RX - -  002   [1]  01
 (2022-01-19 14:52:46.159425)  can0  RX - -  002   [2]  02 00
 (2022-01-19 14:52:46.659597)  can0  RX - -  002   [3]  03 00 00
 (2022-01-19 14:52:47.159744)  can0  RX - -  002   [4]  04 00 00 00
 (2022-01-19 14:52:47.659815)  can0  RX - -  002   [5]  05 00 00 00 00
 (2022-01-19 14:52:48.159983)  can0  RX - -  002   [6]  06 00 00 00 00 00
 (2022-01-19 14:52:48.660118)  can0  RX - -  002   [7]  07 00 00 00 00 00 00
 (2022-01-19 14:52:49.160262)  can0  RX - -  002   [8]  08 00 00 00 00 00 00 00
 (2022-01-19 14:52:49.660324)  can0  RX - -  002   [1]  09
 (2022-01-19 14:52:50.160334)  can0  RX - -  002   [1]  0A
 (2022-01-19 14:52:50.660485)  can0  RX - -  002   [2]  0B 00
 (2022-01-19 14:52:51.160733)  can0  RX - -  002   [3]  0C 00 00
 (2022-01-19 14:52:51.660876)  can0  RX - -  002   [4]  0D 00 00 00
 (2022-01-19 14:52:52.161052)  can0  RX - -  002   [5]  0E 00 00 00 00
 (2022-01-19 14:52:52.661169)  can0  RX - -  002   [6]  0F 00 00 00 00 00
 (2022-01-19 14:52:53.161308)  can0  RX - -  002   [7]  10 00 00 00 00 00 00
 (2022-01-19 14:52:53.661451)  can0  RX - -  002   [8]  11 00 00 00 00 00 00 00
 (2022-01-19 14:52:54.161489)  can0  RX - -  002   [1]  12
 (2022-01-19 14:52:54.661626)  can0  RX - -  002   [1]  13
 (2022-01-19 14:52:55.161793)  can0  RX - -  002   [2]  14 00
 (2022-01-19 14:52:55.661923)  can0  RX - -  002   [3]  15 00 00
 (2022-01-19 14:52:56.162071)  can0  RX - -  002   [4]  16 00 00 00
 (2022-01-19 14:52:56.662295)  can0  RX - -  002   [5]  17 00 00 00 00
 (2022-01-19 14:52:57.162353)  can0  RX - -  002   [6]  18 00 00 00 00 00
 (2022-01-19 14:52:57.662560)  can0  RX - -  002   [7]  19 00 00 00 00 00 00

And will continue to do so, until we stop it or the sender. Next up: figure out where the CAN bus of your CAR is and which bit rate is uses. Given what you've learned you should be well prepared to dump the messages on its CAN busses. The rest is left as an exercise to the reader.


Further Readings

Update of our Remotelab equipment

If it looks like an advertising blogpost, reads like an advertising blogpost ... it probably is an advertising blogpost! Nobody likes to read advertisements and we don't like to write them at all, but like all proud parents, we would like to show you the new products that our corporate subsidiary, Linux Automation GmbH, has freshly added to their store. With these new products we, and maybe soon you, will complete (y)our Remotelab infrastructure.


The LXA IOBus line of lab automation devices

I would like to present to you the LXA IOBus, a CAN-based ecosystem consisting of a protocol, a gateway server and new class of Linux Automation GmbH devices, including the Ethernet-Mux and the 4DO-3DI-3AI input/output board.


Did you know? Initializing CAN interfaces with systemd-networkd

Chris Fiege | | didyouknow, iobus, can-bus

End of January systemd 250 was added to Debian bullseye backports. With a lots of new features and fixes now comes the possibility to set the timing of CAN bus interfaces with systemd-networkd. In this blogpost I will take a look at why this helps us maintain our embedded Linux labs.


labgrid Tutorials

This week, we started our series of YouTube labgrid tutorials. In the next few weeks we will publish more video tutorials showing you labgrid's features and giving you handy tips and tricks.


Showcase: Fail-Safe (OTA) Field Updating

Enrico Jörns | | didyouknow, rauc

Being able to robustly and securely update embedded systems and IoT devices in the field is a key requirement of every product today. The update framework RAUC is the basis for a modern and future-proof solution. In this showcase we present the basic principles of a fail-safe update system and how Pengutronix can support you with implement this for your platform.


Showcase: Embedded off-the-shelf

A firmware upgrade is due. A newly implemented feature needs to be rolled out, a security issue patched or new hardware support added. The software, while capable, is complex. Pengutronix' strategy to handle this complexity is working on a version- controlled Board Support Package (BSP) with continuous updates and tests on the latest mainline Linux kernel.


Launch of Linux Automation GmbH

Chris Fiege | | linux-automation

We proudly present our new spin-off Linux Automation GmbH for selling hardware products, like USB-SD-Mux.


USB-SD-Mux: EMC Testing

Today Jonas and I went to our EMC testing lab to continue the measurements needed to certify electromagnetic compatibility for the USB-SD-Mux.