How do I read data from serial port in Linux using C?

62,005

Solution 1

In theory, all you have to do is open the relevant port for reading, and use read() to get the data.

int
read_port(void)
{
    int fd = open("/dev/ttyS0", O_RDONLY | O_NOCTTY);
    if (fd == -1)
    {
        /* Could not open the port. */
        perror("open_port: Unable to open /dev/ttyS0 - ");
    }

    char buffer[32];
    int n = read(fd, buffer, sizeof(buffer));
    if (n < 0)
        fputs("read failed!\n", stderr);
    return (fd);
}

There are differences; notably, the read needs a buffer to put the data in. The code shown discards the first message read. Note that a short read simply indicates that there was less data available than requested at the time when the read completed. It does not automatically indicate an error. Think of a command line; some commands might be one or two characters (ls) where others might be quite complex (find /some/where -name '*.pdf' -mtime -3 -print). The fact that the same buffer is used to read both isn't a problem; one read gives 3 characters (newline is included), the other 47 or so.

Solution 2

The program posted makes a lot of assumptions about the state of the port. In a real world application you should do all the important setup explicitly. I think the best source for learning serial port programming under POSIX is the

Serial Programming Guide for POSIX Operating Systems

I'm mirroring it here: https://www.cmrr.umn.edu/~strupp/serial.html

Share:
62,005
Amit Singh Tomar
Author by

Amit Singh Tomar

SOreadytohelp

Updated on December 06, 2020

Comments

  • Amit Singh Tomar
    Amit Singh Tomar over 3 years

    I am new to serial programming in Linux using C. I have found a small piece of code to write data on serial port which I am sharing here. After running this code I may assume that data has written on a specific port. Now I would like to open another terminal and using separate code want to read the data written on that specific port - how do I do that?

    #include <stdio.h>   /* Standard input/output definitions */
    #include <string.h>  /* String function definitions */
    #include <unistd.h>  /* UNIX standard function definitions */
    #include <fcntl.h>   /* File control definitions */
    #include <errno.h>   /* Error number definitions */
    #include <termios.h> /* POSIX terminal control definitions */
    
    /*
     * 'open_port()' - Open serial port 1.
     *
     * Returns the file descriptor on success or -1 on error.
     */
    int
    open_port(void)
    {
      int fd; /* File descriptor for the port */
    
      fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
      if (fd == -1)
      {
       /* Could not open the port. */
        perror("open_port: Unable to open /dev/ttyS0 - ");
      }
      else
        fcntl(fd, F_SETFL, 0);
    
      n = write(fd, "ATZ\r", 4);
      if (n < 0)
        fputs("write() of 4 bytes failed!\n", stderr);
    
      return (fd);
    }
    

    The code above will write the data on a specific port.

  • Amit Singh Tomar
    Amit Singh Tomar over 12 years
    Thanks @Jonathan for your kind response .But when I am trying to run this piece of code in other terminal am getting read failed error ,Why its not reading the data when i successfully wrote the data on port using other terminal.I actually wanted to do it like socket where i communicate between terminal using loopbackaddress!!
  • Jonathan Leffler
    Jonathan Leffler over 12 years
    That's where the practice gets in the way of theory. To read successfully from the port, there must be a gadget connected to the port that writes the data for you to read. So, you have to worry about the hardware on the other side of the port; how it is going to react to data written to it by the computer, and how it is going to write data back for the computer to read.
  • Amit Singh Tomar
    Amit Singh Tomar over 12 years
    Really @Jonathan the way I am approaching is just have Linux box and trying to communicate using terminal .On one terminal am trying to write data to port and on other terminal trying to read it ,same way started Linux learning socket programming But now its looks like i need some serial cable as well and two machine .Any way Jonathan Thank you very much for gentle help!!
  • datenwolf
    datenwolf almost 10 years
    @n0rd: Thanks for the heads up. I've setup a mirror copy on my server.
  • Chris Stratton
    Chris Stratton almost 9 years
    This isn't going to work very well in most cases without configuring the port - baud rate, translation, etc.
  • Jonathan Leffler
    Jonathan Leffler almost 9 years
    @ChrisStratton: hmm...yes, you are probably right about that. You can rapidly get into lots of system-specific code then. You definitely need to know what are the appropriate settings from somewhere to use the functions from <termios.h> correctly (at least some parts of which are not system-specific — but if you need to set baud rate, for example, you need to know what's the correct baud rate to set for the serial device you opened).
  • Electron
    Electron over 8 years
    @datenwolf: the main page is mirrored, but all the links to subpages seem to be dead. I can find the content here: cmrr.umn.edu/~strupp/serial.html
  • datenwolf
    datenwolf over 8 years
    @Electron: This document has no subpages. It's just one long HTML file. The problem was, that the links in the ToC included a filename serial.html instead of simple intra-document anchors. I changed the links in the HTML to such intra document anchors.