Solved

Com Ports

Posted on 1997-04-21
2
1,518 Views
Last Modified: 2013-12-04
Hi,

I've been using the following code to open and read data from a com port

      h = CreateFile("Com1",
                           GENERIC_READ|GENERIC_WRITE,
                           0,NULL,
                           OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);

      if(h == INVALID_HANDLE_VALUE) {
         PrintError("Failed to open port",ComNumber);
         return;
      }

***** To read from the port

      COMMTIMEOUTS cto = { 2, 1, 1, 0, 0 };
            
      if(!SetCommTimeouts(h,&cto))
            PrintError("SetCommTimeouts failed",ComNumber);


      // create event for overlapped I/O
   osRead.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
   if(osRead.hEvent == INVALID_HANDLE_VALUE)
      PrintError("CreateEvent failed", ComNumber);

   // wait for received characters
   if(!SetCommMask(h,EV_RXCHAR | EV_RLSD))
      PrintError("SetCommMask failed", ComNumber);

   Finished=FALSE;
   while( !Finished ) {
      // get the event mask
      if( !WaitCommEvent(h,&mask,&osRead) ) {
         DWORD e = GetLastError();
         if( e == ERROR_IO_PENDING ) {
            DWORD r;
            if( !GetOverlappedResult(h,&osRead,&r,TRUE) ) {
               PrintError("GetOverlappedResult failed",ComNumber);
               break;
            }
         } else {
            PrintError("WaitCommEvent failed", ComNumber);
            break;
         }
      }

      // if no event, then UI thread terminated with SetCommMask(h,0)
      if( mask == 0 ) {
         return ExitThread;
      }

      if( mask & EV_RLSD)
        {
              return CDLost;
        }
        else{
         char buf[10];
         DWORD read;

   

             do {
                  memset(buf,'\0',sizeof(buf));
             read = 0;
            if( !ReadFile(h,buf,sizeof(buf),&read,&osRead) ) {
               if( GetLastError() == ERROR_IO_PENDING ) {
                  if( !GetOverlappedResult(h,&osRead,&read,TRUE) ) {
                     PrintError("GetOverlappedResult failed", ComNumber);
                     break;
                  }
               } else {
                  PrintError("ReadFile failed", ComNumber);
                  break;
               }
            }
            if(read)
                  {
*** We have some data

All works ok.  The routine waits until data is received then reads it in.  If their is a change in CD signal this is also recognised.

The problem I have is I wish the GetOverlappedresult function to return after a set time interval.   Whether there is any data or not.

I have tried the following

      COMMTIMEOUTS cto = { 200, 1, 3000, 0, 0 };


    if(!SetCommTimeouts(h,&cto))
        PrintError("SetCommTimeouts failed",ComNumber);            
        if( !ReadFile(h,buf,MaxCharNumber,&read,&osRead) ) {
                        PrintError("ReadFile failed", ComNumber);
                        return FALSE;
                        break;
                  }

            if (read)
            {
            *** We have data      

Which works as required. I.E if after 3 seconds no data is received ReadFile returns with read=0, if data is received ReadFile returns straight away with the data.

But.  If i call  ReadFile again it returns straight away even when there is no data,  How do I get it to perform as it does the first time i called ReadFile.

Or can I change the first example code so that  GetOverLappedResult returns after a set interval.
      
0
Comment
Question by:Robert888
2 Comments
 
LVL 15

Expert Comment

by:NickRepin
ID: 1334703
Can you post source code with ReadFile and comments for what ReadFile(), GetOverlappedResult(), GetLastError() returns in each case?
0
 
LVL 3

Accepted Solution

by:
Melange earned 100 total points
ID: 1334704
   Instead of immediately calling GetOverlappedResult after WaitCommEvent, wait on your event object with WaitForSingleObject. You can set the timeout period for waiting on the event in milliseconds in the call to WaitForSingleObject.
    Also I would recommend using a manual reset event when doing timeouts. This way if you do timeout, you can still check the status of the event later on without having to worry about missing it.
    Once you get a signalled event (not a timeout), call ResetEvent and then call GetOverlappedResult. Since the operation should now be completed, GetOverlappedResult will now return immediately with the requested info (either success or failure). If you need more info, let me know.
0

Featured Post

Simplifying Server Workload Migrations

This use case outlines the migration challenges that organizations face and how the Acronis AnyData Engine supports physical-to-physical (P2P), physical-to-virtual (P2V), virtual to physical (V2P), and cross-virtual (V2V) migration scenarios to address these challenges.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

This article describes how to use the timestamp of existing data in a database to allow Tableau to calculate the prior work day instead of relying on case statements or if statements to calculate the days of the week.
Let’s list some of the technologies that enable smooth teleworking. 
This video demonstrates how to use each tool, their shortcuts, where and when to use them, and how to use the keyboard to improve workflow.
The viewer will learn how to successfully download and install the SARDU utility on Windows 7, without downloading adware.

840 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question