Unter Linux erfolgt die Anbindung von CAN-Bus Hardware meistens per SocketCAN über den Kernel. Dabei wird im System dann ein CAN-Interface bereitgestellt, zum Beispiel can0.

Mit der Software Cannelloni von Maximilian Güntner ist es möglich dieses CAN-Interface über eine Ethernetverbindung an einen anderen Linux-Rechner weiterzuleiten. Hierbei wird auf dem zweiten Rechner ein virtuelles CAN-Interface, zum Beispiel vcan0, erzeugt. Die CAN-Nachrichten werden dann mittels UDP zwischen beiden Systemen übertragen.

Dies ist beispielsweise dann sinnvoll, wenn man Software auf einem System testen möchte, das keine echte CAN-Hardware angeschlossen hat. So kann man sich dann beispielsweise das CAN-Interface von einem Raspberry Pi auf seinen Development-PC holen und dort direkt mit dem virtuellen Interface arbeiten.

Wichtiger Hinweis: Cannelloni ist nicht für den Produktiveinsatz vorgesehen und sollte nur dort verwendet werden, wo ein Paketverlust toleriert werden kann. Es gibt keine Garantie, dass die CAN-Nachrichten ihr Ziel (das jeweils andere System) erreichen, oder dass sie in der richtigen Reihenfolge ankommen.

Installation von Cannelloni

Für die Installation muss Cannelloni auf dem jeweiligen System kompiliert werden. Hierzu installieren wir zunächst die benötigten Tools:

sudo apt install build-essential cmake git

Anschließend laden wir uns den aktuellen Quellcode von GitHub und kompilieren Cannelloni:

git clone https://github.com/mguentner/cannelloni.git
cd cannelloni
cmake -DCMAKE_BUILD_TYPE=Release
make

Nun können wir schon Cannelloni im aktuellen Verzeichnis mittels ./cannelloni [...] ausführen, oder wir installieren es global im System:

sudo make install

Beispiel zur Nutzung

In diesem Beispiel werden wir das physikalische CAN-Interface can0 von einem Raspberry Pi mit der IP-Adresse 192.168.1.50 auf das virtuelle CAN-Interface vcan0 eines Desktop-PCs mit der IP-Adresse 192.168.1.201 weiterleiten.

Zur Vorbereitung laden wir zunächst auf dem Desktop-PC das Kernelmodul vcan und legen das Interface vcan0 an:

sudo modprobe vcan
sudo ip link add name vcan0 type vcan
sudo ip link set dev vcan0 up

Da das virtuelle CAN-Interface vcan0 im Normalfall immer schneller ist als das echte CAN-Interface, müssen wir die Bandbreite von vcan0 auf dem Desktop-PC begrenzen. Hierzu nutzen wir die Traffic Control vom Linux Kernel.
Idealerweise sollte die Bandbreite des virtuellen vcan0 Interfaces der des echten can0 Interfaces entsprechen. In diesem Beispiel sind es 500 kBit/s.

sudo /sbin/tc qdisc add dev vcan0 root tbf rate 500kbit latency 100ms burst 1000

Anschließend starten wir Cannelloni auf dem Desktop-PC mit dem virtuellen CAN-Interface, der IP-Adresse des Raspberry Pi und der Ausgabe der CAN-Nachrichten.
Optional könnten mit -r und -l noch der entfernte und der lokale Port mit angegeben werden. Ohne Angabe wird für beides der Standardport 20000 verwendet.

user@desktop-pc:~/cannelloni$ ./cannelloni -I vcan0 -R 192.168.1.50 -d c
INFO:udpthread.cpp[146]:run:UDPThread up and running
INFO:canthread.cpp[108]:run:CANThread up and running

Nun folgt noch der Start von Cannelloni auf dem Raspberry Pi nach dem gleichen Muster, nur dieses mal dem physikalischen CAN-Interface und der IP-Adresse des Desktop-PCs.

pi@raspberrypi:~/cannelloni$ ./cannelloni -I can0 -R 192.168.1.201 -d c
INFO:ERROR:udpthread.cpp[146]:run:UDPThread up and running
canthread.cpp[88]:start:CAN_FD is not supported on >can0<
INFO:canthread.cpp[108]:run:CANThread up and running

Solange nun Cannelloni auf beiden Systemen läuft, werden die CAN-Nachrichten bidirektional über das Ethernet zwischen beiden CAN-Interfaces ausgetauscht. Das heißt Nachrichten, die am Raspberry Pi auf can0 ankommen, kommen auch auf dem Desktop-PC auf vcan0 an und Nachrichten, die am Desktop-PC an vcan0 gesendet werden, werden auch am Raspberry Pi über can0 gesendet.

Durch den Parameter -d c beim Start von Cannelloni werden zudem im jeweiligen Terminal die eingehenden und ausgehenden CAN-Nachrichten angezeigt:

LC|EFF Frame ID[83902468]        Length:8        0 0 f4 40 0 0 12 41
LC|EFF Frame ID[520093697]       Length:7        15 14 5 7 e 7 0
LC|EFF Frame ID[83902468]        Length:8        0 0 fc 40 0 0 12 41
LC|EFF Frame ID[83902468]        Length:8        0 0 f0 40 0 0 12 41
LC|EFF Frame ID[520093697]       Length:7        15 14 5 7 e 8 0
LC|EFF Frame ID[83902468]        Length:8        0 0 ec 40 0 0 12 41
LC|EFF Frame ID[83902468]        Length:8        0 0 ec 40 0 0 12 41
LC|EFF Frame ID[520093697]       Length:7        15 14 5 7 e 9 0

Das virtuelle CAN-Interface vcan0 am Desktop-PC kann nun (nahezu) identisch dem physikalischen CAN-Interface can0 das Raspberry Pi verwendet werden. Alle Daten werden zwischen beiden Interfaces quasi gespiegelt.

Weitere Informationen

Weitere Informationen zur genauen Funktionsweise von Cannelloni, möglichen Verzögerungen bei der Übertragung, Timeouts, oder der Nutzung von SCTP anstelle von UDP sind auf der GitHub-Seite von Cannelloni zu finden.