Add Ken Pettit's SMART FS

This commit is contained in:
Gregory Nutt 2013-04-30 20:13:30 -06:00
parent 25d5706ca3
commit 7ed7749a40
16 changed files with 4151 additions and 12 deletions

View File

@ -4651,4 +4651,5 @@
* configs/sim/mtdpart: A new configuration to test MTD
partitions (2013-4-30).
* configs/sim/mkroe-stm32f4: Support for the MikroElektronika
Mikromedia for STM32F4 development board (from Ken Petit, 2013-4-30).
Mikromedia for STM32F4 development board (from Ken Petit, 2013-4-30).
* fs/smartfs: Add Ken Pettits SMART FS (2013-4-30).

View File

@ -14,6 +14,7 @@ source fs/fat/Kconfig
source fs/nfs/Kconfig
source fs/nxffs/Kconfig
source fs/romfs/Kconfig
source fs/smartfs/Kconfig
source fs/binfs/Kconfig
comment "System Logging"

View File

@ -103,6 +103,7 @@ include fat/Make.defs
include romfs/Make.defs
include nxffs/Make.defs
include nfs/Make.defs
include smartfs/Make.defs
include binfs/Make.defs
endif

View File

@ -99,6 +99,9 @@ extern const struct mountpt_operations fat_operations;
#ifdef CONFIG_FS_ROMFS
extern const struct mountpt_operations romfs_operations;
#endif
#ifdef CONFIG_FS_SMARTFS
extern const struct mountpt_operations smartfs_operations;
#endif
static const struct fsmap_t g_bdfsmap[] =
{
@ -107,6 +110,9 @@ static const struct fsmap_t g_bdfsmap[] =
#endif
#ifdef CONFIG_FS_ROMFS
{ "romfs", &romfs_operations },
#endif
#ifdef CONFIG_FS_SMARTFS
{ "smartfs", &smartfs_operations },
#endif
{ NULL, NULL },
};

53
fs/smartfs/Kconfig Normal file
View File

@ -0,0 +1,53 @@
#
# For a description of the syntax of this configuration file,
# see misc/tools/kconfig-language.txt.
#
config FS_SMARTFS
bool "SMART file system"
default n
depends on !DISABLE_MOUNTPOINT
---help---
Enable NuttX SMART Flash file system (SMARTFS) support.
if FS_SMARTFS
config SMARTFS_ERASEDSTATE
hex "FLASH erased state"
default 0xff
---help---
The erased state of FLASH.
This must have one of the values of 0xff or 0x00.
Default: 0xff.
config SMARTFS_MAXNAMLEN
int "Maximum file name length"
default 16
---help---
The maximum size of a SMARTFS file name at a given
directory level. Overall path name is not restricted
by this value, only individual segments in a path,
such as (assuming /usr is the mount point):
/usr/games/chess/player_stats/game1.xml
Default: 16.
config SMARTFS_MULTI_ROOT_DIRS
bool "Support multiple Root Directories / Mount Points"
default n
---help---
Enables support for multiple root directory entries
on the SMART FLASH. Multiple root directories means
the device can have multiple mount point in the VFS,
each with it's own unique directory structure under it.
When this option is enabled, instead of reporting the
SMART block devices as "/dev/mtdsmart0", they will be
reported as "/dev/mtdsmart0d1", "/dev/mtdsmart0d2", etc.
The number of root entries actually created is set
during the "mksmartfs" command when the device is
initialized.
Default: y.
endif

54
fs/smartfs/Make.defs Normal file
View File

@ -0,0 +1,54 @@
############################################################################
# Make.defs
#
# Copyright (C) 2008, 2011, 2013 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name Nuttx nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
ifeq ($(CONFIG_FS_SMARTFS),y)
# Files required for SmartFS file system support
ASRCS +=
CSRCS += smartfs_smart.c smartfs_utils.c
# Files required for mksmartfs utility function
ASRCS +=
CSRCS += smartfs_mksmartfs.c
# Include SMART build support
DEPPATH += --dep-path smartfs
VPATH += :smartfs
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)fs$(DELIM)smartfs}
endif

353
fs/smartfs/smartfs.h Normal file
View File

@ -0,0 +1,353 @@
/****************************************************************************
* fs/smartfs/smartfs.h
*
* Copyright (C) 2013 Ken Pettit. All rights reserved.
* Author: Ken Pettit <pettitkd@gmail.com>
*
* References: Linux/Documentation/filesystems/romfs.txt
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __FS_SMARTFS_SMARTFS_H
#define __FS_SMARTFS_SMARTFS_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <stdbool.h>
#include <semaphore.h>
#include <nuttx/mtd.h>
#include <nuttx/smart.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* SMART Definitions ********************************************************/
/* General SMART organization. The following example assumes 4 logical
* sectors per FLASH erase block. The actual relationship is determined by
* the FLASH geometry reported by the MTD driver.
*
* ERASE LOGICAL Sectors begin with a sector header. Sectors may
* BLOCK SECTOR CONTENTS be marked as "released," pending garbage collection
* n 4*n --+---------------+
* Hdr |LLLLLLLLLLLLLLL| Logical sector number (2 bytes)
* |QQQQQQQQQQQQQQQ| Sequence number (2 bytes)
* |SSSSSSSSSSSSSSS| Status bits (1 byte)
* +---------------+
* |TTTTTTTTTTTTTTT| Sector Type (dir or file) (1 byte)
* |NNNNNNNNNNNNNNN| Number of next logical sector in chain
* |UUUUUUUUUUUUUUU| Number of bytes used in this sector
* | |
* | (Sector Data) |
* | |
* 4*n+1 --+---------------+
* Sector Hdr |LLLLLLLLLLLLLLL| Logical sector number (2 bytes)
* |QQQQQQQQQQQQQQQ| Sequence number (2 bytes)
* |SSSSSSSSSSSSSSS| Status bits (1 byte)
* +---------------+
* FS Hdr |TTTTTTTTTTTTTTT| Sector Type (dir or file) (1 byte)
* |NNNNNNNNNNNNNNN| Number of next logical sector in chain
* |UUUUUUUUUUUUUUU| Number of bytes used in this sector
* | |
* | (Sector Data) |
* | |
* 4*n+2 --+---------------+
* Sector Hdr |LLLLLLLLLLLLLLL| Logical sector number (2 bytes)
* |QQQQQQQQQQQQQQQ| Sequence number (2 bytes)
* |SSSSSSSSSSSSSSS| Status bits (1 byte)
* +---------------+
* FS Hdr |TTTTTTTTTTTTTTT| Sector Type (dir or file) (1 byte)
* |NNNNNNNNNNNNNNN| Number of next logical sector in chain
* |UUUUUUUUUUUUUUU| Number of bytes used in this sector
* | |
* | (Sector Data) |
* | |
* 4*n+3 --+---------------+
* Sector Hdr |LLLLLLLLLLLLLLL| Logical sector number (2 bytes)
* |QQQQQQQQQQQQQQQ| Sequence number (2 bytes)
* |SSSSSSSSSSSSSSS| Status bits (1 byte)
* +---------------+
* FS Hdr |TTTTTTTTTTTTTTT| Sector Type (dir or file) (1 byte)
* |NNNNNNNNNNNNNNN| Number of next logical sector in chain
* |UUUUUUUUUUUUUUU| Number of bytes used in this sector
* | |
* | (Sector Data) |
* | |
* n+1 4*(n+1) --+---------------+
* Sector Hdr |LLLLLLLLLLLLLLL| Logical sector number (2 bytes)
* |QQQQQQQQQQQQQQQ| Sequence number (2 bytes)
* |SSSSSSSSSSSSSSS| Status bits (1 byte)
* +---------------+
* FS Hdr |TTTTTTTTTTTTTTT| Sector Type (dir or file) (1 byte)
* |NNNNNNNNNNNNNNN| Number of next logical sector in chain
* |UUUUUUUUUUUUUUU| Number of bytes used in this sector
* | |
* | |
* | |
* --+---------------+
*
* General operation:
* Physical sectors are allocated and assigned a logical sector number
* and a starting sequence number of zero.
*
* SECTOR HEADER:
* The sector header (first 5 bytes) tracks the state of each sector and
* is used by the SMART MTD block driver. At the block level, there is
* no notion of sector chaining, only allocated sectors within erase
* blocks.
*
* FILE SYSTEM (FS) HEADER:
* The file system header (next 5 bytes) tracks file and directory entries
* and chains.
*
* SMART Limitations:
* 1. SMART currently depends on the underlying MTD block driver supporting
* single-byte programming operation. This is due to the method it
* uses for marking a sector as "released", committed, etc.
* 2. Garbage collection can occur when a new sector is allocated or when
* existing sector data is overwritten with new data. Thus, occasionally,
* file writing may take longer than other times.
* 3. The implementation curently does not track bad blocks on the device.
* 4. There is no true wear-leveling implemented yet, though provesion have
* been made to reserve logical sectors to allow it to be added using
* a "sector aging" tracking mechanism.
*/
/* Values for SMART inode state.
*
* SMART_STATE_FILE - The inode is a valid usuable, file
* INODE_STATE_DELETED - The inode has been deleted.
* Other values - The inode is bad and has an invalid state.
*
* Care is taken so that the VALID to DELETED transition only involves burning
* bits from the erased to non-erased state.
*/
#define INODE_STATE_FILE (CONFIG_NXFFS_ERASEDSTATE ^ 0x22)
#define INODE_STATE_DELETED (CONFIG_NXFFS_ERASEDSTATE ^ 0xaa)
/* Directory entry flag definitions */
#define SMARTFS_DIRENT_EMPTY 0x8000 /* Set to non-erase state when entry used */
#define SMARTFS_DIRENT_ACTIVE 0x4000 /* Set to erase state when entry is active */
#define SMARTFS_DIRENT_TYPE 0x2000 /* Indicates the type of entry (file/dir) */
#define SMARTFS_DIRENT_DELETING 0x1000 /* Directory entry is being deleted */
#define SMARTFS_DIRENT_RESERVED 0x0E00 /* Reserved bits */
#define SMARTFS_DIRENT_MODE 0x01FF /* Mode the file was created with */
#define SMARTFS_DIRENT_TYPE_DIR 0x2000
#define SMARTFS_DIRENT_TYPE_FILE 0x0000
/* Number of bytes in the SMART magic sequences */
#define SMART_MAGICSIZE 4
/* Quasi-standard definitions */
#ifndef MIN
# define MIN(a,b) (a < b ? a : b)
#endif
#ifndef MAX
# define MAX(a,b) (a > b ? a : b)
#endif
/* Underlying MTD Block driver access functions */
#define FS_BOPS(f) (f)->fs_blkdriver->u.i_bops
#define FS_IOCTL(f,c,a) (FS_BOPS(f)->ioctl ? FS_BOPS(f)->ioctl((f)->fs_blkdriver,c,a) : (-ENOSYS))
/* The logical sector number of the root directory. */
#define SMARTFS_ROOT_DIR_SECTOR 3
/* Defines the sector types */
#define SMARTFS_SECTOR_TYPE_DIR 1
#define SMARTFS_SECTOR_TYPE_FILE 2
#ifndef CONFIG_SMARTFS_DIRDEPTH
#define CONFIG_SMARTFS_DIRDEPTH 8
#endif
#define SMARTFS_ERASEDSTATE_16BIT (uint16_t) ((CONFIG_SMARTFS_ERASEDSTATE << 8) | \
CONFIG_SMARTFS_ERASEDSTATE)
#ifndef offsetof
#define offsetof(type, member) ( (size_t) &( ( (type *) 0)->member))
#endif
#define SMARTFS_NEXTSECTOR(h) ( *((uint16_t *) h->nextsector))
#define SMARTFS_USED(h) ( *((uint16_t *) h->used))
/****************************************************************************
* Public Types
****************************************************************************/
/* This structure defines each packed block on the FLASH media */
/* This is an in-memory representation of the SMART inode as extracted from
* FLASH and with additional state information.
*/
struct smartfs_entry_s
{
uint16_t firstsector; /* Sector number of the name */
uint16_t dsector; /* Sector number of the directory entry */
uint16_t doffset; /* Offset of the directory entry */
uint16_t dfirst; /* 1st sector number of the directory entry */
uint16_t flags; /* Flags, including mode */
FAR char *name; /* inode name */
uint32_t utc; /* Time stamp */
uint32_t datlen; /* Length of inode data */
};
/* This is an on-device representation of the SMART inode it esists on
* the FLASH.
*/
struct smartfs_entry_header_s
{
uint16_t flags; /* Flags, including permissions:
15: Empty entry
14: Active entry
12-0: Permissions bits */
int16_t firstsector; /* Sector number of the name */
uint32_t utc; /* Time stamp */
char name[0]; /* inode name */
};
/* This structure describes the smartfs header at the start of each
* sector. It manages the sector chain and used bytes in the sector.
*/
struct smartfs_chain_header_s
{
uint8_t type; /* Type of sector entry (file or dir) */
uint8_t nextsector[2];/* Next logical sector in the chain */
uint8_t used[2]; /* Number of bytes used in this sector */
};
/* This structure describes the state of one open file. This structure
* is protected by the volume semaphore.
*/
struct smartfs_ofile_s
{
struct smartfs_ofile_s *fnext; /* Supports a singly linked list */
int16_t crefs; /* Reference count */
mode_t oflags; /* Open mode */
struct smartfs_entry_s entry; /* Describes the SMARTFS inode entry */
size_t filepos; /* Current file position */
uint16_t currsector; /* Current sector of filepos */
uint16_t curroffset; /* Current offset in sector */
uint16_t byteswritten;/* Count of bytes written to currsector
* that have not been recorded in the
* sector yet. We delay updating the
* used field until the file is closed,
* a seek, or more data is written that
* causes the sector to change. */
};
/* This structure represents the overall mountpoint state. An instance of this
* structure is retained as inode private data on each mountpoint that is
* mounted with a smartfs filesystem.
*/
struct smartfs_mountpt_s
{
#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS
struct smartfs_mountpt_s *fs_next; /* Pointer to next SMART filesystem */
#endif
FAR struct inode *fs_blkdriver; /* Our underlying block device */
sem_t *fs_sem; /* Used to assure thread-safe access */
FAR struct smartfs_ofile_s *fs_head; /* A singly-linked list of open files */
bool fs_mounted; /* true: The file system is ready */
struct smart_format_s fs_llformat; /* Low level device format info */
char *fs_rwbuffer; /* Read/Write working buffer */
char *fs_workbuffer;/* Working buffer */
uint8_t fs_rootsector;/* Root directory sector num */
};
/****************************************************************************
* Public Variables
****************************************************************************/
/****************************************************************************
* Internal function prototypes
****************************************************************************/
/* Semaphore access for internal use */
void smartfs_semtake(struct smartfs_mountpt_s *fs);
void smartfs_semgive(struct smartfs_mountpt_s *fs);
/* Forward references for utility functions */
struct smartfs_mountpt_s;
/* Utility functions */
int smartfs_mount(struct smartfs_mountpt_s *fs, bool writeable);
int smartfs_unmount(struct smartfs_mountpt_s *fs);
int smartfs_finddirentry(struct smartfs_mountpt_s *fs,
struct smartfs_entry_s *direntry, const char *relpath,
uint16_t *parentdirsector, const char **filename);
int smartfs_createentry(struct smartfs_mountpt_s *fs,
uint16_t parentdirsector, const char* filename,
uint16_t type,
mode_t mode, struct smartfs_entry_s *direntry,
uint16_t sectorno);
int smartfs_deleteentry(struct smartfs_mountpt_s *fs,
struct smartfs_entry_s *entry);
int smartfs_countdirentries(struct smartfs_mountpt_s *fs,
struct smartfs_entry_s *entry);
int smartfs_truncatefile(struct smartfs_mountpt_s *fs,
struct smartfs_entry_s *entry);
struct file; /* Forward references */
struct inode;
struct fs_dirent_s;
struct statfs;
struct stat;
#endif /* __FS_SMARTFS_SMARTFS_H */

View File

@ -0,0 +1,191 @@
/****************************************************************************
* fs/smartfs/smartfs_mksmartfs.c
*
* Copyright (C) 2013 Ken Pettit. All rights reserved.
* Author: Ken Pettit <pettitkd@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <debug.h>
#include <errno.h>
#include <nuttx/kmalloc.h>
#include <nuttx/fs/fs.h>
#include <nuttx/fs/mksmartfs.h>
#include <nuttx/fs/ioctl.h>
#include <nuttx/smart.h>
#include "smartfs.h"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: mksmartfs
*
* Description:
* Make a SMART Flash file system image on the specified block device
*
* Inputs:
* pathname - the full path to a registered block driver
* nrootdirs - Number of root directory entries to create.
*
* Return:
* Zero (OK) on success; -1 (ERROR) on failure with errno set appropriately:
*
* EINVAL - NULL block driver string, bad number of FATS in 'fmt', bad FAT
* size in 'fmt', bad cluster size in 'fmt'
* ENOENT - 'pathname' does not refer to anything in the filesystem.
* ENOTBLK - 'pathname' does not refer to a block driver
* EACCES - block driver does not support wrie or geometry methods
*
* Assumptions:
* - The caller must assure that the block driver is not mounted and not in
* use when this function is called. The result of formatting a mounted
* device is indeterminate (but likely not good).
*
****************************************************************************/
#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS
int mksmartfs(FAR const char *pathname, uint8_t nrootdirs)
#else
int mksmartfs(FAR const char *pathname)
#endif
{
struct inode* inode;
struct smart_format_s fmt;
int ret;
int x;
uint8_t type;
struct smart_read_write_s request;
/* Find the inode of the block driver indentified by 'source' */
ret = open_blockdriver(pathname, 0, &inode);
if (ret < 0)
{
fdbg("Failed to open %s\n", pathname);
goto errout;
}
/* Make sure that the inode supports the write and geometry methods at a minimum */
if (!inode->u.i_bops->write || !inode->u.i_bops->geometry)
{
fdbg("%s does not support write or geometry methods\n", pathname);
ret = -EACCES;
goto errout_with_driver;
}
/* Validate the block device is a SMART device */
/* Perform a low-level SMART format */
#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS
ret = inode->u.i_bops->ioctl(inode, BIOC_LLFORMAT, nrootdirs);
#else
ret = inode->u.i_bops->ioctl(inode, BIOC_LLFORMAT, 0);
#endif
if (ret != OK)
{
fdbg("Error creating low-level format: %d\n", ret);
goto errout_with_driver;
}
/* Get the format information so we know how big the sectors are */
ret = inode->u.i_bops->ioctl(inode, BIOC_GETFORMAT, (unsigned long) &fmt);
/* Now Write the filesystem to media. Loop for each root dir entry and
* allocate the reserved Root Dir Enty, then write a blank root dir for it.
*/
type = SMARTFS_SECTOR_TYPE_DIR;
request.offset = 0;
request.count = 1;
request.buffer = &type;
x = 0;
#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS
for (; x < nrootdirs; x++)
#endif
{
ret = inode->u.i_bops->ioctl(inode, BIOC_ALLOCSECT, SMARTFS_ROOT_DIR_SECTOR + x);
if (ret != SMARTFS_ROOT_DIR_SECTOR + x)
{
ret = -EIO;
goto errout_with_driver;
}
/* Mark this block as a directory entry */
request.logsector = SMARTFS_ROOT_DIR_SECTOR + x;
/* Issue a write to the sector, single byte */
ret = inode->u.i_bops->ioctl(inode, BIOC_WRITESECT, (unsigned long) &request);
if (ret != 0)
{
ret = -EIO;
goto errout_with_driver;
}
}
errout_with_driver:
/* Close the driver */
(void)close_blockdriver(inode);
errout:
/* Release all allocated memory */
/* Return any reported errors */
if (ret < 0)
{
errno = -ret;
return ERROR;
}
return OK;
}

1981
fs/smartfs/smartfs_smart.c Normal file

File diff suppressed because it is too large Load Diff

1293
fs/smartfs/smartfs_utils.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -134,6 +134,20 @@ struct nfsdir_s
};
#endif
#ifdef CONFIG_FS_SMARTFS
/* SMARTFS is the Sector Mapped Allocation for Really Tiny FLASH filesystem.
* it is designed to use small sectors on small serial FLASH devices, using
* minimal RAM footprint.
*/
struct fs_smartfsdir_s
{
uint16_t fs_firstsector; /* First sector of directory list */
uint16_t fs_currsector; /* Current sector of directory list */
uint16_t fs_curroffset; /* Current offset withing current sector */
};
#endif
#endif /* CONFIG_DISABLE_MOUNTPOINT */
struct fs_dirent_s
@ -174,19 +188,22 @@ struct fs_dirent_s
#ifndef CONFIG_DISABLE_MOUNTPOINT
#ifdef CONFIG_FS_FAT
struct fs_fatdir_s fat;
struct fs_fatdir_s fat;
#endif
#ifdef CONFIG_FS_ROMFS
struct fs_romfsdir_s romfs;
struct fs_romfsdir_s romfs;
#endif
#ifdef CONFIG_FS_BINFS
struct fs_binfsdir_s binfs;
struct fs_binfsdir_s binfs;
#endif
#ifdef CONFIG_FS_NXFFS
struct fs_nxffsdir_s nxffs;
struct fs_nxffsdir_s nxffs;
#endif
#ifdef CONFIG_NFS
struct nfsdir_s nfs;
struct nfsdir_s nfs;
#endif
#ifdef CONFIG_FS_SMARTFS
struct fs_smartfsdir_s smartfs;
#endif
#endif /* !CONFIG_DISABLE_MOUNTPOINT */
} u;

View File

@ -105,7 +105,7 @@
#define FIOC_OPTIMIZE _FIOC(0x0003) /* IN: None
* OUT: None
*/
#define FIOC_FILENAME _FIOC(0x0004) /* IN: FAR const char ** pointer
#define FIOC_FILENAME _FIOC(0x0004) /* IN: FAR const char ** pointer
* OUT: Pointer to a persistent file name
* (Guaranteed to persist while the file
* is open).
@ -146,6 +146,35 @@
* IN: None
* OUT: None (ioctl return value provides
* success/failure indication). */
#define BIOC_LLFORMAT _BIOC(0x0004) /* Low-Level Format on SMART flash devices
* IN: None
* OUT: None (ioctl return value provides
* success/failure indication). */
#define BIOC_GETFORMAT _BIOC(0x0005) /* Returns SMART flash format information
* such as format status, logical sector
* size, total sectors, free sectors, etc.
* IN: None
* OUT: Pointer to the format information. */
#define BIOC_ALLOCSECT _BIOC(0x0006) /* Allocate a logical sector from the block
* device.
* IN: None
* OUT: Logical sector number allocated. */
#define BIOC_FREESECT _BIOC(0x0007) /* Allocate a logical sector from the block
* device.
* IN: None
* OUT: Logical sector number allocated. */
#define BIOC_READSECT _BIOC(0x0008) /* Read a logical sector from the block
* device.
* IN: Pointer to sector read data (the
* logical sector number, count and
* read buffer address
* OUT: Number of bytes read or error */
#define BIOC_WRITESECT _BIOC(0x0009) /* Write to data to a logical sector
* IN: Pointer to sector write data (the
* logical secor number and write
* buffer address
* OUT: None (ioctl return value provides
* success/failure indication). */
/* NuttX MTD driver ioctl definitions ***************************************/
@ -164,6 +193,15 @@
* of device memory */
#define MTDIOC_BULKERASE _MTDIOC(0x0003) /* IN: None
* OUT: None */
#define MTDIOC_GETCAPS _MTDIOC(0x0004) /* IN: None
* OUT: Capabilities flags */
#define MTDIOC_SECTERASE _MTDIOC(0x0005) /* IN: Sector number to erase
* OUT: None */
#define MTDIOC_BYTEWRITE _MTDIOC(0x0006) /* IN: Pointer to bytewrite structure
* OUT: None */
#define MTDIOC_CAPS_SECTERASE 0x01
#define MTDIOC_CAPS_BYTEWRITE 0x02
/* NuttX ARP driver ioctl definitions (see netinet/arp.h) *******************/

View File

@ -0,0 +1,109 @@
/****************************************************************************
* include/nuttx/fs/mksmartfs.h
*
* Copyright (C) 2013 Ken Pettit. All rights reserved.
* Author: Ken Pettit <pettitkd@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __INCLUDE_NUTTX_SMART_MKSMARTFS_H
#define __INCLUDE_NUTTX_SMART_MKSMARTFS_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Types
****************************************************************************/
/****************************************************************************
* Global Variables
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C" {
#else
#define EXTERN extern
#endif
/****************************************************************************
* Name: mksmartfs
*
* Description:
* Make a SMART (Sector Mapped Allocation for Really Tiny) Flash file
* system image on the specified block device (must be a SMART device).
*
* Inputs:
* pathname - the full path to a registered block driver
* nrootdirs - the number of Root Directory entries to support
* on this device (supports multiple mount points).
*
* Return:
* Zero (OK) on success; -1 (ERROR) on failure with errno set appropriately:
*
* EINVAL - NULL block driver string
* ENOENT - 'pathname' does not refer to anything in the filesystem.
* ENOTBLK - 'pathname' does not refer to a block driver
* EACCESS - block driver does not support write or geometry methods or
* is not a SMART device
*
* Assumptions:
* - The caller must assure that the block driver is not mounted and not in
* use when this function is called. The result of formatting a mounted
* device is indeterminate (but likely not good).
*
****************************************************************************/
#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS
EXTERN int mksmartfs(FAR const char *pathname, uint8_t nrootdirs);
#else
EXTERN int mksmartfs(FAR const char *pathname);
#endif
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __INCLUDE_NUTTX_SMART_MKSMARTFS_H */

View File

@ -58,6 +58,14 @@
#define MTD_BWRITE(d,s,n,b)((d)->bwrite ? (d)->bwrite(d,s,n,b) : (-ENOSYS))
#define MTD_IOCTL(d,c,a) ((d)->ioctl ? (d)->ioctl(d,c,a) : (-ENOSYS))
/* If any of the low-level device drivers declare they want sub-sector erase
* support, then define MTD_SUBSECTOR_ERASE.
*/
#if defined(CONFIG_MP25P_SUBSECTOR_ERASE)
# define CONFIG_MTD_SUBSECTOR_ERASE 1
#endif
/****************************************************************************
* Public Types
****************************************************************************/
@ -70,10 +78,25 @@
struct mtd_geometry_s
{
uint16_t blocksize; /* Size of one read/write block */
uint16_t erasesize; /* Size of one erase blocks -- must be a multiple
* of blocksize. */
size_t neraseblocks; /* Number of erase blocks */
uint16_t blocksize; /* Size of one read/write block */
uint16_t erasesize; /* Size of one erase blocks -- must be a multiple
* of blocksize. */
size_t neraseblocks; /* Number of erase blocks */
#ifdef CONFIG_MTD_SUBSECTOR_ERASE
uint16_t subsectorsize; /* Size of the sub-sector erase block */
uint16_t nsubsectors; /* Number of sub-sector erase blocks */
#endif
};
/* The following defines the information for writing bytes to a sector
* that are not a full page write (bytewrite).
*/
struct mtd_byte_write_s
{
uint32_t offset; /* Offset within the device to write to */
uint16_t count; /* Number of bytes to write */
const uint8_t *buffer; /* Pointer to the data to write */
};
/* This structure defines the interface to a simple memory technology device.
@ -169,6 +192,22 @@ FAR struct mtd_dev_s *mtd_partition(FAR struct mtd_dev_s *mtd,
int ftl_initialize(int minor, FAR struct mtd_dev_s *mtd);
/****************************************************************************
* Name: smart_initialize
*
* Description:
* Initialize to provide a Sector Mapped Allocation for Really Tiny (SMART)
* Flash block driver wrapper around an MTD interface
*
* Input Parameters:
* minor - The minor device number. The MTD block device will be
* registered as as /dev/mtdsmartN where N is the minor number.
* mtd - The MTD device that supports the FLASH interface.
*
****************************************************************************/
int smart_initialize(int minor, FAR struct mtd_dev_s *mtd);
/****************************************************************************
* Name: flash_eraseall
*

View File

@ -357,7 +357,8 @@ enum spi_dev_e
SPIDEV_WIRELESS, /* Select SPI Wireless device */
SPIDEV_TOUCHSCREEN, /* Select SPI touchscreen device */
SPIDEV_EXPANDER, /* Select SPI I/O expander device */
SPIDEV_MUX /* Select SPI multiplexer device */
SPIDEV_MUX, /* Select SPI multiplexer device */
SPIDEV_AUDIO /* Select SPI audio codec device */
};
/* Certain SPI devices may required differnt clocking modes */

View File

@ -100,6 +100,7 @@
#define BINFS_MAGIC 0x4242
#define NXFFS_MAGIC 0x4747
#define SMARTFS_MAGIC 0x54524D53
/****************************************************************************
* Type Definitions