Click here to Skip to main content
15,893,588 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi
I would like to receive data via async serial port from another server by coding VC++.

I use the ReadFile() function like as this:

char buf[1024];
size = 1;

ReadFile (hComm, buf, size, dwRead, 0);

This can receive data one byte and one byte sequentially.

But any action during receiving may lost the data from above port in the case of thread change or faster baudrate.

So I would change the state from signalled state to event driven using overlapped structure variable.

As a novice, It is very difficult for me to find sample of ReadFile() using last parameter overlapped.

To receive safely, I was recommened that "using overlapped variable" in the ReadFile() do not lost any character in the serial commnication - is this right?

So, please let me know the method with right sample of it.

Thank you.

What I have tried:

More 1 week wasted for this problem.
Posted
Updated 22-Oct-17 21:45pm

I don't know whay you wasted a week doing, but it took Google 1 second to find Synchronization and Overlapped Input and Output (Windows)[^].
 
Share this answer
 
A simplified example and descriptions can be found at Serial Communications[^].

When using overlapped I/O, you have to pass an overlapped structure to all ReadFile() and WriteFile() calls. For each operation that might be in a pending state you have to create an event, place the event handle in the corresponding overlapped structure, call WaitForSingleObject() / WaitForMultipleObjects() and GetOverlappedResult() when the event occured.

But with serial receiving it is often not predictable how many bytes may be received. Then you might also use serial events to be notified when data has been arrived. To do this call SetCommMask() with EV_RXCHAR and optionally EV_ERR, and in the receive loop WaitCommEvent() passing another overlapped structure. I have provided sample code once in this CP solution: Serial Communication issue[^]

Upon the EV_RXCHAR and EV_ERR events call then ClearCommError() to check for errors and get the number of available bytes. When passing the number of available bytes from the above to ReadFile(), you can simple use an empty overlapped structure there because the call will return immediately (no pending). When using the code from my above solution it should look like:
// At begin of receive thread function
OVERLAPPED ovRead = {0};

// Inside loop after waiting
if (nEvent & (EV_RXCHAR | EV_ERR))
{
    DWORD dwComErrors = 0;
    COMSTAT tComStat;
    ::ClearCommError(m_hCom, &dwComErrors, &tComStat);
    if (dwComErrors)
    {
        // handle error here
    }
    if (tComStat.cbInQue)
    {
        DWORD dwRead;
        // Ensure that pBuf is large enough.
        // If not, read and process data in chunks.
        // This call will succeed (no pending) because we know how many data
        //  are available.
        // So we can pass an empty overlapped structure here.
        ::ReadFile(m_hCom, pBuf, tComStat.cbInQue, &dwRead, &ovRead);
    }
}

Quote:
To receive safely, I was recommened that "using overlapped variable" in the ReadFile() do not lost any character in the serial commnication - is this right?
That is not right because the internal receive buffer may still overrun when receive events are not handled in time.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900