@ Brett: not wrong at all but I found another class which I am using which allows you to read and write setting by their individual names.
@ samjones3: I’m not sure if you could write to flash from MFDeploy but it’s worth the try I guess.
The class I’m using save and reads the “collection” of settings as an XML string. It used to use System.XML.Legacy BUT when deploying the solution to the Panda II that class alone uses up just more than 55k! So I removed the class and changed to code a little to compensate for that.
Here’s the class:
using System.Collections;
using System.IO;
using System.Text;
//using System.Xml; //System.Xml.Legacy.dll
using GHIElectronics.NETMF.Hardware;
using Utility = Microsoft.SPOT.Hardware.Utility;
public static class InternalFlashStorageEx
{
static Hashtable myHashtable = null;
const byte FlashPopulatedMarker = 1;
public static void Initialize()
{
Release();
byte[] storage = new byte[InternalFlashStorage.Size];
InternalFlashStorage.Read(storage);
byte[] leadBytes = Utility.ExtractRangeFromArray(storage, 0, 3);
// Check to see if our marker, "<s>", is in the first three bytes of the data.
if (leadBytes[0] == 60 && leadBytes[1] == 115 && leadBytes[2] == 62)
{
string s = new string(System.Text.Encoding.UTF8.GetChars(storage));
storage = null;
/// instead of building a hashtable (which is slow) to store the settings
/// rather keep them in an xml document and later on just get the value attribute for a setting with a specific name attribute
MemoryStream ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(s));
s = null;
myHashtable = GetHashtableFromXMLMemoryStream(ms);
}
else myHashtable = new Hashtable();
}
private static Hashtable GetHashtableFromXMLMemoryStream(MemoryStream ms)
{
Hashtable table = new Hashtable();
ms.Position = 0;
StreamReader reader = new StreamReader(ms);
string msLine = reader.ReadLine();
int start = 0;
int end = 0;
if (msLine != "")
{
ArrayList kv = new ArrayList();
while (true)
{
start = msLine.IndexOf("<a", end);
if (start == -1) break;
end = msLine.IndexOf("/>", start);
kv.Add(msLine.Substring(start, (end + 2) - start));
}
foreach (string item in kv)
{
start = item.IndexOf(" k='") + 4;
end = item.IndexOf("'", start);
string key = item.Substring(start, end - start);
start = item.IndexOf(" v='") + 4;
end = item.IndexOf("'", start);
string value = item.Substring(start, end - start);
if (key != "") table.Add(key, value);
}
kv.Clear();
}
reader.Close();
reader.Dispose();
ms.Close();
ms.Dispose();
return table;
}
public static void Add(string key, string value)
{
if (myHashtable == null) Initialize();
myHashtable.Add(key, value);
Save();
}
public static void Update(string key, string value)
{
if (myHashtable == null) Initialize();
// If you try to update a value that did not exist, I don't care, I will just add it for you.
if (!Contains(key)) myHashtable.Add(key, value);
else myHashtable[key] = value;
Save();
}
public static bool Contains(string key)
{
if (myHashtable == null) Initialize();
return myHashtable.Contains(key);
}
public static string GetValue(string key)
{
if (myHashtable == null) Initialize();
if (Contains(key)) return (string)myHashtable[key];
else return null;
}
public static void Clear()
{
if (myHashtable != null) myHashtable.Clear();
Save();
}
private static void Save()
{
string xml = "<s>";
if (myHashtable != null)
foreach(DictionaryEntry entry in myHashtable)
xml += "<a k='" + entry.Key + "' v='" + entry.Value + "' />";
xml += "</s>";
byte[] storage = new byte[InternalFlashStorage.Size];
Encoding.UTF8.GetBytes(xml).CopyTo(storage, 0);
InternalFlashStorage.Write(storage);
}
// Calling this will free up the memory the Hash table is using up.
public static void Release()
{
if (myHashtable != null) myHashtable = null;
}
}
And here’s an example to read settings (where LOG is the setting name):
InternalFlashStorageEx.Initialize();
if (!InternalFlashStorageEx.Contains("LOG"))
InternalFlashStorageEx.Add("LOG", "0");
else
log_data = (InternalFlashStorageEx.GetValue("LOG") == "0" ? false : true);
InternalFlashStorageEx.Release();
Here’s an example on updating an existing setting:
InternalFlashStorageEx.Initialize();
InternalFlashStorageEx.Update("Trip", data.Trip.ToString("F6"));
InternalFlashStorageEx.Release();
Remember to do the “Release” command before powering off as I have found it to corrupt the flash if I don’t.
Hope this help for you