First write to SDCard fails but thereafter subsequent writes are ok

My Cerberus application mounts the SD card every 10 seconds, and writes text string into a file on the SD card and then dismounts it again. It keeps repeating this.

The mounting works fine for the first time, but then when it tries to write to the SD card for the first time it cause a failure like this : [quote]Failed allocation for 343 blocks, 4116 bytes[/quote]. But thereafter subsequent mounts->write->dismounts works just fine. However if I reboot the application it fails again for the first write.

The section of code where the SD card write happens that causes the failure is this:

[quote]
if (_isMounted)
{
DebugPrint(“Use Streamwriter to write a text file”);
StreamWriter textFile = new StreamWriter(_rootDirectory + filename, true);
textFile.WriteLine( “[” + DateTime.Now.ToString(“hh:mm:ss.fff”) + "] " + strdata);
textFile.Close();
}[/quote]

This threw me for a while, because at first I only tried once and it made me think the writes to the SD card did not want to work at all. But then I tried to write repeatedly and found it was only the first write that fails.

I was interested to know if anyone else have experienced this behaviour. (I’m using VS2012 and NetMF 4.3)

Werner, I think that first error you show is actually a memory allocation failure on your device, not failing to allocate the file. Can you wrap your code with try/catches and see if you have an exception there, plus force GC to run using debug.gc() and also see how much memory is used.

Thanks for the advise Brett. Ok, I’ll try that. I also want to try a few other SD cards as well and see if it happens on all of them. At least it is useable for me at the moment. Even if I have to make a dirty fix by making a dummy write before I start logging.

Brett, this is quite interesting…

After I added Debug.GC into the code as shown below, I no longer get the error. But if I remove it again, the error is back. (The try catch unfortunately did not catch any exception)

This was the first time I’m using Debug.GC. I’ll have to read up a bit about it to see what exactly it does. But it was interesting that its inclusion resolved the problem! :slight_smile:

Replace the GC lines with 100ms delay. Does it work still?

Thanks Gus. Do you mean Thread.Sleep(100)? If so, then unfortunately the answer is that the problem still happens with the delay.

Very strange

What you need to look at is intellisense. As you’re typing a command, it reports usually enough information for you to understand what it does. In this case though, you want to do debug.gc(true) to force compaction of memory, and report how much free memory there is. Debug.GC Method | Microsoft Learn describes GC class.

debug.print("memory available:"+debug.gc(true).tostring());

Try that before and after and see what info you can get from it. The “failed allocation” message just means that you have fragmented memory before that point, and then forcing GC means it cleans that up - does your application do lots of work with strings before this point in the app, since that’s usually what causes this kind of behaviour.

I noticed the sleep added in the SD Card Mount method in a recent GHI codeplex firmware check in. I merged this into my 4.3 firmware build and I have an odd issue. The first time I run my device, it works – mount, read, write, list files, etc. Then, when I stop and start debugging again it won’t boot. But, if I remove the SD card, it boots again.

Thanks Brett for the info about Debug.GC. I tried did this and could see the available memory never goes below about 30 000. However now after I removed the Debug.GC , the problem appears to have disappeared. I am no longer able to reproduce it, which is probably a good thing. But it worries me a bit that I still do not know what caused it to happen earlier on.

One last question… I searched the forum and found a few posts that seemed to indicate there is still some unresolved problems with Cerberus and SDcard causing the CPUto lock up. Can this be confirmed? Do you think I would be better off using a Panda II board in my product if I need to reliably log data on an SDcard? I kind of like the Panda II for various reasons including the fact that its got three serial ports and built in RealTime clock, USB & SDCard. So if you think the Panda’s SDCard capability is more reliable than the Cerberus, then its probably the better choice for me anyway.

Panda is more mature so from that perspective it may be more robust. But as far as I know there are a number of updates in the latest SDK that have addressed SD related issues. What firmware version are you using (see my other comment in the other thread about this :slight_smile: )

I’m using GHI 4.2 and .NETMF4.3 SDK and developing with VS2012 on Win 8.

I’m glad to hear the Panda II is quite a mature product. My question about the Cerberus is more to try and separate truth from fiction. I saw some posts on the forum that worried me a little bit, but they might very well have referred to older versions of the firmware.

you’re probably not “using” 4.3… Also remember that Panda is 4.1 only…

I confirm same issue on hydra board but not on emx and not on g120. After 10-15 reboot the hydra fw is corrupted and need to flash from samba-CDC.

Thank you Brett. Good point about Panda only on 3.1. I did not even think about that until now. Dobova and Valkyrie-MT that is quite a big concern what you are saying. So this only happens when you are using SD card writes? Is it relatively easy to replicate? Do either of you perhaps have a sample small program that I can run on my Cerbuino to see if it also happens on my device?

@ wernert -
I have not the code in my hand in this moment, but was very easy. Just create a gadgeteer project and use SDCard class or put sdcard in the designer. Create a method that write some data to SD card with StreamWriter() … then close stream.
Try to start debug with vs and you will see the board running, then stop and start degug again and board won’t reboot. Include an unmount after stream close and you are fine.
I had display T35 connected to the board, for completness of information.
Unless you exctract the SD you will not boot again. If you insist for 10 times, you burn the firmware. Premium boards don’t show this issue.
The firmware is last release, but also the previous gets the same result.

Thanks. I wrote a small program now to see if I get the same as you and it definitely does not happen on my Cerberus board running with the following:

This was the program I used:

 
using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Touch;
using System.IO;
using Gadgeteer.Modules.GHIElectronics;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;

namespace GadgeteerApp2
{
    public partial class Program
    {  
        void ProgramStarted()
        {

            Debug.Print("Program Started");
            sdCard.SDCardMounted += new SDCard.SDCardMountedEventHandler(sdCard_SDCardMounted);
            sdCard.SDCardMounted += new SDCard.SDCardMountedEventHandler(sdCard_SDCardMounted);
            sdCard.SDCardUnmounted += new SDCard.SDCardUnmountedEventHandler(sdCard_SDCardUnmounted);
            Microsoft.SPOT.IO.RemovableMedia.Eject += new Microsoft.SPOT.IO.EjectEventHandler(RemovableMedia_Eject);
            Microsoft.SPOT.IO.RemovableMedia.Insert += new Microsoft.SPOT.IO.InsertEventHandler(RemovableMedia_Insert);

            sdCard.MountSDCard();
            System.Threading.Thread.Sleep(500);
        }

        void sdCard_SDCardUnmounted(SDCard sender)
        {
            Debug.Print("Event Unmounted");
        }

        void sdCard_SDCardMounted(SDCard sender, GT.StorageDevice SDCard)
        {
            Debug.Print("Mounted");
            writeSDcard();
        }
        

        void RemovableMedia_Insert(object sender, Microsoft.SPOT.IO.MediaEventArgs e)
        {
            Debug.Print("Event Inserted : " + e.Volume.Name);
        }

        void RemovableMedia_Eject(object sender, Microsoft.SPOT.IO.MediaEventArgs e)
        {
            Debug.Print("Event Ejected : " + e.Volume.Name);
        }

        void writeSDcard()
        {
            //Get the root directory
            string rootDirectory = sdCard.GetStorageDevice().RootDirectory;
            Debug.Print("Writing to : " + rootDirectory);
            //Use Streamwriter to write a text file
            StreamWriter textFile = new StreamWriter(rootDirectory + @ "\hello.txt");
            textFile.WriteLine("Hello SD card");
            textFile.Close();
        }

    }
}

@ wernert -
Yes, to me this happen only on Hydra, not on Cerberus.

@ wernert: Curious as to why you have 2 sdCard.SDCardMounted declarations in the ProgramStarted() region?

So you’ve confirmed SD card is working good now for Cerberus? I’m trying to create a datalogger and SD card writing will be my next step after I get all sensors working.

Thanks for the info!

Hi logictechs… ha ha… that was a copy and paste bug. Thanks, I was wondering why I got double messages for the mount but did not spend any time investigating it.