Hi All,
I have a little problem with ExtendedWeakReference, because It doesn’t save the data to the flash on the G30TH module. But same code works on the Fez Raptor.
The Fez raptor is a Gadgetter application, the G30TH module’s program is a console application.
Should I initialize something in the console application?
@ equitis - The G30 does not support Extended Weak References.
@ John - Is there any way to write to the flash of the G30?
There is always the 80 Bytes of Battery Ram
7.20 Battery RAM
Battery-backed RAM is provided as part of the internal RTC.
This memory retains its contents when the power is lost as long as there is a backup battery.
There are 80 bytes of battery backed RAM available.
Consult the processor's documentation for details on use.
@ equitis - you may also be able to use the Configuration class to write small amounts of data.
@ John - Thank you! It works. But I have a problem, there is not enough memory to load the GHI.Hardware.dll. I tried to call the NativeWriteEntry and the NativeReadEntry method but It was not successful. How I can call a native method? or How I can implement the Configuration class in my application.
@ equitis - You shouldn’t need to call the native methods yourself, they’re private and may change. You can call Configuration.ReadEntry and Configuration.WriteEntry. They will handle everything for you.
If you can’t load GHI.Hardware, you may need to remove other assemblies or refactor your project.
@ John - The problem is the GHI.Hardware.dll is 66kbytes. If i attach this dll to the references, the assembly will be approx 150kb. And the G30TH module has not enough flash memory for my assembly, that’s why I cannot use this dll.
Why not use a disassembler to extract the parts from GHI.Hardware that you need and include this as a class in your solution.
using System;
using System.Runtime.CompilerServices;
namespace GHI.Processor
{
/// <summary>Provides access to the device's underlying configuration sector.</summary>
public static class Configuration
{
private static uint size;
private static uint address;
/// <summary>The maximum length of a config entry name.</summary>
public static int MaximumNameLength
{
get
{
return 63;
}
}
/// <summary>The size of the configuration sector.</summary>
public static int TotalSize
{
get
{
return (int)Configuration.size;
}
}
static Configuration()
{
Configuration.NativeGetParameters(out Configuration.address, out Configuration.size);
}
/// <summary>
/// Gets the total size of the entry specified by name.
/// </summary>
/// <param name="name">The name of the entry.</param>
/// <returns>The size. A size of 0 means no entry was found.</returns>
public static int GetEntrySize(string name)
{
if (name == null || name == "")
{
throw new ArgumentException("name cannot be null or empty.", "name");
}
if (name.Length > Configuration.MaximumNameLength)
{
throw new ArgumentException("name.Length must be no more than MaximumNameLength", "name");
}
return Configuration.NativeGetEntrySize(name);
}
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern int NativeGetEntrySize(string name);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void NativeGetParameters(out uint address, out uint size);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern bool NativeRead(byte[] buffer);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern bool NativeReadEntry(string name, byte[] buffer);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern bool NativeWrite(byte[] buffer);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern bool NativeWriteEntry(string name, byte[] buffer);
/// <summary>Reads the configuration.</summary>
/// <returns>The configuration.</returns>
public static byte[] Read()
{
byte[] numArray = new byte[Configuration.TotalSize];
Configuration.Read(numArray);
return numArray;
}
/// <summary>Reads the configuration into the given buffer.</summary>
/// <param name="buffer">The buffer to read into.</param>
/// <returns>Whether or not the configuration was successfully read.</returns>
public static bool Read(byte[] buffer)
{
if (buffer == null)
{
throw new ArgumentNullException("buffer");
}
if ((int)buffer.Length != Configuration.TotalSize)
{
throw new ArgumentException("buffer", "buffer.Length must equal Configuration.TotalSize.");
}
return Configuration.NativeRead(buffer);
}
/// <summary>
/// Reads the configuration entry specified by name.
/// </summary>
/// <param name="name">The name of the entry.</param>
/// <returns>The entry, null if not found.</returns>
public static byte[] ReadEntry(string name)
{
byte[] numArray = new byte[Configuration.GetEntrySize(name)];
if (!Configuration.ReadEntry(name, numArray))
{
return null;
}
return numArray;
}
/// <summary>
/// Reads the configuration entry specified by name.
/// </summary>
/// <param name="name">The name of the entry.</param>
/// <param name="buffer">The buffer to read into.</param>
/// <returns>Whether or not the entry was found and read.</returns>
public static bool ReadEntry(string name, byte[] buffer)
{
if (name == null || name == "")
{
throw new ArgumentException("name cannot be null or empty.", "name");
}
if (name.Length > Configuration.MaximumNameLength)
{
throw new ArgumentException("name.Length must be no more than MaximumNameLength", "name");
}
if (buffer == null)
{
throw new ArgumentNullException("buffer");
}
if ((int)buffer.Length != Configuration.GetEntrySize(name))
{
throw new ArgumentException("buffer.Length - offset must be the same size as returned by GetEntrySize.", "buffer");
}
return Configuration.NativeReadEntry(name, buffer);
}
/// <summary>Writes the given buffer to the configuration sector.</summary>
/// <param name="buffer">The buffer to write.</param>
/// <returns>Whether or not the configuration was successfully written.</returns>
/// <remarks>
/// Make sure the buffer is one you have previously read from the same type of device. It is not advised to write a configuration read from a
/// previous firmware version.
/// </remarks>
public static bool Write(byte[] buffer)
{
if (buffer == null)
{
throw new ArgumentNullException("buffer");
}
if ((int)buffer.Length != Configuration.TotalSize)
{
throw new ArgumentException("buffer", "buffer.Length must equal Configuration.TotalSize.");
}
return Configuration.NativeWrite(buffer);
}
/// <summary>
/// Writes the configuration entry specified by name.
/// </summary>
/// <param name="name">The entry name.</param>
/// <param name="buffer">The buffer to write from.</param>
/// <returns>Whether or not the entry was written.</returns>
public static bool WriteEntry(string name, byte[] buffer)
{
if (name == null || name == "")
{
throw new ArgumentException("name cannot be null or empty.", "name");
}
if (name.Length > Configuration.MaximumNameLength)
{
throw new ArgumentException("name.Length must be no more than MaximumNameLength", "name");
}
if (buffer == null)
{
throw new ArgumentNullException("buffer");
}
if ((int)buffer.Length < 1)
{
throw new ArgumentException("buffer.Length must be at least 1.", "buffer");
}
return Configuration.NativeWriteEntry(name, buffer);
}
}
}
@ equitis - The only way to use the Configuration class is to load GHI.Hardware unfortunately. You can’t call the native methods without it either.
@ scardinale - I have tried, but it didn’t work.
@ John - Thank you John. Sorry but I have to solve this problem. That’s why I modify my question. How can I write to the flash, after my program. First I would like to get the size of my program, (i think this is a native method also), and write area of the flash over the program. Are the native methods compiled in the GHI.Hardware.dll?
“You have very good products, that’s why I chose GHI, and this is very important for me, please help me a little bit”
@ equitis - Looks like you are exceeding the memory size limits of the G30. The right answer would be in using G80 or even G120. Even if you got it all squeezed in today but you are close to the limits, I am afraid you will run out of space again very shortly.
@ Gus - That will be the last chance. The GHI.Hardware.dll allocates the 50% of the flash memory. I don’t want to choose the G80TH because I would like to keep the costs low. And the Ardunio mini is cheaper than the G80TH. The memory of the G30 is enough for me, i just want to store a few setting data in the flash memory.
@ equitis - It is actually the pe file that gets deployed to your device, not the dll. GHI.Hardware will only take up 30% of the deployment. We realize that is still a lot and would like to improve it, but unfortunately we do not have anything right now.
The Configuration class is the only way we provide to write to the flash. Look inside the bin folder of your project, check the sizes of the various PE files and see if you can reduce anything in the assemblies included or your own application.
@ John - I compiled a release version of the program. Now the space is enough. I hope the configuration will be in a separated dll in the next version of the GHI SDK.