Search code examples
c++cserial-portwindows-ce

Com port write read methodology


I'm communicating with a Wince 6.0 embedded device and read/write some data by c/c++ code. Now I'm using below code snippets for read/write to com port.

void ConvertIntToByte(int iValue, BYTE* ucRawBuffer, int iOffset)
{
  ucRawBuffer[iOffset]   = ((iValue >> 24) & 0xFF);
  ucRawBuffer[iOffset+1] = ((iValue >> 16) & 0xFF);
  ucRawBuffer[iOffset+2] = ((iValue >> 8) & 0xFF);
  ucRawBuffer[iOffset+3] = (iValue & 0xFF);
}

ReadWriteDataThread()
{
    BYTE ucInitMsg[32] = {0};
    ucInitMsg[0] = 0x0A;
    ConvertIntToByte(iUTCTime, ucInitMsg, 1);
    ucInitMsg[21] = 0x02;
    ucInitMsg[22] = 0x3E;
    ucInitMsg[31] = 0xCA;
    m_objComm.WriteCommPort(ucInitMsg, 32);  //Its a standard comm port write function which used WriteFile windows API
}

Now, my concern is am I writing Bytes to com port in correct manner? Am I doing correct in bit shifting? I found the code for int to byte conversion on web and I'm not very much strong in bit/byte manipulation.

UPDATE

After I knew that my platform is little-endian I changed my routines of Byte conversion to below. Can anyone please verify?

void ConvertIntToByte(int iValue, BYTE* ucRawBuffer, int iOffset)
{
  ucRawBuffer[iOffset]   = iValue & 0xFF;
  ucRawBuffer[iOffset+1] = (iValue >> 8) & 0xFF;
  ucRawBuffer[iOffset+2] = (iValue >> 16) & 0xFF;
  ucRawBuffer[iOffset+3] = (iValue >> 24) & 0xFF;
}

void ConvertShortToByte(short iValue, BYTE* ucRawBuffer, int iOffset)
{
  ucRawBuffer[iOffset]    = iValue & 0xFF;
  ucRawBuffer[iOffset+1]  = (iValue >> 8) & 0xFF;
}

Solution

  • Short answer: ConvertIntToByte() looks ok, but it will produce big-endian "on the wire" regardless of the platform where it runs, being little-endian, or big-endian. If this "big-endian on the wire" is what you need - depends on target device/protocol requirements.

    Long answer:

    The code above doesn't rely on any casts; all operations it uses, are endianness-agnostic operations (for example, numeric result of i>>8 is always the same regardless of endianness, and >> in general is endianness-agnostic, as any other arithmetic or bitwise operation), so it will produce the same results on any platform, whether little-endian or big-endian.

    Due to the way the code is written, it will produce big endian "on the wire" even when running on little-endian system. So, the remaining question is "what exactly target device expects - big-endian or little-endian". If target device expects little-endian, then the code should be rewritten as:

    ucRawBuffer[iOffset] = (iValue & 0xFF);
    ucRawBuffer[iOffset+1] = ((iValue >> 8) & 0xFF);
    ucRawBuffer[iOffset+2] = ((iValue >> 16) & 0xFF);
    ucRawBuffer[iOffset+3]   = ((iValue >> 24) & 0xFF);