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
Post a Comment