title: linux serial port read() wrong data
body: <p>I am writing a small program to communicate with a AVR MCU, on PC side I used posix write() and read() to access the serial port, I connected the serial port's RX and TX pins to test if it can properly send and receive data, in theory everything sent out should end up exactly the same in the receive buffer, it is the case when the message being sent is short and sending frequency is low, read() returns the same message as sent out, but when the message gets longer and sent more frequently, read() returns the wrong data, the characters seem to be in the wrong order, my guess is read() or write() is not in block mode, so when old transfer hasn't finish yet, new transfer(write()?) arrived, interrupts the old transfer and changed the TX buffer. </p>
  
  <p>I am a newbie in Linux programing, please anybody help me on this, it's killing me ... 
  any help is greatly appreciated.</p>
  
  <p>Edit: I noticed in the write() man page: 
  A successful return from write() does not make any guarantee that data has been committed to disk. In fact, on some buggy implementations, it does not even guarantee that space has successfully been reserved for the data. The only way to be sure is to call fsync(2) after you are done writing all your data. </p>
  
  <p>I tried the fsync() function, still getting the same wrong result.</p>
  
  <p>Here is the code:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdio.h&gt;   /* Standard input/output definitions */
  #include &lt;string.h&gt;  /* String function definitions */
  #include &lt;unistd.h&gt;  /* UNIX standard function definitions */
  #include &lt;fcntl.h&gt;   /* File control definitions */
  #include &lt;errno.h&gt;   /* Error number definitions */
  #include &lt;termios.h&gt; /* POSIX terminal control definitions */
  
  int main(void) {
  
      int fd;
  //  fd = open("/dev/tty.usbmodem1a21", O_RDWR | O_NOCTTY | O_NDELAY);
      fd = open("/dev/tty.usbmodem1a21", O_RDWR | O_NOCTTY);
      if (fd == -1) {
          //Could not open the port.
          perror("open_port: Unable to open port ");
      }
          else
          fcntl(fd, F_SETFL, 0);
  
      char s[] = "Hello, this is a test of the serial port access";
  
      int cnt;
      unsigned char in[100];
      for(cnt=0; cnt&lt;10; cnt++) {
          int n = write(fd, s, sizeof(s));
          if (n &lt; 0)
              fputs("write() failed!\n", stderr);
  
          usleep(50000);  // works fine with delay
  
          read(fd, in, 100);
  
  
              printf("%s\n", in);
      }
  
      return 0;
  }
  </code></pre>
  
  <p><img src="https://i.stack.imgur.com/T34jc.png" alt="with sleep() between write() and read()">
  <img src="https://i.stack.imgur.com/vmYMx.png" alt="without sleep() between write() and read()"></p>
  
  <p>Eric</p>