summaryrefslogtreecommitdiff
path: root/nuttx/fs
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-05-01 00:26:38 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-05-01 00:26:38 +0000
commite120ff0a0ef5c0f0125fc0e4b21bead8c67f8727 (patch)
tree6e3b77b0b0d5de8d3bfae8a61f9d9b3e16536f26 /nuttx/fs
parente17d3eedc63a01896b7bf8ed9a592748f61246ce (diff)
downloadpx4-nuttx-e120ff0a0ef5c0f0125fc0e4b21bead8c67f8727.tar.gz
px4-nuttx-e120ff0a0ef5c0f0125fc0e4b21bead8c67f8727.tar.bz2
px4-nuttx-e120ff0a0ef5c0f0125fc0e4b21bead8c67f8727.zip
Add basic NXFFS read logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3546 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/fs')
-rw-r--r--nuttx/fs/nxffs/nxffs.h29
-rw-r--r--nuttx/fs/nxffs/nxffs_cache.c66
-rw-r--r--nuttx/fs/nxffs/nxffs_open.c4
-rw-r--r--nuttx/fs/nxffs/nxffs_read.c201
-rw-r--r--nuttx/fs/nxffs/nxffs_unlink.c2
-rw-r--r--nuttx/fs/nxffs/nxffs_write.c4
6 files changed, 234 insertions, 72 deletions
diff --git a/nuttx/fs/nxffs/nxffs.h b/nuttx/fs/nxffs/nxffs.h
index d9c4f3c88..9ed65cf67 100644
--- a/nuttx/fs/nxffs/nxffs.h
+++ b/nuttx/fs/nxffs/nxffs.h
@@ -496,19 +496,15 @@ extern int nxffs_rdcache(FAR struct nxffs_volume_s *volume, off_t block,
*
* Input Parameters:
* volume - Describes the current volume
- * block - The first logical block to write
- * nblocks - The number of logical blocks to be write.
*
* Returned Value:
* Negated errnos are returned only in the case of MTD reported failures.
- * Nothing in the volume data itself will generate errors.
*
* Defined in nxffs_cache.c
*
****************************************************************************/
-extern int nxffs_wrcache(FAR struct nxffs_volume_s *volume, off_t block,
- uint8_t nblocks);
+extern int nxffs_wrcache(FAR struct nxffs_volume_s *volume);
/****************************************************************************
* Name: nxffs_ioseek
@@ -595,29 +591,6 @@ extern ssize_t nxffs_rddata(FAR struct nxffs_volume_s *volume,
FAR uint8_t *buffer, size_t buflen);
/****************************************************************************
- * Name: nxffs_wrdata
- *
- * Description:
- * Write a sequence of data bytes into volume cache memory. Nothing is
- * actually written to FLASH! This function allows the data in the formatted
- * FLASH blocks to be read as a continuous byte stream, skipping over bad
- * blocks and block headers as necessary.
- *
- * Input Parameters:
- * volume - Describes the NXFFS volume.
- * buffer - A pointer to memory to containing the data to write to FLASH.
- * buflen - The maximum number of bytes to write to FLASH.
- *
- * Returned Value:
- * The number of bytes written is returned on success. Otherwise, a negated
- * errno indicating the nature of the failure.
- *
- ****************************************************************************/
-
-extern ssize_t nxffs_wrdata(FAR struct nxffs_volume_s *volume,
- FAR const uint8_t *buffer, size_t buflen);
-
-/****************************************************************************
* Name: nxffs_freeentry
*
* Description:
diff --git a/nuttx/fs/nxffs/nxffs_cache.c b/nuttx/fs/nxffs/nxffs_cache.c
index 41974bf93..7f563820f 100644
--- a/nuttx/fs/nxffs/nxffs_cache.c
+++ b/nuttx/fs/nxffs/nxffs_cache.c
@@ -103,7 +103,7 @@ int nxffs_rdcache(FAR struct nxffs_volume_s *volume, off_t block,
if (nxfrd != nblocks)
{
fdbg("Read block %d-%d failed: %d\n",
- block, block + nblocks -1, nxfrd);
+ block, block + nblocks - 1, nxfrd);
return -EIO;
}
@@ -123,22 +123,41 @@ int nxffs_rdcache(FAR struct nxffs_volume_s *volume, off_t block,
*
* Input Parameters:
* volume - Describes the current volume
- * block - The first logical block to write
- * nblocks - The number of logical blocks to be write.
*
* Returned Value:
* Negated errnos are returned only in the case of MTD reported failures.
- * Nothing in the volume data itself will generate errors.
- *
- * Defined in nxffs_cache.c
*
****************************************************************************/
-int nxffs_wrcache(FAR struct nxffs_volume_s *volume, off_t block,
- uint8_t nblocks)
+int nxffs_wrcache(FAR struct nxffs_volume_s *volume)
{
-#warning "Missing logic"
- return OK;
+ size_t nxfrd;
+
+ /* Check if there are blocks in the cache */
+
+ if (volume->ncached > 0)
+ {
+ /* Read the specified blocks into cache */
+
+ nxfrd = MTD_BWRITE(volume->mtd, volume->cblock, volume->ncached,
+ volume->cache);
+ if (nxfrd != volume->ncached)
+ {
+ fdbg("Write block %d-%d failed: %d\n",
+ volume->cblock, volume->cblock + volume->ncached - 1, nxfrd);
+ return -EIO;
+ }
+
+ /* Write was successful */
+
+ return OK;
+ }
+
+ /* Probably won't get here because there is almost always something in
+ * the cache
+ */
+
+ return -EINVAL;
}
/****************************************************************************
@@ -287,30 +306,3 @@ ssize_t nxffs_rddata(FAR struct nxffs_volume_s *volume,
return buflen;
}
-
-/****************************************************************************
- * Name: nxffs_wrdata
- *
- * Description:
- * Write a sequence of data bytes into volume cache memory. Nothing is
- * actually written to FLASH! This function allows the data in the formatted
- * FLASH blocks to be read as a continuous byte stream, skipping over bad
- * blocks and block headers as necessary.
- *
- * Input Parameters:
- * volume - Describes the NXFFS volume.
- * buffer - A pointer to memory to containing the data to write to FLASH.
- * buflen - The maximum number of bytes to write to FLASH.
- *
- * Returned Value:
- * The number of bytes written is returned on success. Otherwise, a negated
- * errno indicating the nature of the failure.
- *
- ****************************************************************************/
-
-ssize_t nxffs_wrdata(FAR struct nxffs_volume_s *volume,
- FAR const uint8_t *buffer, size_t buflen)
-{
-#warning "Missing Logic"
- return -ENOSYS;
-}
diff --git a/nuttx/fs/nxffs/nxffs_open.c b/nuttx/fs/nxffs/nxffs_open.c
index 45168d3da..09a82f6e9 100644
--- a/nuttx/fs/nxffs/nxffs_open.c
+++ b/nuttx/fs/nxffs/nxffs_open.c
@@ -820,7 +820,7 @@ static int nxffs_wrclose(FAR struct nxffs_volume_s *volume,
{
/* Write the block with the inode header */
- ret = nxffs_wrcache(volume, volume->ioblock, 1);
+ ret = nxffs_wrcache(volume);
if (ret < 0)
{
fdbg("Failed to write inode header block %d: %d\n", volume->ioblock, -ret);
@@ -842,7 +842,7 @@ static int nxffs_wrclose(FAR struct nxffs_volume_s *volume,
/* Finally, copy the inode name to the cache and write the inode name block */
memcpy(&volume->cache[namoffset], wrfile->ofile.entry.name, namlen);
- ret = nxffs_wrcache(volume, volume->ioblock, 1);
+ ret = nxffs_wrcache(volume);
if (ret < 0)
{
fdbg("Failed to write inode header block %d: %d\n", volume->ioblock, -ret);
diff --git a/nuttx/fs/nxffs/nxffs_read.c b/nuttx/fs/nxffs/nxffs_read.c
index d8c2e9567..3648c1314 100644
--- a/nuttx/fs/nxffs/nxffs_read.c
+++ b/nuttx/fs/nxffs/nxffs_read.c
@@ -43,6 +43,7 @@
#include <string.h>
#include <fcntl.h>
+#include <crc32.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
@@ -69,6 +70,178 @@
****************************************************************************/
/****************************************************************************
+ * Name: nxffs_rdblkhdr
+ *
+ * Description:
+ * Read the dataa block header at this offset. Called only from nxffs_nextblock().
+ *
+ * Input Parameters:
+ * volume - Describes the current volume.
+ * offset - The byte offset from the beginning of FLASH where the data block
+ * header is expected.
+ * datlen - A memory location to return the data block length.
+ *
+ * Returned Value:
+ * Zero on success. Otherwise, a negater errno value is returned
+ * indicating the nature of the failure.
+ *
+ ****************************************************************************/
+
+static int nxffs_rdblkhdr(FAR struct nxffs_volume_s *volume, off_t offset,
+ FAR size_t *datlen)
+{
+ struct nxffs_data_s blkhdr;
+ uint32_t ecrc;
+ uint32_t crc;
+ uint16_t doffset;
+ uint16_t dlen;
+ int ret;
+
+ /* Read the header at the FLASH offset */
+
+ nxffs_ioseek(volume, offset);
+ ret = nxffs_rddata(volume, (FAR uint8_t *)&blkhdr, SIZEOF_NXFFS_DATA_HDR);
+ if (ret < 0)
+ {
+ fdbg("Failed to read data block header, offset %d: %d\n", offset, -ret);
+ return -EIO;
+ }
+ doffset = volume->iooffset;
+
+ /* Extract the data length */
+
+ dlen = nxffs_rdle16(blkhdr.datlen);
+ if ((uint32_t)doffset + (uint32_t)dlen > (uint32_t)volume->geo.blocksize)
+ {
+ fdbg("Data length=%d is unreasonable at offset=%d\n", dlen, doffset);
+ return -EIO;
+ }
+
+ /* Extract the expected CRC and calculate the CRC of the data block */
+
+ ecrc = nxffs_rdle32(blkhdr.crc);
+
+ nxffs_wrle16(blkhdr.crc, 0);
+ crc = crc32((FAR const uint8_t *)&blkhdr, SIZEOF_NXFFS_DATA_HDR);
+ crc = crc32part(&volume->cache[doffset], dlen, crc);
+ if (crc != ecrc)
+ {
+ fdbg("CRC failure\n");
+ return -EIO;
+ }
+
+ /* Looks good! Return the data length and success */
+
+ *datlen = dlen;
+ return OK;
+}
+
+/****************************************************************************
+ * Name: nxffs_nextblock
+ *
+ * Description:
+ * Search for the next valid data block starting at the provided FLASH offset.
+ *
+ * Input Parameters:
+ * volume - Describes the NXFFS volume.
+ * offset - The FLASH memory offset to begin searching.
+ * datlen - A memory location to return the data block length.
+ *
+ * Returned Value:
+ * Zero is returned on success. Otherwise, a negated errno is returned
+ * that indicates the nature of the failure.
+ *
+ ****************************************************************************/
+
+int nxffs_nextblock(FAR struct nxffs_volume_s *volume, off_t offset,
+ FAR size_t *datlen)
+{
+ int nmagic;
+ int ch;
+ int nerased;
+ int ret;
+
+ /* Seek to the first FLASH offset provided by the caller. */
+
+ nxffs_ioseek(volume, offset);
+
+ /* Then begin searching */
+
+ nerased = 0;
+ nmagic = 0;
+
+ for (;;)
+ {
+ /* Read the next character */
+
+ ch = nxffs_getc(volume);
+ if (ch < 0)
+ {
+ fvdbg("nxffs_getc failed: %d\n", -ch);
+ return ch;
+ }
+
+ /* Check for another erased byte */
+
+ else if (ch == CONFIG_NXFFS_ERASEDSTATE)
+ {
+ /* If we have encountered NXFFS_NERASED number of consecutive
+ * erased bytes, then presume we have reached the end of valid
+ * data.
+ */
+
+ if (++nerased >= NXFFS_NERASED)
+ {
+ fvdbg("No entry found\n");
+ return -ENOENT;
+ }
+ }
+ else
+ {
+ nerased = 0;
+
+ /* Check for the magic sequence indicating the start of an NXFFS
+ * data block or start of the next inode. There is the possibility
+ * of this magic sequnce occurring in FLASH data. However, the
+ * data block CRC should distinguish between real NXFFS data blocks
+ * headers and such false alarms.
+ */
+
+ if (ch != g_datamagic[nmagic])
+ {
+ nmagic = 0;
+ }
+ else if (nmagic < NXFFS_MAGICSIZE - 1)
+ {
+ nmagic++;
+ }
+
+ /* We have found the magic sequence in the FLASH data that may
+ * indicate the beginning of an NXFFS data block.
+ */
+
+ else
+ {
+ ret = nxffs_rdblkhdr(volume, offset, datlen);
+ if (ret == OK)
+ {
+ fdbg("Found a valid fileheader\n");
+ return OK;
+ }
+
+ /* False alarm.. keep looking */
+
+ nmagic = 0;
+ }
+ }
+ }
+
+ /* We won't get here, but to keep some compilers happy: */
+
+ return -ENOENT;
+}
+
+/****************************************************************************
* Name: nxffs_rdseek
*
* Description:
@@ -88,8 +261,32 @@ static ssize_t nxffs_rdseek(FAR struct nxffs_volume_s *volume,
FAR struct nxffs_entry_s *entry,
off_t fpos)
{
-#warning "Missing Logic"
- return 0;
+ size_t datlen = 0;
+ size_t blklen = 0;
+ off_t offset = fpos;
+ int ret;
+
+ /* Loop until we read the data block containing the desired position */
+
+ do
+ {
+ /* Get the data offset at the start of the next data block */
+
+ datlen += blklen;
+
+ /* Get the length of the next data block */
+
+ ret = nxffs_nextblock(volume, offset, &blklen);
+ if (ret < 0)
+ {
+ fdbg("nxffs_nextblock failed: %d\n", -ret);
+ return ret;
+ }
+ }
+ while (datlen <= fpos && datlen + blklen > fpos);
+
+ volume->iooffset += (fpos - datlen);
+ return OK;
}
/****************************************************************************
diff --git a/nuttx/fs/nxffs/nxffs_unlink.c b/nuttx/fs/nxffs/nxffs_unlink.c
index 8e25a1557..47abf61dd 100644
--- a/nuttx/fs/nxffs/nxffs_unlink.c
+++ b/nuttx/fs/nxffs/nxffs_unlink.c
@@ -137,7 +137,7 @@ int nxffs_rminode(FAR struct nxffs_volume_s *volume, FAR const char *name)
/* Then write the cached block back to FLASH */
- ret = nxffs_wrcache(volume, volume->ioblock, 1);
+ ret = nxffs_wrcache(volume);
if (ret < 0)
{
fdbg("Failed to read data into cache: %d\n", ret);
diff --git a/nuttx/fs/nxffs/nxffs_write.c b/nuttx/fs/nxffs/nxffs_write.c
index 3d7ad063d..8e91d2a7e 100644
--- a/nuttx/fs/nxffs/nxffs_write.c
+++ b/nuttx/fs/nxffs/nxffs_write.c
@@ -403,7 +403,7 @@ static inline ssize_t nxffs_wrappend(FAR struct nxffs_volume_s *volume,
if (nbytesleft > 0)
{
- ret = nxffs_wrcache(volume, volume->ioblock, 1);
+ ret = nxffs_wrcache(volume);
if (ret < 0)
{
fdbg("nxffs_wrcache failed: %d\n", -ret);
@@ -811,7 +811,7 @@ int nxffs_wrblkhdr(FAR struct nxffs_volume_s *volume,
/* And write the data block to FLASH */
- ret = nxffs_wrcache(volume, volume->ioblock, 1);
+ ret = nxffs_wrcache(volume);
if (ret < 0)
{
fdbg("nxffs_wrcache failed: %d\n", -ret);