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

发布于 2024-10-19 08:12:50 字数 43 浏览 2 评论 0原文

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

Posix requires changing RTS pin on port opening. I want a way to avoid it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

凉城凉梦凉人心 2024-10-26 08:12:50

我不知道你为什么要这样做,但这可以通过修改串行控制台的 Linux 内核驱动程序来轻松完成,这样它就不会切换 RTS。例如,对于 drivers/tty/serial/8250/ 中的 8250 系列驱动程序,您可以更改对 MCR 寄存器 (UART_MCR) 的每次写入,以确保永远不会设置位 1(掩码为 UART_MCR_RTS) 。

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

I have no idea why you'd want to do this, but this can be done pretty easily by modifying the linux kernel driver for your serial console so it doesn't toggle RTS. For example, for the 8250-series driver in drivers/tty/serial/8250/ you could change every write to the MCR register (UART_MCR) to ensure that bit 1 (mask is UART_MCR_RTS) is never set.

Since it's abstracted away in userspace, you're out of luck if you want to do this without modifying the kernel driver.

御弟哥哥 2024-10-26 08:12:50

遇到同样的问题,我会通过修补 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
}

调用 open() 时,RTS 握手行不再更改。
请注意,只要加载了修改后的内核驱动程序,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 适配器。

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

Having the same problem, I'd give it a try by patching the ftdi_sio kernel driver. You just need to uncomment a small piece of code in ftdi_dtr_rts() like this:

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
}

and the RTS handshake line is not longer changed upon open() call.
Note, that the uart than might not longer working with RTS/CTS hardware handshake, as long as your modified kernel driver is loaded. But you can still control the state of the RTS handshake line manually by calling e.g.:

    int opins = TIOCM_RTS;
    ioctl(tty_fd, TIOCMBIC, &opins);

I'd tested this with the Ctrl+A+G command of picocom 2.3a, running Kubuntu 16.04 64 bit and Ftdi FT2232H based usb uart adapter.

You might find more details on this topic here.

戏舞 2024-10-26 08:12:50

使用命令行可以(最终)避免 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 was running这是在 Raspberry Pi 上进行的,但我刚刚在 x86_64 上的 Linux Mint 上尝试过,它有效。我不知道RTS是如何受到影响的。

我发现它有用的原因是与 Arduino Nano 进行通信 - 它具有 USB-> 接口。板载串行芯片 - 通常每次从 Linux 打开串行端口时 Arduino 都会重置(DTR 的上升沿会导致重置)。对于某些应用程序来说,这不是问题,但对于其他应用程序来说,避免这种情况显然很有用,而且从 Arduino 上移除连接 DTR 进行复位的微型电容器并不容易。

当执行 stty 命令时(插入 USB 电缆后),您仍然会得到一次重置。但至少您可以在此之后继续打开和关闭串行端口,而无需进一步重置。

A change in the DTR pin can be (eventually) avoided using the command line

stty -F /dev/ttyUSB0 -hupcl

This has the effect of making DTR turn on; and subsequently when the port is opened and closed, DTR is not affected.

Source: https://raspberrypi.stackexchange.com/questions/9695/disable-dtr-on-ttyusb0/27706#27706

And there is code there to do the same thing from python via termios, this can be done before opening the port via 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)

The OP was running this on a Raspberry Pi, but I just tried it on Linux Mint on x86_64, it worked. I don't know how RTS is affected.

The reason I find this useful, is for communication with an Arduino Nano - which has a USB-> serial chip on board - and normally the Arduino gets reset every time you open the serial port from linux (rising edge of DTR causes reset). For some applications, this is not a problem, but it's clearly useful to avoid this for other applications, and it's not so easy to remove that tiny capacitor from the Arduino which connects DTR to reset.

You will still get a single reset when the stty command is executed (after plugging in the USB cable). But at least you can then keep opening and closing the serial port after that without further resets.

2024-10-26 08:12:50

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

我组装了一个支持 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...

例如,我使用 rigctl 来控制连接到我的计算机的无线电;以前,运行任何 rigctl 命令都会触发无线电上的 PTT 并使其开始传输。

使用 LD_PRELOAD 注入库后,我可以运行 rigctl 命令,而不会影响 PTT 控制。

I found my way here looking for a solution to the same problem. My challenge is that I'm working with a variety of pre-existing software, and I was not looking forward to patching everything individually.

I put together an LD_PRELOAD-able library that automatically sets RTS low after opening a serial port; you can find it at https://github.com/larsks/force_rts/. Using it looks like this:

export LD_PRELOAD=$PWD/force_rts.so
export FORCE_RTS_DEVICES="/dev/ttyUSB0:/dev/ttyS0"
...some command here...

For example, I'm using rigctl to control a radio attached to my computer; previously, running any rigctl command would trigger PTT on the radio and cause it to start transmitting.

With the library injected using LD_PRELOAD, I can run the rigctl commands without impacting the PTT control.

魂牵梦绕锁你心扉 2024-10-26 08:12:50

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

calling fopen("/dev/ACM0", "r") doesn't require you do do anything:) You may not receive the data you expect though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文