Hello,

I have one application that reads and writes from the serial port.

Sometimes the function read():
"read(fd,buffer,numbytes)" returns before than read bytes reachs numbytes. (Because there are more data in the serial port buffer)
I mean. if numbytes is 32, sometimes read returns 12, and in the next read returns the 20 remaining.

I want to avoid that and I want that "read()" does not return until reads all the numbytes.

Some ideas?

I have tried to "open()" with different configurations but all the time "read()" does not wait until reads everything.

Also I have thought about to change the mode from the default one "byte-stream" to " message-nondiscard" but when I try to use the functions:
ioctl(fd,I_SRDOPT,param)
ioctl(fd,I_GRDOPT,param)
both functions returns -1 with errno = EINVAL and I do not know if it is bercause I set badly the parameters or is because "Stream is linked under a multiplexing driver" (REALLY I DO NOT WHAT THIS MEANS).

Here I write how I use ioctl:

int a;
ioctl(fd,I_GRDOPT,&a); -> //fails -1 and errno = EINVAL

ioctlfd,I_SRDOPT,RMSGN) > //fails -1 and errno = EINVAL.

So if I am using correctly both functions, could somebody explain me the error:
"[EINVAL] fd refers to a Stream that is linked under a multiplexing driver. If a Stream is linked under a multiplexing driver, all ioctl(2s) commands other than I_UNLINK or I_PUNLINK will return [EINVAL]. "?

How can I do that "read()" waits until all the bytes are read as requiered?

Thank you.

You didn't state exactly which POSIX OS you're using.

It's easy enough to create a myRead() which just calls read() in a loop until it's got the required number of bytes.

That is not a solution for me, because I need to receive all the data at once.
e.g: if I want to read 20 bytes, I want to read the 20 at once, because the buffer_receive is a struct of bit fields, so then is easy to recognize which data is which.

If I receive those 20 using two read(), i.e. for example in the first I read 12 and in the second I read 8. Then I do not know to recognize what data are the 8 left.

Above is one example, sometimes the first read can be 12 another 14, ... Thats why I want to do "read()" does not return until having all the 20 bytes required.

Thank you.

If you know you want exactly 20 bytes from incoming data then your program should just wait until it gets all 20 bytes before proceeding. That means it will have to sit in a loop waiting for incoming data at the port. The input buffer should be just an unsigned char array rather than a structure.

For this to work you will have to compile with 0 packing.

#pragma pack(0)
void GetData(unsigned char* buffer)
{
top of loop
   read port
   add data to tail of buffer
   have we read 20 bytes yet
   No, then delay a bit and return to top of loop
   yes, exit loop
end of loop
}

int main()
{
    struct bitfields bf;
    GetData((unsigned char*)&bf);
}
Comments
Exactamundo!

AD's pseudo-code is exactly what I said.

Yup -- but apparently he didn't understand what you meant. For that matter, he may not understand my pseudo code either :)

This article has been dead for over six months. Start a new discussion instead.