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

Dependencies:   USBDevice

Dependents:   SD_USB_FS_HelloWorld S25FL216K_USBFileSystem USBFileSystem_RAMDISK_HelloWorld

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBFileSystem.h Source File

USBFileSystem.h

00001 #ifndef USBFILESYSTEM_H
00002 #define USBFILESYSTEM_H
00003 
00004 #include "FATFileSystem.h"
00005 #include "USBMSD.h"
00006 #include "FATFileHandle.h"
00007 
00008 class FATFileSystem_ds : public FATFileSystem {    
00009     public:
00010     FATFileSystem_ds(const char* n) : FATFileSystem(n) {};
00011     
00012     protected:
00013     virtual int disk_status_fat( void ) = 0;
00014     virtual int disk_status( void ) {return disk_status_fat();}
00015 };
00016 
00017 class USBMSD_ds : public USBMSD {    
00018     public:
00019     USBMSD_ds() {};
00020     
00021     protected:
00022     virtual int disk_status_msd( void ) = 0;
00023     virtual int disk_status( void ) {return disk_status_msd();}
00024 };
00025 
00026 /** Class which combines FATFileSystem with USBMSD device
00027 *
00028 * The functions to be implemented by the child class are the same as
00029 * those that have to be implemented when using FATFileSystem/USBMSD.
00030 * However there are some caveats: _disk_status() and _disk_write MUST
00031 * be named with the '_' in front of it. You are not allowed to have a
00032 * function without the '_'. Those functions may not be inherited, but
00033 * with this version of C++ I cannot prevent the child from doing so.
00034 *
00035 * Next the size of a disk sector must be 512 bytes. This is because
00036 * FATFileSystem only accepts that. If disk_size is not implemented
00037 * this is done automatically. 
00038 *
00039 * What the library does is block write access locally when USB writes,
00040 * and USB write access is blocked when with fopen a file is opened for
00041 * write locally. This way they can't both write at the same time. Read
00042 * access is not blocked.
00043 *
00044 * The final issue to take into account is caching: FATFileSystem will not
00045 * re-open a file if you read twice the same data from it. So if USBMSD
00046 * changed it, it will not show up different. If you close the file and
00047 * call fopen again it will work. The USBMSD part has the
00048 * same issue, but worse. Windows at least will only load everything once!
00049 * So if you open a file, and then change it manually, you will never find
00050 * out until the device is disconnected. If the disk is write protected
00051 * it will not tell you so. It will write/delete what you want, only when
00052 * you reconnect the device will it show it didn't actually do anything!
00053 *
00054 * See the program's wiki for more documentation!
00055 */
00056 class USBFileSystem : public FATFileSystem_ds, public USBMSD_ds {
00057 public:
00058     /** 
00059     * Constructor for USBFileSystem
00060     *
00061     * @param n - Name for the file system
00062     */
00063     USBFileSystem(const char* n);
00064     
00065     /** Attach a function to be called when locally the filesystem is occupied/freed
00066     *
00067     * The function is called with 'true' as argument when it is freed, false when it is occupied
00068     *
00069     * @param function - Function to be called, must have void as return type, and a single boolean argument
00070     */
00071     void attachLocal(void (*function)(bool));
00072     
00073     /** Attach a function to be called when USB occupies/frees the filesystem 
00074     *
00075     * The function is called with 'true' as argument when it is freed, false when it is occupied
00076     *
00077     * @param function - Function to be called, must have void as return type, and a single boolean argument
00078     */
00079     void attachUSB(void (*function)(bool));
00080     
00081     /** Check if locally files are opened for write
00082     *
00083     * @return - true if none are opened for write, false otherwise
00084     */
00085     bool localSafe( void );
00086     
00087     /** Check if via USB files files are being written
00088     *
00089     * @return - true if none are being written, false otherwise
00090     */
00091     bool usbSafe( void );
00092     
00093     /** Sets the USB mode
00094     *
00095     * Argument = 0: USB is write protected when not available.
00096     * Argument = 1: USB is disconnected when not available (default).
00097     *
00098     * @param mode - USB safety mode
00099     */
00100     void usbMode( int mode );
00101     
00102     
00103 protected:
00104     //Functions to be implemented by child:
00105     virtual int disk_initialize() { return 0; }
00106     virtual int _disk_status() { return 0; }
00107     virtual int disk_read(uint8_t * buffer, uint64_t sector, uint8_t count) { return 0;}
00108     virtual int _disk_write(const uint8_t * buffer, uint64_t sector, uint8_t count) = 0;
00109     virtual int disk_sync() { return 0; }
00110     virtual uint64_t disk_sectors() = 0;
00111     virtual uint64_t disk_size() {return 512 * disk_sectors();}
00112     
00113     //Not to be implemented by child:
00114     virtual FileHandle* open(const char* name, int flags);
00115     void localOpen( bool open );
00116     void usbFree( void );
00117     
00118 private:
00119     virtual int disk_status_fat(void);
00120     virtual int disk_status_msd(void);
00121     virtual int disk_write(const uint8_t * buffer, uint64_t sector, uint8_t count);
00122     
00123     int local_count;
00124     int usbmode;
00125     Timeout usb_write;
00126     bool usbfree;
00127     
00128     void (*localFunction)(bool);
00129     void (*usbFunction)(bool);
00130     
00131     friend class USBFileHandle;
00132 
00133 };
00134 
00135 
00136 class USBFileHandle : public FATFileHandle {    
00137     public:
00138     USBFileHandle(FIL fh, USBFileSystem *p, bool write) : FATFileHandle(fh) {
00139      _p = p;
00140      _write = write;
00141     }
00142     
00143     protected:
00144     USBFileSystem *_p;
00145     bool _write;
00146     
00147     virtual int close() {
00148         int retval = FATFileHandle::close();
00149         if (_write)
00150             _p->localOpen(false);
00151         return retval;
00152         }
00153 };
00154 
00155 
00156 
00157 
00158 
00159 #endif