NAME

NAND Flash File Server - nandfsys

SYNOPSIS

#include <fsysinit.h>

#include <device.h>

#include <fsys.h>

#include <nand_flash.h>

pthread_create(&tid, &attr, (void *(*)(void*))_nand_file_server, (char*)&fsysinit)
THREAD _nand_file_server( (char *)&fsysinit)
    struct fsysinit {
            uint_16 fsi_msgsize;
            uint_16 fsi_nclones;    /* Number of servers to create. */
            uint_32 fsi_datalog;    /* datlog bit definition */
            uint_16 fsi_nbuffers;   /* Number of buffers in buffer cache, minimum 2*/
            uint_16 fsi_blocksize;  /* Memory block size: 256 for NAND Flash, 512 for sd/mmc-card */
            uint_16 fsi_maxopen;    /* Max number of open files */
            uint_16 fsi_ndrives;    /* Maximum number of allocated disks, valid for FATFS only*/
    };

DESCRIPTION

The NAND Flash file server - fsys is Linux compatible file system with NAND Flash . File can use RAM disc or SD card or equivalent or NAND flash depending of low level driver implementation specified in demo application. The files are devstrad.c, nand_flash.c and nand_flash.h (see example below)

Nandfsys 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 file server involves several steps common in various operating system environments including Linux. There is no difference with the various media choices.

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

  2. Register the 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 (formatting media, all content will be deleted).

  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 options are for the Nand Flash File Server. The driver has the second set of options.

    FSYSDEBUG
    Enable overall debug logging with xprintf.
    DEBUGFSYS
    Enable deep structure debug logging with xprintf.
    MOUNTDEBUG
    Enable Mount debug logging with xprintf.
    RWDEBUG
    Enable read write debug logging with xprintf.
    DEBUGGING
    Enable superblock debug logging with xprintf.
    NOCLOCK
    No clock is used so return a fake time.
    NAND_ECC_ENABLE
    Enable ECC for NAND.

    NAND Driver Options setup in devstrad

    DEV_TYPE
    Device type, in this case DEV_NAND, DEV_SD, DEV_RAM
    DEV_PAGE_SIZE
    Device page size. Used only for DEV_NAND type.
    DEV_PAGE_DATA_SIZE
    Device page data size. Used only for DEV_NAND type.
    SPARE_PAGE_SIZE
    Spare device page size. Used only for DEV_NAND type.
    DEV_NUM_PAGE_BLOCKS
    Number of pages in a physical block. Used only for DEV_NAND type.
    DEV_NUM_BLOCKS
    Number of blocks in the device. Used only for DEV_NAND type.
    DEV_BLOCK_ERASE
    Erase the block. Used only for DEV_NAND type.
    DEV_BLOCK_CHECK
    Verify the block. Used only for DEV_NAND type.

    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
    Set the number of parallel file servers. Each one is implemented as a separate thread.
    fsi_datalog
    Set the number of the file server for dynamic data logging.
    fsi_nbuffers
    Number of buffers in buffer cache. Note that the cache can be disabled using an ioctl.
    fsi_maxopen
    Set the maximum number of open files.
    fsi_blocksize
    Set the PAGE_DATA_SIZE for the NAND flash. The other common values are 256 for the RAM disc and 512 for the SD and uSD cards. The NAND flash requires additional information from NAND driver, see NAND Driver Options setup above.

    Open Options

    O_CONTIG
    Preallocates a specific size for the file using continuous blocks and extents.
    O_CREATE, O_CREAT
    Create the file if it does not exist except if O_EXCL is set.
    O_WRITE, O_WRONLY
    Open for writing.
    O_READ, O_RDONLY
    Open for reading.
    O_DIRECT
    Do not use buffer cache and use DMA hardware to write directly to the media. Not implemented on all systems.
    O_EXCLUSIVE, O_EXCL
    If this is set with O_CREATE, the creation will fail if the file exists. Useful for simple file locking.
    O_TRUNC, O_TRUNCATE
    Erases the file by setting the file length to zero. Does not alter file contents or free space.
    O_APPEND, O_APPENDD
    Set the seek pointer to the end of the file prior to each write
    O_UNBUF
    No space to be allocated for buffered I/O.

    IOCTL Options for NAND Flash

    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

    In case of any errors during operation with fsys system 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;    /* datlog bit definition */
            uint_16 fsi_nbuffers;   /* Number of buffers in buffer cache, minimum 2*/
            uint_16 fsi_blocksize;  /* Memory block size: 256 for NAND Flash, 512 for sd/mmc-card */
            uint_16 fsi_maxopen;    /* Max number of open files */
            uint_16 fsi_ndrives;    /* Maximum number of allocated disks, valid for FATFS only*/
    };
    
    ...
    
            /*
             *   FSYS Initialization
             */
    
            /* create the File server and mount the ram disk */
            fsysinit.fsi_msgsize = sizeof(struct fsysinit);
            fsysinit.fsi_nclones = 1;
            fsysinit.fsi_datalog = 0x3;     
            fsysinit.fsi_nbuffers = 4; /* num of disk buffers (cache size) */
            fsysinit.fsi_maxopen = 2; /* max num of open files */
            fsysinit.fsi_blocksize = PAGE_DATA_SIZE;
    
            // set up stack size and priority for main fsys threads and all clones
            pthread_attr_init(&attr);
            pthread_attr_setstacksize(&attr, FSYSSTACKSIZE);
            myNewFsysPriority.sched_priority = FSYSPRIO;
            pthread_attr_setschedparam(&attr, &myNewFsysPriority);
    
            if(!pthread_create(&tid, &attr, (void*(*)(void*))_nand_file_server, (char*)&fsysinit))
            {
                    if(!dir_register(FSYS_DIRECTORY, tid, TYPE_SERVER))
                    {
                            xprintf("..Unable to register name of Nand File Server..\n");
                            xprintf("..Required resource not present - aborting..\n");
    #if RTOS_DEBUG
                            dir_deregister("Main thread");
    #endif
                            pthread_exit((void*)1);
                    }
            }
                    
            else
            {
                    xprintf("..Unable to create File Server..\n");
                    xprintf("..Required resource for program not present - aborting..\n");
    #if RTOS_DEBUG
                    dir_deregister("Main thread");
    #endif
                    pthread_exit((void*)1);
            }
    
            xprintf(".. Nand Fsys File server is now created..\n");
            xprintf("..Attempting to mkfs and mount it...\n");
    
            // parameters found in main.h
            mkfs_status = mkfs(FSYS_DIRECTORY, NAND_DEVICE_NO,  0, NAND_DISK_MAX_FILES);
            if(mkfs_status == -1)
            {
                    xprintf("..Unable to make a file system. errno=%d\n", errno);
                    xprintf("..Please fix me\n");
    #if RTOS_DEBUG
                    dir_deregister("Main thread");
    #endif
                    pthread_exit((void*)1);
            }
    
            // must mount a directory for each mount point, here d1,
            // unique name for each
            if((mount_status = mount(NAND_DEVICE_NO, FSYS_MOUNT, 0)) == -1)
            {
                    xprintf("..Unable to mount nand flash disk. errno=%d\n", errno);
                    xprintf("..Please fix me\n");
    #if RTOS_DEBUG
                    dir_deregister("Main thread");
    #endif
                    pthread_exit((void*)1);
            }
         
    ...  
    File devstrad.c content
    ...  
    ******** NAND FLASH usage *********
    struct bdevsw bdevsw[] = {
            {(int(*)(udev_t,int,int,char*,int))nodev,  nodev,  nodev,(int(*)(udev_t,char,void*))nodev,  0}, /* zero is an invalid dev num */
            {disk_strategy, disk_open, disk_close,disk_ioctl,0}
    };
    
    ...  
    int disk_open(udev_t dev)  - will initialize the NAND flash driver
    int disk_close(udev_t dev)  - will close the NAND flash driver.
    int disk_strategy(udev_t dev, int_32 off, int len, char *buf, int rwflag)- this routine is used to read/write data from/to the NAND flash disk 
    int disk_ioctl(udev_t dev, char ctrl, void *buff)- this routine is used to control NAND flash parameters and spare page operations for the NAND flash disk 
    
    
    See demo examples for more details

      SEE ALSO

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


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