如何在不改变任何引脚的情况下在linux中打开串口?

问题描述 投票:0回答:5

Posix 需要在端口打开时更改 RTS 引脚。我想要一种方法来避免它。

linux serial-port posix
5个回答
7
投票

我不知道你为什么要这样做,但这可以通过修改串行控制台的 Linux 内核驱动程序来轻松完成,这样它就不会切换 RTS。例如,对于

drivers/tty/serial/8250/
中的 8250 系列驱动程序,您可以更改对 MCR 寄存器 (UART_MCR) 的每次写入,以确保永远不会设置位 1(掩码为 UART_MCR_RTS)。

由于它是在用户空间中抽象出来的,如果您想在不修改内核驱动程序的情况下执行此操作,那么您就不走运了。


4
投票

遇到同样的问题,我会尝试修补

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 适配器。

您可能会在此处找到有关此主题的更多详细信息。


3
投票

使用命令行(最终)可以避免 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 电缆后),您仍然会得到一次重置。但至少您可以在此之后继续打开和关闭串行端口,而无需进一步重置。


0
投票

我在这里找到了解决同样问题的方法。我的挑战是我正在使用各种预先存在的软件,并且我并不期待单独修补所有内容。

我组装了一个支持

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...

-3
投票

调用

fopen("/dev/ACM0", "r")
不需要您执行任何操作:) 但您可能不会收到您期望的数据。

© www.soinside.com 2019 - 2024. All rights reserved.