2

I want to start slcand (the userspace daemon for the serial line CAN interface driver) when my Lawicel CanUSB dongle is plugged in. I followed Pascal Walter's step-by-step guide and all seems to work (slcan0 is there and i can bind(2)), except I never actually receive anything (only outgoing messages are visible in candump and Wireshark).

The udev rule looks as follows:

# Lawicel CANUSB module
ACTION=="add", ENV{ID_MODEL}=="CANUSB", ENV{SUBSYSTEM}=="tty", RUN+="/usr/bin/logger [udev] Lawicel CANUSB detected - running slcan_add.sh!", RUN+="/usr/local/bin/slcan_add.sh $kernel"
ACTION=="remove", ENV{ID_MODEL}=="CANUSB", ENV{SUBSYSTEM}=="usb", RUN+="/usr/bin/logger [udev] Lawicel CANUSB removed - running slcan_remove.sh!", RUN+="/usr/local/bin/slcan_remove.sh"

with /usr/local/bin/slcan_add.sh

#!/bin/sh
# Bind the USBCAN device
slcand -o -c -f -s8 /dev/$1 slcan0
sleep 2
ifconfig slcan0 up 

and /usr/local/bin/slcan_remove.sh

#!/bin/sh
# Remove the USBCAN device
pkill slcand

However when I manually execute sudo /usr/local/bin/slcan_remove.sh && sudo /usr/local/bin/slcan_add.sh ttyUSB0, everything works as expected and I can see all CAN messages with candump slcan0).

The interface looks just the same as with udev. ip link show slcan0 gives:

91: slcan0: <NOARP,UP,LOWER_UP> mtu 16 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 10

The NetworkManager has a problem with slcan0, but that appears also when creating slcan0 manually as described above. The output of tail -f /var/log/syslog when plugging in is:

May 26 18:29:18 laurenz-T440p logger: [udev] Lawicel CANUSB detected - running slcan_add.sh
May 26 18:29:18 laurenz-T440p slcand[14924]: starting on TTY device /dev/ttyUSB0
May 26 18:29:18 laurenz-T440p slcand[14925]: attached TTY /dev/ttyUSB0 to netdevice slcan0
May 26 18:29:18 laurenz-T440p slcand[14925]: netdevice slcan0 renamed to slcan0
May 26 18:29:18 laurenz-T440p NetworkManager[866]:    SCPlugin-Ifupdown: devices added (path: /sys/devices/virtual/net/slcan0, iface: slcan0)
May 26 18:29:18 laurenz-T440p NetworkManager[866]:    SCPlugin-Ifupdown: device added (path: /sys/devices/virtual/net/slcan0, iface: slcan0): no ifupdown configuration found.
May 26 18:29:18 laurenz-T440p NetworkManager[866]: <warn> /sys/devices/virtual/net/slcan0: couldn't determine device driver; ignoring...

ps -fauxw | grep can (manual start as above):

root      1221  0.0  0.0   4336   100 ?        Ss   11:38   0:00          \_ slcand -o -c -f -s8 /dev/ttyUSB0 slcan0

ps -fauxw | grep can (re-plugging triggered udev start):

root      1362  0.0  0.0   4336    96 ?        Ss   11:45   0:00 slcand -o -c -f -s8 /dev/ttyUSB0 slcan0

What could the problem with udev be? How can I fix it?

Update: Ok, so I added an Ixxat USB-to-CAN V2 and installed its SocketCan driver. It has the same problem: Tx fine, Rx not working.
Interestingly, I can just plug the two together (120R in the middle). Then I run candump -d -e -c -x -t absolute any,0:0,#FFFFFFFF in one Terminal. In another, I send CAN frames with cansend can0 000# (Send one frame with CanID 0, length 0 via can0 (the Ixxat adapter)). The result depends on if I started the slcand manually or via udev.

Manual (as described above):

$ candump -d -e -c -x -t absolute any,0:0,#FFFFFFFF
(1464614442.246548)  can0  TX - -  000   [0] 
(1464614442.249320)  slcan0  RX - -  000   [0]

Via Udev:

$ candump -d -e -c -x -t absolute any,0:0,#FFFFFFFF
 (1464614643.800545)  can0  RX - -  20000020   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
    no-acknowledgement-on-tx
 (1464614643.807361)  can0  RX - -  20000020   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
    no-acknowledgement-on-tx
 (1464614643.814058)  can0  RX - -  20000020   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
    no-acknowledgement-on-tx
 (1464614643.820840)  can0  RX - -  20000020   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
    no-acknowledgement-on-tx
[and so on...]

Here is my lsmod | grep can:

vcan                   16384  0 
slcan                  16384  1 
can_dev                24576  2 ixx_pci,ixx_usb
can_raw                20480  0 
can                    45056  1 can_raw

I'm on a Ubuntu 14.04 machine with a 4.4 kernel. uname -rv:

4.4.0-21-generic #37~14.04.1-Ubuntu SMP Wed Apr 20 16:33:38 UTC 2016
Laurenz
  • 205

2 Answers2

2

So the solution to making the Canusb work in udev was found by Kurt Van Dijck:

Sometimes one can have race conditions with udev rules since not all attributes are present on the launch of the uevent

This updated /usr/local/bin/slcan_add.sh makes the CanUsb work correctly with udev when plugged in:

#!/bin/sh
# Bind the USBCAN device
sleep 1
/usr/local/bin/slcand -o -c -f -s8 /dev/$1 slcan0
sleep 2
ifconfig slcan0 up

I still have to find out how to make the Ixxat Can-to-Usb V2 work with SocketCan.

Laurenz
  • 205
0

It seems like udev can't handle long running process.
And slcand starts a long running process. Using one of the answer of the thread aboves solve the issue.

My solution was to create a multiple instances service which is started and stopped when an adapter is added and removed.

Service

[Unit]
Description="Instance of slcand for can #%i"

[Service] Type=simple User=root ExecStart=/usr/local/bin/slcan_add %i

slcan_add

#!/bin/sh
/usr/bin/slcand -o -c -f -s8 /dev/tty$1 $1
sleep 2
/sbin/ip link set up $1
/sbin/ip link set $1 txqueuelen 80

while :; do sleep 86400; done

udev rule

SUBSYSTEM=="tty", ..., ACTION=="add", SYMLINK+="name1", RUN+="/usr/sbin/service can@name1 start"
SUBSYSTEM=="tty", ..., ACTION=="remove", RUN+="/usr/sbin/service can@name1 stop"

The .. contains the idVendor, idProduct and serial of the can adapters.

Notes :

Having multiple instances of slcan running for a device can cause problem.
Use ps aux | grep slcan to check if an instance of slcan is already running.
The following command kills all process started with a command containing slcan :

sudo kill $(ps aux | grep slcand | awk -F ' ' '{print $2}' | head -1)
lblenner
  • 131