Main Site Documentation

USB Host - Writing to Memstick


#1

Hi All,

I’ve been trying to make a little usb log class for writing data into a text file of sorts. I created the following class, which seems to be working fine, except that there is no actual data in the file. Even though it does create the file on the memstick.



  class USBLog
  {
    private UsbHost usbHostModule;
    private StorageDevice usbStorage;
    private string logFileName = "";
    private TextWriter logFile;
    
    public bool DriveConnected = false;

    public USBLog(UsbHost usbHost, string fileName)
    {
      usbHostModule = usbHost;
      usbHostModule.DebugPrintEnabled = true;

      // add events
      usbHostModule.USBDriveConnected += new UsbHost.USBDriveConnectedEventHandler(usbHostModule_USBDriveConnected);
      usbHostModule.USBDriveDisconnected += new UsbHost.USBDriveDisconnectedEventHandler(usbHostModule_USBDriveDisconnected);

      logFileName = fileName;

      // setup flags
      DriveConnected = false;
    }

    void usbHostModule_USBDriveDisconnected(UsbHost sender)
    {
      DriveConnected = false;

      try
      {
        // device is gone, but probably need to close anyways
        logFile.Close();
      }
      catch (Exception Ex)
      {
        Debug.Print("Drive Disconnected: " + Ex.Message);
      }
    }

    void usbHostModule_USBDriveConnected(UsbHost sender, StorageDevice storageDevice)
    {
      DriveConnected = true;
      usbStorage = storageDevice;

      // try to open file

      Debug.Print( "Connected ! - Opening File" );

      try
      {
        logFile = new StreamWriter(storageDevice.OpenWrite(logFileName));
      }
      catch (Exception Ex)
      {
        Debug.Print("Error opening file: " + Ex.Message);
      }

    }

    public void close()
    {
      DriveConnected = false;
      logFile.Close();
    }

    public bool log(string msg)
    {
      if (!DriveConnected) return false;

      Debug.Print("Writing Log Entry: " + msg);
      
      try
      {
        logFile.WriteLine(msg);
        logFile.Flush();

        Debug.Print("Done");
      }
      catch (Exception Ex)
      {
        Debug.Print("Error writing to log");
        return false;
      }

      return true;
    }

  }

I tested this class with the following code:



using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Touch;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;
using Gadgeteer;

namespace USBLogger
{
  public partial class Program
  {
    // This method is run when the mainboard is powered up or reset.

    private USBLog log;
    private bool firstTime = true;

    void ProgramStarted()
    {
      usbHost.DebugPrintEnabled = true;

      log = new USBLog(usbHost, "temp.log");
     
      Debug.Print("Program Started");

      GT.Timer test= new GT.Timer(1000);
      test.Tick += new GT.Timer.TickEventHandler(test_Tick);
      test.Start();
    }

    void test_Tick(GT.Timer timer)
    {
      if (log.DriveConnected && firstTime )
      {
        log.log("Test 1");
        log.log("Test 2");
        log.log("Test 3");
        log.log("Test 4");
        log.log("Test 5");

        firstTime = false;
      }

    }

  }
}

and this is the output in Visual Studio


Program Started
Connected ! - Opening File
Writing Log Entry: Test 1
Done
Writing Log Entry: Test 2
Done
Writing Log Entry: Test 3
Done
Writing Log Entry: Test 4
Done
Writing Log Entry: Test 5
Done

Like I said, the file gets created in the root of the memory stick, but it stays empty.

Any ideas? Or am I missing something?


#2

Close the files and unmount the media before removing it.


#3

I was under the impression that doing a flush after writing would write everything to the disk?

I can close the file as well, which doesn’t make a difference. How would I go about the unmount the disk ?

Neither the StorageDevice or the usbhost gives me an option to unmount it.

If I close the file and then stop the project then the data is written nicely. But if I remove the memstick without stopping the project then it doesn’t write the data in the file, even though the file has been closed. I would like to be able to write data, flush everything so that it is written (even though it is still “mounted”).

Thanks for the help,
Tom


#4

My guess is that your order is wrong for close, flush and disconnect. I can try your class tonight and confirm.

You should close the file (to ensure that it is written properly - memory at this stage, potentially not to disk yet), then flush the storage (to ensure it is fully written to disk). Then you would be free to disconnect the storage.

Closing the file is not enough from what I have read of the USB/storageDevice spec. There is additional caching that takes place to ensure that read/write speeds to and from storage in the embedded platform are not held up by the speed of the media (sometimes slow flash). Not closing the file will prevent it being written to file. Not flushing the disk will prevent it from being written to storage before the storage is disconnected.

Hope that helps.

Cheers,
Matt