I have the following C++ code and when I run the program sometimes it works and sometimes it does not!
I think the problem occurs when I try to open the serial port while there is data left to be read.
Sometimes after running this program, it makes Windows XP restart unexpectedly! It does not Blue Screen, it justs restarts.
I am using Visual Studio 2010 to compile it.
main()
{
while(0) { // BIG FAT WARNING: MIGHT SUDDEN REBOOT YOUR MACHINE IF ENABLED
read_from_serial(_data);
}
}
bool read_from_serial(octed_string &_data)
{
HANDLE hSerial;
hSerial = CreateFile(TEXT("COM2"),
GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if (hSerial == INVALID_HANDLE_VALUE)
{
if (GetLastError() == ERROR_FILE_NOT_FOUND)
{
cout << "1:";
return false;
//serialportdoesnotexist.Informuser.
}
cout << "2:";
return false;
//someothererroroccurred.Informuser.
}
DCB dcbSerialParams = {0};
dcbSerialParams.DCBlength=sizeof(dcbSerialParams);
if(!GetCommState(hSerial,&dcbSerialParams))
{
cout<<"3:";
return false;
//errorgettingstate
}
dcbSerialParams.BaudRate=CBR_9600;
dcbSerialParams.ByteSize=7;
dcbSerialParams.StopBits=ONESTOPBIT;
dcbSerialParams.Parity=EVENPARITY;
if (!SetCommState(hSerial,&dcbSerialParams))
{
cout<<"4:";
return false;
//errorsettingserialportstate
}
COMMTIMEOUTS timeouts={0};
timeouts.ReadIntervalTimeout=50;
timeouts.ReadTotalTimeoutConstant=10;
timeouts.ReadTotalTimeoutMultiplier=10;
timeouts.WriteTotalTimeoutConstant=50;
timeouts.WriteTotalTimeoutMultiplier=10;
if (!SetCommTimeouts(hSerial,&timeouts))
{
cout<<"5:";
return false;
//erroroccureed.Informuser
}
const int n=1;
DWORD dwBytesRead=0;
char_t tmp_receive[255]={0};
char_t buff[255];
int len=255;
if (!ReadFile(hSerial,tmp_receive,len,&dwBytesRead,NULL))
{
cout<<"6:";
CloseHandle(hSerial);
return false;
}
CloseHandle(hSerial);
tmp_receive[dwBytesRead+1]=END_OF_STRING;
string tmp_buff_str=tmp_receive;
_data.append(tmp_buff_str);
return true;
}
Cause
I have a suspicion that your program is crashing on this line
You defined the
tmp_receivearray with255elements, which makes the possible indexes0to254. You then initializedlento255. If there are 255 bytes available to read on the call toReadFile(...), thendwBytesReadwill be equal to255and the line I mentioned above will effectively be as follows, and would mean you’re attempting to write to memory outside of the scope of thetmp_receivearray.As for the rebooting, I don’t know for sure, but maybe your program is causing a system crash when it attempts to write to invalid memory and you have Windows XP configured to reboot instead of displaying a BSOD.
Solutions
In order to keep your program from crashing I see that you have 2 options. I can’t say which one is better since I don’t know what the format of the data you’re expecting to receive is, so you will have to analyize the outcomes of each option and decide for yourself.
Option #1
Use an element count of
257when defining thetmp_receivearray.Option #2
Subtract 2 from
lenwhen making the call toReadFile(...)Additional Information
Have a look at the MSDN documentation on
ReadFile(...)for more information on the behaviour of theReadFile(...)Windows API.If you would like to learn more about how strings are stored in memory, I would suggest having a look at the Character Sequences article on http://www.cplusplus.com.