Main Site Documentation

Panda II - SD unmounting problems


#1

I am trying to have the Panda access the SD card when the button is pressed. The problem occurs when I try to unmount the SD, so that program does not crash the next time I press the button. However I always get the following message (even when I put a sleep delay):

Error Message:
#### Exception System.IO.IOException - CLR_E_FILE_IO (4) ####
#### Message:
#### Microsoft.SPOT.IO.VolumeInfo::.ctor [IP: 0000] ####
#### Microsoft.SPOT.IO.RemovableMedia::MessageHandler [IP: 0022] ####
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

By putting in the debug print commands, the error appears after the unmount and dispose.

What is interesting is that when I remove the unmount and dispose lines it works fine the first time, but crashes when it tries to remount the sd the second time I press the button.

Here is the code that I am using, and would appreciate any help or advise.


using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Runtime.CompilerServices;
using Microsoft.SPOT;
using Microsoft.SPOT.IO;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.IO;
using GHIElectronics.NETMF.System;
using GHIElectronics.NETMF.Hardware;
using GHIElectronics.NETMF.USBHost;

namespace MFConsoleApplication1
{
    public class Program
    {
        static InputPort sdDetectPin = new InputPort((Cpu.Pin)FEZ_Pin.Digital.Di50, false, Port.ResistorMode.PullUp);
        static PersistentStorage sd;

        public static void Main()
        {
            // Subscribe to RemovableMedia events
            RemovableMedia.Insert += RemovableMedia_Insert;
            RemovableMedia.Eject += RemovableMedia_Eject;

            // Subscribe & Mount USB Memory
            USBHostController.DeviceConnectedEvent += DeviceConnectedEvent;

            // Create Button object assigned to the a Button Component connected to Di2 with interrupt feature
            FEZ_Components.Button myButton12 = new FEZ_Components.Button(FEZ_Pin.Interrupt.Di2);        

            // Assign a method to run when any event happens with the component.
            myButton12.ButtonPressEvent += new FEZ_Components.Button.ButtonPressEventHandler(myButton12_ButtonPressEvent);
           
            Thread.Sleep(Timeout.Infinite);
        }

         // For When the button is pressed
        static void myButton12_ButtonPressEvent(FEZ_Pin.Interrupt pin, FEZ_Components.Button.ButtonState state)
        {
            if (state == FEZ_Components.Button.ButtonState.Pressed)
            {
                // Check is SD Card is in
                bool sdExists = sdDetectPin.Read();
                if (sdExists == true)
                {
                    // Mount SD Card
                    if (sd == null)
                    {
                        sd = new PersistentStorage("SD");
                        sd.MountFileSystem();

                        Debug.Print("New SD card is mounted");
                        Debug.Print("");
                        Thread.Sleep(5000);
                        sd.UnmountFileSystem();
                        Debug.Print("SD card has been unmounted");

                    }
                    else
                    {
                        Debug.Print("Old SD card is still  mounted");
                        Thread.Sleep(5000);
                        sd.UnmountFileSystem();
                        Debug.Print("Old SD card has been unmounted");
                    }                  
                }
                else
                {
                    Debug.Print("No SD inserted");
                }
                Debug.Print("End of Button Press");            
            }
        }

         static void RemovableMedia_Eject(object sender, MediaEventArgs e)
        {
            Debug.Print("Storage \"" + e.Volume.RootDirectory + "\" is ejected.");
        }
    }

    public static partial class FEZ_Components
    {
        public class Button : IDisposable
        {
            InputPort button;

            public Button(FEZ_Pin.Digital pin)
            {
                button = new InputPort((Cpu.Pin)pin, false, Port.ResistorMode.PullUp);
            }

            public Button(FEZ_Pin.Interrupt pin)
            {
                button = new InterruptPort((Cpu.Pin)pin, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
                button.OnInterrupt += new NativeEventHandler(OnInterrupt);
            }

            void OnInterrupt(uint data1, uint data2, DateTime time)
            {
                ButtonState state = (data2 == 0) ? ButtonState.Pressed : ButtonState.NotPressed;
                ButtonPressEvent((FEZ_Pin.Interrupt)data1, state);
            }

            public void Dispose()
            {
                button.Dispose();
            }

            public enum ButtonState : byte
            {
                NotPressed = 0,
                Pressed = 1,
            }

            public ButtonState GetState()
            {
                return (button.Read() == false) ? ButtonState.Pressed : ButtonState.NotPressed;
            }
            public delegate void ButtonPressEventHandler(FEZ_Pin.Interrupt pin, ButtonState state);
            public event ButtonPressEventHandler ButtonPressEvent = delegate { };
        }
    }
}



#2

This will explain:
http://netmf.codeplex.com/workitem/80

“…This seems because the SD card is removed before it got a chance to raise the event…”