Serial Port Programming Part 5 - tcflush - TCIFLUSH,TCOFLUSH example
tcflush flushes/discards
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)
TransmitCode:(tcflush_output)
Output:
- 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:
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 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; | |
} |
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)
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 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; | |
} |
TransmitCode:(tcflush_output)
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 <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
Post a Comment