CobraII USB Unmount Exception

If I use the USB Interface occurs an exception during removal of the stick.

#### Exception System.NullReferenceException - CLR_E_NULL_REFERENCE (4) ####
#### Message: 
#### GHI.Usb.Host.BaseDevice::OnDisconnected [IP: 0017] ####
#### GHI.Usb.Host.Controller::OnDisconnect [IP: 002b] ####
#### GHI.Utilities.InternalEvent::RaiseEvent [IP: 000d] ####
#### GHI.Utilities.InternalEvent::OnEvent [IP: 0035] ####

Does anyone have an idea how to use the interface properly ?

Thx a lot.

Michael

Please post some code to reproduce this exception.

I have generated an application based on the gageteer application wizard with the board CobraIIEco.

-> ProgramStarted


       void ProgramStarted()
        {
            Mainboard.MassStorageMounted += Mainboard_MassStorageMounted;
            Mainboard.MassStorageUnmounted += Mainboard_MassStorageUnmounted;

            Mainboard.SDCardMounted += Mainboard_SDCardMounted;
            Mainboard.SDCardUnmounted += Mainboard_SDCardUnmounted;

            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");

            if (Mainboard.IsSDCardInserted)
            {
                if (Mainboard.IsSDCardMounted)
                {
                    StorageDevice sd = Mainboard.SDCardStorageDevice;

                    if (sd.Volume.IsFormatted)
                    {
                        string rootDirectory = sd.RootDirectory;
                        string[] files = Directory.GetFiles(rootDirectory);
                        string[] folders = Directory.GetDirectories(rootDirectory);

                        Debug.Print("Files available on " + rootDirectory + ":");
                        for (int i = 0; i < files.Length; i++)
                            Debug.Print(files[i]);
                        Debug.Print("Folders available on " + rootDirectory + ":");
                        for (int i = 0; i < folders.Length; i++)
                            Debug.Print(folders[i]);

                    }

                }
            }
        }

        void Mainboard_SDCardUnmounted(GHIElectronics.Gadgeteer.FEZCobraIIEco sender, EventArgs e)
        {
            
        }

        void Mainboard_SDCardMounted(GHIElectronics.Gadgeteer.FEZCobraIIEco sender, GT.StorageDevice device)
        {
            device.CreateDirectory("MSSNET");
        }

        void Mainboard_MassStorageUnmounted(GHIElectronics.Gadgeteer.FEZCobraIIEco sender, EventArgs e)
        {
            
        }

        void Mainboard_MassStorageMounted(GHIElectronics.Gadgeteer.FEZCobraIIEco sender, GT.StorageDevice device)
        {
            string rootDirectory = device.RootDirectory;
            string[] files = Directory.GetFiles(rootDirectory);
            string[] folders = Directory.GetDirectories(rootDirectory);
        
            Debug.Print("Files available on " + rootDirectory + ":");
            for (int i = 0; i < files.Length; i++)
                Debug.Print(files[i]);
            Debug.Print("Folders available on " + rootDirectory + ":");
            for (int i = 0; i < folders.Length; i++)
                Debug.Print(folders[i]);
        }
    }

The event “MassStorageMounted” is fired if plug in the Stick and I can read the content.
But if I remove the stick the exception occured.

thx a lot.

Michael

@ MHSchmidt - This is an issue that should be fixed for the next SDK.

OK.
It’s a workaround possible for this time ?

Thx.

@ MHSchmidt - Sadly no, it is a race condition in the driver for the mass storage class.

use the example code below, should work.

using System;
using System.IO;
using System.Threading;
using GHI.Usb;
using GHI.Usb.Host;
using Microsoft.SPOT;
using Microsoft.SPOT.IO;
using Microsoft.SPOT.Hardware;

namespace Test_USBH
{
    public class Program
    {
        //static OutputPort led = new OutputPort((Cpu.Pin)(3 * 32 + 3), true); // G400
        static Boolean testWrite = true;
        static OutputPort led = new OutputPort((Cpu.Pin)(47), true);
        //static InputPort button = new InputPort((Cpu.Pin)(30), false, Port.ResistorMode.PullUp); // emx
        static InputPort button = new InputPort((Cpu.Pin)(22), false, Port.ResistorMode.PullUp); // g120
        public static void Main()
        {
            led.Write(true);         
            while (button.Read()==true) 
            {
             
                Thread.Sleep(100);
                led.Write(true);
                Thread.Sleep(100);
                led.Write(!true);
            }
            RemovableMedia.Insert += new InsertEventHandler(RemovableMedia_Insert);
            RemovableMedia.Eject += new EjectEventHandler(RemovableMedia_Eject);
            GHI.Usb.Host.Controller.MassStorageConnected += Controller_MassStorageConnected;
            GHI.Usb.Host.Controller.Start();
            led.Write(!true);
            const int BLOCK_LEN = 10*1024;
            const int BLOCK_COUNT = 10; // 1M
            byte[] bufferwrite = new byte[BLOCK_LEN];
            for (int i = 0; i < BLOCK_LEN; i++)
            {
                bufferwrite[i] = (byte)(i % 0xFF);
            }
            while (true)
            {
                Thread.Sleep(100);       
                if (canWrite)
                {
                    VolumeInfo vol = VolumeInfo.GetVolumes()[0];
                    string root = vol.RootDirectory;
                    if (testWrite)
                    {
                        
                        FileStream fs = new FileStream(root + @ "\testUsb.txt", FileMode.Create);
                        for (int i = 0; i < BLOCK_COUNT; i++)
                        {
                            if (i % 10 == 0)
                                Debug.Print("i = " + i);
                            fs.Write(bufferwrite, 0, BLOCK_LEN);
                        }
                        fs.Flush();
                        fs.Close();
                        ps.Unmount();
                        canWrite = false;
                        Debug.Print("Write done");
                        led.Write(true);
                        break;
                    }
                    else
                    {
                        FileStream fs = new FileStream(root + @ "\testUsb.txt", FileMode.Open);
                        byte[] readdata = new byte[BLOCK_COUNT];
                        if (BLOCK_COUNT != fs.Read(readdata, 0, BLOCK_COUNT))
                        {
                            throw new Exception("Can not read!");
                        }
                        else
                        {
                            for (int i = 0; i < BLOCK_COUNT; i++)
                            {
                                if (readdata[i] != bufferwrite[i])
                                {
                                    throw new Exception("Read error at " +  i );
                                }
                            }
                            Debug.Print("Read OK");
                            break;
                        }

                    }
                }

            }
            Thread.Sleep(-1);
        }
        static void Controller_MassStorageConnected(object sender, MassStorage e)
        {
            ps = e;
            ps.Mount();
            Debug.Print("Thumb drive detected...");
        }
        static void Controller_DeviceConnectFailed()
        {
            Debug.Print("Device disconnected...");
           
        }
        static void RemovableMedia_Eject(object sender, MediaEventArgs e)
        {
            Debug.Print("Thumb drive unmounted...");
            canWrite = false;
        }
        static bool canWrite= false;
        static void RemovableMedia_Insert(object sender, MediaEventArgs e)
        {
            Debug.Print("Thumb drive mounted...");
            canWrite = true;
        }
        static GHI.Usb.Host.MassStorage ps;
        

    }
}