我有多个完全相同的USB设备。每个设备枚举/ dev目录下的多个ttyACM端口。每个端口都有其独特的用途,一个用于处理某些命令,另一个用于诊断,等等。我想要的是通过创建符号链接来为特定设备别名tty,以区分该端口属于哪个设备。
例如:
DEVICE_UNIQUENUM_PURPOSE
/dev/MODULE_0_DIAG
/dev/MODULE_0_CMD
/dev/MODULE_1_DIAG
/dev/MODULE_1_CMD
为此,我开始与udev一起为我的设备编写规则。我了解到udev无法以我想要的复杂方式枚举同一设备的符号链接。因此,我决定编写bash脚本来完成所有工作。规则如下:
ACTION=="add", KERNEL=="ttyACM[0-9]*", SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{idVendor}=="1e2d", ATTRS{idProduct}=="0063", PROGRAM="/bin/bash /home/user/script.sh %k", SYMLINK+="%c"
ACTION=="remove", SUBSYSTEM=="usb", DRIVER=="usb", ATTRS{idVendor}=="1e2d", ATTRS{idProduct}=="0063", PROGRAM="/bin/bash /home/user/script.sh"
基本上,脚本先检查“添加”或“删除”后发生了什么动作,然后根据该动作执行下一步。棘手的部分是“添加”的规则将一次触发脚本多次,因为同时处理多个tty设备。因此,为了同步我的脚本,我基于在某个地方创建目录的方式实现了简单的互斥锁。如果存在目录,则其他脚本将等待,直到它们可以创建一个为止。继续,添加操作:
删除操作:
现在是问题所在。由于某种原因,“删除”操作无法正确触发我的脚本。对于动作“添加”,所有操作都完美无缺。设备插入后,记录将正确地写入每个tty的数据库文件中。当我插入设备脚本时,大部分时间甚至都不会运行。有时会。以前,我对“删除”和“添加”的操作规则几乎相同:
ACTION=="remove", KERNEL=="ttyACM[0-9]*", SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{idVendor}=="1e2d", ATTRS{idProduct}=="0063", PROGRAM="/bin/bash /home/user/script.sh %k"
该脚本有时为一个tty运行脚本,有时为更多的脚本运行。完全不确定。我不知道为什么会这样。
当我使用“ udevadm测试”实用程序来模拟设备的“删除”操作时,它每次都能完美运行。但是对于真正的外挂却不是。我还使用“ udevadm监视器”检查了发生了什么事件,并且设备存在“删除”操作,因此一切看起来正确。
我尝试的另一件事是将“ PROGRAM”命令更改为“ RUN”命令,但没有帮助。
此后,我决定进行尽可能简单的测试。我已经写了这条规则:
ACTION=="remove", SUBSYSTEM=="usb", DRIVER=="usb", ATTRS{idVendor}=="1244", ATTRS{idProduct}=="206d", RUN+="/bin/touch /home/user/udev/%k"
此文件假设创建一个以设备的“ KERNEL”参数命名的文件。这也没有发生!但是对于动作“添加”来说,它是可行的!
这使我发疯。我想念什么吗?我知道udev指定只能通过“ PROGRAM / RUN”运行短任务,但是如果这不是短任务,那又是什么呢?一切也都适用于动作“添加”。我完全没有主意。也许这是udev的缺陷?