Spider : SDCard : Why my files are not always written to the SDcard?

Hi,

A couple of questions about using the SDCard because I see some strange behaviors while testing. I use a Spider in Gadgeteer mode. I’m basically looking at managing a set of configuration files stored in a directory. I need to read and write key/value pairs as lines in files.

First : Does the gadgeteer code listed as SDCard usage examples on SDCard description work on Premiums as well ?

When I write lines into a simple file, it’s not always written down to the SDCard. The following code should add 10 lines to a file and close it but that does not work systematically. What do I do wrong ? (I fire this function in the SDCard mount event…)


        public void WriteLine(string file, string line)
        {
            StreamWriter tw = new StreamWriter( file,true );

            for (int i = 0; i < 10; i++)
            {
                tw.WriteLine( i.ToString () + " : " + line);
                Debug.Print(i.ToString() + " : " + line);
            }
            tw.Flush();
            tw.Close();
        }

Reading files looks ok using the following code :


        public void ReadFile(string fileName)
        {
            if ((fileName != null) && File.Exists(fileName))
            {
                using (StreamReader input = new StreamReader(fileName))
                {
                    string textLine = input.ReadLine();

                    while (textLine != null)
                    {
                        Debug.Print(textLine);
                        textLine = input.ReadLine();
                    }
                    input.Close();
                }
            }
            else
            {
                Debug.Print("SDCardService : file doesn't exist");
            }
        }

Thanks.

Stephan

1 Like

I think you should flush the filesystem, not the the StreamWriter. I use command

VolumeInfo.GetVolumes()[0].FlushAll();

But now I cannot check if it’s not for NETMF 4.1. Will do that tommorow, if I don’t forget…

Do you know what the expected (somewhere specified?) behavior of file system flushing is? Is the FlushAll a workaround because of a NETMF bug, or is it the intended way of doing things?

I believe flushing is normal for such slow storage devices as SD card.

In the sense that flushing an individual file has no effect for up to a minute, whereas FlushAll of the volume immediately forces a “real” flush of all files?

Well, I guess so. This FlushAll, as far as I remember, is not even in API documentation. But kind of worked for me.

I personally think SD card (at least GHI’s implementation) is totally unsuitable for industry applications, so I avoid it wherever I can.

With pleasure.

  1. It’s not written anywhere, but if you connect SD power to MCU and not the main +3.3V line — be ready for problems. All kinds of.
  2. Formatting sometimes works, sometimes not. If something is wrong with the card (like, file system is corrupted), formatting should help, right? No! Wrong. Formatting sometimes fails (at least on my EMX).
  3. If power is disconnected while SD card is still mounted and, God save us, there’s some action going with the card, filesystem is corrupted and could not mount next time. If I plug such damaged card into my PC, it offers to repair it. It repairs, data is preserved, and the card mounts on EMX again. And how does one guarantee the client does not disconnect the device while there’s something is being written to the card? One then has to include an accumulator or a supercapacitor. Or something.
  4. Sometimes the card does not mount on first try, one has to try again a few times.

I’ve wasted lots of time making this thing work reliably. Eventually I gave up and moved to FRAM. Flying to the other side of the world to service the whole product just because a SD card locked up is little bit too expensive, you know :slight_smile: I may still use SD for something really, really not critical — at some time in the future. Perhaps…

Simon’s answer did solve the problem. Now that I systematically flush the File System using :

VolumeInfo.GetVolumes()[0].FlushAll();

I do have everything correctly written on the SD Card. I do a flush at the end of each file modification.

By the way, I tried many scenarios : eject, then reinsert the SDcard, and using the FlushAll function, I never saw any corruption of the filesystem on the SDCard.

Stephan.

It is in a NETMF-specific namespace, Microsoft.SPOT.IO:

But if I interpret the MSDN documentation on Stream.Flush correctly, the workaround with FlushAll should not be necessary. Therefore I posted an issue on Codeplex:

https://netmf.codeplex.com/workitem/2149

1 Like

It’s not something that happens everyday. It just happens sometimes, and if at that moment your SD card is not on your desk, but 10000km away, you know you’re in trouble…

I have also the same feeling!!! Not reliable at all. But it’s too late, products are already installed…

It is probably related to the user removing the card before prooer flush on buffered data.

If you think it is otherwise then please provide your test and we will gladly look into it.

In our configuration, sd can not be removed by user but power can be switch off suddenly. We used to have card not readble after a while card not writable, card full (8GB) whereas there’s only few kB of data inside, file that return XXkB whereas there’s no data inside corrupted files… The major problem is to find a reproductible scheme that shows the issue.

The board does not decide when there’s power or not. There’s a lack on this point in our design… Now we have to live with (or without) that

To work around this problem, I’ve added power detection pin and a 0.5F capacitor on +5V line. Enough to keep the board alive for ~3 seconds, so all writes could be finalized.

1 Like

it’d be great if we had a reliable framework for writing and flushing to minimise the potential exposure of this, as well as making the file system more robust (behind-the-scenes flushing?)

I am just experiencing the problem again…

I don’t know what exactly happend but here’s the scheme:

I receive xml file from Canbus using a can_DataReceivedEvent.

According to the king of can message:

I create first a backup file
I create a filestream using:

 f = new FileStream("\\SD\\IFUNDR\\Playset.xml", FileMode.OpenOrCreate, FileAccess.ReadWrite);

I fill in the filestream using:

 
if (msgList[i].ArbID == candtrx)
                    {
                        GHI.Premium.Hardware.LowLevel.Watchdog.ResetCounter();
                        switch (can_command)
                        {
                            case 1:  //alors app.hex
                                {
                                    byte[] b = msgList[i].Data;
                                    f.Write(b, 0, b.Length); f.Flush();
                                } break;
                            case 2: //alors PS.xml
                                {
                                    byte[] b = msgList[i].Data;
                                    f.Write(b, 0, b.Length); f.Flush();
                                } break;
                            case 3: //alors DS.xml
                                {
                                    byte[] b = msgList[i].Data;
                                    f.Write(b, 0, b.Length); f.Flush();
                                } break;

                        }
                    }

and when I clode the file:


f.Seek(0, SeekOrigin.Begin);
f.SetLength((long)requested_size);
f.Close();
f.Dispose();
VolumeInfo.GetVolumes()[0].FlushAll();
Thread.Sleep(1000);
while (can.PostMessages(mess, 0, 1) != 1)
{
 }


If I am sending app.hex and call system update, then no problem the app.hex file is ok. If I try to get xml file, I have a problem with the file.close statement (CLR_E_FILE_IO).

SD card is new and freshly formatted

PS: code button does not work anymore