Class that combined FATFileSystem with a USBMSD device, similar to LocalFileSystem

Dependencies:   USBDevice

Dependents:   SD_USB_FS_HelloWorld S25FL216K_USBFileSystem USBFileSystem_RAMDISK_HelloWorld

Introduction

USBFileSystem is a combination of FATFileSystem and USB-MSD (Mass-Storage Device). This way it allows you to create a filesystem that is both accessible on your PC with the USB cable plugged in, and on the device itself. This is very similar to LocalFileSystem, only you can use any Serial Flash, SD, etc as storage medium.

If your code works with either FATFileSystem or USBMSD it will with very little modification also work with USBFileSystem.

Basic functionality

Since both FATFileSystem and USBMSD write binary data to a the storage medium, if both are writing somewhere at the same time we have a problem. This library makes the medium read only for the local side, if USB is writing, and vice versa. Local is considered to be writing as long as you have opened a file for write. USB is considered writing as soon as a write command comes from USB, and this continues for a short time after the last write command. This is needed because I cannot know when the last sector is written by USB, so I have to wait a little while to see if more data is written.

Reading

You can still read when the other one is writing. This can result in issues. Using the functions given you can easily make sure that won't happen. However regardless if you do that or not, it is a good idea to make sure your program can handle unexpected situations. For example if you open a file locally, and you get a NULL pointer, do not immediatly go into an error condition, but just try it again.

USB MSD on your PC

When you write to / read from a USB drive Windows (and I expect other OS's too) will cache everything. The result is that once you read a file on your PC, it will never change, even if your mbed does change the data. And if you write/delete a file when the mbed is locally using the file system, it will be read only, however your PC will tell you data was succesfully written/removed.

If this is a problem for your device, you can disconnect the USB part when the mbed is writing to the storage medium locally. The library can do this automatically for you.

Required code

The virtual functions that need to be implemented by you are:

virtual int disk_initialize() { return 0; }
virtual int _disk_status() { return 0; }
virtual int disk_read(uint8_t * buffer, uint64_t sector) { return 0;}
virtual int _disk_write(const uint8_t * buffer, uint64_t sector) = 0;
virtual int disk_sync() { return 0; }
virtual uint64_t disk_sectors() = 0;

Some of those are optional, but disk_read, _disk_write and disk_sectors have to be defined in the child class.

Sector size

The sector size must be 512 bytes. In USBMSD this requirement isn't present, but FATFileSystem has this requirement!

Function name

Note the '_' at the beginning of _disk_status and _disk_write. You may not inherit it without the '_', that will break the library. Since the parent libraries made it virtual I cannot block it from happening, so just watch out.

Available functions for the user

The USBFileSystem library allows for some extra functions the user can use. The API documentation lists them, but summarized: You can attach functions which are called once either USB is writing to the storage medium, or when this is done locally. There are two functions which will tell you if currently USB/local is writing to the storage medium, and you can set the usbMode. Set it to mode 0 and USB is read only when the storage is used locally, set it to mode 1 and it is disconnected (default and recommended).

Besides that there are of course the standard USB functions (connect/disconnect for example), and you can use 'fopen', 'mkdir', etc similar to FATFileSystem.

Hello World

Currently available:

RAM-disk for KL25Z and LPC1768 (this one disappeared for some reason, I re-published it, should still work):

Import programUSBFileSystem_RAMDISK_HelloWorld

RAMDisk example for the USBFileSystem

Wi-Go serial flash:

Import programS25FL216K_HelloWorld

Helloworld program for the S25FL216K flash memory in combination with USBFileSystem

SD card (different from others):

Import programSD_USB_FS_HelloWorld

SD USB MSD helloworld

Note that this one is not mine, if you have problems with it check if there are updates for the library.

Committer:
Sissors
Date:
Sun Jan 18 21:43:06 2015 +0000
Revision:
8:a9e1dffac4bd
Parent:
6:15b73dae124e
Actually use count argument

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sissors 6:15b73dae124e 1 /* mbed Microcontroller Library - MemFileSystem
Sissors 6:15b73dae124e 2 * Copyright (c) 2008, sford
Sissors 6:15b73dae124e 3 */
Sissors 6:15b73dae124e 4
Sissors 6:15b73dae124e 5
Sissors 6:15b73dae124e 6 #ifndef MBED_MEMFILESYSTEM_H
Sissors 6:15b73dae124e 7 #define MBED_MEMFILESYSTEM_H
Sissors 6:15b73dae124e 8
Sissors 6:15b73dae124e 9 #include "FATFileSystem.h"
Sissors 6:15b73dae124e 10
Sissors 6:15b73dae124e 11 namespace mbed
Sissors 6:15b73dae124e 12 {
Sissors 6:15b73dae124e 13
Sissors 6:15b73dae124e 14 class MemFileSystem : public FATFileSystem
Sissors 6:15b73dae124e 15 {
Sissors 6:15b73dae124e 16 public:
Sissors 6:15b73dae124e 17
Sissors 6:15b73dae124e 18 // 2000 sectors, each 512 bytes (malloced as required)
Sissors 6:15b73dae124e 19 char *sectors[2000];
Sissors 6:15b73dae124e 20
Sissors 6:15b73dae124e 21 MemFileSystem(const char* name) : FATFileSystem(name) {
Sissors 6:15b73dae124e 22 memset(sectors, 0, sizeof(sectors));
Sissors 6:15b73dae124e 23 }
Sissors 6:15b73dae124e 24
Sissors 6:15b73dae124e 25 virtual ~MemFileSystem() {
Sissors 6:15b73dae124e 26 for(int i = 0; i < 2000; i++) {
Sissors 6:15b73dae124e 27 if(sectors[i]) {
Sissors 6:15b73dae124e 28 free(sectors[i]);
Sissors 6:15b73dae124e 29 }
Sissors 6:15b73dae124e 30 }
Sissors 6:15b73dae124e 31 }
Sissors 6:15b73dae124e 32
Sissors 6:15b73dae124e 33 // read a sector in to the buffer, return 0 if ok
Sissors 6:15b73dae124e 34 virtual int disk_read(char *buffer, int sector) {
Sissors 6:15b73dae124e 35 if(sectors[sector] == 0) {
Sissors 6:15b73dae124e 36 // nothing allocated means sector is empty
Sissors 6:15b73dae124e 37 memset(buffer, 0, 512);
Sissors 6:15b73dae124e 38 } else {
Sissors 6:15b73dae124e 39 memcpy(buffer, sectors[sector], 512);
Sissors 6:15b73dae124e 40 }
Sissors 6:15b73dae124e 41 return 0;
Sissors 6:15b73dae124e 42 }
Sissors 6:15b73dae124e 43
Sissors 6:15b73dae124e 44 // write a sector from the buffer, return 0 if ok
Sissors 6:15b73dae124e 45 virtual int disk_write(const char *buffer, int sector) {
Sissors 6:15b73dae124e 46 // if buffer is zero deallocate sector
Sissors 6:15b73dae124e 47 char zero[512];
Sissors 6:15b73dae124e 48 memset(zero, 0, 512);
Sissors 6:15b73dae124e 49 if(memcmp(zero, buffer, 512)==0) {
Sissors 6:15b73dae124e 50 if(sectors[sector] != 0) {
Sissors 6:15b73dae124e 51 free(sectors[sector]);
Sissors 6:15b73dae124e 52 sectors[sector] = 0;
Sissors 6:15b73dae124e 53 }
Sissors 6:15b73dae124e 54 return 0;
Sissors 6:15b73dae124e 55 }
Sissors 6:15b73dae124e 56 // else allocate a sector if needed, and write
Sissors 6:15b73dae124e 57 if(sectors[sector] == 0) {
Sissors 6:15b73dae124e 58 char *sec = (char*)malloc(512);
Sissors 6:15b73dae124e 59 if(sec==0) {
Sissors 6:15b73dae124e 60 return 1; // out of memory
Sissors 6:15b73dae124e 61 }
Sissors 6:15b73dae124e 62 sectors[sector] = sec;
Sissors 6:15b73dae124e 63 }
Sissors 6:15b73dae124e 64 memcpy(sectors[sector], buffer, 512);
Sissors 6:15b73dae124e 65 return 0;
Sissors 6:15b73dae124e 66 }
Sissors 6:15b73dae124e 67
Sissors 6:15b73dae124e 68 // return the number of sectors
Sissors 6:15b73dae124e 69 virtual int disk_sectors() {
Sissors 6:15b73dae124e 70 return sizeof(sectors)/sizeof(sectors[0]);
Sissors 6:15b73dae124e 71 }
Sissors 6:15b73dae124e 72
Sissors 6:15b73dae124e 73 };
Sissors 6:15b73dae124e 74
Sissors 6:15b73dae124e 75 }
Sissors 6:15b73dae124e 76
Sissors 6:15b73dae124e 77 #endif