Main Site Documentation

Binary Reader endian issue?


#1

Hi everyone,

I’m working with a G30 using Netmf SDK 4.3.

My desktop team used a MemoryStream and BinaryWriter to serialize some data. So I thought I’d use a memory stream and Binary Reader to deserialize it on the G30. I’m having an issue and I think it has to do with endian configurations and perhaps the specifics of the netmf binary reader implementation.

Lets say my serialized data looks like this:

first byte : 0x01
second byte: 0x00

And I know that this data is meant to represent a decimal 1. This makes sense to me because the binary write uses little endian encoding to write a UInt16 so the LSB is before the MSB. The bytes themselves seem to be big endian.

On my G30 I get these two bytes into an array called rawData. Then I run this function:

 public static void deserialize()
    {
        using (var stream = new MemoryStream(rawData))
        {
            using (var reader = new BinaryReader(stream))
            {
                Uint16 deserializedValue = reader.ReadUInt16();
            }
        }
    }

The problem I’m facing is that after this executes I will have deserializedValue = 256 decimal. Which would make sense if the data were taken as MSB first: 0x0100 is indeed 256 in big endian notation.

Am I mixing up my endians? Shouldn’t it just work if both the writer and reader use the same endian encoding?

Does the G30 just treat it this way? Causing me to have to flip the bytes around on the desktop (keeping the G30 code smaller would be better)


#2

What namespace and assembly is BinaryReader from?


#3

I used serialization on a project a couple of years ago and I’m pretty sure the Desktop implementation is not compatible with the .Net Micro implementation. My recollection is someone wrote a .Net Micro compatible serializer that ran on a desktop. If I get a chance, I’ll sort through my old projects and looks for more details.

http://old.ghielectronics.com/docs/23/serialization


#4

@John_Brochue - My mistake. My associate had actually placed the source code of this class into the project. MemoryStream came from System.IO and I guess I just forgot to check the other. I can simply reverse the order myself.

@Gene I would really appreciate any details on how you have handled serialization in the past. And I will check this link to see if I can improve performance with one of these methods.


#5

I used to send a serialized “mission” file from my desktop to my gizmo floating around in the ocean using Iridium satellite telemetry. I was able to dig up what looks to be the program I used to test serialize/deserialize. Most of it creates a “missionConfig” class that is very specific to my app, serializes it and then deserializes it so I could use the debugger to check that whatever went into the serializer came out of the deserializer the same. I couldn’t find a desktop app that created a .net micro framework compatible serialized object. If I remember correctly, I was able to serialize with the .net micro emulator and store the serialized file on my PC just using the emulator. Then I could send the serialized file to my device using Iridium telemetry.

Here’s the code:

using System;

using Microsoft.SPOT;

using System.Text;

namespace SerializeTest
{
public class Program
{

    [Serializable]
    public struct DepthTable
    {
        public short depth;
        public short PV;
        public byte sampleList;
        public byte parkHours;
        public byte parkMinutes;
        public byte parkSeconds;
        [NonSerializedAttribute]
        public TimeSpan parkTime;
    }

    [Serializable]
    public class MissionConfig
    {
        public readonly String configName;
        public bool recoveryMode = false;
        public byte samplePeriodMinutes = 1;
        public byte samplePeriodSeconds = 0;
        public DepthTable[] descendTable;
        public DepthTable[] ascendTable;

        public MissionConfig(String name)
        {
            configName = name;
        }
    }

    public static MissionConfig inMission = new MissionConfig("500m");
    public static MissionConfig outMission;

    public static void Main()
    {
        Debug.Print("Program Started");

        inMission.descendTable = new DepthTable[1];
        inMission.descendTable[0].depth = (short)501;
        inMission.descendTable[0].PV = (short)100;
        inMission.descendTable[0].sampleList = (byte)7;
        inMission.descendTable[0].parkHours = (byte)1;
        inMission.descendTable[0].parkMinutes = (byte)2;
        inMission.descendTable[0].parkSeconds = (byte)3;
        inMission.descendTable[0].parkTime = new TimeSpan((int)inMission.descendTable[0].parkHours, (int)inMission.descendTable[0].parkMinutes, (int)inMission.descendTable[0].parkSeconds);

        int depthNum = 0;
        float[] calcDepth = new float[500];
        float ascendDepth = (float)500.0;

        while( ascendDepth > 0)
        {
            calcDepth[depthNum] = ascendDepth;
            depthNum = depthNum + 1;
            
            if (ascendDepth > 200)
                ascendDepth = (float)(ascendDepth - 5);
            else
                ascendDepth = (float)(ascendDepth - 2);
        }

        inMission.ascendTable = new DepthTable[depthNum + 1];
        for (int i = 0; i < depthNum; i++)
        {
            inMission.ascendTable[i].depth = (short)calcDepth[i];
            inMission.ascendTable[i].PV = (byte)((100 - (i * .1)));
            inMission.descendTable[0].parkHours = (byte)0;
            inMission.descendTable[0].parkMinutes = (byte)0;
            inMission.descendTable[0].parkSeconds = (byte)0;
            inMission.ascendTable[i].sampleList = (byte)3;
        }

        inMission.ascendTable[depthNum].depth = (short)0;
        inMission.ascendTable[depthNum].PV = (byte)0;
        inMission.descendTable[0].parkHours = (byte)0;
        inMission.descendTable[0].parkMinutes = (byte)0;
        inMission.descendTable[0].parkSeconds = (byte)0;
        inMission.ascendTable[depthNum].sampleList = (byte)0;

        byte[] buffer = Reflection.Serialize(inMission, typeof(MissionConfig));

        MissionConfig outMission = (MissionConfig)Reflection.Deserialize(buffer, typeof(MissionConfig));

        Debug.Print("Mission name = " + outMission.configName);
        Debug.Print("Num of ascend table elements = " + outMission.ascendTable.Length.ToString());
        Debug.Print("Number of bytes in buffer = " + buffer.Length.ToString());
    }
}

}