How to Open Serial Port in Linux Without Changing Any Pin

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

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.

Virtual Serial Port for Linux

You can use a pty ("pseudo-teletype", where a serial port is a "real teletype") for this. From one end, open /dev/ptyp5, and then attach your program to /dev/ttyp5; ttyp5 will act just like a serial port, but will send/receive everything it does via /dev/ptyp5.

If you really need it to talk to a file called /dev/ttys2, then simply move your old /dev/ttys2 out of the way and make a symlink from ptyp5 to ttys2.

Of course you can use some number other than ptyp5. Perhaps pick one with a high number to avoid duplicates, since all your login terminals will also be using ptys.

Wikipedia has more about ptys: http://en.wikipedia.org/wiki/Pseudo_terminal

rs 232 pin configuration in linux pc

Control Pins

For the other pins DTR CTS etc, you will need to use ioctl() to toggle the pin.

Here is a simple example (no error checking) to do that for the DTR line:

#include <termios.h>
#include <unistd.h>
#include <sys/ioctl.h>

int f = open( "/dev/ttyS0", O_RDWR | O_NOCTTY);
int pins;
ioctl( f, TIOCMGET, &pins);
pins = pins | TIOCM_DTR;
ioctl( f, TIOCMSET, &pins) // the order you do this depends
sleep(1);
ioctl( f, TIOCMGET, &pins);
pins = pins & ~TIOCM_DTR;
ioctl( f, TIOCMSET, &pins)

The various flags are described in the man page for open and tty_ioctl

Transmit Pin

Using the TX pin is probably a bit tricker; in theory the output is normally 1, but then you can set a 'break' for a period of time which set it to 0. You could probably use the following, but I havent tried it:

ioctl( f, TIOCSBRK)

Caution

Note that in traditional rs232 the levels are notionally +/- 12v ( between +/-3,15V) where negative is 1 and positive is zero, which might be the opposite of what you are expecting. But these days a lot of serials port use TTL or 3v3 levels instead.

I used the above in an application where we used DTR as an output GPIO; remember to use appropriate resistors or other buffering as needed, so you don't blow up your PC serial port.

YMMV with USB serial dongles.

PNP(Plug and Play) event handling in Serial Port Programming

So, there are no direct PNP events for traditional serial ports - obviously a USB serial port will at some level be a serial port, but I believe that is handled by the "usb driver" for the serial device, and not something you need to deal with.

Unfortunnately, there is no distinct way to determine that something is connected on a serial port in it's most basic behaviour (three wires for RX, TX and ground). If you use at least four wires, you can use DCD (Data Carrier Detect) to notice that a serial port is "connected at the other end". In linux, there is no way to recognise the change in the DCD pin itself in user-mode. It can be used to "wait for serial port to become active" if you try to use fd = open("/dev/ttyS0", O_RDWR); - if you specify O_NONBLOCK it will open immediately, regardless of the state of DCD. If you don't specify O_NONBLOCK, the OS waits for the carrier to be present before it opens. It is possible to change the file to non-blocking later, should you need to. You will then have to poll the DCD using IOCTL calls (or some other wrapping of these): http://man7.org/linux/man-pages/man4/tty_ioctl.4.html

The other way to "detect" serial ports is simply to send something out the port, and see if you get a reply (of the right kind). This obviously assumes that the device is actually designed to respond to some activity on the serial port in some way - a modem for example, will accept "Hayes Commands" or "AT commands", and give some information back to those commands. But of course, for this to work, you need to first open the device, then send something, and (in case of a modem) it can be difficult to detect when the device goes away. Of course, if you have "your own" device at the other end, you can, if there is no "traffic" going on, send a "ping" command to ask if the other machine is still there. If no reply, then the device has gone...

Getting DTR and RTS pin of serial port in C on Windows platform

Using inc\api\ntddser.h API and winioctl.h, you can access DTR and RTS status. Call DeviceIoControl, set the second parameter to IOCTL_SERIAL_GET_DTRRTS:

Call:

DeviceIoControl(
handle, // handle returned by CreateFile
IOCTL_SERIAL_GET_DTRRTS,
NULL,
0,
&Status, // pointer to a DWORD variable 1
sizeof(Status),
&unused, // pointer to a DWORD variable
pOverlapped // optional pointer to overlapped buffer (may be NULL)
);

Documentation about DeviceIoControl here.

Cannot open UART on the 40-pin header

The two UART ports exposed on the Coral dev board (UART1 and UART3) map to the following file handles:

  • UART1/dev/ttymxc0
  • UART3/dev/ttymxc2

You can access these ports through the 40-pin I/O connector and through the serial console interface (the USB to UART bridge exposes two ports when connected to your workstation).

The current release of Mendel (chef) comes with the following caveats:

  1. UART1 is shared with the serial debug console. You will need to disable the console in Linux to use this port with applications.
  2. UART3 is not enabled by default in the base package. You need to update the packages on your board to enable this. We've added instructions to the I/O documentation.


Related Topics



Leave a reply



Submit