How to open serial port in linux without changing any pin?

后端 未结 4 1089
南旧
南旧 2021-02-19 00:39

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

相关标签:
4条回答
  • 2021-02-19 01:10

    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.

    0 讨论(0)
  • 2021-02-19 01:26

    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.

    0 讨论(0)
  • 2021-02-19 01:35

    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.

    0 讨论(0)
  • 2021-02-19 01:35

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

    0 讨论(0)
提交回复
热议问题