NAME

FAT File Server - fatfs

SYNOPSIS

#include <device.h>
#include <fsysinit.h>

pthread_create(&tid, &attr, (void*(*)(void*))_fatfs_server, (char*)&fsysinit)
THREAD _fatfs_server( (char *)&fsysinit)
struct fsysinit {
    uint_16 fsi_msgsize;
    uint_16 fsi_nclones;    /* Number of servers to create, not used for FATFS */
    uint_32 fsi_datalog;    /* 1 - enable xprintf output for debug purpose, 0 - disable */
    uint_16 fsi_nbuffers;   /* Number of buffers in buffer cache, minimum 2, not used for FATFS*/
    uint_16 fsi_blocksize;   /* Memory block size: 256 for RAM-disc, 512 for sd/mmc-card, not used for FATFS */
    uint_16 fsi_maxopen;    /* Max number of open files */
    uint_16 fsi_ndrives;    /* Maximum number of allocated disk, valid for FATFS only*/
    };

DESCRIPTION

The fat file server, fatfs provides fast fat based, windows fat compatible file system. It is fully compatible with the multimedia file system and can be used to replace the multimedia file system with a FAT compatible file system for use with SD cards, uSD cards, MMC cards, and USB data sticks. It supports the following operations:

mkfs
make a file system, minor device numbers are used for different partitions
mount
mount a file system at a specific device and directory
open
open/create a file using flags
close
close a file
read
read from a file
write
write to a file
mkdir
make a directory
rmdir
remove directory
stat
get file information
fstat
get file information
link
create a link to a file
unlink
remove a link to a file
lseek
goto a specific offset in a file
umount
unmount a file system
chmod
change mode of a file relative to directory file descriptor
sync
schedule file system updates
getdirentries
get directory entries in a filesystem independent format

Typical operation for the fat file server involves several steps common in various operating system environments including Linux.

  1. Create a fat file server first so that commands can be carried out for the selected media. Use pthread_create to do this.

  2. Register the fat file server so that it can be found as a server in the system.

  3. Make a file system using mkfs. This creates a root directory structure on the media (doing device formatting, all information on media will be erased). It uses the optimal FAT 12, 16 or 32 format depending on the size of the media. This step is optional, and used only if need to create file system at new media. If media already has FAT, then this step could be avoided.

  4. Mount the file system. Note that an extra directory or a root directory is specified in addition to the registered file server name.

  5. The file system is now ready to use with the remaining file system commands.

    Compile Options

    The following compile time options may be used. Additional file compile time options do exist but should not be used without consulting the factory.

    _USE_LFN
    Use long file names may be set to one of three values, 0 - not used, 1 - on with BSS buffer, and 2 - on with stack buffer. The buffer size is set at 240 bytes.
    _MAX_SS
    Define the maximum sector size to be handled. The options are: 512/1024/2048/4096. The value of 512 is used for SD cards and Compact Flash, and it is the default.

    Run Time Options

    Initialization Options

    fsi_msgsize
    This is the size in bytes of the structure set for all standard Unison messages and initialization records.
    fsi_nclones
    This value is not used for fatfs
    fsi_datalog
    1 - enable xprintf output for debug purpose, 0 - disable
    fsi_nbuffers
    This value is not used fro fatfs
    fsi_maxopen
    Set the maximum number of open files.
    fsi_blocksize
    Set the file system block or sector size using the conditional compiliation values. This value is not used for fatfs.
    fsi_ndrives
    Maximum number of allocated disk, typically 1 for SD/MMC. But could be up to 9, if necessary to create different discs.

    Open Options

    O_CONTIG
    Not Supported.
    O_CREAT
    Create the file if it does not exist.
    O_WRITE, O_WRONLY
    Open for writing.
    O_READ, O_RDONLY
    Open for reading.
    O_DIRECT
    Not supported.
    O_EXCL
    Not supported.
    O_TRUNC
    Erases the file by setting the file length to zero. Does not alter file contents or free space.
    O_APPEND
    Set the seek pointer to the end of the file prior to each write
    O_UNBUF
    Not Supported.
    O_NONBLOCK
    The file is always open.

    IOCTL Options

    For more details, see functions description in I/O Library.

      RETURN VALUES

    In case of successful start up pthread_create will return 0 value.

      ERRORS

    If any of the following conditions occur, the function call shall return -1 and set errno to the corresponding POSIX compatible error code.

    EACCES
    Search permission is denied on a component of the path prefix, pr the file exists and the permissions specified b oflag are denied, or the file does not exist and write permission is denied for the parent directory of the file to be created, or O_TRUNC is specified and write permission is denied.
    EEXIST
    O_CREAT and O_EXCL are set and the named file exists.
    EINVAL
    The implementation does not support synchronized I/O for this file or another invalid parameter has been passed into the file server.
    EISDIR
    The named file is a directory, and the oflag argument specifies write or read/write access.
    EMFILE
    Too many file descriptors are currently in use.
    EMLINI
    Too many file links are currently in use.
    ENODEV
    The device is not available.
    ENFILE
    Too many files currently open in the system.
    ENOENT
    O_CREAT is not set and the named file does not exist, or O_CREAT is set and either the path prefix does not exist or the path argument points to an empty string.
    ENOMEM
    Insufficient memory exists to complete the request.
    ENOTDIR
    A component of the path prefix is not a directory.
    EROFS
    The named file resides on a read-only file system and either O_WRONLY, O_RDWR, O_CREAT (if the file does not exist), or O_TRUNC is set in oflag argument.
    EIO
    A physical I/O error occured.
    EPERM
    Insufficient ownership for the file operation.
    ENOTEMPTY
    The file or directory is not empty and the operation cannot be completed.
    ENOTSUPPORTED
    The fatfs file system does not support this operation.
    EBUSY
    The file system is busy and cannot complete the operation.
    ENODEV
    No such device.
    EFAULT
    File system error.
    EBADF
    Bad file operation.
    EBADFSYS
    File system is corrupted.

      EXAMPLE

    struct fsysinit {
            uint_16 fsi_msgsize;
            uint_16 fsi_nclones;    /* Number of servers to create. */
            uint_32 fsi_datalog;    /* 1 - enable xprintf output for debug purpose, 0 - disable */
            uint_16 fsi_nbuffers;   /* Number of buffers in buffer cache, minimum 2*/
            uint_16 fsi_blocksize;   /* Memory block size: 256 for RAM-disc, 512 for sd/mmc-card */
            uint_16 fsi_maxopen;    /* Max number of open files */
            uint_16 fsi_ndrives;    /* Maximum number of allocated disk, valid for FATFS only*/
    };
    
    #define FATFS_DIRECTORY "/dev/sd"
    #define FATFS_MOUNT FATFS_DIRECTORY "/d1"
    ...
    
            /*
             *
             *   FAT FS Initialization 
             *
             *
             */
    
            /* create the File server and mount disk */
            fsysinit.fsi_nclones = 1;       //should be at least 1
            fsysinit.fsi_datalog = 1;       //1 - enable xprintf output for debug purpose, 0 - disable
            fsysinit.fsi_ndrives = 1;       //maximum allowed disks, MAX  = 9
    
            // set up stack size and priority for main fsys threads and all clones
          pthread_attr_init(&attr);
          pthread_attr_setstacksize(&attr, FATFSSTACKSIZE);
            myNewFsysPriority.sched_priority = FATFSPRIO;
            pthread_attr_setschedparam(&attr, &myNewFsysPriority);
    
            if(!pthread_create(&tid, &attr, (void*(*)(void*))_fatfs_server, (char*)&fsysinit))
            {
                    if(!dir_register(FATFS_DIRECTORY, tid, TYPE_SERVER))
                    {
                            xprintf("..Unable to register name of File Server..\n");
                            xprintf("..Required resource not present - aborting..\n");
    #if RTOS_DEBUG
                            dir_deregister("Main thread");
    #endif
                            pthread_exit((void*)1);
                    }
            }
    
            /*preparing adding driver for SD/MMC/CF card disk*/
            hw_fat_drv.disk_initialize = hw_disk_initialize;
            hw_fat_drv.disk_ioctl = hw_disk_ioctl;
            hw_fat_drv.disk_read = hw_disk_read;
            hw_fat_drv.disk_write = hw_disk_write;
            hw_fat_drv.disk_status = hw_disk_status;
            hw_fat_drv.disk_timerproc = hw_disk_timerproc;
    
            res = fatfs_add_drv(FATFS_DIRECTORY, &hw_fat_drv, &HW_DEVICE_NO); //add new disk driver to driver list structure //return HW_DEVICE_NO - local disk driver num
    
    #ifdef MAKE_DISK_FORMATTING
            //mkfs will create FAT system at specified HW_DEVICE_NO.
            //FAT type will be automatically chooses, depending of flash drive capacity 
            mkfs_status = mkfs(FATFS_DIRECTORY, HW_DEVICE_NO, 0, 0);
    #endif
            
            mount(HW_DEVICE_NO, FATFS_MOUNT, 0);
            
            //Now FATFS ready for usage.    
    
    ...  
    ****** Hardware dependent low level driver functions ******
    
    //Initialize Disk Drive 
    DSTATUS hw_disk_initialize (void);
    //Get Disk Status
    DSTATUS hw_disk_status ();
    //Read Sector(s) 
    DRESULT hw_disk_read (BYTE *,DWORD , BYTE );
    //Write Sector(s)  
    DRESULT hw_disk_write (const BYTE *, DWORD, BYTE );
    //Functions to obtain disc parameters - 
    //GET_SECTOR_COUNT - Get number of sectors on the disk
    //GET_SECTOR_SIZE  - Get sector size (WORD)
    //From these values FATFS know capacity of drive.
    DRESULT hw_disk_ioctl (BYTE , void *);
    //typically used for SD cards to automatically detect card insert/eject and write protect.
    void    hw_disk_timerproc (void);           
    
    See demo examples for more details

      SEE ALSO

    chmod(), close(), lseek(),mkdir(), mkfs(), mount(), open(), read(), stat(), write(), fsys,


    < Copyright Rowebots Research Inc. and Multiprocessor Toolsmiths Inc. 1987-2011 >