user2110605
user2110605

Reputation: 21

C How to use Asynchronous readFile

Hello I have a question about async reading from a comm port.

I have a function, which should read one byte asynchronous from a comm port. This Function is called about every 10ms. I tried to do it synchronous but a buffer overruns, because the function is called faster, than it can complete. Now i want to implement it asynchronous. But don't understand how it is working.

My Function call (is called every 10 ms):

// read one byte into receiveChar
bytesReceived = BSP_cliGetChar(&receiveChar);

The Function body

int BSP_cliGetChar(char *rxBuffer)
{
DWORD numOfBytesRead;
OVERLAPPED readOverlapped;
HANDLE hEvent;
BOOL fOverlapped;
char str[255];

hEvent = CreateEvent(NULL,    // default security attribute
                     TRUE,    // manual-reset event 
                     TRUE,    // initial state = signaled 
                     NULL);   // unnamed event object 

// set up overlapped structure fields
readOverlapped.Offset     = 0; 
readOverlapped.OffsetHigh = 0; 
readOverlapped.hEvent     = hEvent; 

if (!ReadFile(hComm, rxBuffer, 1, &numOfBytesRead, &readOverlapped))
{
  if (GetLastError() != ERROR_IO_PENDING)
  {
     // Some other error occurred while reading the file.
     ExitProcess(0);
  }
  else
     fOverlapped = TRUE;
}
else
{
  // Operation has completed immediately.
  fOverlapped = FALSE;
  return (int) numOfBytesRead;
}
while(!HasOverlappedIoCompleted(&readOverlapped))
{
   sprintf_s(str, "%d", &numOfBytesRead);
   OutputDebugString(str);
}

}

Now what i want is to read one byte from com port. If ERROR_IO_PENDING is returned, the calling function should continue. And only if one byte was received the BSP_cliGetChar function should return. The Problem is, that the method stays in the while loop, instead of continuing the calling procedure.

Anyone who has ideas how to solve this?

Thank you for your help.

Upvotes: 2

Views: 999

Answers (1)

Paul T
Paul T

Reputation: 336

I took your code and tossed it into a project with the following main function

BSP_cliGetChar(char *rxBuffer);

HANDLE hComm;

int main() {
    char buf;
    DWORD numRead;

    hComm = CreateFile(
        "COM2",
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        FILE_FLAG_OVERLAPPED,
        NULL);
    if (hComm == INVALID_HANDLE_VALUE)
    {
        printf("error createfile: %d\n", GetLastError());
        return 1;
    }

    do
    {
        BSP_cliGetChar(&buf);
        printf("%c", buf);
    } while (buf != 'X');

    CloseHandle(hComm);
    return 0;
}

I used Virtual Serial Port Driver to create a linked pair of COM Ports COM1 and COM2. I opened COM1 with PuTTY and then ran my program. As expected I sat in the HasOverlappedIoCompleted loop. As soon as I sent a character over PuTTY the loop exited and my character was printed.

This being said I don't know your environment and it could have something to do with your actual hardware and configuring your COM port correctly in your code. MSDN has great info on configuring your serial communications with special notice to the Device Control Block (DCB) Structure

Hope that helps. Maybe you can provide some more detail to your scenario.

Upvotes: 1

Related Questions