I've two application software running (sender and receiver) on 2 different booard comunicating beetween then via rs232 links The rs232 port on boths side has been configuarte in same way and sender side I've 2 second sleep between 2 trasmission. The data send is a simple counter and the sender increase its value every 2 seconds
What happens? it happens that after few packets recived the read() on receiver side return 0 with errno set to "Success" and none error on sender side. When the trasmission delay is 1 second, the read() return 0 after 9 or 10 messages and when set at 2 seconds this delay, the number of events before return 0 is around 4 or 5
Below the settings :
int Set_RS232_Params(int fd, speed_t speed)
{
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\n");
}
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\n");
}
}
/*set input baudrate */
if (error == 0)
{
v_ret = -1;
v_ret = cfsetispeed(&attribs, speed);
if (v_ret != 0)
{
error = 1;
printf("ERROR\n");
}
}
/*modify and save attributes */
if (error == 0)
{
/*CFLAG */
attribs.c_cflag &= ~PARENB;
attribs.c_cflag &= ~CSTOPB;
attribs.c_cflag &= ~CSIZE;
attribs.c_cflag |= CS8;
attribs.c_cflag &= ~CRTSCTS;
attribs.c_cflag |= CREAD;
attribs.c_cflag |= CLOCAL;
/*LFLAG */
attribs.c_lflag &= ~ECHO;
attribs.c_lflag &= ~ECHOE;
attribs.c_lflag &= ~ECHONL;
attribs.c_lflag &= ~ICANON;
attribs.c_lflag &= ~ISIG;
/*IFLAG */
attribs.c_iflag &= ~(IXON | IXOFF | IXANY);
attribs.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL);
/*OFLAG */
attribs.c_oflag &= ~OPOST;
attribs.c_oflag &= ~ONLCR;
/*VMIN and VTIME */
attribs.c_cc[VMIN] = 0;
attribs.c_cc[VTIME] = 0;
/*save attributes */
v_ret = -1;
v_ret = tcsetattr(fd, TCSANOW, &attribs);
if (v_ret != 0)
{
error = 1;
printf("ERROR\n");
}
}
return error;
}
Thanks
If you are going to assign all the parameters and flags in the
termiosstructure, then you had better to do normal assignments, instead of using&=and|=operators individually for each field.Should I have to do this full initialization, I should a
static struct termiosvariable already initialized with the full set of flags, and should not modify all the values one by one.For this you have two approaches:
&=at once, as in:and you'll augment readability of your code. Or
and then use it in your code.
Read()returns -1 on error, and then (and only then, in portable code) you can askerrnoabout the success/failure of a system call. A return value of 0 is only given byread()in case the end of input has been detected. As you have (supposedly) set your terminal to raw mode, Ctrl-D is no longer the END OF FILE control character, so you should never receive 0 as return (except if you have specified 0 as the size of the buffer toread()or if yourtcsetattr()call failed (which is something you don't say is happening)There's a case (which you actually are configuring) is when you assign both
VMINandVTIMEequal to zero (both) you will get the behaviour you describe in case you read the input line and there's no data already stored in the buffer. If you want to return only the available data, but block if there's no such available data, you have to useVMIN == 1andVTIME = 0(this is described in termios(3) manual page). That will return the available data if some is, but will block until data arrives (the first byte arriving will trigger the unblock into the read system call)You are recommended by this page on why you should send a complete, and verifiable example, so we can play around with your failing code in order to make a diagnostic, but I cannot go further, and it seems to me that the problem is not in this function, but elsewhere. Please read the page referenced above, as I cannot make a diagnostic without a full working program to test.