SMART block driver plus changes to M25P and RAM drivers needed for SMART support

This commit is contained in:
Gregory Nutt 2013-04-30 19:10:54 -06:00
parent c73bd9b906
commit 25d5706ca3
10 changed files with 2657 additions and 28 deletions

View File

@ -153,7 +153,7 @@
****************************************************************************/
/* Pre-allocated simulated flash */
#ifdef CONFIG_MTD_RAM
#ifdef CONFIG_RAMMTD
//static uint8_t g_simflash[CONFIG_EXAMPLES_SMART_BUFSIZE];
#endif
@ -217,7 +217,7 @@ int nsh_archinitialize(void)
/* Create a RAM MTD device if configured */
#ifdef CONFIG_MTD_RAM
#ifdef CONFIG_RAMMTD
{
uint8_t *start = (uint8_t *) kmalloc(CONFIG_EXAMPLES_SMART_BUFSIZE);
mtd = rammtd_initialize(start, CONFIG_EXAMPLES_SMART_BUFSIZE);
@ -229,7 +229,7 @@ int nsh_archinitialize(void)
#endif
}
#endif /* CONFIG_MTD_RAM */
#endif /* CONFIG_RAMMTD */
#endif /* CONFIG_MTD */
#endif /* CONFIG_STM32_SPI3 */

View File

@ -413,8 +413,8 @@ CONFIG_MP25P_BYTEWRITE=y
CONFIG_MTD_SMART=y
CONFIG_MTD_SMART_SECTOR_SIZE=512
# CONFIG_MTD_RAMTRON is not set
CONFIG_MTD_RAM=y
CONFIG_MTD_RAM_SMART=y
CONFIG_RAMMTD=y
CONFIG_RAMMTD_SMART=y
# CONFIG_MTD_SST25 is not set
# CONFIG_MTD_SST39FV is not set
# CONFIG_MTD_W25 is not set

View File

@ -216,7 +216,6 @@ CONFIG_RAMMTD_FLASHSIM=y
# CONFIG_MTD_AT45DB is not set
# CONFIG_MTD_MP25P is not set
# CONFIG_MTD_RAMTRON is not set
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_SST25 is not set
# CONFIG_MTD_SST39FV is not set
# CONFIG_MTD_W25 is not set

View File

@ -216,7 +216,6 @@ CONFIG_RAMMTD_FLASHSIM=y
# CONFIG_MTD_AT45DB is not set
# CONFIG_MTD_MP25P is not set
# CONFIG_MTD_RAMTRON is not set
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_SST25 is not set
# CONFIG_MTD_SST39FV is not set
# CONFIG_MTD_W25 is not set

View File

@ -51,6 +51,13 @@ config RAMMTD_FLASHSIM
RAMMTD_FLASHSIM will add some extra logic to improve the level of
FLASH simulation.
config RAMMTD_SMART
bool "SMART block driver support in the RAM MTD driver"
default n
---help---
Builds in additional ioctl and interface code to support the
SMART block driver / filesystem.
endif
config MTD_AT24XX
@ -113,8 +120,54 @@ config MP25P_MANUFACTURER
for the STMicro MP25x serial FLASH. If, for example, you are using the a Macronix
International MX25 serial FLASH, the correct manufacturer ID would be 0xc2.
config MP25P_MEMORY_TYPE
hex "MP25P memory type ID"
default 0x20
---help---
The memory type for M25 "P" series is 0x20, but the driver also supports "F" series
devices, such as the EON EN25F80 part which adds a 4K sector erase capability. The
ID for "F" series parts from EON is 0x31.
config MP25P_SUBSECTOR_ERASE
bool "Sub-Sector Erase"
default n
---help---
Some devices (the EON EN25F80) support a smaller erase block size (4K vs 64K).
This option enables support for sub-sector erase. The SMART file system can
take advantage of this option if it is enabled.
config MP25P_BYTEWRITE
bool "Enable ByteWrite ioctl support"
default n
---help---
The MP25P series of devices allow writing to a page with less than a full-page
size of data. In this case, only the written bytes are updated without affecting
the other bytes in the page. The SMART FS requires this option for proper operation.
endif
config MTD_SMART
bool "Sector Mapped Allocation for Really Tiny (SMART) Flash support"
default y
select MP25P_BYTEWRITE
---help---
The MP25x series of Flash devices are typically very small and have a very large
erase block size. This causes issues with the standard Flash Translation Layer
block driver since it tries to allocate a RAM block the size of a flash erase
block, which is typically 64K. This block driver uses a different approach
to sacrifice performance for RAM memory footprint by saving data in sectors
(typically 2K - 4K based on memory size) and relocating sectors as needed when
an erase block needs to be erased.
config MTD_SMART_SECTOR_SIZE
int "SMART Device sector size"
depends on MTD_SMART
default 1024
---help---
Sets the size of a single alloction on the SMART device. Larger sector sizes
reduce overhead per sector, but cause more wasted space with a lot of smaller
files.
config MTD_RAMTRON
bool "SPI-based RAMTRON NVRAM Devices FM25V10"
default n
@ -122,10 +175,6 @@ config MTD_RAMTRON
---help---
SPI-based RAMTRON NVRAM Devices FM25V10
config MTD_RAM
bool "Memory bus ram"
default n
config MTD_SST25
bool "SPI-based SST25 FLASH"
default n

View File

@ -3,7 +3,7 @@
# These driver supports various Memory Technology Devices (MTD) using the
# NuttX MTD interface.
#
# Copyright (C) 2009-2012 Gregory Nutt. All rights reserved.
# Copyright (C) 2009-2013 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
@ -39,12 +39,16 @@
ifeq ($(CONFIG_MTD),y)
CSRCS += at45db.c flash_eraseall.c ftl.c m25px.c rammtd.c ramtron.c
CSRCS += at45db.c flash_eraseall.c ftl.c m25px.c ramtron.c
ifeq ($(CONFIG_MTD_PARTITION),y)
CSRCS += mtd_partition.c
endif
ifeq ($(CONFIG_RAMMTD),y)
CSRCS += rammtd.c
endif
ifeq ($(CONFIG_MTD_AT24XX),y)
CSRCS += at24xx.c
endif
@ -65,6 +69,12 @@ ifeq ($(CONFIG_MTD_AT25),y)
CSRCS += at25.c
endif
ifeq ($(CONFIG_MTD_SMART),y)
ifeq ($(CONFIG_FS_SMARTFS),y)
CSRCS += smart.c
endif
endif
# Include MTD driver support
DEPPATH += --dep-path mtd

View File

@ -78,12 +78,18 @@
# define CONFIG_MP25P_MANUFACTURER 0x20
#endif
#ifndef CONFIG_MP25P_MEMORY_TYPE
# define CONFIG_MP25P_MEMORY_TYPE 0x20
#endif
/* M25P Registers *******************************************************************/
/* Indentification register values */
#define M25P_MANUFACTURER CONFIG_MP25P_MANUFACTURER
#define M25P_MEMORY_TYPE 0x20
#define M25P_MEMORY_TYPE CONFIG_MP25P_MEMORY_TYPE
#define M25P_RES_ID 0x13
#define M25P_M25P1_CAPACITY 0x11 /* 1 M-bit */
#define M25P_EN25F80_CAPACITY 0x14 /* 8 M-bit */
#define M25P_M25P32_CAPACITY 0x16 /* 32 M-bit */
#define M25P_M25P64_CAPACITY 0x17 /* 64 M-bit */
#define M25P_M25P128_CAPACITY 0x18 /* 128 M-bit */
@ -98,6 +104,17 @@
#define M25P_M25P1_PAGE_SHIFT 8 /* Page size 1 << 8 = 256 */
#define M25P_M25P1_NPAGES 512
/* EN25F80 capacity is 1,048,576 bytes:
* (16 sectors) * (65,536 bytes per sector)
* (512 pages) * (256 bytes per page)
*/
#define M25P_EN25F80_SECTOR_SHIFT 16 /* Sector size 1 << 15 = 65,536 */
#define M25P_EN25F80_NSECTORS 16
#define M25P_EN25F80_PAGE_SHIFT 8 /* Page size 1 << 8 = 256 */
#define M25P_EN25F80_NPAGES 4096
#define M25P_EN25F80_SUBSECT_SHIFT 12 /* Sub-Sector size 1 << 12 = 4,096 */
/* M25P32 capacity is 4,194,304 bytes:
* (64 sectors) * (65,536 bytes per sector)
* (16384 pages) * (256 bytes per page)
@ -142,6 +159,7 @@
#define M25P_BE 0xc7 /* 1 Bulk Erase 0 0 0 */
#define M25P_DP 0xb9 /* 2 Deep power down 0 0 0 */
#define M25P_RES 0xab /* 2 Read Electronic Signature 0 3 >=1 */
#define M25P_SSE 0x20 /* 1 Sub-Sector Erase 0 0 0 */
/* NOTE 1: All parts, NOTE 2: M25P632/M25P64 */
@ -181,6 +199,9 @@ struct m25p_dev_s
uint8_t pageshift; /* 8 */
uint16_t nsectors; /* 128 or 64 */
uint32_t npages; /* 32,768 or 65,536 */
#ifdef CONFIG_MP25P_SUBSECTOR_ERASE
uint8_t subsectorshift; /* 0, 12 or 13 (4K or 8K) */
#endif
};
/************************************************************************************
@ -198,6 +219,9 @@ static inline void m25p_sectorerase(struct m25p_dev_s *priv, off_t offset);
static inline int m25p_bulkerase(struct m25p_dev_s *priv);
static inline void m25p_pagewrite(struct m25p_dev_s *priv, FAR const uint8_t *buffer,
off_t offset);
#ifdef CONFIG_MP25P_SUBSECTOR_ERASE
static inline void m25p_subsectorerase(struct m25p_dev_s *priv, off_t offset);
#endif
/* MTD driver methods */
@ -292,6 +316,10 @@ static inline int m25p_readid(struct m25p_dev_s *priv)
{
/* Okay.. is it a FLASH capacity that we understand? */
#ifdef CONFIG_MP25P_SUBSECTOR_ERASE
priv->subsectorshift = 0;
#endif
if (capacity == M25P_M25P1_CAPACITY)
{
/* Save the FLASH geometry */
@ -302,6 +330,19 @@ static inline int m25p_readid(struct m25p_dev_s *priv)
priv->npages = M25P_M25P1_NPAGES;
return OK;
}
else if (capacity == M25P_EN25F80_CAPACITY)
{
/* Save the FLASH geometry */
priv->sectorshift = M25P_EN25F80_SECTOR_SHIFT;
priv->nsectors = M25P_EN25F80_NSECTORS;
priv->pageshift = M25P_EN25F80_PAGE_SHIFT;
priv->npages = M25P_EN25F80_NPAGES;
#ifdef CONFIG_MP25P_SUBSECTOR_ERASE
priv->subsectorshift = M25P_EN25F80_SUBSECT_SHIFT;
#endif
return OK;
}
else if (capacity == M25P_M25P32_CAPACITY)
{
/* Save the FLASH geometry */
@ -356,7 +397,7 @@ static void m25p_waitwritecomplete(struct m25p_dev_s *priv)
/* Send "Read Status Register (RDSR)" command */
(void)SPI_SEND(priv->dev, M25P_RDSR);
/* Loop as long as the memory is busy with a write cycle */
do
@ -424,7 +465,7 @@ static void m25p_writeenable(struct m25p_dev_s *priv)
/* Send "Write Enable (WREN)" command */
(void)SPI_SEND(priv->dev, M25P_WREN);
/* Deselect the FLASH */
SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
@ -476,6 +517,53 @@ static inline void m25p_sectorerase(struct m25p_dev_s *priv, off_t sector)
fvdbg("Erased\n");
}
/************************************************************************************
* Name: m25p_subsectorerase
************************************************************************************/
#ifdef CONFIG_MP25P_SUBSECTOR_ERASE
static inline void m25p_subsectorerase(struct m25p_dev_s *priv, off_t subsector)
{
off_t offset = subsector << priv->subsectorshift;
fvdbg("subsector: %9lx\n", (long)subsector);
/* Wait for any preceding write to complete. We could simplify things by
* perform this wait at the end of each write operation (rather than at
* the beginning of ALL operations), but have the wait first will slightly
* improve performance.
*/
m25p_waitwritecomplete(priv);
/* Send write enable instruction */
m25p_writeenable(priv);
/* Select this FLASH part */
SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
/* Send the "Sub-Sector Erase (SSE)" instruction */
(void)SPI_SEND(priv->dev, M25P_SSE);
/* Send the sector offset high byte first. For all of the supported
* parts, the sector number is completely contained in the first byte
* and the values used in the following two bytes don't really matter.
*/
(void)SPI_SEND(priv->dev, (offset >> 16) & 0xff);
(void)SPI_SEND(priv->dev, (offset >> 8) & 0xff);
(void)SPI_SEND(priv->dev, offset & 0xff);
/* Deselect the FLASH */
SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
fvdbg("Erased\n");
}
#endif
/************************************************************************************
* Name: m25p_bulkerase
************************************************************************************/
@ -533,7 +621,7 @@ static inline void m25p_pagewrite(struct m25p_dev_s *priv, FAR const uint8_t *bu
/* Enable the write access to the FLASH */
m25p_writeenable(priv);
/* Select this FLASH part */
SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
@ -551,13 +639,60 @@ static inline void m25p_pagewrite(struct m25p_dev_s *priv, FAR const uint8_t *bu
/* Then write the specified number of bytes */
SPI_SNDBLOCK(priv->dev, buffer, 1 << priv->pageshift);
/* Deselect the FLASH: Chip Select high */
SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
fvdbg("Written\n");
}
/************************************************************************************
* Name: m25p_bytewrite
************************************************************************************/
#ifdef CONFIG_MP25P_BYTEWRITE
static inline void m25p_bytewrite(struct m25p_dev_s *priv, FAR const uint8_t *buffer,
off_t offset, uint16_t count)
{
fvdbg("offset: %08lx count:%d\n", (long)offset, count);
/* Wait for any preceding write to complete. We could simplify things by
* perform this wait at the end of each write operation (rather than at
* the beginning of ALL operations), but have the wait first will slightly
* improve performance.
*/
m25p_waitwritecomplete(priv);
/* Enable the write access to the FLASH */
m25p_writeenable(priv);
/* Select this FLASH part */
SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
/* Send "Page Program (PP)" command */
(void)SPI_SEND(priv->dev, M25P_PP);
/* Send the page offset high byte first. */
(void)SPI_SEND(priv->dev, (offset >> 16) & 0xff);
(void)SPI_SEND(priv->dev, (offset >> 8) & 0xff);
(void)SPI_SEND(priv->dev, offset & 0xff);
/* Then write the specified number of bytes */
SPI_SNDBLOCK(priv->dev, buffer, count);
/* Deselect the FLASH: Chip Select high */
SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
fvdbg("Written\n");
}
#endif
/************************************************************************************
* Name: m25p_erase
************************************************************************************/
@ -614,6 +749,7 @@ static ssize_t m25p_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t n
{
FAR struct m25p_dev_s *priv = (FAR struct m25p_dev_s *)dev;
size_t blocksleft = nblocks;
size_t pagesize = 1 << priv->pageshift;
fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
@ -623,6 +759,7 @@ static ssize_t m25p_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t n
while (blocksleft-- > 0)
{
m25p_pagewrite(priv, buffer, startblock);
buffer += pagesize;
startblock++;
}
m25p_unlock(priv->dev);
@ -703,10 +840,15 @@ static int m25p_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
* appear so.
*/
geo->blocksize = (1 << priv->pageshift);
geo->erasesize = (1 << priv->sectorshift);
geo->neraseblocks = priv->nsectors;
ret = OK;
geo->blocksize = (1 << priv->pageshift);
geo->erasesize = (1 << priv->sectorshift);
geo->neraseblocks = priv->nsectors;
#ifdef CONFIG_MP25P_SUBSECTOR_ERASE
geo->subsectorsize = (1 << priv->subsectorshift);
geo->nsubsectors = priv->nsectors * (1 << (priv->sectorshift -
priv->subsectorshift));
#endif
ret = OK;
fvdbg("blocksize: %d erasesize: %d neraseblocks: %d\n",
geo->blocksize, geo->erasesize, geo->neraseblocks);
@ -723,7 +865,98 @@ static int m25p_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
m25p_unlock(priv->dev);
}
break;
#ifdef CONFIG_FS_SMARTFS
case MTDIOC_GETCAPS:
{
ret = 0;
#ifdef CONFIG_MP25P_BYTEWRITE
ret |= MTDIOC_CAPS_BYTEWRITE;
#endif
#ifdef CONFIG_MP25P_SUBSECTOR_ERASE
ret |= MTDIOC_CAPS_SECTERASE;
#endif
break;
}
#endif /* CONFIG_FS_SMARTFS */
#ifdef CONFIG_MP25P_SUBSECTOR_ERASE
case MTDIOC_SECTERASE:
{
m25p_subsectorerase(priv, (off_t) arg);
ret = OK;
break;
}
#endif
#ifdef CONFIG_MP25P_BYTEWRITE
case MTDIOC_BYTEWRITE:
{
struct mtd_byte_write_s *bytewrite = (struct mtd_byte_write_s *) arg;
int startpage;
int endpage;
int count;
int index;
int pagesize;
int bytestowrite;
size_t offset;
/* We must test if the offset + count crosses one or more pages
* and perform individual writes. The devices can only write in
* page increments.
*/
startpage = bytewrite->offset / (1 << priv->pageshift);
endpage = (bytewrite->offset + bytewrite->count) / (1 << priv->pageshift);
if (startpage == endpage)
{
m25p_bytewrite(priv, bytewrite->buffer, bytewrite->offset,
bytewrite->count);
}
else
{
/* Write the 1st partial-page */
count = bytewrite->count;
pagesize = (1 << priv->pageshift);
offset = bytewrite->offset;
bytestowrite = pagesize - (bytewrite->offset & (pagesize-1));
m25p_bytewrite(priv, bytewrite->buffer, offset, bytestowrite);
/* Update offset and count */
offset += bytestowrite;
count -= bytestowrite;
index = bytestowrite;
/* Write full pages */
while (count >= pagesize)
{
m25p_bytewrite(priv, &bytewrite->buffer[index], offset, pagesize);
/* Update offset and count */
offset += pagesize;
count -= pagesize;
index += pagesize;
}
/* Now write any partial page at the end */
if (count > 0)
{
m25p_bytewrite(priv, &bytewrite->buffer[index], offset, count);
}
}
ret = OK;
break;
}
#endif
case MTDIOC_XIPBASE:
default:
ret = -ENOTTY; /* Bad command */

View File

@ -1,7 +1,7 @@
/****************************************************************************
* drivers/mtd/rammtd.c
*
* Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2011-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -224,6 +224,30 @@ static int ram_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks
return OK;
}
/****************************************************************************
* Name: ram_readbytes
****************************************************************************/
#ifdef CONFIG_RAMMTD_SMART
static ssize_t ram_read_bytes(FAR struct mtd_dev_s *dev, off_t offset,
size_t nbytes, FAR uint8_t *buf)
{
FAR struct ram_dev_s *priv = (FAR struct ram_dev_s *)dev;
DEBUGASSERT(dev && buf);
/* Don't let read read past end of buffer */
if (offset + nbytes > priv->nblocks * CONFIG_RAMMTD_ERASESIZE)
{
return 0;
}
ram_read(buf, &priv->start[offset], nbytes);
return nbytes;
}
#endif
/****************************************************************************
* Name: ram_bread
****************************************************************************/
@ -349,13 +373,31 @@ static int ram_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
{
size_t size = priv->nblocks * CONFIG_RAMMTD_ERASESIZE;
/* Erase the entire device */
/* Erase the entire device */
memset(priv->start, CONFIG_RAMMTD_ERASESTATE, size);
ret = OK;
ret = OK;
}
break;
#ifdef CONFIG_RAMMTD_SMART
case MTDIOC_GETCAPS:
{
ret = MTDIOC_CAPS_BYTEWRITE;
break;
}
case MTDIOC_BYTEWRITE:
{
struct mtd_byte_write_s *bytewrite = (struct mtd_byte_write_s *) arg;
ram_write(&priv->start[bytewrite->offset], bytewrite->buffer,
bytewrite->count);
ret = OK;
break;
}
#endif
default:
ret = -ENOTTY; /* Bad command */
break;
@ -402,7 +444,7 @@ FAR struct mtd_dev_s *rammtd_initialize(FAR uint8_t *start, size_t size)
fdbg("Need to provide at least one full erase block\n");
return NULL;
}
/* Perform initialization as necessary */
priv->mtd.erase = ram_erase;
@ -411,6 +453,10 @@ FAR struct mtd_dev_s *rammtd_initialize(FAR uint8_t *start, size_t size)
priv->mtd.ioctl = ram_ioctl;
priv->mtd.erase = ram_erase;
#ifdef CONFIG_RAMMTD_SMART
priv->mtd.read = ram_read_bytes;
#endif
priv->start = start;
priv->nblocks = nblocks;
return &priv->mtd;

2177
drivers/mtd/smart.c Normal file

File diff suppressed because it is too large Load Diff

116
include/nuttx/smart.h Normal file
View File

@ -0,0 +1,116 @@
/****************************************************************************
* include/nuttx/smart.h
* Sector Mapped Allocation for Really Tiny (SMART) FLASH interface
*
* 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_H
#define __INCLUDE_NUTTX_SMART_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
/****************************************************************************
* Pre-Processor Definitions
****************************************************************************/
/* Macros to hide implementation */
#define SMART_FMT_ISFORMATTED 0x01
#define SMART_FMT_HASBYTEWRITE 0x02
/****************************************************************************
* Public Types
****************************************************************************/
/* The following defines the format information for the device. This
* information is retrieved via the BIOC_GETFORMAT ioctl.
*/
struct smart_format_s
{
uint16_t sectorsize; /* Size of one read/write sector */
uint16_t availbytes; /* Number of bytes available in each sector */
uint16_t nsectors; /* Total number of sectors on device */
uint16_t nfreesectors; /* Number of free sectors on device */
uint8_t flags; /* Format flags (see above) */
uint8_t namesize; /* Size of filenames on this volume */
#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS
uint8_t nrootdirentries; /* Number of root directories on this device */
uint8_t rootdirnum; /* Root directory number for this dev entry */
#endif
};
/* The following defines the information for writing a logical sector
* to the device.
*/
struct smart_read_write_s
{
uint16_t logsector; /* The logical sector number */
uint16_t offset; /* Offset within the sector to write to */
uint16_t count; /* Number of bytes to write */
const uint8_t *buffer; /* Pointer to the data to write */
};
/****************************************************************************
* Public Data
****************************************************************************/
#ifndef __ASSEMBLY__
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __INCLUDE_NUTTX_SMART_H */