Did you know? Initializing CAN interfaces with systemd-networkd
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.
Why CAN in our labs?
At Pengutronix we run a lot of labs where we can remote control embedded Linux devices. We use these labs for interactive development and continuous testing. If you want to have a closer look at our lab infrastructure you should take a look at my talk from ELC 2021 or into our blogpost about remote working.
tl;dr: Our labs are build around a 19" server rack, an Ethernet switch, a mains power switch, a fanless x64 mini-server, and lots of USB hubs and USB devices.
One thing we learned over the years: Do not use USB if you want your embedded Linux lab to be reliable. So we started to reduce the number of USB devices where possible. Wherever we need GPIOs (for example to control the boot mode or reset of a device under test) we nowadays use the CAN-based LXA IOBus in our labs.
So reducing the number of USB devices comes at the price of maintaining a new bus in our labs.
In our labs we use Peak Systems Mini-PCIe CAN FD cards. (But to be honest: On our developer's desk we often use the more cost-sensitive and Open Source and Open Hardware candleLight.)
The old way
Until now configuring this bus was a mishmash of systemd-networkd and some additional commands. networkd renamed the network device to a well-known name and set up the bitrate:
cfi@rlabA-srv:~$ cat /etc/systemd/network/80_can0-iobus.link # This file is managed by ptx-admin-ansible. Changes will be overwritten. [Match] OriginalName=can0 [Link] Name=can0_iobus cfi@rlabA-srv:~$ cat /etc/systemd/network/80_can0-iobus.network # This file is managed by ptx-admin-ansible. Changes will be overwritten. [Match] Name=can0_iobus [CAN] BitRate=100000 FDMode=False RestartSec=10s
But: Timing on a CAN bus is defined by a lot more parameters than just the bitrate. Other important parameters are:
- Sampling Point: The point in time inside a bit on the bus at which the value of the bit is determined.
- Time Quanta: The length of a sub-bit. Usually given in nanoseconds.
- Synchronization Jump Width: The number of time quanta the clocks of sending and receiving node are allowed to deviate. Especially important if some nodes on the bus derive their clock from a trimmed RC-oscillator rather than a crystal.
Since we want to set a specific sampling point and synchronization jump width for the LXA IOBus we had to set these parameters after systemd-networkd has already set up our interface. This was cumbersome done as ExecStartPre-statements in the LXA IOBus Server service-unit:
cfi@rlabA-srv:~$ cat /etc/systemd/system/lxa-iobus.service # This file is managed by ptx-admin-ansible. Changes will be overwritten. [Unit] Description=LXA iobus Server After=network.target [Service] Type=simple ExecStartPre=/bin/mkdir -p /var/cache/lxa-iobus ExecStartPre=/bin/ip l set can0_iobus down ExecStart=/bin/ip link set can0_iobus type can tq 500 prop-seg 9 phase-seg1 5 phase-seg2 5 sjw 4 ExecStartPre=/bin/ip l set can0_iobus up ExecStart=/usr/ptx-venvs/lxa-iobus/bin/lxa-iobus-server -l WARN --lss-address-cache-file /var/cache/lxa-iobus/lss-cache --host "*" can0_iobus Environment="PYTHONUNBUFFERED=1" Restart=always RestartSec=30 [Install] WantedBy=multi-user.target
While writing this blogpost I even realized that setting the detailed timing in the lxa-iobus.service -unit overrides the bitrate set in the .network -file. So consolidating this seems a good idea 😀.
The new way
Thanks to yuwata for PR 20442! This change now allow us to set these additional timing parameters using systemd-networkd.
Taking a look into the documentation we can change our .network file as follows:
cfi@rlabA-srv:~$ cat /etc/systemd/network/80_can0-iobus.network [Match] Name=can0_iobus [CAN] TimeQuantaNSec=500 PropagationSegment=9 PhaseBufferSegment1=5 PhaseBufferSegment2=2 SyncJumpWidth=4 RestartSec=10
Note that you can only define the bitrate or the detailed timing parameters since defining both would be overdetermined. In this case we define the detailed timing parameters. We can control the actual bitrate using:
cfi@rlabA-srv:~$ ip -detail link show dev can0_iobus 5: can0_iobus: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10 link/can promiscuity 0 minmtu 0 maxmtu 0 can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 10000 bitrate 100000 sample-point 0.750 tq 500 prop-seg 9 phase-seg1 5 phase-seg2 5 sjw 4 peak_canfd: tseg1 1..256 tseg2 1..128 sjw 1..128 brp 1..1024 brp-inc 1 peak_canfd: dtseg1 1..32 dtseg2 1..16 dsjw 1..16 dbrp 1..1024 dbrp-inc 1 clock 80000000 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
Further Readings
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.
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.
Linux Automation's Optick: A Glass-to-Glass Latency Measurement Tool
New Linux Automation GmbH products are often inspired by needs we observe in our day-to-day development work at Pengutronix. Today's new product, the Optick, was inspired by our graphics team, that works with different kinds of video pipelines and optimizes them based on customer demands. One such demand is minimizing the latency of camera to display video pipelines.
Linux Automation Test Automation Controller: A one Device labgrid Exporter
Our subsidiary Linux Automation GmbH introduces the LXA TAC (Linux Automation Test Automation Controller): an all-in-one labgrid exporter. The LXA TAC offers the usual interfaces to control one or more embedded devices (DUTs, devices under test) interactively or automatically with labgrid.
candleLight FD - Open Hardware USB-to-CAN-FD interface
This week Linux Automation has released a CAN-FD version of the low-cost USB-to-CAN interface candleLight: the candleLight FD. And as the candleLight the candleLight FD is Open Hardware. Check the KiCad project on Github.
Yes we CAN... add new features
Have you ever experienced an otherwise fine product that is missing just the one feature you need for your application?
DSA in Barebox
The v2022.05.0 Release of barebox introduced initial support for the Distributed Switch Architecture (DSA) Framework. DSA is originally a subsystem from the Linux Kernel, which exposes the individual ports of a network switch IC as virtual network interfaces.
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.