The Netduino forums have been replaced by new forums at community.wildernesslabs.co.
This site has been preserved for archival purposes only
and the ability to make new accounts or posts has been turned off.
I was hoping to use the native serialization / deserialization support of the framework to save / load / marshall object state. However, it appears that such functions aren't implemented.
using System;
using System.IO.Ports;
using System.Threading;
using Microsoft.SPOT;
using SecretLabs.NETMF.Hardware.Netduino;
namespace Serializer
{
public class Program
{
public static void Main()
{
int i = 0;
var buffer = Reflection.Serialize(i, i.GetType());
}
}
}
The thread '<No Name>' (0x2) has exited with code 0 (0x0).
#### Exception System.NotImplementedException - 0xca000000 (1) ####
#### Message:
#### Microsoft.SPOT.Reflection::Serialize [IP: 0000] ####
#### Serializer.Program::Main [IP: 0011] ####
A first chance exception of type 'System.NotImplementedException' occurred in Microsoft.SPOT.Native.dll
An unhandled exception of type 'System.NotImplementedException' occurred in Microsoft.SPOT.Native.dll
Are there plans to port this to the netduino framework in the future?
Hi Fabien,
I believe that serialization support would be pretty big. We can look into adding it (or you can add it in the open source code if available)...but my guess is that it'd be too big for small micros.
Chris
building a lightweight serializer wouldnt be too hard, I have some old source that could work, its optimistic and only handles simple objects. I will more than likely be re-visiting it soon in my quad project. What are you wanting to serialize (what types of objects)?
building a lightweight serializer wouldnt be too hard, I have some old source that could work, its optimistic and only handles simple objects. I will more than likely be re-visiting it soon in my quad project. What are you wanting to serialize (what types of objects)?
I agree: it is fairly simple to write.
Basically, I want to binary-serialize / deserialize the ValueTypes and some of the objects found in the System namespace.
Generally, any 'object' type would be handled through recursive reflection, looking within each object for System ValueTypes and System objects supported by the custom serializer.
Collections of objects would also need to be supported (ArrayList, Hashtable, Queue, Stack) according to the same reflection mechanics.
i think if we just did value types and collections of value types with recursion of more complex obecjts as long as they were all inheriting the same interface to start we could open it up from there, i'm new here and wondering if you guys have a svn or git repository going yet? if not I could host something up on mine if need be.
Hopefully if i can help on the code side you guys can scratch my back a bit on the hardware side
Wow, Fabien... I didn't realize that XBox Live was based off of ASP.NET. That's awesome (and makes a lot of sense).
The Netduino implementation of .NET MF is the core one provided in the .NET MF porting firmware with some enhancements (variable-bit PWM, I2C repeated start bit, analog inputs, PWM, etc. etc.) We have some room in flash to add a few features. If serialization can be added without taking up much room, we might be able to fit it on the chip; and if not, perhaps a managed-code version from your netduino.helpers library can be deployed at runtime.
Thanks for all your contributions, Fabien.
Chris
Wow, Fabien... I didn't realize that XBox Live was based off of ASP.NET. That's awesome (and makes a lot of sense).
The Netduino implementation of .NET MF is the core one provided in the .NET MF porting firmware with some enhancements (variable-bit PWM, I2C repeated start bit, analog inputs, PWM, etc. etc.) We have some room in flash to add a few features. If serialization can be added without taking up much room, we might be able to fit it on the chip; and if not, perhaps a managed-code version from your netduino.helpers library can be deployed at runtime.
Thanks for all your contributions, Fabien.
Chris
It's a mix of ASP.Net, the standard .Net Framework and some C++ where applicable
I agree with you: it should only be added to the core framework if it doesn't take much room since there are lightweight alternatives which can be deployed only as needed. I'm curious to hear what your dev team thinks...
greg and i worked together for 5 years that initial implementation was ours, albeit naive it suited our purposes. They are all teeny, almost any well written serialization implementations will be, i'd love to help out.
Brandon,
That's great news! I'd love for you to contribute to the netduino.helpers library with your lightweight serialization class. Go for it!
Let me know when you have something that I can test and I'll integrate it.
Are you OK releasing it under the MIT license? And of course, you get the credit!
Cheers,
-Fabien.
So i started to get into it and I have come across some road blocks and cant seem to find a way around it.
Reflection being limited i cant even call CreateInstance() or the other method i had up my sleeve FormatterServices.GetUninitializedObject() or Activator.CreateInstance, is there anyway to initialize an object from a string at all in netmf, otherwise i think we're shit out of luck short of some ugly case statements
is there anyway to initialize an object from a string at all in netmf
Does this help?
using System;
using Microsoft.SPOT;
namespace NetduinoApplication14 {
public class Program {
public static void Main() {
var z=Type.GetType("NetduinoApplication14.Zamboni").GetConstructor(new Type[0]).Invoke(new object[0]);
}
}
public class Zamboni {
public Zamboni() {
Debug.Print("Inside constructor");
}
}
}
i ended up finding that shortly thereafter, thanks Corey.
I've stubbed out the whole thing just going for some optimization now. My current application for it is the quadrocopter so has to be heavily optimized and optimistic, a more generic library can be made off it after, will post when done
Heres a very prelim write of this with some simple implementations as you can see i am putting the responsibility on the ISerializable object for now, not a full object graph, as i extend this i will update, right now its pretty ugly and specific
EDIT: didnt like what i posted earlier, here`s a revamp
using Quad.Net.Commons.Serialization;
namespace Quad.Net.Commons.Logging
{
public interface ILogger
{
void Flush();
void Write(ISerializable obj);
}
}
using System.IO;
using Quad.Net.Commons.Serialization;
namespace Quad.Net.Commons.Logging
{
public class PersistenceWriter : ILogger
{
private readonly IBinaryFormatter _formatter;
private readonly string _fileName;
private readonly FileStream _fileStream;
public PersistenceWriter(string fileName, IBinaryFormatter formatter)
{
_formatter = formatter;
_fileName = fileName;
_fileStream = new FileStream(_fileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, 512);
}
public void Flush()
{
_fileStream.Flush();
}
public void Write(ISerializable obj)
{
_formatter.Serialize(_fileStream, obj);
}
}
}
using System.IO;
using Quad.Net.Commons.Serialization;
namespace Quad.Net.Commons.Logging
{
public class PersistanceReader
{
private readonly IBinaryFormatter _binaryFormatter;
public PersistanceReader(IBinaryFormatter binaryFormatter)
{
_binaryFormatter = binaryFormatter;
}
public ISerializable[] GetMessages(string readPath)
{
FileStream readFile = new FileStream(readPath, FileMode.Open, FileAccess.Read);
return _binaryFormatter.Deserialize(readFile);
}
}
}
using System;
using System.IO;
namespace Quad.Net.Commons.Serialization
{
public interface IBinaryFormatter
{
void Serialize(Stream stream, Object graph);//not implemented
ISerializable[] Deserialize(Stream stream);
void Serialize(Stream stream, ISerializable graph);//optimistic
}
}
namespace Quad.Net.Commons.Serialization
{
public interface ISerializable //: where T : new() in classic C# this is what i would do force a parameterless contructor, cant do thisin netmf
{
byte[] Serialize();
object Deserialize(byte[] buffer);
}
}
using System;
using System.Collections;
using System.IO;
namespace Quad.Net.Commons.Serialization
{
public class TelemetryFormatter:IBinaryFormatter
{
public void Serialize(Stream stream, object graph)
{
throw new NotImplementedException();
}
public ISerializable[] Deserialize(Stream stream)
{
ISerializable[] items = new ISerializable[stream.Length/44];
int counter = 0;
while (stream.Position < stream.Length)
{
byte[] buffer = new byte[44];
stream.Read(buffer, 0, 44);
ISerializable item = (ISerializable) typeof(TelemetryData).GetConstructor(new Type[0]).Invoke(new object[0]);
item.Deserialize(buffer);
items[counter] = item;
counter++;
}
return items;
}
public void Serialize(Stream stream, ISerializable graph)
{
byte[] buffer = graph.Serialize();
stream.Write(buffer, 0, buffer.Length);
}
}
}
using System;
using Microsoft.SPOT.Hardware;
using Quad.Net.Avionics;
using Quad.Net.Commons.Serialization;
using Quad.Net.Commons.Utilities;
namespace Quad.Net.FlightController
{
public class TelemetryData : ISerializable
{
private readonly AircraftPrincipalAxes _gyroAxes;
private readonly AircraftPrincipalAxes _radioAxes;
private readonly AircraftPrincipalAxes _pidAxes;
private long _currentTime;
private readonly byte[] _buffer;
public TelemetryData()
{
_gyroAxes= new AircraftPrincipalAxes(0,0,0);
_radioAxes = new AircraftPrincipalAxes(0, 0, 0);
_pidAxes = new AircraftPrincipalAxes(0, 0, 0);
_currentTime = DateTime.Now.Ticks;
_buffer = new byte[44];
}
public void Update(AircraftPrincipalAxes gyroAxes, AircraftPrincipalAxes radioAxes, AircraftPrincipalAxes pidAxes, long currentTime)
{
_gyroAxes.Update(gyroAxes.Pitch,gyroAxes.Roll,gyroAxes.Yaw);
_radioAxes.Update(radioAxes.Pitch, radioAxes.Roll, radioAxes.Yaw);
_pidAxes.Update(pidAxes.Pitch, pidAxes.Roll, pidAxes.Yaw);
}
public byte[] Serialize()
{
Utility.InsertValueIntoArray(_buffer, 0, 4, (uint)(_currentTime >> 32));
Utility.InsertValueIntoArray(_buffer, 4, 4, (uint)_currentTime);
Utility.InsertValueIntoArray(_buffer, 8, 4, (uint)_gyroAxes.Pitch);
Utility.InsertValueIntoArray(_buffer, 12, 4, (uint)_gyroAxes.Roll);
Utility.InsertValueIntoArray(_buffer, 16, 4, (uint)_gyroAxes.Yaw);
Utility.InsertValueIntoArray(_buffer, 20, 4, (uint)_radioAxes.Pitch);
Utility.InsertValueIntoArray(_buffer, 24, 4, (uint)_radioAxes.Roll);
Utility.InsertValueIntoArray(_buffer, 28, 4, (uint)_radioAxes.Yaw);
Utility.InsertValueIntoArray(_buffer, 32, 4, (uint)_pidAxes.Pitch);
Utility.InsertValueIntoArray(_buffer, 36, 4, (uint)_pidAxes.Roll);
Utility.InsertValueIntoArray(_buffer, 40, 4, (uint)_pidAxes.Yaw);
return _buffer;
}
public object Deserialize(byte[] buffer)
{
_currentTime = BitConverter.ToLong(buffer, 0);
_gyroAxes.Update(
Utility.ExtractValueFromArray(buffer, 8, 4),
Utility.ExtractValueFromArray(buffer, 12, 4),
Utility.ExtractValueFromArray(buffer, 16, 4)
);
_radioAxes.Update(
Utility.ExtractValueFromArray(buffer, 20, 4),
Utility.ExtractValueFromArray(buffer, 24, 4),
Utility.ExtractValueFromArray(buffer, 28, 4)
);
_pidAxes.Update(
Utility.ExtractValueFromArray(buffer, 32, 4),
Utility.ExtractValueFromArray(buffer, 36, 4),
Utility.ExtractValueFromArray(buffer, 40, 4)
);
return this;
}
public override string ToString()
{
//csv format
return _currentTime + "," +
_gyroAxes.Pitch + "," +
_gyroAxes.Roll + "," +
_gyroAxes.Yaw + "," +
_radioAxes.Pitch + "," +
_radioAxes.Roll + "," +
_radioAxes.Yaw + "," +
_pidAxes.Pitch + "," +
_pidAxes.Roll + "," +
_pidAxes.Yaw + ",";
}
}
}
updated above, as i said this a very very specific and optimistic serialization system for my exact purposes, but the idea is sound and could be used in other places, u merely have to implement ISerializable on your class and insert a type into the serialize message in order to dynamically invoke the constructor, i know i am in this instance only serializing one type with this formatter so i have put that statically in, you could easily put in a header to accomplish this such as
stx....type...data...etx
once you know your type merely parse and dynamically invoke and assume T : new()