繁体   English   中英

从串口C ++读取

[英]read from serial port c++

我有以下C ++代码,当我运行程序时,有时它可以工作,有时却不起作用!

我认为在有剩余数据要读取的情况下尝试打开串行端口时会出现问题。

有时,运行此程序后,它会使Windows XP意外重启! 它不是蓝屏,只是重启。

我正在使用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;
}

原因

我怀疑您的程序在此行崩溃了

tmp_receive[dwBytesRead+1]=END_OF_STRING;

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

tmp_receive[256] = END_OF_STRING;

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


解决方案

为了防止您的程序崩溃,我看到您有2个选择。 我不能说哪个更好,因为我不知道您期望接收的数据格式是什么,因此您将必须分析每个选项的结果并自己决定。

选项1

定义tmp_receive数组时,使用元素计数为257

选项#2

调用ReadFile(...)时从len减去2

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

附加信息

暂无
暂无

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

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