c - Serial port programming in Linux -


i want use rs232 port on board communicate pc. understand can use "dev/ttys0" purpose.

i can open , write data pc using write() function. problem i can't read "dev/ttys0". every time use read function, "resource temporarily unavailable". can u guys tell me how solve problem?

here code:

#include <stdio.h> #include <string.h> #include <fcntl.h> #include <termios.h> #include <unistd.h>  int main() {     int n = 0, fd = 0, bytes = 0;     char ch = 0;      char buffer[10], *bufptr;     int nbytes = 0, tries = 0, x = 0;      struct termios term;      fd = open("/dev/ttys0", o_rdwr | o_noctty | o_ndelay);      if (fd == -1)     {         perror("open");         return;     }     else     {         fcntl(fd, f_setfl, 0);         perror("port");     }      if (n = tcgetattr(fd, &term) == -1)     {         perror("tcgetattr");         return;     }      if (n = cfsetispeed(&term, b115200) == -1)     {         perror("cfsetispeed");         return;     }      if (n = cfsetospeed(&term, b115200) == -1)     {         perror("cfsetospeed");         return;     }      term.c_cflag |= (clocal | cread);     term.c_cflag &= ~parenb;     term.c_cflag &= ~cstopb;     term.c_cflag &= ~csize;     term.c_cflag |= cs8;     term.c_lflag &= ~(icanon | echo | echoe | isig);     term.c_iflag &= ~(ixon | ixoff | ixany);     term.c_cflag &= ~crtscts;     term.c_oflag &= ~opost;       if (n = tcsetattr(fd, tcsanow, &term) == -1)     {         perror("tcsetattr");         return;     }      write(fd,"linux",5);     perror("write");      fcntl(fd, f_setfl, fndelay);         perror("fcntl");     bytes = read(fd, buffer, sizeof(buffer));     perror("read");     printf("bytes : %d , data: %s\n", bytes, buffer); } 

what test? shortcutting pin 2 , 3 of rs232 db9 connector?

otherwise read return -1 if there no data read.

this code supposed using o_ndelay flag opening serial line.

to avoid read if there no data read, use select in case:

struct timeval tv; fd_set rset; int retv; int timeout = 5000; // 5 seconds  tv.tv_usec = (timeout * 1000) % 1000000; tv.tv_sec = timeout / 1000;  fd_zero ( &rset ); fd_set (  fd, &rset ); retv = select ( fd+1, &rset, null, null, &tv );  if( retv == 0 ) {    // timeout stuff } else if( retv < 0 ) {     // error stuff. read errno see happened } else {    // read data } 

edit

remove fcntl(fd, f_setfl, fndelay); if want normal blocking read, unset flag.

in code assuming read return sent chars not true. read return chars available read. means if send "linux" 5 times read requested read 5 chars sent.

last thing

printf("bytes : %d , data: %s\n", bytes, buffer); 

is undefined behavior because of buffer not null terminated string. solve looping on received chars , print %c format, or null terminating buffer with:

if (bytes > 0)    buffer[bytes] = '\0'; 

or

char stringtosend[] = "linux"; size_t len = strlen(stringtosend) +1 ;  write(fd,"linux", len); perror("write");  size_t receivedbytes = 0; bytes = 0; while (receivedbytes<len) {    bytes = read(fd, &buffer[receivedbytes], sizeof(buffer)-1);    perror("read");     if (bytes > 0)        receivedbytes += bytes; }  printf("bytes : %d , data: %s\n", receivedbytes, buffer); 

Comments

Popular posts from this blog

php - Wordpress website dashboard page or post editor content is not showing but front end data is showing properly -

How to get the ip address of VM and use it to configure SSH connection dynamically in Ansible -

javascript - Get parameter of GET request -