简体   繁体   中英

read from serial port c++

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

tmp_receive[dwBytesRead+1]=END_OF_STRING;

You defined the tmp_receive array with 255 elements, which makes the possible indexes 0 to 254 . You then initialized len to 255 . If there are 255 bytes available to read on the call to ReadFile(...) , then dwBytesRead will be equal to 255 and 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 the tmp_receive array.

tmp_receive[256] = END_OF_STRING;

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 257 when defining the tmp_receive array.

Option #2

Subtract 2 from len when making the call to ReadFile(...)

if (!ReadFile(hSerial,tmp_receive,len-2,&dwBytesRead,NULL))

Additional Information

  • Have a look at the MSDN documentation on ReadFile(...) for more information on the behaviour of the ReadFile(...) 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 www.cplusplus.com .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM