Linux - Embedded & Single-board computerThis forum is for the discussion of Linux on both embedded devices and single-board computers (such as the Raspberry Pi, BeagleBoard and PandaBoard). Discussions involving Arduino, plug computers and other micro-controller like devices are also welcome.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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.
Just do this on your linux desktop, take out all the complexities of yocto lets you use valgrind & gdb.
Get it working in the easy environment, then get it working in the difficult environment. (You can write that down as a rule for life).
Suggestion two.
strace is fantastic and lighweight enough to pull into yocto no problem.
Hello Cyent,
thanks for suggestion but was not possible test on PC but maybe I'found the problem.On Yocto is present putty with uncorrect settings. The ttymxc0 was set as serial port for console usage so during my test I recived a login request and this massege maybe caused the problem.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.