设置 SocketCAN 套接字的 Udev 规则仅在手动运行时才能正常工作

设置 SocketCAN 套接字的 Udev 规则仅在手动运行时才能正常工作

我想启动slcand(串行线 CAN 接口驱动程序的用户空间守护进程)Lawicel CanUSB加密狗已插入。我跟着帕斯卡·沃尔特 (Pascal Walter) 的分步指南一切似乎都有效(slcan0在吗,我可以绑定(2)candump),除了我实际上从未收到过任何东西(只有传出消息在Wireshark中可见)。

udev 规则如下所示:

# 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"

/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 

/usr/local/bin/slcan_remove.sh

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

然而,当我手动执行时sudo /usr/local/bin/slcan_remove.sh && sudo /usr/local/bin/slcan_add.sh ttyUSB0,一切都会按预期工作,并且我可以使用candump slcan0) 看到所有 CAN 消息。

该界面看起来与 udev 相同。ip link show slcan0给出:

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

NetworkManager 的 slcan0 存在问题,但在如上所述手动创建 slcan0 时也会出现该问题。tail -f /var/log/syslog插入时的输出是:

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(手动启动同上):

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(重新插入触发udev启动):

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

udev 的问题可能是什么?我该如何修复它?

更新:好的,所以我添加了 Ixxat USB-to-CAN V2 并安装了其 SocketCan 驱动程序。它有同样的问题:Tx 正常,Rx 不工作。
有趣的是,我可以将两者插在一起(120R 在中间)。然后我candump -d -e -c -x -t absolute any,0:0,#FFFFFFFF在一个终端中运行。在另一个例子中,我发送 CAN 帧cansend can0 000#(通过 can0(Ixxat 适配器)发送一个带有 CanID 0、长度 0 的帧)。结果取决于我是手动启动 slcand 还是通过 udev 启动。

手册(如上所述):

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

通过乌德夫:

$ 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...]

这是我的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

我使用的是带有 4.4 内核的 Ubuntu 14.04 机器。uname -rv

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

答案1

所以让 Canusb 在 udev 中工作的解决方案是库尔特·范迪克发现:

有时,由于 uevent 启动时并非所有属性都存在,因此 udev 规则可能会出现竞争条件

此更新/usr/local/bin/slcan_add.sh使 CanUsb 在插入时可以与 udev 正常工作:

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

我仍然需要找出如何使 Ixxat Can-to-Usb V2 与 SocketCan 一起工作。

答案2

这好像是udev 无法处理长时间运行的进程
slcand 启动一个长时间运行的进程。使用上述线程的答案之一可以解决该问题。

我的解决方案是创建多实例服务当添加或删除适配器时启动和停止。

服务

[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规则

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

.. 包含 idVendor、idProduct 和 CAN 适配器的序列号。

注意事项:

为一个设备运行多个 slcan 实例可能会导致问题。
用于ps aux | grep slcan检查 slcan 实例是否已在运行。
以下命令将终止使用包含以下内容的命令启动的所有进程slcan

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

相关内容