Problems using USB mass storage device, USBHost in general and about Glide

Hi everyone,

I’m new here and I’m not familiar with .NET MF (I’m learning it for less than a month), and this is my first serious attempt with handling USB storage.

I. Well, I wrote a big program for FEZ Cobra, where a small part is about sending a file to the flash drive connected via USB. I’m using one 4GB flash drive.
When I tried for the first time, it looked ok. At second attempt… I connected my pendrive to a PC to see if everything is ok. Well… It wasn’t. I saw such mess for the first time! There were few folders and files with names containing some letters and various nonalphanumeric characters. Some of them had size over 3GB. I wasn’t able to access or delete any of them. So I formatted the device.
Later I have extracted the part which is related to handling the flash drive and done several tests.
Here it is:

using System.IO;
using System.Text;
using System.Threading;
using GHIElectronics.NETMF.Hardware;
using GHIElectronics.NETMF.IO;
using GHIElectronics.NETMF.USBHost;
using System;
using Microsoft.SPOT.IO;
using NetMf.CommonExtensions; //http://netmfcommonext.codeplex.com/

namespace MFConsoleApplication1
{
    public class Program
    {
        private static PersistentStorage _ps;

        public static void Main()
        {
            RemovableMedia.Insert += RemovableMedia_Insert;
            RemovableMedia.Eject += RemovableMedia_Eject;
            USBHostController.DeviceConnectedEvent += DeviceConnectedEvent;
            
            Thread.Sleep(Timeout.Infinite);
        }

        static void DeviceConnectedEvent(USBH_Device device)
        {
                try
                {
                    _ps = new PersistentStorage(device); //exception at first attempt after formatting the device
                    _ps.MountFileSystem();
                }
                catch (Exception)
                {
                }
        }
        
        static void RemovableMedia_Insert(object sender, MediaEventArgs e) 
        {
            if (!e.Volume.IsFormatted)
                return;

            var path = e.Volume.RootDirectory + @ "\" + Timestamp() + ".txt";
            using (var logStream = new FileStream(path, FileMode.Create, FileAccess.Write)) //sometimes an exception
            {
                logStream.Write(Encoding.UTF8.GetBytes("hewhjw"), 0, 6);
                File.SetAttributes(path, FileAttributes.ReadOnly);
                logStream.Flush();
                e.Volume.FlushAll();
                logStream.Close();
            }
        }

        static void RemovableMedia_Eject(object sender, MediaEventArgs e)
        {
            _ps.UnmountFileSystem();
            _ps.Dispose();
        }

        private static string Timestamp()
        {
            var datetime = RealTimeClock.GetTime().ToString();
            datetime = datetime.Replace(" ", "_");
            datetime = datetime.Replace(":", "");
            datetime = datetime.Replace("/", "");
            return datetime;
        }
    }
}

What have I seen? When I format the device (and maybe create some file there), always for the first time I get an exception in the line where the PersistentStorage constructor is called (unfortunately, I don’t remember what kind of exception, I will be able to check it tomorrow). When I connect the device again (without resetting Cobra), it is ok, but…
Sometimes PersistentStorage was created successfuly, but RemovableMedia.Eject event didn’t occur. It turned out that I have to format my flash drive then.
Sometimes, even if the device is freshly formatted and empty (I couldn’t discover what conditions are needed - it’s somehow random for me) I get the IO_Exception on the line where the FileStream constructor is called. It’s weird because as I read @ Microsoft, it occurs when using FileMode.CreateNew while there already exists a file with the same path, and my device is empty. I’ll try it again tomorrow but resetting the Cobra (60% probability) or formatting the device was fixing it.

Ok, when I got both devices set (with a bit of luck) into state when no Exception was thrown, what turned out… An example:

  1. Format the pen drive.
  2. Turn Cobra on.
  3. Insert the USB mass storage -> PersistentStorage() throws an exception
  4. Reconnect the USB mass storage -> Code execution analysis shows, that everything is fine
  5. Check on PC -> file created
  6. Once again -> file created
  7. Once again -> bush again!
    This problem occurs with random attempt. I don’t know what is the problem. I only know, that the program stopped at writing to the FileStream for a little bit longer time.

Tomorrow I will try with another pen drive if I find, and I’ll write here what kind of exception is thrown when PersistentStorage constructor is invoked for the first time. Although, if someone knows already how to solve the problem, please help.

II. I saw, when I have a program in debug mode, and I simply subscribe DeviceConnectedEvent for USB device, when I run my program in debug mode, it detects USB device that has already been connected (before starting the program). When I power the device (Cobra, Domino, Mini) via power connector, it works in the same way. When I power the device via USB cable (without using debug mode), I have to reconnect the plug. Why? How to solve this? Or in the other way - do I have to solve this?

Regards,
Tomasz

P.S. One thing my mind recovered, not related… Did anyone use Glide? It’s easy to create GUI, but am I able somehow to handle OnTouchDown and OnTouchUp with this? I would like to change the button image when the image is pressed and released. OnTapEvent is not suitable for this.

Tomasz

I played around with your sample code. I changed the TimeStamp class as I did not have the TimeStamp classes that you used handy.

My change :


private static string Timestamp()
        {
            var datetime = Microsoft.SPOT.Hardware.Utility.GetMachineTime();//RealTimeClock.GetTime().ToString();
            return datetime.Hours.ToString() + datetime.Minutes.ToString() + datetime.Milliseconds.ToString();
            //datetime = datetime.Replace(" ", "_");
            //datetime = datetime.Replace(":", "");
            //datetime = datetime.Replace("/", "");
            //return datetime;
        }

I did multiple tests in debug mode with a 4GB stick and there were no problems. All the events fired proper. However I am not sure of the use of the


_ps.UnmountFileSystem();

after the media is removed.

I was able to get consistent writes to the USB stick in debug, run and non USB powered mode [using external power] when the USB stick was plugged in prior to powerup.

However when I used external power and plugged out the USB, Windows reported an USB error when I tried to read the contents. See attached image.

However if I ignore the error, I do see that the file(s) have been created. The Windows scan did not find any errors. The advisory is that the device may have been dismounted before the media was closed.

Please try with another USB stick and improve error handling. In any case the user should have a way to unmount the USB before ejecting. May be a button or UI option will help.

HTH

Hi,

I have edited RemovableMedia_Insert event unmounting the drive in the end, for I assume that after writing a file, flash drive is to be ejected. I had to understand in a wrong way some steps found here: http://www.ghielectronics.com/downloads/NETMF/Library%20Documentation/html/54b37f26-0981-f721-57fe-1cefaf27a246.htm (The user detects that the storage device SD, or USB is removed or changed. → It should be unmounted using myPS.UnmountFileSystem().)

Here is the code:

static void RemovableMedia_Insert(object sender, MediaEventArgs e)
{
    if (!e.Volume.IsFormatted)
        return;

    var path = e.Volume.RootDirectory + @ "\" + Timestamp() + ".txt";
    using (var logStream = new FileStream(path, FileMode.Create, FileAccess.Write))
    {
        logStream.Write(Encoding.UTF8.GetBytes("hewhjw"), 0, 6);
        File.SetAttributes(path, FileAttributes.ReadOnly);
        logStream.Flush();
        e.Volume.FlushAll();
        logStream.Close();
    }
    Thread.Sleep(100);
    _ps.UnmountFileSystem();
    Debug.Print("Eject.");
}

Using the same USB drive, the same exception occurs when a freshly formatted drive is inserted:

[quote] #### Exception System.Exception - 0xffffffff (3) ####
#### Message:
#### GHIElectronics.NETMF.IO.PersistentStorage::PersistentStorage_Helper [IP: 0000] ####
#### GHIElectronics.NETMF.IO.PersistentStorage::.ctor [IP: 0011] ####
#### MFConsoleApplication1.Program::DeviceConnectedEvent [IP: 0006] ####
#### GHIElectronics.NETMF.USBHost.USBH_DeviceConnectionEventHandler::Invoke [IP: 0000] ####
#### GHIElectronics.NETMF.USBHost.USBHostController::nativeEventDispatcher_OnInterrupt [IP: 0037] ####
#### GHIElectronics.NETMF.System.InternalEvent::nativeEventDispatcher_OnInterrupt [IP: 0054] ####
A first chance exception of type ‘System.Exception’ occurred in GHIElectronics.NETMF.IO.dll[/quote]

Also I got once this random issue when creating PersistentStorage and Mounting the device didn’t throw an exception, but nothing happened later.
After formatting the device once it created the file properly, and in the next attempt I got the spaghetti again.
I have checked the device, it found an error (combined with created weirdfile) which was fixed.
Next attempt returned the same System.Exception. Next attempt wasn’t successful, I got an Insert event finished but after that the LED inside a pen drive case was still blinking for many seconds (I interrupted this), and after that I saw that nothing has been saved to a drive. After that I got 4 successful attempts. Next… Spaghetti.

I have obtained another flash drive. Device reset, first attempt… Ok. Next… Ok. Next… Ok. Next… Ok. Next… Ok.
Now without debug mode: 5 times everything ok.
Now with external power source: 5 times everything ok.

I assume that my flash drive is junk-ready. It’s not nice to hear, because for two years it was doing fine and it still looks ok when using with PC, so I didn’t think about that it might be something about the drive. Lesson #1.

Thanks a lot for your support :slight_smile:
Regards