Zur Kommunikation zwischen Computer und Steuergerät mit CAN-Bus eignen sich günstige USB-CAN Adapter. Unter Linux laufen viele dieser Adapter bereits mit den aktuellen Kerneltreibern. Jedoch muss die Netzwerkschnittstelle zum Gerät oft manuell gestartet werden, was bei automatisierten Prozessen, z.B. beim automatischem Zugriff auf Steuergeräte nach Start des Rechners hinderlich sein kann. Zum Glück kann man mittels udev Regeln schnell und einfach Abhilfe schaffen. Als Beispiel dient ein einfacher CAN-USB Adapter „CANUSB I550“ mit der vendorID:productID 0403:ffa8 unter Ubuntu 16.04.
offset += 4;
Zuerst müssen die nötigen CAN tools installiert werden:
sudo apt-get install can-utils
Danach kann dann ein Netzwerkgerät für den Adapter erstellt werden. Der Adapter ist als serialdevice unter /dev/ttyUSB0 zu finden. Dafür muss der slcand daemon gestartet werden. Als Parameter werden u.a. die CAN-Bus Geschwindigkeit und das Gerät übergeben:
sudo slcand -o -s6 -t hw -S 3000000 /dev/ttyUSB0
Nun findet man z.B. mit ifconfig das Netzwerkinterface slcan0, welches nun gestartet werden kann:
sudo ip link set up slcan0
Im can-utils Paket ist u.a. auch ein Snifferprogramm, das alle Daten auf dem Bus in der Konsole ausgibt.
cansniffer slcan0
Möchte man nun den slcand daemon automatisch beim Einstecken des Adapters starten, braucht man nur eine udev Regel zu erstellen, die slcand als Dienst startet. Dafür erstellt man einfach die udev Regel mit:
sudo nano /etc/udev/rules.d/90-slcan.rules
Mit folgendem Inhalt:
# CAN connect KERNEL=="ttyUSB?", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="ffa8", ACTION=="add", RUN+="/bin/systemctl start slcan@ttyUSB%E{MINOR}.service" # CAN connect (new product ID 6001) KERNEL=="ttyUSB?", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ACTION=="add", RUN+="/bin/systemctl start slcan@ttyUSB%E{MINOR}.service" # CAN disconnect ACTION=="remove", ENV{ID_MODEL}=="CANUSB", ENV{SUBSYSTEM}=="usb", RUN+="/usr/bin/logger [udev] Lawicel CANUSB removed - running slcan_remove.sh!", RUN+="/bin/systemctl start slcan@ttyUSB%E{MINOR}.service"
Die Regel sucht das device mit der vendorID 0403 und der productID ffa8 und startet beim Einstecken einen unter RUN angegebenen Befehl. Hier könnte man nun ein einfaches Bash-Script angeben. Leider ist der slcand daemon nur ein Kindprozess des Bash-Scripts, der nach Beendigung des Scripts ebenso beendet wird. Dieses Problem lässt sich umgehen, wenn das Script als Service mittels systemd (neuere Ubuntu Versionen) gestartet wird. Im Beispiel wird der systemd Service sclan@.service, dem die ID des tty Geräts übergeben wird, gestartet. Jetzt muss der Starter für den Service angelegt werden:
sudo nano /etc/systemd/system/slcan@.service
[Unit] Description=Starts slcan device [Service] User=root Restart=always Type=forking ExecStartPre=/bin/sleep 1 ExecStart=/usr/local/bin/slcan.sh %I ExecStop=/usr/local/bin/slcan_remove.sh %I [Install] WantedBy=multi-user.target
Und das eigentliche Script, das unseren Adapter als Netzwerkinterface zur Verfügung stellt:
sudo nano /usr/local/bin/slcan.sh
#!/bin/sh if [ -z ${DEVNAME+x} ]; then if [ -z ${1+x} ]; then echo "No device $DEVNAME" exit 1 fi DEVNAME=${1} fi # Read device name and extract the tty/usb# (id) ID=$(echo ${DEVNAME} | grep -o -E '[0-9]+') # create new slcan network device slcand -o -s6 -t hw -S 3000000 $DEVNAME slcan${ID} &> /dev/null sleep 1 ip link set up slcan${ID}
Das Sript zum Beenden
sudo nano /usr/local/bin/slcan_remove.sh
#!/bin/sh ID=$(echo ${DEVNAME} | grep -o -E '[0-9]+') PROCESS=$(echo ps ax | pgrep -f slcan[$ID]) kill $PROCESS
Anschließend beide Scripte ausführbar machen:
sudo chmod +x /usr/local/bin/slcan.sh sudo chmod +x /usr/local/bin/slcan_remove.sh
Das Gerät wird beim Einstecken bzw. Systemstart erkannt, als Netzwerkinterface initialisiert und gestartet.
Beim Entfernen des Adapters wird der Service beendet.
Lawicel changed ID to default 6001 in 2015:
http://www.can232.com/?page_id=75