我想使用 statserial 读取 PL2303 USB2RS232 转换器的单个状态行 (txd、dtr 等)。我已经将 PL2303 连接到 ttyUSB0 端口。但要读取数据,我需要命令 statserial,它只接受 ttyS*(如果我尝试将其与 ttyUSB* 一起使用,则会出现“权限被拒绝”信息)。如何将 ttyUSB* 更改为 ttyS*“地址”?
lsusb:
gernot@gernot-Lenovo-G505s:~$ lsusb
Bus 002 Device 002: ID 0bda:0129 Realtek Semiconductor Corp. RTS5129 Card Reader Controller
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 004: ID 174f:147b Syntek
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 004: ID 0cf3:3004 Atheros Communications, Inc.
Bus 003 Device 002: ID 062a:4101 Creative Labs
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 005 Device 002: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
dmesg:
...
[ 53.186869] ISO 9660 Extensions: Microsoft Joliet Level 3
[ 54.986337] ISOFS: changing to secondary root
[ 76.485704] usb 5-1: new full-speed USB device number 2 using xhci_hcd
[ 76.522777] usb 5-1: New USB device found, idVendor=067b, idProduct=2303
[ 76.522786] usb 5-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 76.522791] usb 5-1: Product: USB-Serial Controller
[ 76.522795] usb 5-1: Manufacturer: Prolific Technology Inc.
[ 76.557641] usbcore: registered new interface driver usbserial
[ 76.557658] usbcore: registered new interface driver usbserial_generic
[ 76.557668] usbserial: USB Serial support registered for generic
[ 76.559702] usbcore: registered new interface driver pl2303
[ 76.559719] usbserial: USB Serial support registered for pl2303
[ 76.560192] pl2303 5-1:1.0: pl2303 converter detected
[ 76.588044] usb 5-1: pl2303 converter now attached to ttyUSB0
...
谢谢您的帮助!
更新:看来我不是 dialout 组的成员。我使用以下方法将我的用户添加到该组:
sudo usermod -a -G dialout <username>
之后,我获得了访问 USB 和串行端口的权限。现在,像 moserial 这样的终端程序可以工作了。但我仍然无法使用 访问状态行statserial
。相反,我收到以下消息:
gernot@gernot-Lenovo-G505s:~$ statserial ttyUSB0
statserial: can't open device `ttyUSB0': No such file or directory
更新 2:我设法使 statserial 工作(我猜这个线程的意义会崩溃):首先,您必须重置端口,然后建立一个到 ttyS* 端口的硬链接,该端口的数量高于标准端口的数量:
sudo rm /dev/ttyS40
sudo ln /dev/ttyUSB0 /dev/ttyS40
但是,我怎样才能将终端中显示的数据复制到任何可以用自制代码读取的对象中?为什么 statserial-tool 对更改的状态行反应如此缓慢?
答案1
通过将您的用户添加到正确的组,您的第一个问题(设备权限)已得到解决。
您的第二个问题(设备路径)似乎是您没有使用完整的设备路径。来自man statserial
:
可选的 device-name 参数是所讨论的串行端口的设备文件的完整名称。如果未指定,则默认从环境变量 MODEM(如果已设置)中获取,否则为 /dev/cua1。
所以你需要做statserial /dev/ttyUSB0
(我检查了源代码以验证这是否正确,它确实做到了fd = open(device,...)
设备是你的 argv[x])
有关串行端口编程的一般信息,请参阅串行编程指南。您可以使用查看 statserial 的源代码(这是一个由195 行长的apt-get source statserial
单个文件编译而成的非常简单的程序)。statserial.c
更新速度慢是因为 statserial 每秒只轮询一次串行端口,主循环是:
for (;;) {
/* get modem status info */
status = ioctl(fd, TIOCMGET, &arg);
if (status != 0) {
perror("statserial: TIOCMGET failed");
exit(1);
}
...
printw("Device: %s\n\n", device);
printw("Signal Pin Pin Direction Status Full\n");
printw("Name (25) (9) (computer) Name\n");
printw("----- --- --- --------- ------ -----\n");
printw("FG 1 - - - Frame Ground\n");
printw("TxD 2 3 out - Transmit Data\n");
printw("RxD 3 2 in - Receive Data\n");
printw("RTS 4 7 out %1d Request To Send\n", !!(arg & TIOCM_RTS));
printw("CTS 5 8 in %1d Clear To Send\n", !!(arg & TIOCM_CTS));
printw("DSR 6 6 in %1d Data Set Ready\n", !!(arg & TIOCM_DSR));
printw("GND 7 5 - - Signal Ground\n");
printw("DCD 8 1 in %1d Data Carrier Detect\n", !!(arg & TIOCM_CAR));
printw("DTR 20 4 out %1d Data Terminal Ready\n", !!(arg & TIOCM_DTR));
printw("RI 22 9 in %1d Ring Indicator\n", !!(arg & TIOCM_RNG));
refresh();
/* break out if -n option was used */
if (n_option)
exit(0);
/* delay 1 second between loops */
sleep(1);
}
如果您要认真使用串行端口,我强烈建议您购买真正的串行端口卡(带有 RS232 控制器的 PCI 卡)。USB 适配器不够可靠,特别是如果您连接到旧硬件,您会发现它们无法准确重现信号时序,这会导致某些设备出现问题。另一个常见问题是 USB 串行端口无法实现(或实现得不好)硬件 RTS/CTS 握手,因此最终与旧串行端口设备不兼容。话虽如此,PL2303 是更好的芯片之一,应该可以与大多数设备配合使用。
答案2
我不知道statserial
(我知道这是一个老问题),但如果您想要一个自定义设备名称,您可以放入一个/etc/udev/rules.d/
像这样的文件(我的名为98-devicename.rules
):
SUBSYSTEM=="tty" ATTRS{idVendor}=="067b" ATTRS{idProduct}=="2303" SYMLINK+="devicename%n" MODE:="0666"
这将匹配 USB ID/供应商,并允许所有用户访问而不属于dialout
组 ( MODE
)。它还将创建一个符号链接/dev/devicename0
->/dev/ttyUSB0
假设它是两者中的第一个。如果您已经插入了具有不同 USB 芯片组(例如 Cypress 芯片组)的其他设备,它可能是两者中的第一个这芯片组,所以/dev/devicename0
-> /dev/ttyUSB1
。通过udev
处理符号链接,您不必担心它被插入不同的端口等 -devicename0
应该总是成为第一个使用该芯片组的设备。
要查找更多可以匹配的事物,请参阅udevadm info -a -p $(udevadm info -q path -n /dev/ttyUSB0)
。
答案3
至于如何将自定义代码连接到串行端口,由于我通常使用 Python,因此我建议查看 pySerial 库https://wiki.python.org/moin/PySerial