I have a serial device connected via a FTDI serial to usb cable. The device sends 78 bytes every 10 msec. I am calling read()
every 1 msec, so I expect read()
to return 78 bytes every 10 calls (possibly split over 2 calls), and 0 bytes for 8-9 calls in between (my read()
call provides a 2k byte buffer). However, what actually happens is read()
returns 496 bytes every ~63 msec. I get all the data, but not as soon as it's available. It seems to be buffered somewhere until 496 bytes are accumulated.
Here's my code snippet that sets termios
. Everything should be set for raw data. I believe that somehow, the buffering is happening in the linux USB driver, since VMIN and VTIME are both set to 0. Any ideas on how to get the data as soon as it's available? Possibly by tweaking the USB driver settings?
char *portname = "/dev/ttyUSB0";
fd = open(portname, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd < 0)
{
printf("Failed to open %s. errno = %d (%s)\n", portname, errno, strerror(errno));
return -1;
}
printf("%s opened successfully\n\n", portname);
struct termios settings;
if (tcgetattr(fd, &settings) < 0)
{
printf("tcgettattr() failed (%i): %s\n", errno, strerror(errno));
return -1;
}
cfsetispeed(&settings, B460800); /* set baud rate */
cfsetospeed(&settings, B460800);
settings.c_cflag &= ~PARENB; /* No parity */
settings.c_cflag &= ~CSTOPB; /* 1 stop bit */
settings.c_cflag &= ~CSIZE; /* Clears the mask for setting the data size */
settings.c_cflag |= CS8; /* Set the data bits = 8 */
settings.c_cflag &= ~CRTSCTS; /* No Hardware flow Control */
settings.c_cflag |= CREAD | CLOCAL; /* Enable receiver, Ignore Modem Control lines */
settings.c_iflag &= ~(IXON | IXOFF | IXANY); /* Disable XON/XOFF flow control both i/p and o/p */
settings.c_iflag &= ~(BRKINT | IGNBRK | ICRNL | INLCR | PARMRK | ISTRIP | IGNCR);
settings.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHONL | ISIG | IEXTEN); /* Non Cannonical mode */
settings.c_lflag |= NOFLSH;
settings.c_oflag &= ~(OPOST | ONLCR); /* No Output Processing */
settings.c_cc[VMIN] = 0;
settings.c_cc[VTIME] = 0;
if ((tcsetattr(fd, TCSANOW, &settings)) != 0) /* Set the attributes to the termios structure */
{
printf("Error setting attributes\n");
return -1;
}