Add an optional byte-oriented write method to the MTD interface

This commit is contained in:
Gregory Nutt 2013-05-01 10:59:57 -06:00
parent ba52f8d3ec
commit 99c2cfc168
16 changed files with 122 additions and 33 deletions

View File

@ -4653,3 +4653,6 @@
* configs/sim/mkroe-stm32f4: Support for the MikroElektronika
Mikromedia for STM32F4 development board (from Ken Petit, 2013-4-30).
* fs/smartfs: Add Ken Pettits SMART FS (2013-4-30).
* include/nuttx/mtd.h and most MTD drivers: Add support for
(optional) method to perform byte oriented writes if so configured
(2013-5-1)

View File

@ -3192,12 +3192,21 @@ extern void up_ledoff(int led);
</ul>
<p>
Some devices may support byte oriented reads (optional).
Most MTD devices are inherently block oriented so byte-oriented writing is not supported.
Most MTD devices are inherently block oriented so byte-oriented accesses are not supported.
It is recommended that low-level drivers not support read() if it requires buffering.
</p>
<ul>
<p><code>ssize_t (*read)(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, FAR uint8_t *buffer);</code></p>
</ul>
<p>
Some devices may also support byte oriented writes (optional).
Most MTD devices are inherently block oriented so byte-oriented accesses are not supported.
It is recommended that low-level drivers not support read() if it requires buffering.
This interface is only available if <code>CONFIG_MTD_BYTE_WRITE</code> is defined.
</p>
<ul>
<p><code>ssize_t (*write)(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, FAR const uint8_t *buffer);</code></p>
</ul>
<p>
Support other, less frequently used commands:
</p>

View File

@ -3,6 +3,8 @@
# see misc/tools/kconfig-language.txt.
#
comment "MTD Configuration"
config MTD_PARTITION
bool "Support MTD partitions"
default n
@ -24,6 +26,17 @@ config MTD_PARTITION
managing the sub-region of flash beginning at 'offset' (in blocks)
and of size 'nblocks' on the device specified by 'mtd'.
config MTD_BYTE_WRITE
bool "Byte write"
default n
---help---
Some devices (such as the EON EN25F80) support writing an arbitrary
number of bytes to FLASH. This setting enables MTD interfaces to
support such writes. The SMART file system can take advantage of
this option if it is enabled.
comment "MTD Device Drivers"
config RAMMTD
bool "RAM-based MTD driver"
default n
@ -132,9 +145,9 @@ 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.
Some devices (such as 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"

View File

@ -10,7 +10,7 @@
*
* Derived from drivers/mtd/m25px.c
*
* Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
* Copyright (C) 2009-2011, 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -365,7 +365,7 @@ static int at24c_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
break;
case MTDIOC_BULKERASE:
ret=at24c_eraseall(priv);
ret = at24c_eraseall(priv);
break;
case MTDIOC_XIPBASE:
@ -413,6 +413,10 @@ FAR struct mtd_dev_s *at24c_initialize(FAR struct i2c_dev_s *dev)
priv->pagesize = AT24XX_PAGESIZE;
priv->npages = AT24XX_NPAGES;
/* NOTE since the pre-allocated device structure lies in .bss, any
* unsupported methods should have been nullified.
*/
priv->mtd.erase = at24c_erase;
priv->mtd.bread = at24c_bread;
priv->mtd.bwrite = at24c_bwrite;

View File

@ -2,7 +2,7 @@
* drivers/mtd/at25.c
* Driver for SPI-based AT25DF321 (32Mbit) flash.
*
* Copyright (C) 2009-2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2009-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Petteri Aimonen <jpa@nx.mail.kapsi.fi>
*
@ -664,10 +664,12 @@ FAR struct mtd_dev_s *at25_initialize(FAR struct spi_dev_s *dev)
* to be extended to handle multiple FLASH parts on the same SPI bus.
*/
priv = (FAR struct at25_dev_s *)kmalloc(sizeof(struct at25_dev_s));
priv = (FAR struct at25_dev_s *)kzalloc(sizeof(struct at25_dev_s));
if (priv)
{
/* Initialize the allocated structure */
/* Initialize the allocated structure (unsupported methods were
* nullified by kzalloc).
*/
priv->mtd.erase = at25_erase;
priv->mtd.bread = at25_bread;

View File

@ -2,7 +2,7 @@
* drivers/mtd/at45db.c
* Driver for SPI-based AT45DB161D (16Mbit)
*
* Copyright (C) 2010-2011 Gregory Nutt. All rights reserved.
* Copyright (C) 2010-2011, 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -827,10 +827,12 @@ FAR struct mtd_dev_s *at45db_initialize(FAR struct spi_dev_s *spi)
* to be extended to handle multiple FLASH parts on the same SPI bus.
*/
priv = (FAR struct at45db_dev_s *)kmalloc(sizeof(struct at45db_dev_s));
priv = (FAR struct at45db_dev_s *)kzalloc(sizeof(struct at45db_dev_s));
if (priv)
{
/* Initialize the allocated structure */
/* Initialize the allocated structure. (unsupported methods were
* nullified by kzalloc).
*/
priv->mtd.erase = at45db_erase;
priv->mtd.bread = at45db_bread;

View File

@ -995,10 +995,12 @@ FAR struct mtd_dev_s *m25p_initialize(FAR struct spi_dev_s *dev)
* to be extended to handle multiple FLASH parts on the same SPI bus.
*/
priv = (FAR struct m25p_dev_s *)kmalloc(sizeof(struct m25p_dev_s));
priv = (FAR struct m25p_dev_s *)kzalloc(sizeof(struct m25p_dev_s));
if (priv)
{
/* Initialize the allocated structure */
/* Initialize the allocated structure. (unsupported methods were
* nullified by kzalloc).
*/
priv->mtd.erase = m25p_erase;
priv->mtd.bread = m25p_bread;

View File

@ -395,14 +395,16 @@ FAR struct mtd_dev_s *mtd_partition(FAR struct mtd_dev_s *mtd, off_t firstblock,
/* Allocate a partition device structure */
part = (FAR struct mtd_partition_s *)malloc(sizeof(struct mtd_partition_s));
part = (FAR struct mtd_partition_s *)kzalloc(sizeof(struct mtd_partition_s));
if (!part)
{
fdbg("ERROR: Failed to allocate memory for the partition device\n");
return NULL;
}
/* Initialize the partition device structure */
/* Initialize the partition device structure. (unsupported methods were
* nullified by kzalloc).
*/
part->child.erase = part_erase;
part->child.bread = part_bread;

View File

@ -429,7 +429,7 @@ FAR struct mtd_dev_s *rammtd_initialize(FAR uint8_t *start, size_t size)
/* Create an instance of the RAM MTD device state structure */
priv = (FAR struct ram_dev_s *)kmalloc(sizeof(struct ram_dev_s));
priv = (FAR struct ram_dev_s *)kzalloc(sizeof(struct ram_dev_s));
if (!priv)
{
fdbg("Failed to allocate the RAM MTD state structure\n");
@ -445,7 +445,9 @@ FAR struct mtd_dev_s *rammtd_initialize(FAR uint8_t *start, size_t size)
return NULL;
}
/* Perform initialization as necessary */
/* Perform initialization as necessary. (unsupported methods were
* nullified by kzalloc).
*/
priv->mtd.erase = ram_erase;
priv->mtd.bread = ram_bread;

View File

@ -660,10 +660,12 @@ FAR struct mtd_dev_s *ramtron_initialize(FAR struct spi_dev_s *dev)
* to be extended to handle multiple FLASH parts on the same SPI bus.
*/
priv = (FAR struct ramtron_dev_s *)kmalloc(sizeof(struct ramtron_dev_s));
priv = (FAR struct ramtron_dev_s *)kzalloc(sizeof(struct ramtron_dev_s));
if (priv)
{
/* Initialize the allocated structure */
/* Initialize the allocated structure. (unsupported methods were
* nullified by kzalloc).
*/
priv->mtd.erase = ramtron_erase;
priv->mtd.bread = ramtron_bread;

View File

@ -79,6 +79,10 @@ static ssize_t skel_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t n
FAR const uint8_t *buf);
static ssize_t skel_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
FAR uint8_t *buffer);
#ifdef CONFIG_MTD_BYTE_WRITE
static ssize_t skel_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
FAR const uint8_t *buffer);
#endif
static int skel_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg);
/****************************************************************************
@ -88,7 +92,15 @@ static int skel_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg);
static struct skel_dev_s g_skeldev =
{
{ skel_erase, skel_rbead, skel_bwrite, skel_read, skel_ioctl },
{ skel_erase,
skel_rbead,
skel_bwrite,
skel_read,
#ifdef CONFIG_MTD_BYTE_WRITE
skel_write,
#endif
skel_ioctl
},
/* Initialization of any other implementation specific data goes here */
};
@ -202,6 +214,23 @@ static ssize_t skel_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
return 0;
}
/****************************************************************************
* Name: skel_write
*
* Description:
* Some FLASH parts have the ability to write an arbitrary number of
* bytes to an arbitrary offset on the device.
*
****************************************************************************/
#ifdef CONFIG_MTD_BYTE_WRITE
static ssize_t skel_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
FAR const uint8_t *buffer)
{
return -ENOSYS;
}
#endif
/****************************************************************************
* Name: skel_ioctl
****************************************************************************/

View File

@ -2,7 +2,7 @@
* drivers/mtd/sst25.c
* Driver for SPI-based SST25 FLASH.
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -1195,7 +1195,9 @@ FAR struct mtd_dev_s *sst25_initialize(FAR struct spi_dev_s *dev)
priv = (FAR struct sst25_dev_s *)kzalloc(sizeof(struct sst25_dev_s));
if (priv)
{
/* Initialize the allocated structure */
/* Initialize the allocated structure. (unsupported methods were
* nullified by kzalloc).
*/
priv->mtd.erase = sst25_erase;
priv->mtd.bread = sst25_bread;

View File

@ -201,7 +201,10 @@ static struct sst39vf_dev_s g_sst39vf =
sst39vf_bread, /* bread method */
sst39vf_bwrite, /* bwrte method */
sst39vf_read, /* read method */
sst39vf_ioctl /* write method */
#ifdef CONFIG_MTD_BYTE_WRITE
NULL, /* write method */
#endif
sst39vf_ioctl /* ioctl method */
},
NULL /* Chip */
};

View File

@ -2,7 +2,7 @@
* drivers/mtd/w25.c
* Driver for SPI-based W25x16, x32, and x64 and W25q16, q32, q64, and q128 FLASH
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -1124,7 +1124,9 @@ FAR struct mtd_dev_s *w25_initialize(FAR struct spi_dev_s *spi)
priv = (FAR struct w25_dev_s *)kzalloc(sizeof(struct w25_dev_s));
if (priv)
{
/* Initialize the allocated structure */
/* Initialize the allocated structure (unsupported methods were
* nullified by kzalloc).
*/
priv->mtd.erase = w25_erase;
priv->mtd.bread = w25_bread;

View File

@ -52,11 +52,12 @@
/* Macros to hide implementation */
#define MTD_ERASE(d,s,n) ((d)->erase ? (d)->erase(d,s,n) : (-ENOSYS))
#define MTD_BREAD(d,s,n,b) ((d)->bread ? (d)->bread(d,s,n,b) : (-ENOSYS))
#define MTD_READ(d,s,n,b) ((d)->read ? (d)->read(d,s,n,b) : (-ENOSYS))
#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))
#define MTD_ERASE(d,s,n) ((d)->erase ? (d)->erase(d,s,n) : (-ENOSYS))
#define MTD_BREAD(d,s,n,b) ((d)->bread ? (d)->bread(d,s,n,b) : (-ENOSYS))
#define MTD_BWRITE(d,s,n,b)((d)->bwrite ? (d)->bwrite(d,s,n,b) : (-ENOSYS))
#define MTD_READ(d,s,n,b) ((d)->read ? (d)->read(d,s,n,b) : (-ENOSYS))
#define MTD_WRITE(d,s,n,b) ((d)->write ? (d)->write(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.
@ -108,7 +109,12 @@ struct mtd_dev_s
{
/* The following methods operate on the MTD: */
/* Erase the specified erase blocks (units are erase blocks) */
/* Erase the specified erase blocks (units are erase blocks). Semantic
* Clarification: Here, we are not referring to the erase block according
* to the FLASH data sheet. Rather, we are referring to the *smallest*
* eraseable part of the FLASH which may have a name like a page or sector
* or subsector.
*/
int (*erase)(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks);
@ -127,6 +133,10 @@ struct mtd_dev_s
ssize_t (*read)(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
FAR uint8_t *buffer);
#ifdef CONFIG_MTD_BYTE_WRITE
ssize_t (*write)(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
FAR const uint8_t *buffer);
#endif
/* Support other, less frequently used commands:
* - MTDIOC_GEOMETRY: Get MTD geometry

View File

@ -208,6 +208,7 @@ int main(int argc, char **argv, char **envp)
printf("# undef CONFIG_FS_FAT\n");
printf("# undef CONFIG_FS_ROMFS\n");
printf("# undef CONFIG_FS_NXFFS\n");
printf("# undef CONFIG_FS_SMARTFS\n");
printf("# undef CONFIG_FS_BINFS\n");
printf("# undef CONFIG_NFS\n");
printf("#endif\n\n");
@ -215,7 +216,8 @@ int main(int argc, char **argv, char **envp)
printf("#undef CONFIG_FS_READABLE\n");
printf("#undef CONFIG_FS_WRITABLE\n");
printf("#if defined(CONFIG_FS_FAT) || defined(CONFIG_FS_ROMFS) || defined(CONFIG_USBMSC) || \\\n");
printf(" defined(CONFIG_FS_NXFFS) || defined(CONFIG_FS_BINFS) || defined(CONFIG_NFS)\n");
printf(" defined(CONFIG_FS_NXFFS) || defined(CONFIG_FS_SMARTFS) || defined(CONFIG_FS_BINFS) || \\\n");
printf(" defined(CONFIG_NFS)\n");
printf("# define CONFIG_FS_READABLE 1\n");
printf("#endif\n\n");
printf("#if defined(CONFIG_FS_FAT) || defined(CONFIG_USBMSC) || defined(CONFIG_FS_NXFFS) || \\\n");