Mount/Unmount filesystem

03 Dec 2010

I am working on a sort of command interpreter, and would like to dynamically mount and unmount filesystems, for example the LocalFileSystem, an SD Card or USB drive. Unmount is needed when taking out a drive and replacing it with something else.

The declaration and initialization of filesystems is always done outside main(), and not in a function. I have tested this inside a switch statement (see below), and it passes compilation, but I cannot open a file. When the declaration is done outside the scope of the function with the switch() statement, it works very well.

 

switch (inbuf[2]) {
case f_sdcard : { SDFileSystem sd(p5, p6, p7, p8, fs_sd); // mount SD card
break;
}
case f_flash  : { LocalFileSystem flash("local");        // mount local flash  
break;
}

}

My other question is if I need to unmount a filesystem prior to physical removal of an SD card or USB drive, and if so, how is this done. Then of ocurse when a new medium is inserted, it needs to be mounted again. How is that accomplished?

Thanks,

03 Dec 2010

Hi Meindert,

In your code example, you are creating the filesystem objects within a switch statement as "local" variables/objects. This means they will be deleted as soon as they go out of scope (after the switch statement).

Here is a simple version of your code:

#include "mbed.h"

int main() {
    switch(4) {
        case 4: 
            LocalFileSystem flash("local");
            break;
    }

    // at this time, flash has gone out of scope and will be destructed!!
    
    FILE *fp = fopen("/local/file.txt", "w");
    if(fp == NULL) {
        error("Couldn't open file!");
    }
    fprintf(fp, "Hello World!\n");
    fclose(fp);
}

This will cause the error "Couldn't open file!", as the filesystem no longer exists.

If you want to dynamically create objects, then you need to dynamically create them using "new" (they will go on the global memory "heap", rather than the local function "stack"). For example:

#include "mbed.h"

LocalFileSystem *flash;

int main() {
    switch(4) {
        case 4: 
            flash = new LocalFileSystem("local");
            break;
    }

    // filesystem dynamically created, so still exists until explicitly deleted
    
    FILE *fp = fopen("/local/file.txt", "w");
    if(fp == NULL) {
        error("Couldn't open file!");
    }
    fprintf(fp, "Hello World!\n");
    fclose(fp);
}

For mounting and un-mounting, you may be able to dynamically create (new) and destroy (delete) these filesystems, although I don't think it has ever been done/tested. These filesystems don't really have an explicit unmount command.

Hope this helps, Simon

05 Dec 2010

Simon

The example above doesn't compile, the compiler returns with:

"No default constructor exists for class "SDFileSystem" (E291)" in file "/ffuncs.cpp"

Basically, I do not mind the creation of the class to be outside a function scope. What I do not know is how to handle the changing of a card. Normally I would unmount the SD filesystem, change the card, and mount again. An SD card works fine when it has been in the mbed from reset, but plugging one in is tricky, I have not been able to get one to work yet.

For the local filesystem this is not in issue of course, as it cannot be unplugged. My next task to add however is a USB thumb drive, and there the plugging/unplugging may be an issue again. Any tips on how to proceed? My knowledge of C is very limited ...

Thanks

05 Dec 2010

Hi Meindert,

The example above doesn't use the SDFileSystem, so I suspect is is a sightly different program you had that didn't compile. "No Default Constructor" means you were trying to create an SDFileSystem object without giving it any arguments, so I suspect you were trying to instance an object when you meant to create a pointer, or something like that.

I think the new/delete method should give you what you want to mount/unmount. If it doesn't, you are probably charting new territory, but it is worth trying as I suspect it might.

Simon

05 Dec 2010

Did a few more tests, and for USB, using msc.disk_initialize() seems to do the trick. Simply pull the stick out and do msc.disk_initialize().

The SD card has the same function is in the libray, but in my case it hangs somewhere in this function after changing a card and doing sd.disk_initialize(), its last message being;

"No disk, or could not put SD card in to SPI idle state"

BTW I am using the Cool Components baseboard.

06 Dec 2010

So I just found myself in unchartered territory ...

I did make a mistake in my C, and could compile Simon's suggestion, but could not open a file, the pc console responds with

"No disk, or could not put SD card in to SPI idle state"

and gets stuck there, it does not return to the application. So back to the standard configuration, and with some trial and error I now have a working configuration, and indeed sd.disk_initialize() does the trick, but to my surprise I have to do it twice after inserting the SD card. This may have to do with the card type, or maybe a time-out in the library is a little bit too short. My results are really consistent, although I have only 2 cards to test, one is a 1 GByte SanDisk, the other one a 64 MByte  Nokia branded card, and both behave identical.

My code now looks like:

    switch (inbuf[2]) {
      case f_sdcard : // create object for SD card
                      // sd = new SDFileSystem(p5, p6, p7, p8, "sd");  
                      DBG_msg("do_fmount", "1st init");                 
                      sd.disk_initialize();             //initialize file system   
                      DBG_msg("do_fmount", "2nd init");
                      sd.disk_initialize();             //initialize file system 
                      break;                      
      case f_local  : // mount local flash, nothing really to do, it is always there                     
                      break;                      
      case f_usb    : msc.disk_initialize();             // enumerate USB device    
                      break;                                            
      default       : do_fdefault();                     // command not recognized
                      break;    
I am curious if others have found this behavior, and if maybe the time out in the laibrary should be made longer. In any case, when the card was already inserted during the reset, there are no problems, just changing a card causes this behavior.

12 May 2011

I may not be as experienced myself, but by playing with SD(hc) cards via the coolcomponents baseboard, i recocnised that the SD cards needs (a lot) of time to become ready.. around a few seconds. I couldnt ever get the SD to work at powerup with the standard (SDHC) library. Only when the device was already on for several seconds and receved a reset it worked, otherwise giving it the same error as you had recieved. I updated the "#define SD_COMMAND_TIMEOUT" to 50000 instead of the usual 5000, now the SD card is ready to use almost always directly when i power up. Maybe this could do some trick for your hotswap-initialisation? btw, what version baseboard do you have? if V2, did you also cut the trace to pin 9 in order to get that UART to work? ;) Hope it helps some..

12 May 2011

(whoops)

10 Jun 2012

With the USB Flash Drive (or equivalent, like an SD card in a USB Reader/Writer aqdapter), using MSCFileSystem, I just try to Open a "trial" file to see if the Drive is there. When the trial-file opens OK, I can Close, Open the one I want to write, Write a little or a lot (but occasionally get a long (700 ms) delay (Why?) in Writing, and Close the file.

After that, it seems like it is OK to remove the Flash Drive, but a Dismount or Eject function would be nice to make sure it is Safe to remove the Drive.

Perhaps the file Close does not return until the last data is written to the file, AND the directory is properly updated, so the Close makes it safe to remove?

Is the Initialize function needed after a second Flash Drive is inserted, to read the new Directory?

25 Feb 2013

Yes, sd.disk_initialize() twice does the trick. I experienced the same behavior and thanks to this post, my problem is solved !