INFO: Serial Communications on Windows CE HPC devices

ID: Q175551

The information in this article applies to:

SUMMARY

Unlike other Win32 platforms, the Windows CE serial driver is implemented as overlapped. This means it can handle multiple concurrent I/O requests even though file handles must be opened as non-overlapped.

MORE INFORMATION

On most Win32 platforms, the I/O manager serializes non-overlapped serial communications. This implies that if there is an I/O request that is blocked, any subsequent I/O request will also be blocked until the pending I/O request completes. This is true even if each request was made from a separate thread.

While the Windows CE API does not support overlapped I/O, the serial driver is implemented as overlapped, that is, it can handle multiple concurrent I/O requests even though file handles are opened as non-overlapped. Therefore, serial communications programs on Windows CE devices have the following implementation option, which will not work on other Win32 platforms. A reading thread may call WaitCommEvent and when a RX_CHAR event arrives then call ReadFile to read characters from the port. The exact amount of data to read can be obtained by calling ClearCommError. A separate thread may simultaneously write to the port without hanging. The following sample code demonstrates this read technique.

Sample Code

   DWORD WINAPI
   ReadThread (LPVOID pvarg)
   {
     DWORD   BytesTransferred;
     DWORD   fdwCommMask;
     DWORD   dwErrors;
     COMSTAT Stat;
     COMMTIMEOUTS CommTimeouts;
     DWORD   t;
     BYTE    ReadBuffer[1024];

     GetCommTimeouts (hPort, &CommTimeouts);
     CommTimeouts.ReadIntervalTimeout = MAXDWORD;
     CommTimeouts.ReadTotalTimeoutMultiplier = 0;
     CommTimeouts.ReadTotalTimeoutConstant = 0;  // Read timeout at 50msec
     SetCommTimeouts (hPort, &CommTimeouts);

     SetCommMask (hPort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD | EV_RING);

     while (!v_bStopThread) {
        WaitCommEvent (hPort, &fdwCommMask, 0);

        // Reset the comm Mask
        SetCommMask (hPort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RING);

        if (fdwCommMask & EV_RXCHAR) {
            // Loop getting data.

         // Need to loop because our buffer is only 1024 bytes
                while (TRUE)
                {
                    ClearCommError( hPort,&dwErrors,&Stat);
                    if (!Stat.cbInQue)
                        break;
                    else
                    {
                        ReadFile (  hPort,
                                    &ReadBuffer,
                                    (Stat.cbInQue>1024)?1024:Stat.cbInQue,
                                    &BytesTransferred,
                                    0
                                    );
                            // do something with data
                    }
                   // Loop around and check for more data
                   // In case additional byte has arrived while reading.
                }
        }

     }

     return 0;
   }

Additional query words:
Keywords          : kbAPI kbKernBase kbWinCE kbComPort 
Version           : WINNT:
Platform          : winnt
Issue type        : kbinfo

Last Reviewed: July 4, 1998