StRiDeR
StRiDeR

Reputation: 170

C program setting port parameters before opening port fails

I am trying to write c code on a Linux system, where I set the serial port parameters then open the serial port, then I have found out that even though the code compiles and runs, I cannot read and write from that serial port (so the serial port was not opened successfully)!

Code that works (not needed):

int fd;
char *portname;
portname = "/dev/ttyUSB0";
struct termios tty;

fd = open(portname, O_RDWR | O_NOCTYY | O_SYNC );

memset(&tty,0,sizeof tty);
tty.c_cflag &= ~PARENB;
tty.c_cflag &= ~CSTOP;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_cflag &= ~CRTSCTS;
tcsetattr(fd,TCSANOW,&tty);

Code that doesn't work (needed)

int fd;
char *portname;
portname = "/dev/ttyUSB0";
struct termios tty;

memset(&tty,0,sizeof tty);
tty.c_cflag &= ~PARENB;
tty.c_cflag &= ~CSTOP;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_cflag &= ~CRTSCTS;
tcsetattr(fd,TCSANOW,&tty);

fd = open(portname, O_RDWR | O_NOCTYY | O_SYNC );

Solid question: My application sequence requires me to set serial port parameters then open the serial port. Is there a way to do this? if yes, how?

I appreciate your help.

Upvotes: 1

Views: 1205

Answers (1)

Gluttton
Gluttton

Reputation: 5958

Update: Removed C++ code noticed by @Alter Mann.
Update: Removed zeroing-out the termios structure noticed by @sawdust.

In first case you get actual file descriptor fd and after use it. In second case you try setting up uninitialized file descriptor fd (probably 0 if it's declared in global scope) and after get actual value of it.

Below is workaround which works for me:

#include <fcntl.h>
#include <termios.h>
#include <strings.h>
#include <stdlib.h>

int main (int argc, char * argv [])
{
    struct termios tty;
    const char * portname = "/dev/ttyUSB0";
    const int fd = open (portname, O_RDONLY);
    if (-1 == fd) {
        // Problem...
        return EXIT_FAILURE;
    }

    if (tcgetattr (fd, &tty) < 0) {
        // Problem...
        return EXIT_FAILURE;
    }

    cfsetospeed (&tty, (speed_t) B9600);
    cfsetispeed (&tty, (speed_t) B9600);

    tty.c_cflag |= B9600;
    tty.c_cflag |= (tty.c_cflag & ~CSIZE) | CS8;
    tty.c_cflag |= (CLOCAL | CREAD);
    tty.c_cflag &= ~(PARENB | PARODD);
    tty.c_cflag |= IGNPAR;
    tty.c_cflag &= ~(CRTSCTS);
    tty.c_cflag &= ~(CSTOPB);
    tty.c_iflag |= IGNBRK;
    tty.c_iflag &= ~(IXON | IXOFF | IXANY);
    tty.c_lflag  = 0;
    tty.c_oflag  = 0;

    tcflush (fd, TCIFLUSH);
    if (tcsetattr (fd, TCSANOW, &tty) ) {
        // Problem...
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

Upvotes: 3

Related Questions