Serial Port Programming Part 2 - Canonical Mode vs Non-Canonical Mode
MIN and TIME |
Behavior |
MIN = 0, TIME = 0 |
Read returns immediately with as many characters available in the queue, up to the number requested. If no characters in the queue, read returns 0 |
MIN = 0, TIME > 0 |
Read waits for TIME time for input to become available, if we receive a single character in the TIME duration, read returns immediately. It returns as many characters up to the number requested. If timer expires and there is no receive characters, read returns 0 |
MIN > 0, TIME = 0 |
Read waits until at least MIN bytes are available in the input queue. At the time, read returns as many characters are available up to the number requested. |
MIN > 0, TIME > 0 |
Read returns until either MIN bytes have arrived in input queue, or TIME elapses with no further input. read always block until the first character arrives, even if TIME elapses first. |
Note: '\r' is Carriage Return , '\n' is Line Feed
canonical_write.c:
#include <stdio.h> | |
#include <sys/types.h> | |
#include <termios.h> | |
#include <fcntl.h> | |
#include <stdlib.h> | |
#define SERIAL_DEVICE "/dev/ttyUSB1" | |
int main() | |
{ | |
struct termios serial_port_settings; | |
int fd; | |
int retval; | |
char buf[256] = "hello world \n bye\n"; | |
char ch; | |
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_oflag &= ~ONLCR; | |
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"); | |
for (i = 0; buf[i] != '\0'; i++) { | |
ch = buf[i]; | |
printf("Writing character :%c ASCII:%d\n", ch, ch); | |
retval = write(fd, &ch, sizeof(ch)); | |
if (retval < 0) { | |
perror("write on SERIAL_DEVICE failed"); | |
exit(6); | |
} | |
sleep(1); | |
} | |
close(fd); | |
return 0; | |
} |
canonical_read.c:
#include <stdio.h> | |
#include <sys/types.h> | |
#include <termios.h> | |
#include <fcntl.h> | |
#include <stdlib.h> | |
#define SERIAL_DEVICE "/dev/ttyUSB0" | |
int main() | |
{ | |
struct termios serial_port_settings; | |
int fd; | |
int retval; | |
char buf[256]; | |
int i, loop = 2; | |
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; | |
//Disable ECHO | |
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 (loop--) { | |
retval = read(fd, buf, sizeof(buf)); | |
if (retval < 0) { | |
perror("Read on SERIAL_DEVICE failed"); | |
exit(6); | |
} | |
printf("Read returned %d bytes\n", retval); | |
for (i = 0; i < retval; i++) { | |
printf("Read Character:%c \t ASCII:%d\n", buf[i], buf[i]); | |
} | |
} | |
close(fd); | |
return 0; | |
} |
#include <stdio.h> | |
#include <sys/types.h> | |
#include <termios.h> | |
#include <fcntl.h> | |
#include <stdlib.h> | |
#define SERIAL_DEVICE "/dev/ttyUSB0" | |
int main() | |
{ | |
struct termios serial_port_settings; | |
int fd; | |
int retval; | |
char buf[256]; | |
int i, loop = 10; | |
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); | |
} | |
//Disable ECHO | |
serial_port_settings.c_lflag &= ~(ICANON); | |
serial_port_settings.c_lflag &= ~(ECHO | ECHOE); | |
serial_port_settings.c_cc[VMIN] = 2; | |
serial_port_settings.c_cc[VTIME] = 10; | |
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 (loop--) { | |
retval = read(fd, buf, sizeof(buf)); | |
if (retval < 0) { | |
perror("Read on SERIAL_DEVICE failed"); | |
exit(6); | |
} | |
printf("Read returned %d bytes\n", retval); | |
for (i = 0; i < retval; i++) { | |
printf("Read Character:%c \t ASCII:%d\n", buf[i], buf[i]); | |
} | |
} | |
close(fd); | |
return 0; | |
} |
#include <stdio.h> | |
#include <sys/types.h> | |
#include <termios.h> | |
#include <fcntl.h> | |
#include <stdlib.h> | |
#define SERIAL_DEVICE "/dev/ttyUSB1" | |
int main() | |
{ | |
struct termios serial_port_settings; | |
int fd; | |
int retval; | |
char buf[256] = "hello world \n bye\n"; | |
char ch; | |
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_oflag &= ~ONLCR; | |
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"); | |
for (i = 0; buf[i] != '\0'; i++) { | |
ch = buf[i]; | |
printf("Writing character :%c ASCII:%d\n", ch, ch); | |
retval = write(fd, &ch, sizeof(ch)); | |
if (retval < 0) { | |
perror("write on SERIAL_DEVICE failed"); | |
exit(6); | |
} | |
sleep(1); | |
} | |
close(fd); | |
return 0; | |
} |
You can observe when you run the code, for each two characters transmitted, read returns with data
Whoops, sorry I'm mistaken, you simply swapped the code and the headline :D
ReplyDeleteSeems like my first comment was lost in the void, now this one sounds a bit dumb...
Delete