I am using G400D and MF 4.3.
I am able to create files, write into files, check if written/created files exist… but after powering off my controller, all data are gone away.
At least I tried to unmount the SDCard, no impact on this behave.
I am able to read data from database without any problem. Also I was able to do read/add transactions with success.
The file system does a lot of data buffering internally to speed up the file access time and to increase the life of the flash media. When you write data to a file,it is often saved somewhere in the internal buffers (rather than immediately being written to the media). To make sure the data is stored on the media, you need to flush the data. Flushing (or closing) a file is the only way to guarantee that the data you are trying to write is on the actual media; in addition to the file data, there is other information,such as directory information, that may not be written to the media when the file is flushed. For example, if you delete a file and remove the card from the system, the file is probably not actually erased because the directory structure was not flushed.
Under current versions of .NET Micro Framework, with the Flush method of FileStream, there can be a variable time delay before the buffers are actually written to the media; which reportedly can be as large as a minute (see: https://netmf.codeplex.com/workitem/2149 ). To guarantee that the file buffers and the meta-data are written to the media you need to flush the volume:
VolumeInfo.GetVolumes()[0].FlushAll(), or
new Microsoft.SPOT.IO.VolumeInfo(“\SD”).FlushAll().
Ideally, you would unmount the media before it is removed from the system. This may not be always possible and so a FlushAll will guarantee your data is saved.
@ EvoMotors - I there a difference between volume.flushall and sdcard.flush(all)? the buffering method is clear for me, if you try to do a lot of write operations on a single file, you’ll get once an io exception.
Did you try to VolumeInfo.GetVolumes()[0].FlushAll() or new Microsoft.SPOT.IO.VolumeInfo("\SD").FlushAll() ? FlushAll will guarantee your data is saved.
@ EvoMotors - VolumeInfo.GetVolumes()[0].FlushAll() did not work. After the Flush Operation I am waiting 10s to unmount SD and power off the device. No IO-Exception! changing from FAT32 to FAT16 does not result in a succeed
demo code:
SDCarte_ = new SDCard();
SDCarte_.Mount();
if (SDCarte_.Mounted)
{
bool fs_ready = false;
RemovableMedia.Insert += (a, b) =>
{
fs_ready = true;
};
while (!fs_ready)
{
System.Threading.Thread.Sleep(1);
}
rootDirectoryvar = VolumeInfo.GetVolumes()[0].RootDirectory;
string f2 = @ "\SD\hello.txt";
FileStream FileHandle = new FileStream(f2, FileMode.Create, FileAccess.ReadWrite);
byte[] data =
Encoding.UTF8.GetBytes("This string will go in the file!");
FileHandle.Write(data, 0, data.Length);
FileHandle.Close();
//VolumeInfo.GetVolumes()[0].FlushAll(); //not working
new Microsoft.SPOT.IO.VolumeInfo("\\SD").FlushAll(); //not working
SDCarte_.Unmount();
I don’t see the code where you flushing FileStream I also don’t see the code where you disposing FileStream. Try this:
using (FileStream FileHandle = new FileStream("f2", FileMode.Create, FileAccess.ReadWrite))
{
byte[] data = Encoding.UTF8.GetBytes("This string will go in the file!");
FileHandle.Write(data, 0, data.Length);
FileHandle.Close();
FileHandle.Flush();
}}
//VolumeInfo.GetVolumes()[0].FlushAll(); //not working
new Microsoft.SPOT.IO.VolumeInfo("\\SD").FlushAll(); //not working
SDCarte_.Unmount();
The above code will throw an ObjectDisposedException as you are closing the FileStream before accessing it through the flush method.
The correct order would be :
using (FileStream FileHandle = new FileStream("f2", FileMode.Create, FileAccess.ReadWrite))
{
byte[] data = Encoding.UTF8.GetBytes("This string will go in the file!");
FileHandle.Write(data, 0, data.Length);
FileHandle.Flush();
FileHandle.Close();
}}
//VolumeInfo.GetVolumes()[0].FlushAll(); //not working
new Microsoft.SPOT.IO.VolumeInfo("\\SD").FlushAll(); //not working
SDCarte_.Unmount(
But the Flush method is really not necessary after the Close method is called as closing the FileStream will flush the buffer automatically.
@ scardinale - no error - no file written
f2 assumed as filename onto SD storage device
how does it take to write back data to the sd-card?
I also tried to use an existing file and appended one text-line. no execution error - nothing written.
Can you try StreamWriter insted of FileStream? Also I noticed that I put “f2” instead of f2 in my previous sample code, so if you didn’t correct it you’ll have to check if file with name f2 got written.
using (StreamWriter FileHandle = new StreamWriter(f2))
{
FileHandle.Write("This string will go in the file!");
FileHandle.Flush();
}
Obviously something is wrong. I and many others writing files to SD card all the time. I’m successfully writing files to SD card with G120TH and G400TH
@ EvoMotors - written without any error; seems to be successfully. after power off and checking filesystem on the pc - no changes on filesystem are available
@ cyberh0me - I’ll try. what about the hardware. the lines are connected correct but I read some about capacitor…
possibly there is a wrong behave caused by hardware.
result:
read existing file content … ok
add file content without error
read back file changes … ok
power down and restart
read file content (“This st”) …result
power down and read content at pc
read file content (“This st”) …result
the only on difference to the previous tests was, In debug mode I didn’t stop execution after unmount.
the partial success in write operation is not always reproduceable.
i plan to write nearly a MegByte of data - this small amount of chars must be no problem in any case
In past I experienced at microcontroller a required minimum blocksize. does it matter on microframework?
I have used your code with minor modifications using a G400TH and a Sparkfun SD Breakout board also on a custom board based on the G400D. It is 100% successful every time.
If you run this code and it fails, the problem must be in your configuration.
private static SDCard _sd;
public static void Main()
{
_sd = new SDCard();
_sd.Mount();
if (_sd.Mounted)
{
bool fsReady = false;
RemovableMedia.Insert += (a, b) =>
{
fsReady = true;
};
while (!fsReady)
{
Thread.Sleep(1);
}
string rootDirectoryvar = VolumeInfo.GetVolumes()[0].RootDirectory;
string f2 = @ "\SD\hello.txt";
FileStream fileHandle = new FileStream(f2, FileMode.Append);
byte[] data = Encoding.UTF8.GetBytes("This string will go in the file!\r\n");
fileHandle.Write(data, 0, data.Length);
fileHandle.Close();
VolumeInfo.GetVolumes()[0].FlushAll(); // is working
//new VolumeInfo("\\SD").FlushAll(); // is working
var readFileHandle = new FileStream(rootDirectoryvar + @ "\hello.txt", FileMode.Open, FileAccess.Read);
data = new byte[readFileHandle.Length];
var readCount = readFileHandle.Read(data, 0, data.Length);
readFileHandle.Close();
readFileHandle.Dispose();
Debug.Print("The size of data read is: " + readCount);
Debug.Print("Data from file:");
Debug.Print(new string(Encoding.UTF8.GetChars(data), 0, readCount));
_sd.Unmount();
_sd.Dispose();
_sd = null;
}
}