-1

" I am wrting program which write data on com port serial communication syncronous operation and read operation is also synchronous when put sleep after writefile it work fine but if remove sleep then i get some wrong data which 0x20 space not all data is wrong but some byte"

i have added write file and readfile which i have used and also create file please advise where i am wrong

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;
}
  • Sleep() is but a workaround for the incorrect WaitForSingleObject() call. You do have to check its return value to verify if the timeout expired, if it did then dwBytesRead must be set to 0. – Hans Passant Jun 02 '19 at 14:12

1 Answers1

0

Your ReadFile() may return TRUE (success) with no data in pBuf. To solve this issue you can set ReadIntervalTimeout to, for example, 10 (milliseconds) instead of MAXDWORD because:

A value of MAXDWORD, combined with zero values for both the ReadTotalTimeoutConstant and ReadTotalTimeoutMultiplier members, specifies that the read operation is to return immediately with the bytes that have already been received, even if no bytes have been received.

(Below not directly related to your issue but some tips for your code.)

Since you set up synchronous operation instead of asynchronous operation, there are some redundant code lines:

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

WaitForSingleObject();

In order to make overlapped operation take effect. You need set FILE_FLAG_OVERLAPPED flag for CrateFile() and configure OVERLAPPED structure for WriteFile() and 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);
Rita Han
  • 9,574
  • 1
  • 11
  • 24