我有一个名为 USBtin 的 USB-CAN 适配器(http://www.fischl.de/usbtin/)。它已连接到运行 Raspbian 的 Raspberry Pi 2 ( Linux raspberrypi 4.4.16-v7+ #1 SMP Fri Aug 5 14:49:49 UTC 2016 armv7l GNU/Linux
)。
我的目标是在 Python 应用程序中发送和接收 CAN 消息。为此,我认为使用 slcan 是一个好主意。我将 slcan-support 编译到内核中,并且使用它时我基本上遵循了Lawicel CANUSB 教程。
我添加了90-slcan.rules
它/etc/udev/rules.d/
,因此它应该与 USBtin 一起使用:
ACTION=="add", ENV{ID_MODEL}=="USBtin", ENV{SUBSYSTEM}=="tty", \
RUN+="/usr/bin/logger [udev] USBtin detected - running slcan_add.sh!", \
RUN+="/usr/local/bin/slcan_add.sh $kernel"
ACTION=="remove", ENV{ID_MODEL}=="USBtin", ENV{SUBSYSTEM}=="usb", \
RUN+="/usr/bin/logger [udev] USBtin removed - running slcan_remove.sh!", \
RUN+="/usr/local/bin/slcan_remove.sh"
添加脚本如下所示:
#!/bin/sh
sleep 7
#slcand -o -c -f -s4 /dev/$1 slcan0
/usr/local/bin/slcand -o -c -f -s4 /dev/$1
logger Return value of slcand was $?
sleep 2
ifconfig slcan0 up
在系统日志中,我可以看到这些是在插入/删除适配器时执行的。我还看到 slcand 生成的系统日志记录。我从系统日志中的 slcand 看到的最后一件事是:(attached TTY /dev/ttyACM0 to netdevice slcan0
见下文)。但是,之后守护进程不再运行,slcan0
界面也不存在。
如果我手动运行
sudo /usr/local/bin/slcand -o -c -f -s4 /dev/ttyACM0
但在控制台上,守护进程运行得很好。
知道为什么当我将其插入并让 udev 执行时它不起作用吗? slcand的代码可以查到在 GitHub 上(我使用的是主干的最新版本)。
系统日志:
Feb 12 17:38:28 raspberrypi kernel: [ 668.511547] usb 1-1.4: new full-speed USB device number 4 using dwc_otg
Feb 12 17:38:28 raspberrypi kernel: [ 668.616867] usb 1-1.4: New USB device found, idVendor=04d8, idProduct=000a
Feb 12 17:38:28 raspberrypi kernel: [ 668.616899] usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
Feb 12 17:38:28 raspberrypi kernel: [ 668.616916] usb 1-1.4: Product: USBtin
Feb 12 17:38:28 raspberrypi kernel: [ 668.616933] usb 1-1.4: Manufacturer: Microchip Technology, Inc.
Feb 12 17:38:28 raspberrypi mtp-probe: checking bus 1, device 4: "/sys/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4"
Feb 12 17:38:28 raspberrypi mtp-probe: bus: 1, device: 4 was not an MTP device
Feb 12 17:38:28 raspberrypi kernel: [ 668.671845] cdc_acm 1-1.4:1.0: ttyACM0: USB ACM device
Feb 12 17:38:28 raspberrypi kernel: [ 668.673109] usbcore: registered new interface driver cdc_acm
Feb 12 17:38:28 raspberrypi kernel: [ 668.673130] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
Feb 12 17:38:28 raspberrypi logger: [udev] USBtin detected - running slcan_add.sh!
Feb 12 17:38:35 raspberrypi slcand[1379]: starting on TTY device /dev/ttyACM0
Feb 12 17:38:35 raspberrypi slcand[1380]: attached TTY /dev/ttyACM0 to netdevice slcan0
Feb 12 17:38:35 raspberrypi logger: Return value of slcand was 0
Feb 12 17:42:29 raspberrypi systemd[1]: Starting Cleanup of Temporary Directories...
这是以下的输出udevadm info -a -n /dev/ttyACM0
:
Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.
looking at device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/tty/ttyACM0':
KERNEL=="ttyACM0"
SUBSYSTEM=="tty"
DRIVER==""
looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0':
KERNELS=="1-1.4:1.0"
SUBSYSTEMS=="usb"
DRIVERS=="cdc_acm"
ATTRS{bInterfaceClass}=="02"
ATTRS{bmCapabilities}=="2"
ATTRS{bInterfaceSubClass}=="02"
ATTRS{bInterfaceProtocol}=="01"
ATTRS{bNumEndpoints}=="01"
ATTRS{authorized}=="1"
ATTRS{supports_autosuspend}=="1"
ATTRS{bAlternateSetting}==" 0"
ATTRS{bInterfaceNumber}=="00"
looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4':
KERNELS=="1-1.4"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bDeviceProtocol}=="00"
ATTRS{devpath}=="1.4"
ATTRS{idVendor}=="04d8"
ATTRS{speed}=="12"
ATTRS{bNumInterfaces}==" 2"
ATTRS{bConfigurationValue}=="1"
ATTRS{bMaxPacketSize0}=="8"
ATTRS{busnum}=="1"
ATTRS{devnum}=="4"
ATTRS{configuration}==""
ATTRS{bMaxPower}=="100mA"
ATTRS{authorized}=="1"
ATTRS{bmAttributes}=="80"
ATTRS{bNumConfigurations}=="1"
ATTRS{maxchild}=="0"
ATTRS{bcdDevice}=="0100"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{quirks}=="0x0"
ATTRS{version}==" 2.00"
ATTRS{urbnum}=="77"
ATTRS{ltm_capable}=="no"
ATTRS{manufacturer}=="Microchip Technology, Inc."
ATTRS{removable}=="removable"
ATTRS{idProduct}=="000a"
ATTRS{bDeviceClass}=="02"
ATTRS{product}=="USBtin"
looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1':
KERNELS=="1-1"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bDeviceProtocol}=="02"
ATTRS{devpath}=="1"
ATTRS{idVendor}=="0424"
ATTRS{speed}=="480"
ATTRS{bNumInterfaces}==" 1"
ATTRS{bConfigurationValue}=="1"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{busnum}=="1"
ATTRS{devnum}=="2"
ATTRS{configuration}==""
ATTRS{bMaxPower}=="2mA"
ATTRS{authorized}=="1"
ATTRS{bmAttributes}=="e0"
ATTRS{bNumConfigurations}=="1"
ATTRS{maxchild}=="5"
ATTRS{bcdDevice}=="0200"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{quirks}=="0x0"
ATTRS{version}==" 2.00"
ATTRS{urbnum}=="38"
ATTRS{ltm_capable}=="no"
ATTRS{removable}=="unknown"
ATTRS{idProduct}=="9514"
ATTRS{bDeviceClass}=="09"
looking at parent device '/devices/platform/soc/3f980000.usb/usb1':
KERNELS=="usb1"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bDeviceProtocol}=="01"
ATTRS{devpath}=="0"
ATTRS{idVendor}=="1d6b"
ATTRS{speed}=="480"
ATTRS{bNumInterfaces}==" 1"
ATTRS{bConfigurationValue}=="1"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{authorized_default}=="1"
ATTRS{busnum}=="1"
ATTRS{devnum}=="1"
ATTRS{configuration}==""
ATTRS{bMaxPower}=="0mA"
ATTRS{authorized}=="1"
ATTRS{bmAttributes}=="e0"
ATTRS{bNumConfigurations}=="1"
ATTRS{maxchild}=="1"
ATTRS{interface_authorized_default}=="1"
ATTRS{bcdDevice}=="0404"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{quirks}=="0x0"
ATTRS{serial}=="3f980000.usb"
ATTRS{version}==" 2.00"
ATTRS{urbnum}=="26"
ATTRS{ltm_capable}=="no"
ATTRS{manufacturer}=="Linux 4.4.16-v7+ dwc_otg_hcd"
ATTRS{removable}=="unknown"
ATTRS{idProduct}=="0002"
ATTRS{bDeviceClass}=="09"
ATTRS{product}=="DWC OTG Controller"
looking at parent device '/devices/platform/soc/3f980000.usb':
KERNELS=="3f980000.usb"
SUBSYSTEMS=="platform"
DRIVERS=="dwc_otg"
ATTRS{hnp}=="HstNegScs = 0x0"
ATTRS{srp}=="SesReqScs = 0x1"
ATTRS{regvalue}=="invalid offset"
ATTRS{hsic_connect}=="HSIC Connect = 0x1"
ATTRS{guid}=="GUID = 0x2708a000"
ATTRS{mode}=="Mode = 0x1"
ATTRS{srpcapable}=="SRPCapable = 0x1"
ATTRS{regdump}=="Register Dump"
ATTRS{gpvndctl}=="GPVNDCTL = 0x00000000"
ATTRS{ggpio}=="GGPIO = 0x00000000"
ATTRS{hprt0}=="HPRT0 = 0x00001005"
ATTRS{wr_reg_test}=="Time to write GNPTXFSIZ reg 10000000 times: 500 msecs (50 jiffies)"
ATTRS{driver_override}=="(null)"
ATTRS{hcd_frrem}=="HCD Dump Frame Remaining"
ATTRS{mode_ch_tim_en}=="Mode Change Ready Timer Enable = 0x0"
ATTRS{gnptxfsiz}=="GNPTXFSIZ = 0x01000306"
ATTRS{remote_wakeup}=="Remote Wakeup Sig = 0 Enabled = 0 LPM Remote Wakeup = 0"
ATTRS{busconnected}=="Bus Connected = 0x1"
ATTRS{hcddump}=="HCD Dump"
ATTRS{gotgctl}=="GOTGCTL = 0x001c0001"
ATTRS{spramdump}=="SPRAM Dump"
ATTRS{grxfsiz}=="GRXFSIZ = 0x00000306"
ATTRS{gsnpsid}=="GSNPSID = 0x4f54280a"
ATTRS{gusbcfg}=="GUSBCFG = 0x20001700"
ATTRS{hptxfsiz}=="HPTXFSIZ = 0x02000406"
ATTRS{devspeed}=="Device Speed = 0x0"
ATTRS{fr_interval}=="Frame Interval = 0x1d4c"
ATTRS{rem_wakeup_pwrdn}==""
ATTRS{bussuspend}=="Bus Suspend = 0x0"
ATTRS{buspower}=="Bus Power = 0x1"
ATTRS{hnpcapable}=="HNPCapable = 0x1"
ATTRS{rd_reg_test}=="Time to read GNPTXFSIZ reg 10000000 times: 1410 msecs (141 jiffies)"
ATTRS{enumspeed}=="Device Enumeration Speed = 0x1"
ATTRS{inv_sel_hsic}=="Invert Select HSIC = 0x0"
ATTRS{regoffset}=="0xffffffff"
looking at parent device '/devices/platform/soc':
KERNELS=="soc"
SUBSYSTEMS=="platform"
DRIVERS==""
ATTRS{driver_override}=="(null)"
looking at parent device '/devices/platform':
KERNELS=="platform"
SUBSYSTEMS==""
DRIVERS==""
答案1
显然不可能通过 UDEV 启动长时间运行的命令(至少在 raspbian 上)。然而,有效的方法是触发 systemd 从 UDEV 启动服务。然后该服务可以启动长时间运行的命令。
就我而言,我是这样做的:
ENV{SYSTEMD_WANTS}="can-usb.service"
在 can-usb.service 中,我启动前面描述的脚本。