From: bicoman on 24 Feb 2005 14:37 "Scott McPhillips [MVP]" wrote: > bicoman wrote: > >>>>I'm having a problem with my serial port routines that does not make any > >>>>sense to me. > >>>>I originally wrote the code to use non-overlapped serial port reading and > >>>>writing. It works great. (the serial port anyway). The problem is the > >>>>waitcommevent method hangs the program and it quits responding. Now for the > >>>>weird part. When I go to overlapped io in CreateFile with > >>>>FILE_FLAG_OVERLAPPED, my serial port stops reading. The program isn't hung > >>>>anymore, and the connected device is definetly transmitting the appropriate > >>>>bytes, the waitCommEvent function just quits seeing them. I know that > >>>>WaitCommEvent is timing out because I checked. I've been fighting with this > >>>>problem all day and am at my wits end. Has anyone ever had a similar problem? > >>> > >>Ian, > >>Thanks for taking the time to respond to this. Here is my code > >>... > > The basic problem is that you don't understand what overlapped I/O does. > When you use it WaitCommEvent is supposed to "fail" and return > quickly, with ERROR_IO_PENDING. This means the operation is continuing > in the background. The purpose is to let your code do other things > while waiting. But you are not doing "other things." Later, when the > background operation has completed, the event in the overlapped struct > will be signaled. But your code is not checking this event. > > It is also very inefficient and slow to wait for one character to be > signaled, then call ReadFile to get the one character. The characters > can arrive faster than an awkward program like this can process them. > Instead, you can simply call ReadFile and it will return when it has the > requested number of characters. > > Either of these approaches will, however, block the GUI thread, so the > port should be read in a separate thread. I suggest you use the code > from the MTTTY sample in MSDN. It shows how to very efficiently input > from the serial port and send the results back to the main thread. > > -- > Scott McPhillips [VC++ MVP] > > Scott, Thanks, I revised the code, it still is not detecting the event, GetOverlappedResult only returns WAIT_TIMEOUT even though bytes have arrived. Here is my newest attempt. bool PickDialog::waitForAnswer(CString* answer){ BicoOutput* bco = new BicoOutput(); OVERLAPPED overlapped; DWORD dwEventMask; DWORD iBytesRead; MSG msg; HANDLE hCom; bool readOnGoing = TRUE; DWORD readResult; DWORD dwRead; char buffer[5]; ddata.getCommDefaults(&cp); //Get comm settings commPort = sp.openPortForReading(cp); //openPort with FILE_FLAG_OVERLAPPED sp.clearCommErrors(commPort); if(!SetCommMask(commPort,EV_RXCHAR)) AfxMessageBox("Failed to Set Communication Mask"); overlapped.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); overlapped.Internal = 0; overlapped.InternalHigh = 0; overlapped.Offset = 0; overlapped.OffsetHigh = 0; assert(overlapped.hEvent); while(readOnGoing){ readResult = WaitForSingleObject(overlapped.hEvent,READ_TIMEOUT); switch(readResult){ case WAIT_OBJECT_0 + 1: f(!GetOverlappedResult(commPort,&overlapped,&dwRead,FALSE)){ ReadFile(commPort,&buffer[0],MESSAGE_SIZE,&iBytesRead,&overlapped); answer->Insert(0,&buffer[0]); AfxMessageBox(*answer); readOnGoing = FALSE; break; } else{ AfxMessageBox("Error reading serial port in WaitForAnswer"); break; } case WAIT_TIMEOUT: PeekMessage(&msg,NULL,0,0,PM_REMOVE); if(msg.message == WM_LBUTTONDOWN){ AfxMessageBox("Exiting Pick"); pickOngoing = FALSE; readOnGoing = FALSE; } break; default: AfxMessageBox("Error waiting to receive bytes in WaitForAnswer"); } } sp.closePort(commPort); ddata.~DefaultData(); return TRUE; }
From: Ian Semmel on 25 Feb 2005 14:19 Scott McPhillips suggested you look at the MTTTY sample in the documentation. Did you do this ? Get the sample working before you go any further. bicoman wrote: > > "Scott McPhillips [MVP]" wrote: > > >>bicoman wrote: >> >>>>>>I'm having a problem with my serial port routines that does not make any >>>>>>sense to me. >>>>>>I originally wrote the code to use non-overlapped serial port reading and >>>>>>writing. It works great. (the serial port anyway). The problem is the >>>>>>waitcommevent method hangs the program and it quits responding. Now for the >>>>>>weird part. When I go to overlapped io in CreateFile with >>>>>>FILE_FLAG_OVERLAPPED, my serial port stops reading. The program isn't hung >>>>>>anymore, and the connected device is definetly transmitting the appropriate >>>>>>bytes, the waitCommEvent function just quits seeing them. I know that >>>>>>WaitCommEvent is timing out because I checked. I've been fighting with this >>>>>>problem all day and am at my wits end. Has anyone ever had a similar problem? >>>>> >>>>Ian, >>>>Thanks for taking the time to respond to this. Here is my code >> >> >>... >> >>The basic problem is that you don't understand what overlapped I/O does. >> When you use it WaitCommEvent is supposed to "fail" and return >>quickly, with ERROR_IO_PENDING. This means the operation is continuing >>in the background. The purpose is to let your code do other things >>while waiting. But you are not doing "other things." Later, when the >>background operation has completed, the event in the overlapped struct >>will be signaled. But your code is not checking this event. >> >>It is also very inefficient and slow to wait for one character to be >>signaled, then call ReadFile to get the one character. The characters >>can arrive faster than an awkward program like this can process them. >>Instead, you can simply call ReadFile and it will return when it has the >>requested number of characters. >> >>Either of these approaches will, however, block the GUI thread, so the >>port should be read in a separate thread. I suggest you use the code >>from the MTTTY sample in MSDN. It shows how to very efficiently input >>from the serial port and send the results back to the main thread. >> >>-- >>Scott McPhillips [VC++ MVP] >> >>Scott, > > Thanks, I revised the code, it still is not detecting the event, > GetOverlappedResult only returns WAIT_TIMEOUT even though bytes have arrived. > Here is my newest attempt. > > bool PickDialog::waitForAnswer(CString* answer){ > > BicoOutput* bco = new BicoOutput(); > OVERLAPPED overlapped; > DWORD dwEventMask; > DWORD iBytesRead; > MSG msg; > HANDLE hCom; > bool readOnGoing = TRUE; > DWORD readResult; > DWORD dwRead; > char buffer[5]; > > ddata.getCommDefaults(&cp); //Get comm settings > commPort = sp.openPortForReading(cp); //openPort with > FILE_FLAG_OVERLAPPED > sp.clearCommErrors(commPort); > > if(!SetCommMask(commPort,EV_RXCHAR)) > AfxMessageBox("Failed to Set Communication Mask"); > > overlapped.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); > overlapped.Internal = 0; > overlapped.InternalHigh = 0; > overlapped.Offset = 0; > overlapped.OffsetHigh = 0; > assert(overlapped.hEvent); > > while(readOnGoing){ > readResult = WaitForSingleObject(overlapped.hEvent,READ_TIMEOUT); > switch(readResult){ > case WAIT_OBJECT_0 + 1: > f(!GetOverlappedResult(commPort,&overlapped,&dwRead,FALSE)){ > > ReadFile(commPort,&buffer[0],MESSAGE_SIZE,&iBytesRead,&overlapped); > answer->Insert(0,&buffer[0]); > AfxMessageBox(*answer); > readOnGoing = FALSE; > break; > } > else{ > AfxMessageBox("Error reading serial port in WaitForAnswer"); > break; > } > case WAIT_TIMEOUT: > PeekMessage(&msg,NULL,0,0,PM_REMOVE); > if(msg.message == WM_LBUTTONDOWN){ > AfxMessageBox("Exiting Pick"); > pickOngoing = FALSE; > readOnGoing = FALSE; > } > break; > default: > AfxMessageBox("Error waiting to receive bytes in > WaitForAnswer"); > } > } > > sp.closePort(commPort); > ddata.~DefaultData(); > return TRUE; > > > } >
First
|
Prev
|
Pages: 1 2 3 Prev: Really simple questions re CSliderCtrl Next: CEdit - Updating without Scrolling |