简体   繁体   English

从串口C ++读取

[英]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! 我有以下C ++代码,当我运行程序时,有时它可以工作,有时却不起作用!

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! 有时,运行此程序后,它会使Windows XP意外重启! It does not Blue Screen, it justs restarts. 它不是蓝屏,只是重启。

I am using Visual Studio 2010 to compile it. 我正在使用Visual Studio 2010进行编译。

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 . 您使用255元素定义了tmp_receive数组,这使可能的索引从0254 You then initialized len to 255 . 然后,您将len初始化为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. 如果在调用ReadFile(...)有255个字节可读取,则dwBytesRead将等于255 ,而我上面提到的行将有效地如下所示,这意味着您正在尝试向外部写入内存tmp_receive数组的范围。

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 . 至于重启,我不确定,但是当您尝试写入无效的内存并且您将Windows XP配置为重启而不显示BSOD时,您的程序可能会导致系统崩溃。


Solutions 解决方案

In order to keep your program from crashing I see that you have 2 options. 为了防止您的程序崩溃,我看到您有2个选择。 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 选项1

Use an element count of 257 when defining the tmp_receive array. 定义tmp_receive数组时,使用元素计数为257

Option #2 选项#2

Subtract 2 from len when making the call to ReadFile(...) 调用ReadFile(...)时从len减去2

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. 有关ReadFile(...) Windows API行为的更多信息,请ReadFile(...)上的MSDN文档。

  • 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 . 如果您想了解有关如何将字符串存储在内存中的更多信息,建议您访问www.cplusplus.com上的Character Sequences文章。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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