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;
}
}