Article 6CVR2 rs232 read() return 0 on YOCTO

rs232 read() return 0 on YOCTO

by
ratataplam
from LinuxQuestions.org on (#6CVR2)
Hello all,
I try to put in service the communication on RS232 between two board with ARM and Linux Yocto
here my scratch software to better explain my needs
Code:#include <linux/types.h>
#include <linux/input.h>
#include <fcntl.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <poll.h>
#include <sys/wait.h>
#include <termios.h>

#define CDH_NO_ERROR 0
#define CDH_READ_ERROR 1
#define CDH_EOF_ERROR 2
#define CDH_EINTR_ERROR 3
#define CDH_WRITE_ERROR 4
#define CDH_POLL_ERROR 5

int writer(void);
int reader(void);
int Set_RS232_Params( int fd, speed_t speed, unsigned char vmin, unsigned char vtime );
int fdh_readn( int fd_desc, void *read_buf, size_t total_bytes, size_t *bytes_ltr );
int fdh_writen( int fd_desc, void *write_buf, size_t total_bytes, size_t *bytes_ltw );

int main(int argc, char *argv[])
{

int role = atoi(argv[1]);

if (role==1)
writer();
else if(role==2)
reader();
else
{
printf(" exit from main\n");
}

}

int reader(void)
{

printf( "--> %s\n", __FUNCTION__);

int fd_rs232=-1;
unsigned int v_rs232msg =0,ev=0;
struct pollfd fds[1];
int poll_status = 0;
size_t bytes_ltr = 0; // byte left in read operation. If >0 there is an error
size_t bytes_ltw = 0; // byte left in write operation. If >0 there is an error
int error = -1;
/* open serial */
fd_rs232 = open( "/dev/ttymxc0", O_RDWR | O_NOCTTY | O_SYNC|O_NONBLOCK ); // O_NONBLOCK removed because it can cause errors
if( fd_rs232 < 0 )
{
error = 1;
printf( "ERROR: Open error %s\n", strerror(errno));
exit(1);
}
else
{
error = 0;
printf( "None error on open: %s\n", strerror(errno));
}
error = Set_RS232_Params( fd_rs232, B19200,sizeof(v_rs232msg),0);
fcntl(fd_rs232, F_SETFL, 0); /* set blocking mode */
printf( " after settings: %s\n", strerror(errno));
fds[0].fd = fd_rs232;
fds[0].events = POLLIN;

while(1)
{
printf( "poll trace: %s\n", strerror(errno));
poll_status = poll(fds, 1, -1);
if( poll_status < 0 )
{
error = 1;
printf("-- %s poll error error=%s \n",strerror(errno));
}

if( poll_status == 0 )
{
printf("-- %s poll tmout error=%s \n",strerror(errno));
}

if( fds[0].revents & POLLIN )
{
error = fdh_readn( fds[0].fd , &v_rs232msg, sizeof(v_rs232msg), &bytes_ltr );
printf("-- read errno=%s v_rs232msg = %u event counter %i\n",strerror(errno),v_rs232msg,ev++);
v_rs232msg=0; // clean the buffer
}
}

} //int reader(void)

int writer(void)
{
printf( "--> %s\n", __FUNCTION__ );
int error = -1;
int fd_rs232=-1;
unsigned int v_rs232msg =0;

struct pollfd fds[1];
int poll_status = 0;
size_t bytes_ltw = 0; // byte left in write operation. If >0 there is an error

/* open serial */
fd_rs232 = open( "/dev/ttymxc0", O_RDWR | O_NOCTTY | O_SYNC ); // O_NONBLOCK removed because it can cause errors
if( fd_rs232 < 0 )
{
error = 1;
printf( "ERROR: Open error %s\n", strerror(errno));
exit(1);
}
else
{
error = 0;
}
error = Set_RS232_Params( fd_rs232, B19200,sizeof(v_rs232msg),0);
fds[0].fd = fd_rs232;
fds[0].events = POLLIN;

while( 1 )
{
poll_status = poll(fds, 1, 2000);
if( poll_status < 0 )
{
error = CDH_POLL_ERROR;
printf("-- poll error %s\n",strerror(errno));
}

else if( poll_status == 0 )
{
printf("-- time out %s\n",strerror(errno));
error = fdh_writen( fd_rs232 , &v_rs232msg, sizeof(v_rs232msg), &bytes_ltw );
v_rs232msg=v_rs232msg+1;
printf("-- write %s v_rs232msg %i\n",strerror(errno),v_rs232msg);
}

}

printf( "<-- %s\n", __FUNCTION__ );

} //int writer(void)

int Set_RS232_Params( int fd, speed_t speed, unsigned char vmin, unsigned char vtime )
{
int error = 0;
int v_ret = -1;
struct termios attribs;

/*get attributes */
v_ret = tcgetattr(fd, &attribs);
if (v_ret != 0)
{
error = 1;
printf("ERROR in tcgetattr %s\n",strerror(errno));
}
else
{
error = 0;
}

/*set output baudrate */
if (error == 0)
{
v_ret = -1;
v_ret = cfsetospeed(&attribs, speed);
if (v_ret != 0)
{
error = 1;
printf("ERROR in cfsetospeed %s\n",strerror(errno));
}
}

/*set input baudrate */
if (error == 0)
{
v_ret = -1;
v_ret = cfsetispeed(&attribs, speed);
if (v_ret != 0)
{
error = 1;
printf("ERROR in cfsetispeed %s\n",strerror(errno));
}
}

/*modify and save attributes */
if (error == 0)
{
/*CFLAG */
attribs.c_cflag &= ~(PARENB | CSTOPB | CSIZE | CRTSCTS);
attribs.c_cflag |= CS8 | CREAD | CLOCAL;
/*LFLAG */
attribs.c_lflag &= ~(ECHO | ECHOE | ECHONL | ICANON | ISIG);
/*IFLAG */
attribs.c_iflag &= ~(IXON | IXOFF | IXANY | IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL);
/*OFLAG */
attribs.c_oflag &= ~(OPOST | ONLCR);
/*VMIN and VTIME */
attribs.c_cc[VMIN] = vmin;
attribs.c_cc[VTIME] = vtime;
/*save attributes */
v_ret = -1;
v_ret = tcsetattr(fd, TCSANOW, &attribs);
if (v_ret != 0)
{
error = 1;
printf("ERROR in tcsetattr %s\n",strerror(errno));
}
}

return error;
}

int fdh_readn( int fd_desc, void *read_buf, size_t total_bytes, size_t *bytes_ltr )
{
int error = -1;
size_t bytes_left = 0; // total bytes left to read
ssize_t bytes_read = 0; // bytes read each time by the 'read' function

bytes_left = total_bytes;

while( ( bytes_left > 0 ) && ( error != CDH_READ_ERROR ) && ( error != CDH_EOF_ERROR ) ) // repeat until no left
{
if( ( bytes_read = read( fd_desc, read_buf, bytes_left ) ) < 0 ) // if interrupted by system call...
{
if( errno == EINTR )
{
error = CDH_EINTR_ERROR; // ...try to read again...
printf( "EINTR error \n");
}
else
{
error = CDH_READ_ERROR; // ...otherwise exit
printf( "ERROR: Read error %s\n", strerror(errno));
}
}
else if( bytes_read == 0 ) // end of file
{
error = CDH_EOF_ERROR; // it means that client closed connection
printf( "WARNING: EOF file descriptor %d errno = %s \n", fd_desc,strerror(errno));
}
else
{
error = CDH_NO_ERROR;
}

/* (see REMARKS) */
if( error == CDH_NO_ERROR )
{
bytes_left -= bytes_read; // set left to read
read_buf += bytes_read; // set pointer
printf( "INFO: %lu bytes left out of %lu bytes total (in %s, row %d)\n", bytes_left, total_bytes, __FUNCTION__, __LINE__ );
}
}

if(bytes_ltr != NULL)
{
*bytes_ltr = bytes_left;
}

printf( "<-- %s\n", __FUNCTION__ );
return error;
}

int fdh_writen( int fd_desc, void *write_buf, size_t total_bytes, size_t *bytes_ltw )
{
printf( "--> %s\n", __FUNCTION__ );
int error = -1;
size_t bytes_left = 0; // total bytes left to write
ssize_t bytes_written = 0; // bytes written each time by the 'write' function

bytes_left = total_bytes;

while( ( bytes_left > 0 ) && ( error != CDH_WRITE_ERROR ) ) // repeat until no left
{
if( ( bytes_written = write( fd_desc, write_buf, bytes_left ) ) < 0 ) // if interrupted by system call...
{
if( errno == EINTR )
{
error = CDH_EINTR_ERROR; // ...try to write again...
printf( "WARNING: EINTR error %s \n", strerror(errno));
}
else
{
error = CDH_WRITE_ERROR; // ...otherwise exit the loop
printf( "ERROR: Write error %s fd=%i \n", strerror(errno),fd_desc);
}
}
else
{
error = CDH_NO_ERROR;
}
if( error == CDH_NO_ERROR )
{
bytes_left -= bytes_written; // set byte left to write
write_buf += bytes_written; // increment pointer

printf( "INFO: %lu bytes left out of %lu bytes total \n", bytes_left, total_bytes);
}
}

if(bytes_ltw != NULL)
{
*bytes_ltw = bytes_left;
}

printf( "<-- %s\n", __FUNCTION__ );
return error;
}Now happen that the board where run the reader receives wrong data (casual number) but with the same frequency of the sender and this for a while (more or less 15 messages) and after the read() function return 0 and goes in freerunning. The dump of errno varialble doesn't report any error and also none error is detected on writer side.

Any suggestion about how solve this problem?

Thanks
External Content
Source RSS or Atom Feed
Feed Location https://feeds.feedburner.com/linuxquestions/latest
Feed Title LinuxQuestions.org
Feed Link https://www.linuxquestions.org/questions/
Reply 0 comments