Serial Port Programming Part 5 - tcflush - TCIFLUSH,TCOFLUSH example

tcflush flushes/discards
  • data which is written but not transmitted and/or 
  • data which is received but not read by user
The exact operation depends on the 'queue_selector' argument .


#include <termios.h>
int tcflush(int fildes, int queue_selector);

Possible values of queue_selector are:

TCIFLUSH - Flushes/Discards received data, but not read
TCOFLUSH - Flushes/Discards written data, but not transmitted
TCIOFLUSH - Flushes/Discards both

Let's write a sample code to check what happens when we
1. Loop until there are bytes in input buffer using 'FIONREAD' ioctl 
2. Call tcflush with queue selector 'TCIFLUSH'
3. Check how many bytes are present in input buffer with 'FIONREAD' ioctl

Need two USB to serial/serial devices connected (TX-RX/RX-TX)

Code:


#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 bytes_available;
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) {
retval = ioctl(fd, FIONREAD, &bytes_available);
if (retval < 0) {
perror("FIONREAD ioctl failed\n");
exit(6);
}
usleep(50*1000L);
if (bytes_available > 0)
break;
}
printf("tcflush: Bytes available in the input buffer before TCIFLUSH:%d\n",
bytes_available);
tcflush(fd, TCIFLUSH);
retval = ioctl(fd, FIONREAD, &bytes_available);
if (retval < 0) {
perror("FIONREAD ioctl failed\n");
exit(7);
}
printf("tcflush:Bytes available in the input buffer after TCIFLUSH:%d\n",
bytes_available);
close(fd);
return 0;
}
view raw tcflush_input.c hosted with ❤ by GitHub

Output:



Same behavior will happen when we call write on the serial port with large number of bytes, and in the next statement call tcflush with queue selector 'TCOFLUSH' not all data will be received by the other serial port.

Receive Code: (fionread)


#include <stdio.h>
#include <sys/types.h>
#include <termios.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#define SERIAL_DEVICE "/dev/ttyUSB0"
int main()
{
struct termios serial_port_settings;
int fd;
int retval;
char buf[256];
int i;
int bytes_available;
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("/dev/ttyUSB0:Successfully set the baud rate\n");
while (1) {
retval = ioctl(fd, FIONREAD, &bytes_available);
if (retval < 0) {
perror("FIONREAD ioctl failed\n");
exit(6);
}
sleep(5);
if (bytes_available > 0)
break;
}
printf("/dev/ttyUSB0:Bytes in input buffer:%d\n", bytes_available);
close(fd);
return 0;
}
view raw fionread.c hosted with ❤ by GitHub

TransmitCode:(tcflush_output)


#include <stdio.h>
#include <sys/types.h>
#include <termios.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#define SERIAL_DEVICE "/dev/ttyUSB1"
int main()
{
struct termios serial_port_settings;
int fd;
int retval;
char *buf = NULL;
int bufsize = 0;
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_oflag |= OCRNL;
serial_port_settings.c_oflag |= OLCUC;
retval = tcsetattr(fd, TCSANOW, &serial_port_settings);
if (retval < 0) {
perror("Failed to set serial attributes");
exit(5);
}
printf("/dev/ttyUSB1:Successfully set the baud rate\n");
loop:
printf("/dev/ttyUSB1:Enter size of the buffer:");
scanf("%d", &bufsize);
if (bufsize <= 0) {
printf("Buffer size should be greater > 0\n");
goto loop;
}
buf = malloc(bufsize);
if (!buf) {
perror("Failed to allocate buffer\n");
exit(6);
}
memset(buf, 'A', bufsize);
buf[bufsize-2] = '\n';
buf[bufsize-1] = '\0';
retval = write(fd, buf, bufsize);
if (retval < 0) {
perror("write on SERIAL_DEVICE failed");
exit(7);
}
tcflush(fd, TCOFLUSH);
printf("/dev/ttyUSB1: Flushing output buffer\n");
free(buf);
close(fd);
return 0;
}

Output:



Comments

Popular posts from this blog

bb.utils.contains yocto

Difference between RDEPENDS and DEPENDS in Yocto

PR, PN and PV Variable in Yocto