Serial Port Programming Part 3 - Finding out the number of bytes available in serial read buffer
Consider the scenario in which I want to wait until 'n' number of bytes received on serial port before calling read, as read system call will remove the contents of the serial input buffer. Such situation can be in case where your packet length is 50 bytes and you want to wait until all the 50 bytes are received.
The FIONREAD ioctl returns the number of bytes present in the serial input buffer.
ioctl(fd, FIONREAD, &bytes);
Let's write a sample code to wait until 50 bytes are present in the serial input buffer and then perform read.
Two USB to serial devices should be connected (TX->RX, RX->TX) to run the program.
Two USB to serial devices should be connected (TX->RX, RX->TX) to run the program.
Code:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <sys/types.h> | |
#include <termios.h> | |
#include <fcntl.h> | |
#include <stdlib.h> | |
#include <sys/ioctl.h> | |
#define MAX_BYTES_TO_READ 50 | |
#define SERIAL_DEVICE "/dev/ttyUSB0" | |
int main() | |
{ | |
struct termios serial_port_settings; | |
int fd; | |
int retval; | |
char buf[256]; | |
int i; | |
fd = open(SERIAL_DEVICE, O_RDWR); | |
if (fd < 0) { | |
perror("Failed to open SERIAL_DEVICE"); | |
exit(1); | |
} | |
retval = tcgetattr(fd, &serial_port_settings); | |
if (retval < 0) { | |
perror("Failed to get termios structure"); | |
exit(2); | |
} | |
//setting baud rate to B38400 | |
retval = cfsetospeed(&serial_port_settings, B38400); | |
if (retval < 0) { | |
perror("Failed to set 38400 output baud rate"); | |
exit(3); | |
} | |
retval = cfsetispeed(&serial_port_settings, B38400); | |
if (retval < 0) { | |
perror("Failed to set 38400 input baud rate"); | |
exit(4); | |
} | |
serial_port_settings.c_lflag &= ~(ICANON); | |
serial_port_settings.c_lflag &= ~(ECHO | ECHOE); | |
retval = tcsetattr(fd, TCSANOW, &serial_port_settings); | |
if (retval < 0) { | |
perror("Failed to set serial attributes"); | |
exit(5); | |
} | |
printf("Successfully set the baud rate\n"); | |
while (1) { | |
int bytes_available; | |
retval = ioctl(fd, FIONREAD, &bytes_available); | |
if (retval < 0) { | |
perror("FIONREAD ioctl failed\n"); | |
exit(6); | |
} | |
usleep(50*1000L); | |
if (bytes_available >= MAX_BYTES_TO_READ) | |
break; | |
} | |
retval = read(fd, buf, MAX_BYTES_TO_READ); | |
if (retval < 0) { | |
perror("read on SERIAL_DEVICE failed\n"); | |
exit(7); | |
} | |
printf("Bytes read:%d\n", retval); | |
close(fd); | |
return 0; | |
} |
Run the noncanonical_write we wrote in previous post multiple times.While loop will exit when more than 50 bytes are present in the serial input buffer
Comments
Post a Comment