2011-04-15 60 views
0

我有三个不同的串行设备连接到三个usb串行转换器(FTDI USB-RS232)。如果我连接它们,我会按预期得到通用设备名称/ dev/ttyUSBx。当我尝试编写一些udev规则时,除了某些设备序列标识属性外,udevadm向我显示了三个设备的相同输出。根据设备响应创建与udev的设备符号链接,而不是udev设备信息

这些序列号会在每个设备上发生变化,所以如果我使用不同的USB串口转换器,我的规则将不再适用。所以,我需要一种方式与连接到串行转换器的特定设备进行通信,并通过其响应来识别它。

"Writing udev rules" HOWTO说,对使用程序功能调用外部程序名称设备如下:

程序用于运行的生产设备名称(他们不应该做的比其他任何东西)计划。当正在执行这些程序,设备节点尚未建立,所以以任何方式作用于该设备是不可能的,

规则例如: SUBSYSTEM=="usb", PROGRAM="/bin/device_namer %k", SYMLINK+="%c"

,所以我不能写/ dev/ttyUSBx从那里识别设备。然后,我具有RUN功能,但它似乎无法创建新的SYMLINK,因为udev无法获得RUN的输出。

规则例如: SUBSYSTEM=="usb", RUN="/bin/program"

我可以指示udev从运行脚本来创建符号链接?或者我可以从那里手工创建该符号链接?

感谢

回答

1

盲目聊天串行端口自动连接到电脑的那一刻就相当做了可怕的事情。你确定你要这么做吗?首先它需要一些时间,这会延迟设备节点的外观,如果udev在创建它之前必须等待结果。如果设备恰好被关闭或者其串行端口被断开,那么您将无法正确命名它(并且您需要有一个超时来检测这个)。最后,如果除了您期望的其中一台设备连接了另一台设备,您可能会发送垃圾,导致意想不到的后果。

您可能会考虑依靠适配器的序列号来区分它们,并将每个适配器以一致的方式与外部设备相关联。如果您的适配器,甚至实际序列号而不是像00000000那样的占位符字符串,那么您已经很幸运了!

不过,这是你如何做到的。

如您怀疑的那样,您不能使用RUN,因为这太迟了,设备节点已经被创建。你必须使用PROGRAM。在你的程序中,你将不得不使用mknod自己创建设备节点,因为udev还没有完成。您应该在临时位置创建一个临时节点,并在程序退出之前将其销毁。

### Create the temporary device node in /tmp 
device="/tmp/udev_device_guesser.$$" 
# Note: mknod does not appear to be vulnerable to a symlink attack 
mknod "$device" c "$MAJOR" "$MINOR" 

### Use this device node to query what's attached to the serial port 
insert your code here 

### Get rid of the temporary node 
rm -f "$device" 
exit 0 
+0

不错的解决方案。感谢您的详细解答 – slara 2012-01-05 20:03:42

1

它实际上可以创建基于设备响应的设备符号链接,使用PROGRAM,尽管文档中说。这只适用于符号链接,而不是设备名称。

要知道,每一个你AFTER匹配,并指定一个SYMLINK规则,应该是这样的,

SYMLINK+= 

所以你SIMLINK规范将用新的级联。在其他情况下,你的符号链接将被删除。要知道正在发生的事情udev

最好的办法是将日志级别设置为调试:

sudo udevadm control --log-priority=debug 

你会在/var/log/messages/var/log/syslog找到这些日志,这取决于你的发行版。