我想启动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)