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 튜토리얼.
USBtin과 함께 작동하도록 90-slcan.rules
이것을 추가했습니다 ./etc/udev/rules.d/
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에서 앞서 설명한 스크립트를 시작합니다.