SaltyEgg
SaltyEgg

Reputation: 1558

Receive extra null byte when using serial port

I'm writing a program for serial port data transmission on Linux, but find that every time the sender opens the port, the receiver gets an extra null byte '\x00'.

Here's the code of sender:

#include <unistd.h>
#include <termios.h>
#include <fcntl.h>

int main(int argc, char* argv[]) {
  int fd_com_ = open("/dev/ttyAM0", O_RDWR | O_NOCTTY | O_NONBLOCK);

  struct termios attrs_;
  attrs_.c_iflag = IGNBRK;
  attrs_.c_oflag = 0;
  attrs_.c_cflag = (CLOCAL | CREAD);
  attrs_.c_cflag |= CS8;
  attrs_.c_lflag = 0;
  attrs_.c_cc[VMIN] = 0;
  attrs_.c_cc[VTIME] = 0;
  cfsetspeed(&attrs_, B115200);

  tcsetattr(fd_com_, TCSANOW, &attrs_);

  const char *s = "abcd";
  write(fd_com_, s, 4);
  sleep(1);
  write(fd_com_, s, 4);
  sleep(1);
  close(fd_com_);

  fd_com_ = open("/dev/ttyAM0", O_RDWR | O_NOCTTY | O_NONBLOCK);
  write(fd_com_, s, 4);

  return 0;
}

The receiver has the same configuration, but receives "\x00abcdabcd\x00abcd". How to fix this problem so the receiver could get "abcdabcdabcd"?


Update:

The code of receiver:

#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>

int main(int argc, char* argv[]) {
  int fd_com_ = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NONBLOCK);

  struct termios attrs_;
  attrs_.c_iflag = IGNBRK;
  attrs_.c_oflag = 0;
  attrs_.c_cflag = (CLOCAL | CREAD);
  attrs_.c_cflag |= CS8;
  attrs_.c_lflag = 0;
  attrs_.c_cc[VMIN] = 0;
  attrs_.c_cc[VTIME] = 0;
  cfsetspeed(&attrs_, B115200);

  tcsetattr(fd_com_, TCSANOW, &attrs_);

  char buf[100];
  ssize_t sz;
  while(1) {
    sz = read(fd_com_, buf, 100);
    if (sz > 0) {
      for (ssize_t i=0; i<sz; i++) {
        printf("%02hhx\n", buf[i]);
      }
    }
    sleep(1);
  }

  return 0;
}

Upvotes: 1

Views: 2900

Answers (2)

user3629249
user3629249

Reputation: 16540

the initial \x0 is the indication that a parity or framing error occurred. this error occurs because the termios fields are not being setup properly. so the initial line high/low status and number of start/stop bits and parity are not being setup properly.

you might read: http://man7.org/linux/man-pages/man3/termios.3.html which discusses each of the fields and their contents and meaning.

(The linked page is way too long to post here)

Upvotes: 1

Kamajii
Kamajii

Reputation: 1878

Please check in your ARM board's documentation how the ARM's UART is hooked up and how it is configured in hardware and by your platform driver.

From what you describe, I would suppose that when opening the UART port on the ARM, the physical UART (i.e., the hardware peripheral module within the ARM or maybe an externally wired UART chip) is enabled or restored from some unknown idle state to the proper -12 Volt idle state of RS232. This transistion may be enough for your PC's UART to recognize a start bit and receive a bogus character.

You may want to check the serial line using an oscilloscope to see what happens when actually opening the port.

Upvotes: 3

Related Questions