当我们插入一个设备时, linux内核都会分配一个串口名称(比如/dev/ttyUSB0,/dev/ttyUSB1...),但这个名称是内核动态分配的,也就是说现在设备插进去是/dev/ttyUSB0, 下次插进去可能是/dev/ttyUSB1了。。。这样每次调试开发的时候都要修改配置代码,非常不方便,那么能不能像固定IP地址那样固定串口名称呢? 当然是可以的。
首先插入设备, 打印一下内核日志,查看系统分配的串口名称:
sudo dmesg
结果如下,可以看到系统分配了/dev/ttyUSB0:
[20818.014340] ch341-uart ttyUSB0: ch341-uart converter now disconnected from ttyUSB0[20818.014352] ch341 1-8:1.0: device disconnected[20821.129056] usb 1-8: new full-speed USB device number 17 using xhci_hcd[20821.256816] usb 1-8: New USB device found, idVendor=1a86, idProduct=7523, bcdDevice= 2.64[20821.256818] usb 1-8: New USB device strings: Mfr=0, Product=2, SerialNumber=0[20821.256819] usb 1-8: Product: USB Serial[20821.258313] ch341 1-8:1.0: ch341-uart converter detected[20821.258749] usb 1-8: ch341-uart converter now attached to ttyUSB0[20976.093400] rtw_8821ce 0000:03:00.0: firmware failed to leave lps state
然后我们查询/dev/ttyUSB0完整的属性,相当于设备的指纹:
udevadm info -a -n /dev/ttyUSB0 | grep -E 'idVendor|idProduct|serial'
(base) $ udevadm info -a -n /dev/ttyUSB0 | grep -E 'idVendor|idProduct|serial' SUBSYSTEMS=="usb-serial" ATTRS{idProduct}=="7523" ATTRS{idVendor}=="1a86" ATTRS{idProduct}=="0002" ATTRS{idVendor}=="1d6b" ATTRS{serial}=="0000:00:14.0" ATTRS{dbc_idProduct}=="0010" ATTRS{dbc_idVendor}=="1d6b"
接下来创建udev规则,比如说我们有一个STM32的板子插入电脑中, 要把设备映射到/dev/ttySTM32:
sudo vim /etc/udev/rules.d/99-stm32.rules
根据上面查询到的属性idVendor和idProduct, 输入以下内容:
# CH340 → /dev/ttySTM32KERNEL=="ttyUSB*", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", \MODE:="0666", SYMLINK+="ttySTM32"
重载并触发udev规则:
sudo udevadm control --reload-rulessudo udevadm trigger
然后重新插拔一下设备, 可以看到:
(base) $ sudo ls -l /dev/ttySTM32lrwxrwxrwx 1 root root 7 7月 15 14:42 /dev/ttySTM32 -> ttyUSB0
之后开发代码中可以安心固定使用 /dev/ttySTM32了,不用再根据系统分配的串口名称修改了。