Неожиданное поведение во время последовательной связи на устройстве - PullRequest
0 голосов
/ 02 июня 2019

"Я пишу программу, которая записывает данные на синхронную операцию последовательной связи com-порта, и операция чтения также является синхронной, когда переводит режим сна в режим записи после записи, он работает нормально, но если удалить режим сна, я получаю некоторые неправильные данные, которые 0x20 занимают место, не все данные неверны но какой-то байт "

Я добавил записываемый файл и файл чтения, которые я использовал, а также создаю файл, пожалуйста, сообщите, где я не прав

int CCommLink::WriteComm (HANDLE hComm, void* pBuf, int iLen, DWORD dwTimeToWait, UINT nBaud)
{

    OVERLAPPED ol;
    memset (&ol, 0, sizeof(OVERLAPPED));
    ol.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);

    COMSTAT ComStat;
    DWORD dwErrorFlags, dwBytesWrite;

    // ---------------------------------------------------------------------
    // clear the buffer
    // ---------------------------------------------------------------------
    ClearCommError (hComm, &dwErrorFlags, &ComStat);
    dwBytesWrite = (DWORD)ComStat.cbOutQue;

    if (dwBytesWrite)
    {
        DWORD dwTickCount = GetTickCount();
        do
        {
            ClearCommError (hComm, &dwErrorFlags, &ComStat);
            dwBytesWrite = (DWORD)ComStat.cbOutQue;
        } while ( dwBytesWrite && GetTickCount() - dwTickCount < 
 dwTimeToWait);
    }



    // ----------------------------------------------------------------
    // write the data to the serial port
    // ---------------------------------------------------------------------
    if (!WriteFile (hComm, pBuf, iLen, &dwBytesWrite, NULL))
    {
        if (GetLastError() == ERROR_IO_PENDING)
        {
//          GetOverlappedResult(hComm, &ol, &dwBytesWrite, TRUE);
            WaitForSingleObject (ol.hEvent, iLen * 40000 / nBaud);
            dwBytesWrite = iLen;
        }
        else
        {
//          CString cs = GetLastErrorStr();
            return 0;
        }
    }


    return dwBytesWrite;    
}




******************* read file function************************


int CCommLink::ReadComm (HANDLE hComm, void* pBuf, DWORD dwTimeToWait, UINT nBaud, DWORD dwBytesToRead)
{

//  dwTimeToWait=100;
    OVERLAPPED ol;
    memset (&ol, 0, sizeof(OVERLAPPED));
    ol.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);

    COMSTAT ComStat;
    DWORD dwErrorFlags, dwBytesRead;

    ClearCommError (hComm, &dwErrorFlags, &ComStat);
    dwBytesRead = (DWORD)ComStat.cbInQue;


    if (!dwBytesRead)
    {
        if (!dwTimeToWait)
            return 0;

        DWORD dwTickCount = GetTickCount();
        do
        {
            ClearCommError (hComm, &dwErrorFlags, &ComStat);
            dwBytesRead = (DWORD)ComStat.cbInQue;
        } while (!dwBytesRead && GetTickCount() - dwTickCount < dwTimeToWait);
    }

    if (!dwBytesRead)
        return -1;

    if (dwBytesRead > dwBytesToRead)
        dwBytesRead = dwBytesToRead;
    (void)memset((void *)pBuf, ' ', (size_t)256);


    if (!ReadFile (hComm, pBuf, 1, &dwBytesRead,  NULL))
    {

        LogResult(_T("********************************************ERROR WHILE READING ***********************************************"));
        if (GetLastError() == ERROR_IO_PENDING)
        {
            DWORD w = (32*10000) / nBaud;
            if (!w)
                w = 16;
            WaitForSingleObject (ol.hEvent, w);
            dwBytesRead = 1;
        }
        else
            dwBytesRead = 0;
    }

    CString str=  LogStr((unsigned char*)pBuf ,1);
    LogResult(str);

      //   pBuf=(void*)UxRx; 
    if (!dwBytesRead)
    {
//      CString cs = GetLastErrorStr();
        return -2;
    } 

    return (int)dwBytesRead;
}





HANDLE CCommLink::SetComm (int iPort, UINT nBaud, int Parity, int StopBits)
{

    // ---------------------------------------------------------------------
    // open a port handle
    // ---------------------------------------------------------------------
    CString cPort;
    if (iPort < 10)
        cPort.Format(_T("COM%d"), iPort);
    else
        cPort.Format(_T("\\\\.\\COM%d"), iPort);

    HANDLE hPort = CreateFile(
        cPort,
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
         0,// FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
        NULL);

    if (INVALID_HANDLE_VALUE == hPort)
        return INVALID_HANDLE_VALUE;

    // ---------------------------------------------------------------------
    // set communication buffer size
    // ---------------------------------------------------------------------
    if (!SetupComm(hPort, eSize_LinkBuffer*2, eSize_LinkBuffer*2))          // h,in,out
    {
        CloseHandle (hPort);
        return INVALID_HANDLE_VALUE;
    }

    // ---------------------------------------------------------------------
    // set timeout contants
    // ---------------------------------------------------------------------
    COMMTIMEOUTS CommTimeOuts;

    CommTimeOuts.ReadIntervalTimeout = MAXDWORD;
    CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
    CommTimeOuts.ReadTotalTimeoutConstant = 0;
    CommTimeOuts.WriteTotalTimeoutMultiplier = 80000/nBaud ? 80000/nBaud : 1;
    CommTimeOuts.WriteTotalTimeoutConstant = CommTimeOuts.WriteTotalTimeoutMultiplier * 8;

    if( !SetCommTimeouts(hPort, &CommTimeOuts) )
    {
        CloseHandle (hPort);
        return INVALID_HANDLE_VALUE;
    }

    // ---------------------------------------------------------------------
    // set port configurations
    // ---------------------------------------------------------------------
    DCB dcb;                                // Initialize the DCBlength member. 
    dcb.DCBlength = sizeof (DCB);           // Get the default port setting information.
    GetCommState (hPort, &dcb);

    // Change the DCB structure settings.
    dcb.BaudRate = nBaud;                   // Current baud 
    dcb.fBinary = TRUE;                     // Binary mode: no EOF check 
    dcb.fParity = TRUE;                     // Parity checking: Disable
    dcb.fOutxCtsFlow = FALSE;               // No CTS output flow control 
    dcb.fOutxDsrFlow = FALSE;               // No DSR output flow control 
    dcb.fDtrControl = DTR_CONTROL_ENABLE;   // DTR flow control type 
    dcb.fDsrSensitivity = FALSE;            // DSR sensitivity 
    dcb.fTXContinueOnXoff = TRUE;           // XOFF continues Tx 
    dcb.fOutX = FALSE;                      // No XON/XOFF out flow control 
    dcb.fInX = FALSE;                       // No XON/XOFF in flow control 
    dcb.fErrorChar = TRUE;                  // Disable error replacement 
    dcb.fNull = FALSE;                      // Disable null stripping 
    dcb.fRtsControl = RTS_CONTROL_ENABLE;   // RTS flow control 
    dcb.fAbortOnError = FALSE;              // Do not abort reads/writes on: error
    dcb.ByteSize = 8;                       // Number of bits/BYTE, 4-8 
    dcb.Parity = Parity;                    // 0-4=no,odd,even,mark,space
    dcb.StopBits = StopBits;                // 0,1,2 = 1, 1.5, 2 
    dcb.ErrorChar = ' ';                    // reaplacement of the TCHAR with parity error 

    if (!SetCommState (hPort, &dcb)) 
    {
        CloseHandle (hPort);
        return INVALID_HANDLE_VALUE;
    }

    return hPort;
}

1 Ответ

0 голосов
/ 03 июня 2019

Ваш ReadFile() может вернуть TRUE (успех) без данных в pBuf. Чтобы решить эту проблему, вы можете установить ReadIntervalTimeout, например, 10 (миллисекунды) вместо MAXDWORD, потому что:

Значение MAXDWORD в сочетании с нулевыми значениями для обоих Члены ReadTotalTimeoutConstant и ReadTotalTimeoutMultiplier, указывает, что операция чтения должна немедленно вернуться с байты, которые уже были получены, , даже если байтов не было получил .

(Ниже приведено не прямое отношение к вашей проблеме, но несколько советов для вашего кода.)

Поскольку вы устанавливаете синхронную операцию вместо асинхронной, есть несколько избыточных строк кода:

OVERLAPPED ol;
memset (&ol, 0, sizeof(OVERLAPPED));
ol.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);

WaitForSingleObject();

Для выполнения операции с перекрытием вступают в силу. Вам необходимо установить флаг FILE_FLAG_OVERLAPPED для CrateFile() и настроить структуру OVERLAPPED для WriteFile() и ReadFile();

//...

    HANDLE hPort = CreateFile(
        L"COM8",
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        FILE_FLAG_OVERLAPPED,
        NULL);

//...

    WriteFile(hComm, pBuf, iLen, NULL, &ol);

//...

    ReadFile(hComm, pBuf, 1, NULL, &ol);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...