Unmount GHI SD card throws an exception

Hi all,

Im trying to mount and unmount a GHI SD card connected to a Cerberus. Every time the program wants to unmount the SD card it throws the following exception:
A first chance exception of type ‘System.IO.IOException’ occurred in Microsoft.SPOT.IO.dll
An unhandled exception of type ‘System.IO.IOException’ occurred in Microsoft.SPOT.IO.dll

Writing, reading to and from the SD-card works without any problem. Removing 400 during mount doesnt solve the issue nor using others SD-cards.
Could someone please explain why this happens or what to do to avoid this exception? Im using .NET MF 4.2 and the SD-card is connected to connector 7.

Code:

using System;
using System.Threading;
using Microsoft.SPOT;

using GHI.OSHW.Hardware;  

namespace SD_Basic
{
    public partial class Program
    {
        void ProgramStarted()
        {
            Debug.Print("Program Started");
            Timer MasterTimer = new Timer(new TimerCallback(Mount_UmountSD), null, 0000, 10000);
        }

        static void Mount_UmountSD(object o)
        {
            Debug.Print("Mount SD");
            StorageDev.MountSD(400);
            Thread.Sleep(1000);
            Debug.Print("Unmount SD_Basic");
            StorageDev.UnmountSD();
        }
    }
} 

Using code tags will make your post more readable. This can be done in two ways:[ol]
Click the “101010” icon and paste your code between the

 tags or...
Select the code within your post and click the "101010" icon.[/ol]
(Generated by QuickReply)

And the best way to “fix” the code issue is to edit your post, select your code block, and hit the 101010 button near the TOP of the message area.

I found out that the exception is caused by unmounting the SD-card in the (timer) event handler. If you mount and unmount the SD-card before initializing the timer there’s no problem. Does this help in solving this issue? I’m really would like this to be solved.

Regards.

can I ask why you want to do this in a timer then ?

It is possible that the file system relies on events but while you are accessing it from with the timer events, are events are locked till the event is finished, which then causes the exception. I haven’t tried it myself but my guess is that this exception will be raised on any NETMF device.

@ Brett, the code shown in the post is part of a larger program. Im building an environmental sensor that measures temperature, humidity, CO2 and light levels. The measured parameters should be stored on SD-card after each reading. The measurement period is in the order of 5 minutes or more. Storing the parameters on SD-card takes about a few tenth of a second. The user should be able to take out the SD-card at any given moment, except of course when the SD-card is accessed. When the SD-card is accessed a LED will be turned on, indicating that the SD-card is in use and should not be removed. The timer event is used to start a measurement and store the parameters on the SD-card. Thats why the mount and unmounts needs to be in the timer event. Next step is to put the Cerberus into sleep mode in between the measurements to save power.

@ Gus, ok point taken… I guess… but if the fs access relies on an event why is then mounting the SD-card in an event possible? Only the unmounting in a (timer) event causes the exception.
Im not a .NET expert but why should an event in an event (fs accessing in the timer event) not be possible? Especially when the fs mounting and unmounting happens within the timer event and could be considered as a local event. I agree that an exception could occur if unmounting would happen outside the initiating (in this case the timer) event.
Am I missing here something?

I didn’t say it is the case but it is possible. Either way, this is a part of the NETMF core which Microsoft wrote. Maybe they have a better input on this so maybe try https://netmf.codeplex.com/

Hi all,

I found a work around by replacing the System.Threading.Timer by the Gadgeteer.Timer. Use the following code:


using System;
using System.Threading;
using Microsoft.SPOT;
using Gadgeteer;

using GHI.OSHW.Hardware;  // Used for StorageDev

namespace SD_Basic
{
    public partial class Program
    {
        // ExtendedTimer Example : http://www.netmf.com/gadgeteer/forum/default.aspx?g=posts&m=8583
        Gadgeteer.Timer MasterTimer = new Gadgeteer.Timer(1000);
        
        void ProgramStarted()
        {
            Debug.Print("Program Started");
            MasterTimer.Tick += new Gadgeteer.Timer.TickEventHandler(Mount_UmountSD);
            MasterTimer.Start();
               
            // The following event timer usages throws an excpetion when unmounting. Do not use.
            //Timer MasterTimer = new Timer(new TimerCallback(Mount_UmountSD), null, 0000, 10000);           
        }

        static void Mount_UmountSD(Gadgeteer.Timer MasterTimer)
        {
            Debug.Print("Mount SD");
            StorageDev.MountSD(400);
            Thread.Sleep(1000);
            Debug.Print("Unmount SD_Basic");
            StorageDev.UnmountSD();
        }
    }
}

Problem solved. No more exceptions when unmounting.

I still don’t know why I see an exception when unmounting if the System.Threading.Timer is used. But the Gadgeteer.Timer saves the day.

Regards.

BTW please note that the


Timer MasterTimer = new Timer(new TimerCallback(Mount_UmountSD), null, 0000, 10000); 

in the first post should be placed before void ProgramStarted() and not in void ProgramStarted().

Probably because your trying to unmount before it is done mounting in the first place. The call to mount is not blocking so it will start the mount process and then return. It takes some small period of time before the the SD will be available to use (or unmount). You could also test to see if the SD is mounted before attempting an unmount.

What is more interesting/weird is that your SD card mount/unmount is in a timer that fires every second and in the code there’s a 1 second sleep. I would think this is a contrived example to try to prove something, which is fine, but I don’t know that it’s a conclusive finding.

@ Jeff_Birt, to avoid unmounting before mounting is finished I placed in a Thread.Sleep of one second. I have to admit that Im unsure which thread will go to sleep (Timer thread, mounting thread if there, or …?) because I dont have the inside of the threading mechanism. But like I explained before the code I posted is part of a larger program. In the actual program lots of things happen between the mounting and unmounting. So there should be more than enough time to finish the mounting process. The code from the first post is a simplified version that shows the problem. Another thing I noticed is that unmounting happens as you might expect despite of the exception. This can be checked if you look at the files written on the SD-card in another computer. If you omit the unmounting nothing is written to the card (basically because the SD-card is still open and not closed properly).

@ Brett, you deserve a bottle of wine! However it doesnt solve the issue. Its a typo. It should be 10 sec. (or at least more time than the mount_unmount function consumes). Look in the previous posts where is set to 10 seconds.

To all, could someone confirm similar behaviour?