2021/05/24

如何偵測 usb device 異動

自 linux kernel 2.6 以後, udev 取代了 devfs 與 hotplug,負責處理 device 偵測與管理。他會動態在 /dev 目錄中 create/remove device node。

例如當我們插上一個 COM 轉 USB 的設備線路時,會產生 /dev/ttyUSB0 這個 device,然後程式就能針對這個 device 進行 COM Port IO 處理,當該設備線路被移除時, /dev/ttyUSB0 這個 device 會被刪除。

udev daemon 就是 systemd-udevd,用來接收 device uevents,並與 kernel 溝通。可以在 /etc/udev/rules.d/ 目錄中,產生 .rules 檔案,用來處理 usb device 異動。

首先要用 udevadm 監控 usb device 異動的 uevents

# udevadm monitor --kernel --property --subsystem-match=usb
monitor will print the received events for:
KERNEL - the kernel uevent

產生 ttyUSB0 時

KERNEL[13411.612407] add      /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1 (usb)
ACTION=add
BUSNUM=002
DEVNAME=/dev/bus/usb/002/008
DEVNUM=008
DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1
DEVTYPE=usb_device
MAJOR=189
MINOR=135
PRODUCT=67b/2303/400
SEQNUM=2450
SUBSYSTEM=usb
TYPE=0/0/0

KERNEL[13411.612646] add      /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1/2-1.1:1.0 (usb)
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1/2-1.1:1.0
DEVTYPE=usb_interface
INTERFACE=255/0/0
MODALIAS=usb:v067Bp2303d0400dc00dsc00dp00icFFisc00ip00in00
PRODUCT=67b/2303/400
SEQNUM=2451
SUBSYSTEM=usb
TYPE=0/0/0

當 ttyUSB0 被移除時

KERNEL[13367.889477] remove   /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1/2-1.1:1.0 (usb)
ACTION=remove
DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1/2-1.1:1.0
DEVTYPE=usb_interface
INTERFACE=255/0/0
MODALIAS=usb:v067Bp2303d0400dc00dsc00dp00icFFisc00ip00in00
PRODUCT=67b/2303/400
SEQNUM=2448
SUBSYSTEM=usb
TYPE=0/0/0

KERNEL[13367.889520] remove   /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1 (usb)
ACTION=remove
BUSNUM=002
DEVNAME=/dev/bus/usb/002/003
DEVNUM=003
DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1
DEVTYPE=usb_device
MAJOR=189
MINOR=130
PRODUCT=67b/2303/400
SEQNUM=2449
SUBSYSTEM=usb
TYPE=0/0/0

建立 add/remove 的 script

sudo vim /root/bin/usbdevice_added.sh

#!/bin/bash
echo "USB device added   at $(date)" >> /var/log/usbdevice.log


sudo vim /root/bin/usbdevice_removed.sh

#!/bin/bash
echo "USB device removed at $(date)" >> /var/log/usbdevice.log


sudo chmod +x /root/bin/usbdevice_added.sh
sudo chmod +x /root/bin/usbdevice_removed.sh

根據 udevadm monitor 得到的屬性 SUBSYSTEM, ACTION, DEVTYPE,設定對應的 script

vim /etc/udev/rules.d/80-usb.rules

SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device",  RUN+="/root/bin/usbdevice_added.sh"
SUBSYSTEM=="usb", ACTION=="remove", ENV{DEVTYPE}=="usb_device", RUN+="/root/bin/usbdevice_removed.sh"

reload udevadm

sudo udevadm control --reload
tail -f /var/log/usbdevice.log

References

How to Run a Script When USB Devices Is Attached or Removed Using UDEV

How to Use Udev for Device Detection and Management in Linux

How to run custom scripts upon USB device plug-in?

沒有留言:

張貼留言