drivers/mtd/mtd_progmem.c: Add an upper-half driver that can be used with any FLASH library that provides the itnerfaces defined in include/nuttx/progmem.h
This commit is contained in:
parent
5eaf368d16
commit
ef59f83a38
@ -11081,4 +11081,7 @@
|
||||
* drivers/mtd/s25fl1.c: The S25FL1xx QuadSPI FLASH driver is now
|
||||
functional (2015-10-11).
|
||||
* arch/arm/samv7: Add an on-chip FLASH driver (2015-11-12).
|
||||
* drivers/mtd/mtd_progmem.c: Add an upper half MTD device that can
|
||||
use the interfaces defined in included/nuttx/progmem.h to provide
|
||||
a standard MTD interface (2015-11-12).
|
||||
|
||||
|
@ -114,6 +114,14 @@ config MTD_NRDBLOCKS
|
||||
|
||||
endif # MTD_READAHEAD
|
||||
|
||||
config MTD_PROGMEM
|
||||
bool "Enable on-chip program FLASH MTD device"
|
||||
default n
|
||||
---help---
|
||||
Enable to support an MTD device that supports the on-chip FLASH
|
||||
using the interfaces defined in include/nuttx/progmem. Those
|
||||
interfaces must be exported by chip-specific logic.
|
||||
|
||||
config MTD_CONFIG
|
||||
bool "Enable Dev Config (MTD based) device"
|
||||
default n
|
||||
|
@ -3,7 +3,7 @@
|
||||
# These driver supports various Memory Technology Devices (MTD) using the
|
||||
# NuttX MTD interface.
|
||||
#
|
||||
# Copyright (C) 2009-2013 Gregory Nutt. All rights reserved.
|
||||
# Copyright (C) 2009-2013, 2015 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@ -57,6 +57,10 @@ CSRCS += mtd_rwbuffer.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_MTD_PROGMEM),y)
|
||||
CSRCS += mtd_progmem.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_MTD_NAND),y)
|
||||
CSRCS += mtd_nand.c mtd_onfi.c mtd_nandscheme.c mtd_nandmodel.c mtd_modeltab.c
|
||||
ifeq ($(CONFIG_MTD_NAND_SWECC),y)
|
||||
|
390
drivers/mtd/mtd_progmem.c
Normal file
390
drivers/mtd/mtd_progmem.c
Normal file
@ -0,0 +1,390 @@
|
||||
/****************************************************************************
|
||||
* drivers/mtd/mtd_progmem.c
|
||||
*
|
||||
* Copyright (C) 2015 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/progmem.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
#include <nuttx/mtd/mtd.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* This type represents the state of the MTD device. The struct mtd_dev_s
|
||||
* must appear at the beginning of the definition so that you can freely
|
||||
* cast between pointers to struct mtd_dev_s and struct progmem_dev_s.
|
||||
*/
|
||||
|
||||
struct progmem_dev_s
|
||||
{
|
||||
/* Publically visible representation of the interface */
|
||||
|
||||
struct mtd_dev_s mtd;
|
||||
|
||||
/* Fields unique to the progmem MTD driver */
|
||||
|
||||
bool initialized; /* True: Already initialized */
|
||||
uint8_t blkshift; /* Log2 of the flash block size */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Internal helper functions */
|
||||
|
||||
static int32_t progmem_log2(size_t blocksize);
|
||||
|
||||
/* MTD driver methods */
|
||||
|
||||
static int progmem_erase(FAR struct mtd_dev_s *dev, off_t startblock,
|
||||
size_t nblocks);
|
||||
static ssize_t progmem_bread(FAR struct mtd_dev_s *dev, off_t startblock,
|
||||
size_t nblocks, FAR uint8_t *buf);
|
||||
static ssize_t progmem_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
|
||||
size_t nblocks, FAR const uint8_t *buf);
|
||||
static ssize_t progmem_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 progmem_write(FAR struct mtd_dev_s *dev, off_t offset,
|
||||
size_t nbytes, FAR const uint8_t *buffer);
|
||||
#endif
|
||||
static int progmem_ioctl(FAR struct mtd_dev_s *dev, int cmd,
|
||||
unsigned long arg);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
/* This structure holds the state of the MTD driver */
|
||||
|
||||
static struct progmem_dev_s g_progmem =
|
||||
{
|
||||
{
|
||||
progmem_erase,
|
||||
progmem_bread,
|
||||
progmem_bwrite,
|
||||
progmem_read,
|
||||
#ifdef CONFIG_MTD_BYTE_WRITE
|
||||
progmem_write,
|
||||
#endif
|
||||
progmem_ioctl
|
||||
}
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: progmem_erase
|
||||
*
|
||||
* Description:
|
||||
* Erase several blocks, each of the size previously reported.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int32_t progmem_log2(uint32_t blocksize)
|
||||
{
|
||||
uint32_t log2 = 0;
|
||||
|
||||
/* Search every bit in the blocksize from bit zero to bit 30 (omitting bit
|
||||
* 31 which is the sign bit on return)
|
||||
*/
|
||||
|
||||
for (log2 = 0; log2 < 31; log2++, blocksize >>= 1)
|
||||
{
|
||||
/* Is bit zero set? */
|
||||
|
||||
if ((blocksize & 1) != 0)
|
||||
{
|
||||
/* Yes... the value should be exactly one. We do not support
|
||||
* block sizes that are not exact powers of two.
|
||||
*/
|
||||
|
||||
return blocksize == 1 ? log2 : -ENOSYS;
|
||||
}
|
||||
}
|
||||
|
||||
return blocksize == 0 ? -EINVAL : -E2BIG;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: progmem_erase
|
||||
*
|
||||
* Description:
|
||||
* Erase several blocks, each of the size previously reported.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int progmem_erase(FAR struct mtd_dev_s *dev, off_t startblock,
|
||||
size_t nblocks)
|
||||
{
|
||||
ssize_t result;
|
||||
|
||||
/* Erase the specified blocks and return status (OK or a negated errno) */
|
||||
|
||||
while (nblocks > 0)
|
||||
{
|
||||
result = up_progmem_erasepage(startblock);
|
||||
if (result < 0)
|
||||
{
|
||||
return (int)result;
|
||||
}
|
||||
|
||||
/* Setup for the next pass through the loop */
|
||||
|
||||
startblock++;
|
||||
nblocks--;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: progmem_bread
|
||||
*
|
||||
* Description:
|
||||
* Read the specified number of blocks into the user provided buffer.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t progmem_bread(FAR struct mtd_dev_s *dev, off_t startblock,
|
||||
size_t nblocks, FAR uint8_t *buffer)
|
||||
{
|
||||
FAR struct progmem_dev_s *priv = (FAR struct progmem_dev_s *)dev;
|
||||
FAR const uint8_t *src;
|
||||
size_t offset;
|
||||
|
||||
/* Read the specified blocks into the provided user buffer and return
|
||||
* status (The positive, number of blocks actually read or a negated
|
||||
* errno).
|
||||
*/
|
||||
|
||||
offset = startblock << priv->blkshift;
|
||||
src = (FAR const uint8_t *)up_progmem_getaddress(offset);
|
||||
memcpy(buffer, src, nblocks << priv->blkshift);
|
||||
return nblocks;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: progmem_bwrite
|
||||
*
|
||||
* Description:
|
||||
* Write the specified number of blocks from the user provided buffer.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t progmem_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
|
||||
size_t nblocks, FAR const uint8_t *buffer)
|
||||
{
|
||||
FAR struct progmem_dev_s *priv = (FAR struct progmem_dev_s *)dev;
|
||||
ssize_t result;
|
||||
|
||||
/* Write the specified blocks from the provided user buffer and return status
|
||||
* (The positive, number of blocks actually written or a negated errno)
|
||||
*/
|
||||
|
||||
result = up_progmem_write(up_progmem_getaddress(startblock), buffer,
|
||||
nblocks << priv->blkshift);
|
||||
return result < 0 ? result : nblocks;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: progmem_read
|
||||
*
|
||||
* Description:
|
||||
* Read the specified number of bytes to the user provided buffer.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t progmem_read(FAR struct mtd_dev_s *dev, off_t offset,
|
||||
size_t nbytes, FAR uint8_t *buffer)
|
||||
{
|
||||
FAR const uint8_t *src;
|
||||
|
||||
/* Read the specified bytes into the provided user buffer and return
|
||||
* status (The positive, number of bytes actually read or a negated
|
||||
* errno)
|
||||
*/
|
||||
|
||||
src = (FAR const uint8_t *)up_progmem_getaddress(offset);
|
||||
memcpy(buffer, src, nbytes);
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: progmem_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 progmem_write(FAR struct mtd_dev_s *dev, off_t offset,
|
||||
size_t nbytes, FAR const uint8_t *buffer)
|
||||
{
|
||||
FAR struct progmem_dev_s *priv = (FAR struct progmem_dev_s *)dev;
|
||||
ssize_t result;
|
||||
|
||||
/* Write the specified blocks from the provided user buffer and return status
|
||||
* (The positive, number of blocks actually written or a negated errno)
|
||||
*/
|
||||
|
||||
result = up_progmem_write(up_progmem_getaddress(offset), buffer, nbytes;
|
||||
return result < 0 ? result : nbytes;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: progmem_ioctl
|
||||
****************************************************************************/
|
||||
|
||||
static int progmem_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
|
||||
{
|
||||
FAR struct progmem_dev_s *priv = (FAR struct progmem_dev_s *)dev;
|
||||
int ret = -EINVAL; /* Assume good command with bad parameters */
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case MTDIOC_GEOMETRY:
|
||||
{
|
||||
FAR struct mtd_geometry_s *geo = (FAR struct mtd_geometry_s *)arg;
|
||||
if (geo)
|
||||
{
|
||||
/* Populate the geometry structure with information needed to know
|
||||
* the capacity and how to access the device.
|
||||
*
|
||||
* NOTE: that the device is treated as though it where just an array
|
||||
* of fixed size blocks. That is most likely not true, but the client
|
||||
* will expect the device logic to do whatever is necessary to make it
|
||||
* appear so.
|
||||
*/
|
||||
|
||||
geo->blocksize = (1 << priv->blkshift); /* Size of one read/write block */
|
||||
geo->erasesize = (1 << priv->blkshift); /* Size of one erase block */
|
||||
geo->neraseblocks = up_progmem_npages(); /* Number of erase blocks */
|
||||
ret = OK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MTDIOC_XIPBASE:
|
||||
{
|
||||
FAR void **ppv = (FAR void**)arg;
|
||||
|
||||
if (ppv)
|
||||
{
|
||||
/* Return (void*) base address of FLASH memory. */
|
||||
|
||||
*ppv = (FAR void *)up_progmem_getaddress(0);
|
||||
ret = OK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MTDIOC_BULKERASE:
|
||||
{
|
||||
size_t nblocks = up_progmem_npages();
|
||||
|
||||
/* Erase the entire device */
|
||||
|
||||
ret = progmem_erase(dev, 0, nblocks);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -ENOTTY; /* Bad command */
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: progmem_initialize
|
||||
*
|
||||
* Description:
|
||||
* Create and initialize an MTD device instance. MTD devices are not
|
||||
* registered in the file system, but are created as instances that can
|
||||
* be bound to other functions (such as a block or character driver front
|
||||
* end).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct mtd_dev_s *progmem_initialize(void)
|
||||
{
|
||||
FAR struct progmem_dev_s *priv = (FAR struct progmem_dev_s *)&g_progmem;
|
||||
int32_t blkshift;
|
||||
|
||||
/* Perform initialization if necessary */
|
||||
|
||||
if (!g_progmem.initialized)
|
||||
{
|
||||
size_t nblocks = up_progmem_npages();
|
||||
blkshift = progmem_log2(nblocks);
|
||||
|
||||
if (blkshift < 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_progmem.blkshift = blkshift;
|
||||
g_progmem.initialized = true;
|
||||
}
|
||||
|
||||
/* Return the implementation-specific state structure as the MTD device */
|
||||
|
||||
return (FAR struct mtd_dev_s *)priv;
|
||||
}
|
@ -72,18 +72,20 @@ struct skel_dev_s
|
||||
|
||||
/* MTD driver methods */
|
||||
|
||||
static int skel_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks);
|
||||
static ssize_t skel_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks,
|
||||
FAR uint8_t *buf);
|
||||
static ssize_t skel_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks,
|
||||
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);
|
||||
static int skel_erase(FAR struct mtd_dev_s *dev, off_t startblock,
|
||||
size_t nblocks);
|
||||
static ssize_t skel_bread(FAR struct mtd_dev_s *dev, off_t startblock,
|
||||
size_t nblocks, FAR uint8_t *buf);
|
||||
static ssize_t skel_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
|
||||
size_t nblocks, 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);
|
||||
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);
|
||||
static int skel_ioctl(FAR struct mtd_dev_s *dev, int cmd,
|
||||
unsigned long arg);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
@ -92,8 +94,9 @@ 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_erase,
|
||||
skel_bread,
|
||||
skel_bwrite,
|
||||
skel_read,
|
||||
#ifdef CONFIG_MTD_BYTE_WRITE
|
||||
@ -101,6 +104,7 @@ static struct skel_dev_s g_skeldev =
|
||||
#endif
|
||||
skel_ioctl
|
||||
},
|
||||
|
||||
/* Initialization of any other implementation specific data goes here */
|
||||
};
|
||||
|
||||
@ -121,9 +125,9 @@ static int skel_erase(FAR struct mtd_dev_s *dev, off_t startblock,
|
||||
{
|
||||
FAR struct skel_dev_s *priv = (FAR struct skel_dev_s *)dev;
|
||||
|
||||
/* The interface definition assumes that all erase blocks are the same size.
|
||||
* If that is not true for this particular device, then transform the
|
||||
* start block and nblocks as necessary.
|
||||
/* The interface definition assumes that all erase blocks are the same
|
||||
* size. If that is not true for this particular device, then transform
|
||||
* the start block and nblocks as necessary.
|
||||
*/
|
||||
|
||||
/* Erase the specified blocks and return status (OK or a negated errno) */
|
||||
@ -139,18 +143,19 @@ static int skel_erase(FAR struct mtd_dev_s *dev, off_t startblock,
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t skel_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks,
|
||||
FAR uint8_t *buf)
|
||||
static ssize_t skel_bread(FAR struct mtd_dev_s *dev, off_t startblock,
|
||||
size_t nblocks, FAR uint8_t *buf)
|
||||
{
|
||||
FAR struct skel_dev_s *priv = (FAR struct skel_dev_s *)dev;
|
||||
|
||||
/* The interface definition assumes that all read/write blocks are the same size.
|
||||
* If that is not true for this particular device, then transform the
|
||||
* start block and nblocks as necessary.
|
||||
/* The interface definition assumes that all read/write blocks are the
|
||||
* same size. If that is not true for this particular device, then
|
||||
* transform the start block and nblocks as necessary.
|
||||
*/
|
||||
|
||||
/* Read the specified blocks into the provided user buffer and return status
|
||||
* (The positive, number of blocks actually read or a negated errno).
|
||||
/* Read the specified blocks into the provided user buffer and return
|
||||
* status (The positive, number of blocks actually read or a negated
|
||||
* errno).
|
||||
*/
|
||||
|
||||
return 0;
|
||||
@ -164,18 +169,19 @@ static ssize_t skel_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nb
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t skel_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks,
|
||||
FAR const uint8_t *buf)
|
||||
static ssize_t skel_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
|
||||
size_t nblocks, FAR const uint8_t *buf)
|
||||
{
|
||||
FAR struct skel_dev_s *priv = (FAR struct skel_dev_s *)dev;
|
||||
|
||||
/* The interface definition assumes that all read/write blocks are the same size.
|
||||
* If that is not true for this particular device, then transform the
|
||||
* start block and nblocks as necessary.
|
||||
/* The interface definition assumes that all read/write blocks are the
|
||||
* same size. If that is not true for this particular device, then
|
||||
* transform the start block and nblocks as necessary.
|
||||
*/
|
||||
|
||||
/* Write the specified blocks from the provided user buffer and return status
|
||||
* (The positive, number of blocks actually written or a negated errno)
|
||||
/* Write the specified blocks from the provided user buffer and return
|
||||
* status (The positive, number of blocks actually written or a negated
|
||||
* errno)
|
||||
*/
|
||||
|
||||
return 0;
|
||||
@ -189,26 +195,27 @@ static ssize_t skel_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t n
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t skel_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
|
||||
FAR uint8_t *buffer)
|
||||
static ssize_t skel_read(FAR struct mtd_dev_s *dev, off_t offset,
|
||||
size_t nbytes, FAR uint8_t *buffer)
|
||||
{
|
||||
FAR struct skel_dev_s *priv = (FAR struct skel_dev_s *)dev;
|
||||
|
||||
/* Some devices may support byte oriented read (optional). Byte-oriented
|
||||
* writing is inherently block oriented on most MTD devices and is not supported.
|
||||
* It is recommended that low-level drivers not support read() if it requires
|
||||
* buffering -- let the higher level logic handle that. If the read method is
|
||||
* not implemented, just set the method pointer to NULL in the struct mtd_dev_s
|
||||
* instance.
|
||||
* writing is inherently block oriented on most MTD devices and is not
|
||||
* supported. It is recommended that low-level drivers not support read()
|
||||
* if it requires buffering -- let the higher level logic handle that. If
|
||||
* the read method is not implemented, just set the method pointer to NULL
|
||||
* in the struct mtd_dev_s instance.
|
||||
*/
|
||||
|
||||
/* The interface definition assumes that all read/write blocks are the same size.
|
||||
* If that is not true for this particular device, then transform the
|
||||
* start block and nblocks as necessary.
|
||||
/* The interface definition assumes that all read/write blocks are the
|
||||
* same size. If that is not true for this particular device, then
|
||||
* transform the start block and nblocks as necessary.
|
||||
*/
|
||||
|
||||
/* Read the specified blocks into the provided user buffer and return status
|
||||
* (The positive, number of blocks actually read or a negated errno)
|
||||
/* Read the specified bytes into the provided user buffer and return
|
||||
* status (The positive, number of bytes actually read or a negated
|
||||
* errno)
|
||||
*/
|
||||
|
||||
return 0;
|
||||
@ -224,8 +231,8 @@ static ssize_t skel_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
|
||||
****************************************************************************/
|
||||
|
||||
#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)
|
||||
static ssize_t skel_write(FAR struct mtd_dev_s *dev, off_t offset,
|
||||
size_t nbytes, FAR const uint8_t *buffer)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ size_t up_progmem_getaddress(size_t page);
|
||||
* Erase selected page.
|
||||
*
|
||||
* Input Parameters:
|
||||
* page -
|
||||
* page - The page index to be erased.
|
||||
*
|
||||
* Returned Value:
|
||||
* Page size or negative value on error. The following errors are reported
|
||||
@ -158,7 +158,7 @@ ssize_t up_progmem_erasepage(size_t page);
|
||||
* Checks whether page is erased
|
||||
*
|
||||
* Input Parameters:
|
||||
* page -
|
||||
* page - The page index to be checked.
|
||||
*
|
||||
* Returned Value:
|
||||
* Returns number of bytes NOT erased or negative value on error. If it
|
||||
|
Loading…
Reference in New Issue
Block a user