0

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;
}
hypheni
  • 756
  • 3
  • 17
  • 37
  • Bit shift is correct. What I can suggest is to test endianless of your system, because of your Wince and your platform can have different endianless . – LPs May 29 '15 at 11:59
  • @LPs: Can you tell, how can I check the endian? – hypheni May 29 '15 at 12:09
  • @hyphenu take a look [HERE](http://stackoverflow.com/questions/2100331/c-macro-definition-to-determine-big-endian-or-little-endian-machine) – LPs May 29 '15 at 12:12
  • @LPs: Thanks for the link. I verified with some simple code. It suppose to be in little endian format. And one thing, I tried the same code on both Windows 7 PC and Win CE 6.0. The result is same. Is it due to Intel x86 architechture? – hypheni May 29 '15 at 12:45
  • Sure. Endianness depends on the HW. – LPs May 29 '15 at 13:12

1 Answers1

1

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);
No-Bugs Hare
  • 1,557
  • 14
  • 15
  • It depends on what the device expects, Wince plays no role. Devices that want big-endian order are a lot more common than big-endian operating systems :) – Hans Passant May 29 '15 at 14:37
  • Yeah. My posted code is off big-endian type. I changed it to little-endian after I found that my platform i.e. WinCE is little-endian. – hypheni May 29 '15 at 15:02