Solved

MFC ReadFile issue

Posted on 2002-04-23
12
1,490 Views
Last Modified: 2013-11-25
I am trying to write some software that will talk over a serial port, async, and in the background.

When I set up my port, I use overlaped comms cuz of the async...

     HANDLE com_port = CreateFile(
          "COM1",
          GENERIC_READ | GENERIC_WRITE,
          0,                                   // comm devices must be opened w/exclusive-access
          NULL,                              // no security attributes
          OPEN_EXISTING,                    // comm devices must use OPEN_EXISTING
          FILE_FLAG_OVERLAPPED,          // overlapped I/O
          NULL);                              // hTemplate must be NULL for comm devices

In this mode, I then setup timeouts and settings to the right speed etc.

I am able to connect a remote Hyperterm with a NULL modem cable and I can send data with write File...

     BOOL w = WriteFile(comms_channel,
          msg.buffer(),
          msg.length(),
          &written,
          &ov);

But I cannot receive data with a read file... (the overlap below is a different one to the one used for the write... I also tried using the same one, or none at all, all round)

          bResult = ReadFile(
               hCommPortHandle,     // handle to file to read from
               &chInputByte,       // pointer to buffer that receives data
               1,                         // number of bytes to read
               &iLengthRead,          // pointer to number of bytes read
               &ov);                    // pointer to overalp structure for data

Without an overlapped port, the read succeeds, but there is no data there... when I connect a local hyperterm... there is definately data in the receive buffer.

Microsoft documentation is pants with regard to the overlapped data stuff, and I cannot get it to work... there was an example of setting the ov.hEvent to be another handle and this is set when the read is finished... but there was no documentation for that either.

Anyone know how I can recieve data over a COM port under windows 2K/NT using a file handle asynchronously whilst writing on it.

Thanks
Nigel.
0
Comment
Question by:nigel5
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 5
12 Comments
 
LVL 3

Expert Comment

by:GGRUNDY
ID: 6962360
Have you tried FILE_FLAG_NO_BUFFERING|FILE_FLAG_OVERLAPPED?

Plus it isn't clear from your example that you are using the same "com_port" HANDLE for your read & write.
0
 

Author Comment

by:nigel5
ID: 6962387
Ah, the com_port handle does change thought the code... :)

It is the same port handle.

After giving the FILE_FLAG_NO_BUFFERING thing a go, still nothing. I sent down a several KB of keypresses, and nothing, when I loaded hyperterm back on the port,,, I got the last few dozen bytes.

Cheers
N.
0
 

Author Comment

by:nigel5
ID: 6962414
Sorry,  I should clarify my last comment, the port handle name does change throughout the code, but thats because I have 3 different threads running, wach using a differnet name... cuz I ripped the code out of the manual in different places.
0
SharePoint Admin?

Enable Your Employees To Focus On The Core With Intuitive Onscreen Guidance That is With You At The Moment of Need.

 
LVL 3

Expert Comment

by:GGRUNDY
ID: 6962424
hmmm - different treads operating on the same file. That's very gutsy. I would have assumed that one would do your open and start your asynchronous read and write off from the same thread and use WaitForMultipleObjects to handle the action.
If the o/s does anysort of "critical section" protection of it's file i/o code then a multitread access could well have problems.
0
 
LVL 3

Expert Comment

by:GGRUNDY
ID: 6962468
do you have an email address ?
cheers
ggrundy@bigpond.com
0
 

Author Comment

by:nigel5
ID: 6962474
I always get ERROR_IO_PENDING when I do a read file.

I have not set up the hEvent as I dunno how that works, and MS documentation is pants.
0
 
LVL 3

Expert Comment

by:GGRUNDY
ID: 6962497
I've knocked together some code
(untested because I can't be bothered setting up a null modem) which I can send you IF I have an email address.
0
 

Author Comment

by:nigel5
ID: 6962654
Currently at nigel.johnson@bt.com

Thanks.
N.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6964794
It is much easier to use synchronous operation.  All com port transactions are:

    send something
    wait for the expected reply or a timeout

so what needs to be asynchronous?

-- Dan
0
 

Author Comment

by:nigel5
ID: 6964862
I am building a generic comms wrapper for a serial command unit... basically remote comms for an autonymous vehicle. Both units share a data pool, and they have to keep the values synchronised. When a value changes at one end, it is broadcast and should change in all the other data pools.

I talk to the remote comms devices by RS232, and the problem is that I won't be requesting all the data to change... (the baud rate is 4K8, so that'd be eating bandwidth.)

In Solaris, async comms is probably one of the simplest things to do... mind you, so is using third party softwre like greenleaf or WFC... but I want to run on a PC (cuz of the GUI front end) and I don't want to deal with redistributing other peoples products.

Besides, once I have Async comms, I can make sync comms out of my base class. :)
0
 
LVL 3

Accepted Solution

by:
GGRUNDY earned 100 total points
ID: 6965262
Try this


  HANDLE vEvent[3]={CreateEvent(NULL, false, false, "Quit"),
                    CreateEvent(NULL, false, false, NULL),
                    CreateEvent(NULL, false, false, NULL)
                    };
  OVERLAPPED ov1={0}; ov1.hEvent = vEvent[1];
  OVERLAPPED ov2={0}; ov2.hEvent = vEvent[2];
  char zOut[] = "hello";
  char zIn[2];

  DWORD dwWritten;
  DWORD dwRead;
  BOOL isOK;

  HANDLE hPort =
ateFile(
         "COM2",
         GENERIC_READ | GENERIC_WRITE,
         0,                                   // comm devices must be opened
w/exclusive-access
         NULL,                              // no security attributes
         OPEN_EXISTING,                    // comm devices must use
OPEN_EXISTING
         FILE_FLAG_OVERLAPPED|FILE_FLAG_NO_BUFFERING ,             //
overlapped I/O
         NULL);                              // hTemplate must be NULL for
comm devices


     isOK = WriteFile(hPort,   zOut,  lstrlen(zOut),  &dwWritten,  &ov1);
     isOK = ReadFile( hPort,   zIn,   1,   &dwRead,  &ov2);  
   
     bool isMore = true;
     do{
        DWORD dw = WaitForMultipleObjects(3, vEvent, false, INFINITE);
       dw -= WAIT_OBJECT_0 ;
       switch(dw){
         case 0:isMore = false; break;
         case 1:{
           isOK = WriteFile(hPort,  zOut,  lstrlen(zOut),  &dwWritten,
&ov1);
           break;
           }


         case 2:{
          TRACE("0x%02x\n", zIn[0]);
           isOK = ReadFile( hPort,  zIn,  1,  &dwRead,  &ov2);
           break;
           }
         }
       }while(isMore);

  CancelIo(hPort);





0
 

Author Comment

by:nigel5
ID: 6965983
Thanks. with some jiggling with my threads, that did it.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
no14 challenge 14 73
Window placement 17 95
firstChar challenge 13 133
Please explain the parts of these 2 LINQ expressions 3 85
Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
A theme is a collection of property settings that allow you to define the look of pages and controls, and then apply the look consistently across pages in an application. Themes can be made up of a set of elements: skins, style sheets, images, and o…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…

733 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