VC++ Serial Comm in Win7: CSerial Overlapped I/O operation error 997

Trips

Well-known member
Joined
Aug 7, 2010
Messages
2,788
Hello,
The serial device and the computer serial port its connected to are both functional since I was able to control the device via a terminal emulator.
I inherited a VC++ MFC project running on Windows 7 that uses the CSerial class (http://www.codeguru.com/cpp/i-n/network/serialcommunications/article.php/c2503). I cant send data to my serial device. CSerial::Open() is called first, apparently successfully
(since GetLastError() = 0 and my port monitor registers an OPEN request). But then when I send some data it ultimately results in an error 997, which apparently is "overlapped operation in progress".
Here is the relevant code. First, CSerial::Open,
<div style="color:Black;background-color:White; <pre>
BOOL CSerial::Open( <span style="color:Blue; int nPort, <span style="color:Blue; int nBaud, BOOL disableFlowCtrl )<br/>
{<br/>
<span style="color:Green; //MessageBox(NULL, "Got in CSerial::Open()", "CSerial Open",0); <br/>
<span style="color:Blue; if( m_bOpened ) <span style="color:Blue; return( TRUE );<br/>
<br/>
<span style="color:Blue; char szPort[15];<br/>
<span style="color:Blue; char szComParams[50];<br/>
DCB dcb;<br/>
<br/>
wsprintf( szPort, <span style="color:#A31515; "COM%d", nPort );<br/>
m_hIDComDev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );<br/>
<span style="color:Blue; if( m_hIDComDev == NULL ) MessageBox(NULL, <span style="color:#A31515; "m_hIDComDev == NULL, exiting !!! ", <span style="color:#A31515; "CSerial exit",0); <br/>
<span style="color:Blue; if( m_hIDComDev == NULL ) <span style="color:Blue; return( FALSE );<br/>
<br/>
memset( &m_OverlappedRead, 0, <span style="color:Blue; sizeof( OVERLAPPED ) );<br/>
memset( &m_OverlappedWrite, 0, <span style="color:Blue; sizeof( OVERLAPPED ) );<br/>
<br/>
COMMTIMEOUTS CommTimeOuts;<br/>
CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;<br/>
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;<br/>
CommTimeOuts.ReadTotalTimeoutConstant = 0;<br/>
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;<br/>
CommTimeOuts.WriteTotalTimeoutConstant = 5000;<br/>
SetCommTimeouts( m_hIDComDev, &CommTimeOuts );<br/>
<br/>
wsprintf( szComParams, <span style="color:#A31515; "COM%d:%d,N,8,1", nPort, nBaud );<br/>
<span style="color:Green; //MessageBox(NULL, "In CSerial::Open(), sent params", "sent CSerial params",0); <br/>
<br/>
<br/>
m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );<br/>
m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );<br/>
dcb.DCBlength = <span style="color:Blue; sizeof( DCB );<br/>
GetCommState( m_hIDComDev, &dcb );<br/>
dcb.BaudRate = nBaud;<br/>
dcb.ByteSize = 8;<br/>
<span style="color:Blue; unsigned <span style="color:Blue; char ucSet;<br/>
ucSet = (<span style="color:Blue; unsigned <span style="color:Blue; char) ( ( FC_RTSCTS & FC_DTRDSR ) != 0 );<br/>
ucSet = (<span style="color:Blue; unsigned <span style="color:Blue; char) ( ( FC_RTSCTS & FC_RTSCTS ) != 0 );<br/>
ucSet = (<span style="color:Blue; unsigned <span style="color:Blue; char) ( ( FC_RTSCTS & FC_XONXOFF ) != 0 );<br/>
<br/>
<br/>
<span style="color:Blue; if( !SetCommState( m_hIDComDev, &dcb ) ||<br/>
!SetupComm( m_hIDComDev, 10000, 10000 ) ||<br/>
m_OverlappedRead.hEvent == NULL ||<br/>
m_OverlappedWrite.hEvent == NULL ){<br/>
<br/>
<br/>
DWORD dwError = GetLastError();<br/>
CString errorString; <br/>
errorString.Format(<span style="color:#A31515; "DWORD value = %d", dwError);<br/>
MessageBox(NULL, errorString, <span style="color:#A31515; "DWORD error", 0) ;<br/>
<br/>
<br/>
<span style="color:Blue; if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );<br/>
<span style="color:Blue; if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );<br/>
CloseHandle( m_hIDComDev );<br/>
<span style="color:Blue; return( FALSE );<br/>
}<br/>
<br/>
m_bOpened = TRUE;<br/>
MessageBox(NULL, <span style="color:#A31515; "CSerial::Open() finished", <span style="color:#A31515; "CSerial finished",0); <br/>
DWORD dwError = GetLastError();<br/>
CString errorString; <br/>
errorString.Format(<span style="color:#A31515; "DWORD value = %d", dwError);<br/>
MessageBox(NULL, errorString, <span style="color:#A31515; "DWORD error", 0) ; <br/>
<span style="color:Blue; return( m_bOpened );<br/>
<br/>
}
[/code]

Next, SendData()
<div style="color:Black;background-color:White; <pre>
<span style="color:Blue; int CSerial::SendData( <span style="color:Blue; const <span style="color:Blue; char *buffer, <span style="color:Blue; int size )
{
MessageBox(NULL, <span style="color:#A31515; "got in SendData()", <span style="color:#A31515; "SendData()",0);
<span style="color:Blue; if (!m_bOpened) MessageBox(NULL, <span style="color:#A31515; "m_bOpened = FALSE !", <span style="color:#A31515; "m_bOpened", 0);
<span style="color:Blue; if (!m_hIDComDev == NULL ) MessageBox(NULL, <span style="color:#A31515; "m_hIDComDev == NULL", <span style="color:#A31515; "m_hIDComDev", 0);
<span style="color:Blue; if( !m_bOpened || m_hIDComDev == NULL ) MessageBox(NULL, <span style="color:#A31515; "PORT NOT OPENED !!!", <span style="color:#A31515; "SendData() without port",0);
<span style="color:Blue; if( !m_bOpened || m_hIDComDev == NULL ) <span style="color:Blue; return( 0 );


DWORD dwBytesWritten = 0;
<span style="color:Blue; int i;
<span style="color:Blue; for( i=0; i<size; i++ ){
WriteCommByte( buffer );
dwBytesWritten++;
}
<span style="color:Blue; return( (<span style="color:Blue; int) dwBytesWritten );

}
[/code]
Lastly, WriteCommByte(), where the 997 error actually occurs:


<div style="color:Black;background-color:White; <pre>
BOOL CSerial::WriteCommByte( <span style="color:Blue; unsigned <span style="color:Blue; char ucByte )
{
BOOL bWriteStat;
DWORD dwBytesWritten;
MessageBox(NULL, <span style="color:#A31515; "inside WriteCommByte", <span style="color:#A31515; "WriteCommByte",0);
bWriteStat = WriteFile( m_hIDComDev, (LPSTR) &ucByte, 1, &dwBytesWritten, &m_OverlappedWrite );
<span style="color:Blue; if( !bWriteStat && ( GetLastError() == ERROR_IO_PENDING ) ){
<span style="color:Blue; if( WaitForSingleObject( m_OverlappedWrite.hEvent, 1000 ) ) dwBytesWritten = 0;
<span style="color:Blue; else{
GetOverlappedResult( m_hIDComDev, &m_OverlappedWrite, &dwBytesWritten, FALSE );
m_OverlappedWrite.Offset += dwBytesWritten;
}
}
DWORD dwError = GetLastError();
CString errorString;
errorString.Format(<span style="color:#A31515; "DWORD value = %d", dwError);
MessageBox(NULL, errorString, <span style="color:#A31515; "DWORD error", 0) ;

<span style="color:Blue; return( TRUE );

}

[/code]
Im not understanding what is happening here: my program is the only thing talking to the device, and I havent sent any other request, there was just Open() then SendData().

Thanks for any thoughts you may have,
--Phu


View the full article
 
Back
Top