ejj
June 14th, 2005, 04:27 PM
I have the following code, which works just great on Windows 2000. I've installed this on a clients machine which is Windows XP SP2, and I've had nothing but problems. The application will run for about 15 - 20 minutes and then blow up.
The application read data from the serial port until it gets a return ('\r') character, then processes that data. Processing the data works great, its just accessing the serial port I'm having problems with. I'm using non-overlapped IO because all I need to do is read a packet (~40 bytes) and process it. Just the main thread will access the serial port, and it will only read from the port, no writing.
Here's the code:
Main function
hCom = CreateFile(COM_Port,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if((DWORD)hCom == 0x0 || (DWORD)hCom == INVALID_HANDLE_VALUE)
{
MessageBox(NULL, "Could not open COM port", "COM Error", MB_OK);
return 0;
}
//
// Create and fill the DCB
//
ZeroMemory(dcb, sizeof(DCB));
BuildCommDCB(COM_Settings, dcb);
SetCommState(hCom, dcb);
SetCommMask(hCom, EV_RXCHAR | EV_RXFLAG); //EV_RXCHAR EV_DSR
//
// Set the timeouts so we can read what's going on
//
ZeroMemory(cto, sizeof(COMMTIMEOUTS));
cto->ReadIntervalTimeout = MAXDWORD;
SetCommTimeouts(hCom, cto);
//
// Start reading from the COM port
//
while(bRunning)
{
ZeroMemory(buff, BUFFER_SIZE);
//
// Blocking read of the serial port
//
BlockReadToTerm(hCom, buff, '\r', BUFFER_SIZE);
if(strlen(buff) > 0)
{
//
// Process this string
//
RecHandler(buff);
}
} //while(bRunning)
The problem seems to be in the BlockReadToTerm function.
BlockReadToTerm
DWORD x=0;
CHAR b[2];
DWORD n=0;
CHAR lChar = '\0';
DWORD lpEvent=0;
DWORD r=0;
DWORD dwEvtMask=0;
DWORD nZeroCount=0;
ZeroMemory(b, 2);
while(lChar != term && x <= buff_size)
{
if(nZeroCount == 10)
{
//
// If we've tried 10 reads and got nothing
// wait until the serial port says that it
// has something for us to read!
//
WaitCommEvent(h, &dwEvtMask, NULL);
nZeroCount = 0;
}
if(n == 0)
{
Sleep(100);
}
r = ReadFile(h, b, 1, &n, NULL);
if(n>0)
{
lChar = b[0];
buffer[x] = lChar;
x++;
}
else
{
lChar = '\0';
nZeroCount++;
}
} //while
It usually craps out during a call to WaitCommEvent. Windows launches it "Watson" window with information that seems rather useless.
Any advice would be great!
The application read data from the serial port until it gets a return ('\r') character, then processes that data. Processing the data works great, its just accessing the serial port I'm having problems with. I'm using non-overlapped IO because all I need to do is read a packet (~40 bytes) and process it. Just the main thread will access the serial port, and it will only read from the port, no writing.
Here's the code:
Main function
hCom = CreateFile(COM_Port,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if((DWORD)hCom == 0x0 || (DWORD)hCom == INVALID_HANDLE_VALUE)
{
MessageBox(NULL, "Could not open COM port", "COM Error", MB_OK);
return 0;
}
//
// Create and fill the DCB
//
ZeroMemory(dcb, sizeof(DCB));
BuildCommDCB(COM_Settings, dcb);
SetCommState(hCom, dcb);
SetCommMask(hCom, EV_RXCHAR | EV_RXFLAG); //EV_RXCHAR EV_DSR
//
// Set the timeouts so we can read what's going on
//
ZeroMemory(cto, sizeof(COMMTIMEOUTS));
cto->ReadIntervalTimeout = MAXDWORD;
SetCommTimeouts(hCom, cto);
//
// Start reading from the COM port
//
while(bRunning)
{
ZeroMemory(buff, BUFFER_SIZE);
//
// Blocking read of the serial port
//
BlockReadToTerm(hCom, buff, '\r', BUFFER_SIZE);
if(strlen(buff) > 0)
{
//
// Process this string
//
RecHandler(buff);
}
} //while(bRunning)
The problem seems to be in the BlockReadToTerm function.
BlockReadToTerm
DWORD x=0;
CHAR b[2];
DWORD n=0;
CHAR lChar = '\0';
DWORD lpEvent=0;
DWORD r=0;
DWORD dwEvtMask=0;
DWORD nZeroCount=0;
ZeroMemory(b, 2);
while(lChar != term && x <= buff_size)
{
if(nZeroCount == 10)
{
//
// If we've tried 10 reads and got nothing
// wait until the serial port says that it
// has something for us to read!
//
WaitCommEvent(h, &dwEvtMask, NULL);
nZeroCount = 0;
}
if(n == 0)
{
Sleep(100);
}
r = ReadFile(h, b, 1, &n, NULL);
if(n>0)
{
lChar = b[0];
buffer[x] = lChar;
x++;
}
else
{
lChar = '\0';
nZeroCount++;
}
} //while
It usually craps out during a call to WaitCommEvent. Windows launches it "Watson" window with information that seems rather useless.
Any advice would be great!