1

I am understanding Canonical Mode for serial port, read will only return until a new line character is met by the input queue.

I connected two PL2303 USB to serial device (TX -> RX, RX->TX)

Wrote two C Codes one for Receiving from /dev/ttyUSB0 and other from writing from /dev/ttyUSB1

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 test \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 9600 output baud rate");
        exit(3);
    }
    retval = cfsetispeed(&serial_port_settings, B38400);
    if (retval < 0) {
        perror("Failed to set 9600 input baud rate");
        exit(4);
    }
    serial_port_settings.c_lflag |= ICANON; 
    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 9600 output baud rate");
        exit(3);
    }
    retval = cfsetispeed(&serial_port_settings, B38400);
    if (retval < 0) {
        perror("Failed to set 9600 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;
}

When running both the programs, the first read successfully returns "hello world", but the second read returns "\n" ASCII 10.

The expected behavior is to return "test" right. Did I miss any settings while configuring ttyUSB0 in canonical_read.c

When I replace the buffer with

char buf[256] = "hello world \r test \n";

I get the proper output.

Thanks for your help and time

md.jamal
  • 4,067
  • 8
  • 45
  • 108
  • Note error messages "Failed to set 9600" seem dubious with `B38400`. – chux - Reinstate Monica Jan 27 '19 at 04:18
  • I solved the problem by adding serial_port_settings.c_oflag &= ~ONLCR; to canonical_write.c – md.jamal Jan 27 '19 at 05:03
  • *"Did I miss any settings while configuring ttyUSB0 in canonical_read.c"* -- See https://stackoverflow.com/questions/41224496/working-with-linux-serial-port-in-c-not-able-to-get-full-data/41252962#41252962 – sawdust Jan 27 '19 at 07:40

0 Answers0