Posix 需要在端口打开时更改 RTS 引脚。我想要一种方法来避免它。
我不知道你为什么要这样做,但这可以通过修改串行控制台的 Linux 内核驱动程序来轻松完成,这样它就不会切换 RTS。例如,对于
drivers/tty/serial/8250/
中的 8250 系列驱动程序,您可以更改对 MCR 寄存器 (UART_MCR) 的每次写入,以确保永远不会设置位 1(掩码为 UART_MCR_RTS)。
由于它是在用户空间中抽象出来的,如果您想在不修改内核驱动程序的情况下执行此操作,那么您就不走运了。
遇到同样的问题,我会尝试修补
ftdi_sio
内核驱动程序。你只需要取消ftdi_dtr_rts()
中一小段代码的注释,如下所示:
static void ftdi_dtr_rts(struct usb_serial_port *port, int on) {
...
/* drop RTS and DTR */
if (on)
set_mctrl(port, TIOCM_DTR /*| TIOCM_RTS*/); // <<-- HERE
else
clear_mctrl(port, TIOCM_DTR /*| TIOCM_RTS*/); // <<-- and HERE
}
并且 RTS 握手线在
open()
调用时不再更改。
请注意,只要加载了修改后的内核驱动程序,uart 可能就不再与 RTS/CTS 硬件握手一起工作。但您仍然可以通过调用以下命令来手动控制 RTS 握手线的状态:
int opins = TIOCM_RTS;
ioctl(tty_fd, TIOCMBIC, &opins);
我使用 picocom 2.3a 的
Ctrl+A+G
命令对此进行了测试,运行 Kubuntu 16.04 64 位和基于 Ftdi FT2232H 的 USB uart 适配器。
您可能会在此处找到有关此主题的更多详细信息。
使用命令行(最终)可以避免 DTR 引脚的更改
stty -F /dev/ttyUSB0 -hupcl
这具有使DTR开启的效果;随后当端口打开和关闭时,DTR 不受影响。
来源:https://raspberrypi.stackexchange.com/questions/9695/disable-dtr-on-ttyusb0/27706#27706
并且有代码可以通过
termios
从 python 执行相同的操作,这可以在通过 pyserial 打开端口之前完成:
import termios
path = '/dev/ttyACM0'
# Disable reset after hangup
with open(path) as f:
attrs = termios.tcgetattr(f)
attrs[2] = attrs[2] & ~termios.HUPCL
termios.tcsetattr(f, termios.TCSAFLUSH, attrs)
OP 在 Raspberry Pi 上运行这个,但我刚刚在 x86_64 上的 Linux Mint 上尝试过,它有效。我不知道RTS是如何受到影响的。
我发现这个有用的原因是为了与 Arduino Nano 进行通信 - 板上有一个 USB-> 串行芯片 - 通常每次从 Linux 打开串行端口时 Arduino 都会重置(DTR 的上升沿会导致重置) 。对于某些应用程序来说,这不是问题,但对于其他应用程序来说,避免这种情况显然很有用,而且从 Arduino 上移除连接 DTR 进行复位的微型电容器并不容易。
执行 stty 命令时(插入 USB 电缆后),您仍然会得到一次重置。但至少您可以在此之后继续打开和关闭串行端口,而无需进一步重置。
我在这里找到了解决同样问题的方法。我的挑战是我正在使用各种预先存在的软件,并且我并不期待单独修补所有内容。
我组装了一个支持
LD_PRELOAD
的库,它可以在打开串行端口后自动将 RTS 设置为低电平;您可以在 https://github.com/larsks/force_rts/ 找到它。使用它看起来像这样:
export LD_PRELOAD=$PWD/force_rts.so
export FORCE_RTS_DEVICES="/dev/ttyUSB0:/dev/ttyS0"
...some command here...
调用
fopen("/dev/ACM0", "r")
不需要您执行任何操作:) 但您可能不会收到您期望的数据。