dsch
asked on
Problems with overlapped Comms
Hi there every one.
I have written my owm com port class (as my version of Builder does not come with it) which works fine with non-overlapped IO.
However, I need to continually test for incomming bytes and deal with them as and when.
Therefore I created a new thread where I pass the handle to an open comm port. In the execute function of the thread I have the following code.
The problem is that after the WaitCommEvent() returns the call to readfile returns immediatly with no byes read.
The call to GetLastError() returns the error "The parameter is incorrect."
While it is waiting for the WaitCommEvent() I can still send on the port using my original class in the main thread.
Any Ideas and help would be great, I have taken the day off to try and sort this problem out. :o/ <stumpped!>
for(;;) {
if (WaitCommEvent(hCom, &dwCommEvent, NULL))
{
DWORD lpErrors;
COMSTAT lpStat;
do {
if (ReadFile(hCom, &a, 1, &ByteCount, NULL))
{ // A byte has been read; process it.
*Str1 = *Str1 + chRead ;
Form1->Memo1->Text = *Str1 ;//Memo1->Text + a;
count++;
}
else
{
// An error occurred in the ReadFile call.
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BU FFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSE RTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
// Display the string.
MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
// Free the buffer.
LocalFree( lpMsgBuf );
ClearCommError(
hCom, // handle to communications device
&lpErrors, // error codes
&lpStat // communications status
);
}
} while (lpStat.cbInQue>0);//(Byte Count);
}
// A byte has been read; process it.
else
{
}
}
I have written my owm com port class (as my version of Builder does not come with it) which works fine with non-overlapped IO.
However, I need to continually test for incomming bytes and deal with them as and when.
Therefore I created a new thread where I pass the handle to an open comm port. In the execute function of the thread I have the following code.
The problem is that after the WaitCommEvent() returns the call to readfile returns immediatly with no byes read.
The call to GetLastError() returns the error "The parameter is incorrect."
While it is waiting for the WaitCommEvent() I can still send on the port using my original class in the main thread.
Any Ideas and help would be great, I have taken the day off to try and sort this problem out. :o/ <stumpped!>
for(;;) {
if (WaitCommEvent(hCom, &dwCommEvent, NULL))
{
DWORD lpErrors;
COMSTAT lpStat;
do {
if (ReadFile(hCom, &a, 1, &ByteCount, NULL))
{ // A byte has been read; process it.
*Str1 = *Str1 + chRead ;
Form1->Memo1->Text = *Str1 ;//Memo1->Text + a;
count++;
}
else
{
// An error occurred in the ReadFile call.
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BU
FORMAT_MESSAGE_FROM_SYSTEM
FORMAT_MESSAGE_IGNORE_INSE
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
// Display the string.
MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
// Free the buffer.
LocalFree( lpMsgBuf );
ClearCommError(
hCom, // handle to communications device
&lpErrors, // error codes
&lpStat // communications status
);
}
} while (lpStat.cbInQue>0);//(Byte
}
// A byte has been read; process it.
else
{
}
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I think I've done what I should have done , but I still get the same result. (no bytes read)
Here is the revised version:
void __fastcall RS232RXThread::Execute()
{
DWORD ByteCount;
char a;
int count = 0;
bool Waiting = FALSE;
// Create the overlapped event. Must be closed before exiting
// to avoid a handle leak.
DWORD dwCommEvent=0;
DWORD dwCommMask = 0;
OVERLAPPED osReader;
memset(&osReader,0,sizeof( OVERLAPPED ));
dwCommMask = EV_RXCHAR;
SetCommMask(hCom, dwCommMask);
DWORD lpErrors;
COMSTAT lpStat;
ByteCount = 1;
LPVOID lpMsgBuf;
osReader.hEvent = CreateEvent(
NULL, // no security attributes
TRUE, // auto reset event
FALSE, // not signaled
NULL // no name
);
while(1) {
if(!Waiting)
{
if (!WaitCommEvent(hCom, &dwCommEvent, &osReader))
{
if (GetLastError() == ERROR_IO_PENDING)
//overlapped I/O-operation cannot be completed immediately operation in background)
{
Waiting = TRUE;
}
}
}
else
{
if (dwCommEvent & EV_RXCHAR)
{
/* ClearCommError(
hCom, // handle to communications device
&lpErrors, // error codes
&lpStat // communications status
); */
if(ReadFile(hCom, &a, 1, &ByteCount, NULL)) ;
{
// A byte has been read; process it.
*Str1 = *Str1 + a ;
Form1->Memo1->Text = *Str1 ;//Memo1->Text + a;
count++;
Waiting = FALSE;
dwCommEvent = 0;
// To do.
}
}
}// end else
}//end While
}//end of function
Here is the revised version:
void __fastcall RS232RXThread::Execute()
{
DWORD ByteCount;
char a;
int count = 0;
bool Waiting = FALSE;
// Create the overlapped event. Must be closed before exiting
// to avoid a handle leak.
DWORD dwCommEvent=0;
DWORD dwCommMask = 0;
OVERLAPPED osReader;
memset(&osReader,0,sizeof(
dwCommMask = EV_RXCHAR;
SetCommMask(hCom, dwCommMask);
DWORD lpErrors;
COMSTAT lpStat;
ByteCount = 1;
LPVOID lpMsgBuf;
osReader.hEvent = CreateEvent(
NULL, // no security attributes
TRUE, // auto reset event
FALSE, // not signaled
NULL // no name
);
while(1) {
if(!Waiting)
{
if (!WaitCommEvent(hCom, &dwCommEvent, &osReader))
{
if (GetLastError() == ERROR_IO_PENDING)
//overlapped I/O-operation cannot be completed immediately operation in background)
{
Waiting = TRUE;
}
}
}
else
{
if (dwCommEvent & EV_RXCHAR)
{
/* ClearCommError(
hCom, // handle to communications device
&lpErrors, // error codes
&lpStat // communications status
); */
if(ReadFile(hCom, &a, 1, &ByteCount, NULL)) ;
{
// A byte has been read; process it.
*Str1 = *Str1 + a ;
Form1->Memo1->Text = *Str1 ;//Memo1->Text + a;
count++;
Waiting = FALSE;
dwCommEvent = 0;
// To do.
}
}
}// end else
}//end While
}//end of function
In ReadFile you need to use overlapped structure 'osReader'
instead of NULL.
Also reset the event object. See my previous answer.
jlsjls
instead of NULL.
Also reset the event object. See my previous answer.
jlsjls
ASKER
Yes, I just noticed that after I submitted.
It all works perfectly,
Thank you very much (and also DAN), I have learnt a lot today. Now I can get on with the rest of the app.
Thanks again
David :o]
It all works perfectly,
Thank you very much (and also DAN), I have learnt a lot today. Now I can get on with the rest of the app.
Thanks again
David :o]
-- Dan