c - How to properly set up serial communication on Linux -


i'm attempting read , write data , fpga board. board came driver create terminal device called ttyusb0 whenever board plugged in. on fpga, asynchronous receiver , transmitter implemented, , seem work.

however, there seems issue on c side of things. i've been using test vectors test if fpga outputting proper information. i've noticed few things things:

  1. the device not open correctly
  2. the terminal attributes fail retrieved or set.
  3. the read non-blocking , doesn't retrieve proper value.

below how set terminal , file descriptor options. of taken here: http://slackware.osuosl.org/slackware-3.3/docs/mini/serial-port-programming

any advice or comments why program may failing helpful.

#include <stdio.h>   // standard input/output definitions #include <string.h>  // string function definitions #include <unistd.h>  // unix standard function definitions #include <fcntl.h>   // file control definitions #include <errno.h>   // error number definitions #include <termios.h> // posix terminal control definitions  int open_port(void){      int fd;    // file descriptor port     fd = open("/dev/ttyusb0", o_rdwr | o_noctty);      if (fd == -1){         fprintf(stderr, "open_port: unable open /dev/ttyusb0 %s\n",strerror(errno));         exit(exit_failure);     }      return (fd); }  int main(void){      int fd = 0;              // file descriptor     struct termios options;  // terminal options      fd = open_port();    // open tty device rd , wr      fcntl(fd, f_setfl);            // configure port reading     tcgetattr(fd, &options);       // current options port     cfsetispeed(&options, b230400);    // set baud rates 230400     cfsetospeed(&options, b230400);      options.c_cflag |= (clocal | cread);    // enable receiver , set local mode     options.c_cflag &= ~parenb;             // no parity bit     options.c_cflag &= ~cstopb;             // 1 stop bit     options.c_cflag &= ~csize;              // mask data size     options.c_cflag |=  cs8;                // select 8 data bits     options.c_cflag &= ~crtscts;            // disable hardware flow control        // enable data processed raw input     options.c_lflag &= ~(icanon | echo | isig);      // set new attributes     tcsetattr(fd, tcsanow, &options);      ////////////////////////////////////     // simple read , write code here//     ////////////////////////////////////      // close file descriptor & exit     close(fd)     return exit_success }   

update i've modified code based on first answer. have now:

#include <errno.h>      // error number definitions #include <stdint.h>     // c99 fixed data types #include <stdio.h>      // standard input/output definitions #include <stdlib.h>     // c standard library #include <string.h>     // string function definitions #include <unistd.h>     // unix standard function definitions #include <fcntl.h>      // file control definitions #include <termios.h>    // posix terminal control definitions  // open usb-serial port reading & writing int open_port(void){      int fd;    // file descriptor port     fd = open("/dev/ttyusb0", o_rdwr | o_noctty);      if (fd == -1){         fprintf(stderr, "open_port: unable open /dev/ttyusb0 %s\n",strerror(errno));         exit(exit_failure);     }      return fd; }  int main(void){      int              fd = 0;     // file descriptor     struct termios   options;    // terminal options     int              rc;         // return value      fd = open_port();            // open tty device rd , wr      // current options port     if((rc = tcgetattr(fd, &options)) < 0){         fprintf(stderr, "failed attr: %d, %s\n", fd, strerror(errno));         exit(exit_failure);     }      // set baud rates 230400     cfsetispeed(&options, b230400);      // set baud rates 230400     cfsetospeed(&options, b230400);      cfmakeraw(&options);     options.c_cflag |= (clocal | cread);   // enable receiver , set local mode     options.c_cflag &= ~cstopb;            // 1 stop bit     options.c_cflag &= ~crtscts;           // disable hardware flow control     options.c_cc[vmin]  = 1;     options.c_cc[vtime] = 2;      // set new attributes     if((rc = tcsetattr(fd, tcsanow, &options)) < 0){         fprintf(stderr, "failed set attr: %d, %s\n", fd, strerror(errno));         exit(exit_failure);     }      ////////////////////////////////         // simple read/write code here//         ////////////////////////////////      // close file descriptor & exit     close(fd);     return exit_success; }  

just clarify, receiver , transmitter use 8 data bits, 1 stop bit, , no parity bit.

i prefer serial programming guide posix operating systems.

you should delete fcntl(mainfd, f_setfl) statement, since it's not required , incorrectly implemented (f_getfl not done prior , missing third argument).

try using cfmakeraw setup non-canonical mode, since initialization code incomplete:

options->c_iflag &= ~(ignbrk | brkint | parmrk | istrip         | inlcr | igncr | icrnl | ixon); options->c_oflag &= ~opost;  

for non-canonical mode, need define

options.c_cc[vmin]  = 1; options.c_cc[vtime] = 2; 

1 , 2 suggested values.

add testing of return status after all system calls.

rc = tcgetattr(mainfd, &options); if (rc < 0) {     printf("failed attr: %d, %s\n", mainfd, strerror(errno));     exit (-3); } 

try testing slower baudrates (e.g. 115200 or 9600).


Comments

Popular posts from this blog

android - getbluetoothservice() called with no bluetoothmanagercallback -

sql - ASP.NET SqlDataSource, like on SelectCommand -

ios - Undefined symbols for architecture armv7: "_OBJC_CLASS_$_SSZipArchive" -