这是我之前问题的延续。 使用 FTDI2XX 驱动程序在非特权用户下访问 USB 设备
这里我有2个usbserial硬件模块,并且规定一次只能使用一个。
1. 0403:6014
2. 0403:6001
我还想确保设备可以读/写访问“plugdev”组
对于设备0403:6014,我不想使用内置的 usbserial(ftdi_sio) 驱动程序。我想使用 FTD2XXX 库访问此设备。对于设备 0403:6001,我想使用 inbulit usbserial(ftdi_sio) 驱动程序。我正在尝试找到一种通用的方法来实现这一目标。
到目前为止我尝试过的路线。自从, 0403:6001设备使用内置 Linux 驱动程序,我正在尝试删除/黑名单(0403:6014) 装载时的驱动程序
试用1
ACTION=="add", SUBSYSTEMS=="usb", KERNEL=="ttyUSB*", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", RUN+="/usr/local/bin/rmmod.sh 4", GROUP="plugdev"
这将删除加载的 FTDI 驱动程序,但不会将设备组从 ROOT 更改为 PLUGDEV
因此,解决该问题时又添加了一条规则行
试用2
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0664", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", GROUP="plugdev" ACTION=="add", SUBSYSTEMS=="usb", KERNEL=="ttyUSB*", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", RUN+="/usr/local/bin/rmmod.sh 4"
此试验将我的设备组设置为“plugdev”,但这不会删除内核 usbserial 模块。
试用3
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0664", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", GROUP="plugdev"
将 ftdi_sio 添加到
/etc/modprobe.d/blacklist.conf
,但这将我的列入黑名单 0403:6001完全地。这种方法适用于0403:6014但这完全掩盖了我的0403:6001设备
请求一些指导来解决此问题
答案1
我遇到了几乎同样的问题,并在sourcejedi的启发下完成了脚本。我不必传递设备路径,因为 udev 已经通过环境提供了相当多的信息(如果您想知道脚本收到了什么,请使用 export > /tmp/vars )。特别是,我使用$DEVNAME,它是/dev 下的设备名称(例如ttyUSB0)。
/etc/udev/rules.d/ftdi.rules
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", KERNEL=="ttyUSB*" RUN+="/etc/udev/scripts/unbind_ftdi.sh"
/etc/udev/scripts/unbind_ftdi.sh
#!/bin/sh
# traverse sysfs to find the USB ID
# of the USB device which is parent/ancestor of ttyUSB*
# something like "1-1.6:1.0"
TTYDEV=$(basename $DEVNAME)
BOUND_DEVICES=/sys/bus/usb/drivers/ftdi_sio/*/
for DEVICE in ${BOUND_DEVICES}; do
if [ -e $DEVICE/$TTYDEV ]; then
USBID=$(basename $DEVICE)
break
fi
done
echo "$USBID" > /sys/bus/usb/drivers/ftdi_sio/unbind
答案2
好的。 sysfs 文档似乎说您无法从驱动程序中删除内置 ID(除非您修补源代码)。所以你需要手动解绑驱动程序每次自动绑定。 (我相信也可以禁用所有 USB 设备的自动绑定,但这听起来是一个糟糕的主意)。
您需要匹配KERNEL="ttyUSB*"
USB ID 才能执行操作后司机已被绑定。您的脚本必须找到父 USB 设备。我注意到有一个奇怪的 /sys/bus/usb-serial
地方/sys/bus/usb
,我只是希望这不会妨碍这里。
我不确定如何填写代码,因为我不知道你的代码DEVPATH
是什么样的(而且我懒得为此编写循环)。我期待类似的事情USBID=$(basename $(dirname $TTY_DEVPATH))
# udev rule
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", KERNEL=="ttyUSB*" RUN+="/usr/local/bin/unbind_ftdi.sh %p"
#!/bin/bash
# unbind_ftdi.sh
TTY_DEVPATH="$1"
# traverse sysfs to find the USB ID
# of the USB device which is parent/ancestor of ttyUSB*
# something like "1-1.6:1.0"
....
echo "$USBID" > /sys/bus/usb/drivers/ftdi_sio/unbind