最近在调试android usb转串口的设备,发现插着开机和开机后再插,生成的设备节点不一样, 通常设备节点名为ttyUSBx(x为0~n), 比如第一个插入的设备编号为ttyUSB0,然后依此加1,变为ttyUSB1,ttyUSB2…… 如果仅仅以设备节点ttyUSBx来区别具体是哪个设备,因为末位的编号是随时会变的,所以就会造成混乱。无法保证A设备就是ttyUSB0,B设备就是ttyUSB1, 所以如何固定ttyUSB串口节点?
要固定ttyUSB串口设备节点名,使其在设备插拔时始终对应同一个设备,可以使用udev规则。udev是Linux系统中的设备管理器,它可以动态创建和删除设备文件。通过为每个USB设备编写特定的udev规则,可以确保设备始终以相同的节点名称出现。
udev
首先,插入你的USB设备并运行以下命令获取设备的信息:
bash udevadm info --name=/dev/ttyUSB0 --attribute-walk
这将显示设备的所有属性,找到唯一标识该设备的属性,如idVendor和idProduct,或者设备的序列号serial.
idVendor
idProduct
serial
例如输出中类似于:
```plaintext looking at device ‘/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0/ttyUSB0/tty/ttyUSB0’: KERNEL==”ttyUSB0” SUBSYSTEM==”tty” DRIVER==”“ ATTR{dev}==”188:0”
looking at parent device ‘/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0/ttyUSB0’: KERNELS==”ttyUSB0” SUBSYSTEMS==”usb-serial” DRIVERS==”ftdi_sio” ATTRS{port_number}==”0”
looking at parent device ‘/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0’: KERNELS==”1-2:1.0” SUBSYSTEMS==”usb” DRIVERS==”ftdi_sio” ATTRS{bInterfaceNumber}==”00” ATTRS{bAlternateSetting}==” 0” ATTRS{bNumEndpoints}==”02” ATTRS{bInterfaceClass}==”ff” ATTRS{bInterfaceSubClass}==”ff” ATTRS{bInterfaceProtocol}==”ff” ATTRS{modalias}==”usb:v0403p6001d0600dc00dsc00dp00icFFiscFFipFFin00” ATTRS{supports_autosuspend}==”1”
looking at parent device ‘/devices/pci0000:00/0000:00:14.0/usb1/1-2’: KERNELS==”1-2” SUBSYSTEMS==”usb” DRIVERS==”usb” ATTRS{configuration}==”“ ATTRS{bNumInterfaces}==” 1” ATTRS{bConfigurationValue}==”1” ATTRS{bmAttributes}==”80” ATTRS{bMaxPower}==”90mA” ATTRS{authorized}==”1” ATTRS{bNumConfigurations}==”1” ATTRS{maxchild}==”0” ATTRS{bcdDevice}==”0600” ATTRS{avoid_reset_quirk}==”0” ATTRS{quirks}==”0x0” ATTRS{serial}==”A6008isF” ATTRS{version}==” 2.00” ATTRS{urbnum}==”74” ATTRS{ltm_capable}==”no” ATTRS{manufacturer}==”FTDI” ATTRS{removable}==”unknown” ATTRS{idProduct}==”6001” ATTRS{idVendor}==”0403” ATTRS{bDeviceClass}==”00” ATTRS{bDeviceSubClass}==”00” ATTRS{bDeviceProtocol}==”00” ATTRS{bNumConfigurations}==”1” ATTRS{bMaxPacketSize0}==”8” ATTRS{speed}==”12” ATTRS{busnum}==”1” ATTRS{devnum}==”4” ATTRS{devpath}==”2” ATTRS{product}==”FT232R USB UART” ```
找到如idVendor、idProduct和serial等唯一标识信息。
使用上面找到的唯一标识信息来编写一个udev规则文件。创建一个新的规则文件,如/etc/udev/rules.d/99-usb-serial.rules:
/etc/udev/rules.d/99-usb-serial.rules
bash sudo nano /etc/udev/rules.d/99-usb-serial.rules
添加类似以下内容:
plaintext # FTDI USB-Serial Converter SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A6008isF", SYMLINK+="ttyUSB_FTDI"
这条规则的含义是:当系统检测到一个tty子系统的设备,并且idVendor为0403,idProduct为6001,serial为A6008isF时,创建一个名为/dev/ttyUSB_FTDI的符号链接指向该设备节点。
tty
0403
6001
A6008isF
/dev/ttyUSB_FTDI
重启udev服务以使规则生效:
bash sudo udevadm control --reload-rules sudo udevadm trigger
重新插入你的USB设备,检查是否生成了指定的符号链接:
bash ls -l /dev/ttyUSB_FTDI
如果一切配置正确,你应该会看到类似下面的输出:
plaintext lrwxrwxrwx 1 root root 7 Jul 3 12:34 /dev/ttyUSB_FTDI -> ttyUSB0
这样,通过编写udev规则,你可以确保特定的USB设备在插入时始终生成一个固定的符号链接名称,无论实际的设备节点名称如何变化。