USB Host : FileSystem.Unmount issue when device disconnected

Using the following code, the line Debug.WriteLine($"{DateTime.Now} : Filesystem unmounted"); is never reached, and the board resets itself after a certain amount of time (probably watchdog).

private static void TestUSBHost()
        {
            var usbHostController = UsbHostController.GetDefault();

            usbHostController.OnConnectionChangedEvent += UsbHostController_OnConnectionChangedEvent;
            usbHostController.Enable();
        }

        private static void UsbHostController_OnConnectionChangedEvent(UsbHostController sender,DeviceConnectionEventArgs e)
        {
            IDriveProvider drive;
            var storageController = StorageController.FromName(SC20260.StorageController.UsbHostMassStorage);

            switch (e.DeviceStatus)
            {
                case DeviceConnectionStatus.Connected:
                    Debug.WriteLine($"{DateTime.Now} : Device connected");
                    drive = FileSystem.Mount(storageController.Hdc);
                    Debug.WriteLine($"{DateTime.Now} : Filesystem mounted, getting drive info...");
                    var driveInfo = new DriveInfo(drive.Name);
                    Debug.WriteLine($"Free: {driveInfo.TotalFreeSpace}");
                    Debug.WriteLine($"TotalSize: {driveInfo.TotalSize}");
                    Debug.WriteLine($"VolumeLabel: {driveInfo.VolumeLabel}");
                    Debug.WriteLine($"RootDirectory: {driveInfo.RootDirectory}");
                    Debug.WriteLine($"DriveFormat: {driveInfo.DriveFormat}");

                    //Show a list of files in the root directory
                    var directory = new DirectoryInfo($"{drive.Name}\\FT810");
                    FileInfo[] files = directory.GetFiles();

                    foreach (FileInfo f in files)
                    {
                        Debug.WriteLine(f.Name);
                    }
                    break;

                case DeviceConnectionStatus.Disconnected:
                    Debug.WriteLine($"{DateTime.Now} : Device Disconnected");
                    FileSystem.Unmount(storageController.Hdc);
                    Debug.WriteLine($"{DateTime.Now} : Filesystem unmounted");
                    break;

                case DeviceConnectionStatus.Bad:
                    Debug.WriteLine("Bad Device");
                    break;
            }
        }

How can I unmount the FS when the device is disconnected ? If I don’t unmount it and I try to insert the USB stick again, I get an exception when it tries to mount the FS again, which is logical.

Nothinh wrong with that code, we will check. What board are you using?

MBN RAM board :wink: (using SC20260E SOM).
But your SC20260 dev board exhibits the same behavior.

Problem is

var directory = new DirectoryInfo($"{drive.Name}\\FT810");

Not sure why GetDirectories() is OK but “new DirectoryInfo()” cause unmount issue.

We will take a look on this issue later, but you can try different way as below:

    //Show a list of files in the root directory
     //var directory = new DirectoryInfo($"{drive.Name}\\FT810");
     //FileInfo[] files = directory.GetFiles();

     //foreach (FileInfo f in files)
     //{
     //    Debug.WriteLine(f.Name);
     //}
                   
     ExploreFolder(driveInfo.RootDirectory, $"{drive.Name}FT810");
static void ExploreFolder(DirectoryInfo directoryInfo, string path)
        {            
            var dirs = directoryInfo.GetDirectories();
            
            foreach (var dir in dirs)
            {
                if (dir.FullName.CompareTo(path) == 0)
                {
                    var files = dir.GetFiles();

                    foreach (var file in files)
                    {
                        Debug.WriteLine(file.Name);
                    }

                    break;
                }
                else
                {
                    ExploreFolder(dir, path);
                }
            }      
        }

Thank you for your reply.

But my initial issue was more “how to unmount the filesystem when the device gets disconnected ?”

I’ve tried to unmount first (before mounting) and I get two cases :

  • “Not mounted exception” the first time, which is expected since the drive has just been inserted
  • No message or exception the second time (once device has been disconnected then reconnected), which is again expected since a FS has been previously mounted.

But in that second case, I still get the exception when I try to mount the FS :frowning:

Is there a way to check if a FS is mounted ? I did not find anything obvious so far.

There is no flag to know that, you will add a flag to check that.

It looks like I did not understand correctly your answer… Are you saying that it’s the use of new DirectoryInfo() that causes the unmount issue afterward ?

If yes, then unfortunately your code does not solve the issue either. FileSystem.Unmount() still hangs the board :frowning:

Can you please send us a full simple project that I can reproduce?

With your first project, I could reproduce the issue and the workaround work fine.

Email sent to Gus, as I don’t know your email address.

Thanks, will check.

Back to this, yes I still can see the issue. Not sure why I didn’t see it before.

Can you please try this:

//Show a list of files in the root directory
var directory = new DirectoryInfo($"{drive.Name}\\FT810");
 FileInfo[] files = directory.GetFiles();

foreach (FileInfo f in files)
{
    Debug.WriteLine(f.Name);
 }

FileSystem.Flush(storageController.Hdc); // try to add this

Just make sure Flush() before Unmount() and not in Disconnected event.

Not sure why I didn’t see it before.

Let me think about how many times I have said the same thing… Sorry, I don’t have enough fingers and toes!

I would like to use my hairs.

1 Like

@Dat_Tran : this does indeed work.

However, this piece of code was purely a test. In a real application, I would not mount/unmount after each transaction.

That’s why I was expecting an unmount() in the Disconnected event.

No Unmount() each transaction.

Here is Flush(). Unmount() can be in Disconnected event, it will be OK. Just make sure Flush() before Unmount(), and Flush() must not inside Disconnected event.

1 Like

In my case, that will not work… :grinning:

1 Like

@Dat_Tran : it does indeed work with FileSystem.Flush() after transaction : I can now unmount in the disconnected event.

Thank you !

Can I add something, however ? There is no write involved in the example code, as it’s only a directory listing, so why should I “flush” the filesystem after that ?!

It does some accessing to device and failed because device is no longer connected, not really flush.

Probably update access last time timestamp, even no modified yet.

1 Like

Probably ? :wink:

Anyway, thank you for your answer.