Solved

Com Ports

Posted on 1997-04-21
2
1,514 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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

I previously wrote an article addressing the use of UBCD4WIN and SARDU. All are great, but I have always been an advocate of SARDU. Recently it was suggested that I go back and take a look at Easy2Boot in comparison.
In our personal lives, we have well-designed consumer apps to delight us and make even the most complex transactions simple. Many enterprise applications, however, are a bit behind the times. For an enterprise app to be successful in today's tech wo…
An overview on how to enroll an hourly employee into the employee database and how to give them access into the clock in terminal.
XMind Plus helps organize all details/aspects of any project from large to small in an orderly and concise manner. If you are working on a complex project, use this micro tutorial to show you how to make a basic flow chart. The software is free when…

743 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now