我将 USB 蜂窝调制解调器连接到运行 voyage linux(基于 Debian Squeeze)的 ALIX 3d2 板上。调制解调器将自身注册为 TTY 设备,因此默认情况下,udev 将在 .txt 文件中创建名为“ttyUSB0”到“ttyUSB3”的 TTY 设备/dev
。但是,可能还连接了其他 USB 转串口设备,我想了解调制解调器的已知参考信息。因此,我编写了一个简单的 udev 规则来建立从调制解调器到 的链接,/dev/ttyModem{0-3}
但是,我能找到自动处理编号的唯一方法是通过%n
udev 中的变量,这存在创建/dev/ttyModem{4-7}
四端口 USB 转-串行适配器在调制解调器之前被枚举。我在旧的 udev 文档中发现了一些对%e
变量的引用,这些引用可以满足我的需要,但它似乎已在前一段时间被删除。
幸运的是,每个 tty 设备都有一个可以从设备引用的端口号,因此我应该能够手动处理编号。我可以根据端口号创建链接,但每当我尝试同时使用端口号和 USB 供应商 ID+产品 ID 时,该规则就不再应用。我怀疑我可能在某个地方违反了“一个单一父设备”规则,因为这些属性根据 不同设备中的识别udevadm info
,但据我所知,所有属性都应该来自一个设备及其父设备。
以下是我应用的规则:
这个规则是有效的,也是我开始使用的,但它生成的数字可能不是从 0 开始。
SUBSYSTEMS=="usb", KERNEL=="ttyUSB*", ATTRS{idVendor}=="1199", ATTRS{idProduct}=="0028", SYMLINK+="ttyUSBID%n"
因此,我尝试使用像这样的四个规则来指定端口号,但是,这失败了,我认为因为它违反了“一个父设备”规则。
SUBSYSTEMS=="usb", KERNEL=="ttyUSB*", ATTRS{port_number}=="0", ATTRS{idVendor}=="1199", ATTRS{idProduct}=="0028", SYMLINK+="ttyFailingPort0"
此规则上的每个条件都应来自同一节点,因此此规则(按您的预期工作)应该能够引用父节点。
SUBSYSTEMS=="usb-serial", KERNELS=="ttyUSB*", ATTRS{port_number}=="0", SYMLINK+="ttyPortNumberChild0"
然而,这个规则失败了,我不知道为什么。
SUBSYSTEMS=="usb-serial", KERNELS=="ttyUSB*", ATTRS{idVendor}=="1199" ATTRS{port_number}=="0", SYMLINK+="ttyFailingPortNumber0
udevadm info --attribute-walk
这是for的输出端口0,端口1,端口2,端口3。顶部第二个设备包含端口号,第四个设备包含 USB 标识信息。
我意识到这有点XY问题,因此,如果您知道为调制解调器指定常量名称的更好方法,请随时将其发布为您的答案。
答案1
调制解调器规则应ACTION=="add", SUBSYSTEM=="tty"
与 idVendor、idProduct 和 port_number 属性相结合:
ACTION=="add", SUBSYSTEM=="tty", ATTRS{idVendor}=="1199", ATTRS{idProduct}=="0028", ATTRS{port_number}=="0", SYMLINK+="ttyPort0"
ACTION=="add", SUBSYSTEM=="tty", ATTRS{idVendor}=="1199", ATTRS{idProduct}=="0028", ATTRS{port_number}=="1", SYMLINK+="ttyPort1"
ACTION=="add", SUBSYSTEM=="tty", ATTRS{idVendor}=="1199", ATTRS{idProduct}=="0028", ATTRS{port_number}=="2", SYMLINK+="ttyPort2"
ACTION=="add", SUBSYSTEM=="tty", ATTRS{idVendor}=="1199", ATTRS{idProduct}=="0028", ATTRS{port_number}=="3", SYMLINK+="ttyPort3"
/dev/serial/by-id
另请检查(如果您的调制解调器具有唯一的序列号,则有帮助)或/dev/serial/by-path
(如果您始终将调制解调器插入同一个 USB 端口,则有效)中的任何现有符号链接是否适合您的目的。
答案2
我最终通过拆分多个规则之间的配置来解决“只有一个父级”的限制。对于那些感兴趣的人,这是我最终得到的代码:
ACTION!="add", GOTO="modem_rules_end"
SUBSYSTEM!="tty" GOTO="modem_rules_end"
#ModemType1
ATTRS{idVendor}=="1199", ATTRS{idProduct}=="0028", GOTO="type1_rules_begin"
GOTO="type1_rules_end"
LABEL="type1_rules_begin"
ATTRS{port_number}=="0", SYMLINK:="ttyType1_0"
ATTRS{port_number}=="1", SYMLINK:="ttyType1_1"
ATTRS{port_number}=="2", SYMLINK:="ttyType1_2"
ATTRS{port_number}=="3", SYMLINK:="ttyType1_3"
LABEL="type1_rules_end"
LABEL="modem_rules_end"
答案3
我遇到了类似的问题,使 USB 蜂窝调制解调器与系统中的编号一致的 USB 调制解调器与其他争夺 /dev/ttyUSB* 编号的 USB tty 设备一起使用。就我而言,它是带有 Telit 芯片组的 EuroTech ReliaCELL 10-20-32。我使用这里的一些想法解决了这个问题,最终在我的 .rules 中摘录了以下内容:
SUBSYSTEMS=="usb", DRIVERS=="option", ATTRS{bInterfaceNumber}=="00", SYMLINK+="ttyUSB_modem_port_0"
SUBSYSTEMS=="usb", DRIVERS=="option", ATTRS{bInterfaceNumber}=="01", SYMLINK+="ttyUSB_modem_port_1"
SUBSYSTEMS=="usb", DRIVERS=="option", ATTRS{bInterfaceNumber}=="02", SYMLINK+="ttyUSB_modem_port_2"
SUBSYSTEMS=="usb", DRIVERS=="option", ATTRS{bInterfaceNumber}=="03", SYMLINK+="ttyUSB_modem_port_3"
答案4
我使用多个相同的 USB 串行适配器进行了设置,用于访问我的 UNIX 机器。
我猜测最后一行中的 KERNELS 属性来自我的“Prolific Technology Inc.”。集线器由两个集线器组成,其中一个集线器连接到另一个集线器。
KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", KERNELS=="1-1.2.5:1.0", SYMLINK+="ttyUSB_Sol1"
KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", KERNELS=="1-1.2.6:1.0", SYMLINK+="ttyUSB_Sol2"
KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", KERNELS=="1-1.2.7:1.0", SYMLINK+="ttyUSB_Sol3"
KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", KERNELS=="1-1.2.4:1.0", SYMLINK+="ttyUSB_Sol4"
KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", KERNELS=="1-1.2.3:1.0", SYMLINK+="ttyUSB_HPUX1"
KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", KERNELS=="1-1.2.2:1.0", SYMLINK+="ttyUSB_HPUX2"
KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", KERNELS=="1-1.2.1.4:1.0", SYMLINK+="ttyUSB_HPUX3"