You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ma...@apache.org on 2016/01/15 18:56:20 UTC

[13/14] incubator-mynewt-larva git commit: Relocate libs/fs -> fs/fs libs/nffs -> fs/nffs.

Relocate libs/fs -> fs/fs libs/nffs -> fs/nffs.


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/commit/cf40853d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/cf40853d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/cf40853d

Branch: refs/heads/master
Commit: cf40853d2bc455ed13ea3844afaf0a51a4ed2ca2
Parents: a4dd006
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Fri Jan 15 09:54:35 2016 -0800
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Fri Jan 15 09:54:35 2016 -0800

----------------------------------------------------------------------
 fs/fs/egg.yml                                   |    5 +
 fs/fs/include/fs/fs.h                           |   75 +
 fs/fs/include/fs/fs_if.h                        |   55 +
 fs/fs/include/fs/fsutil.h                       |   26 +
 fs/fs/src/fs_cli.c                              |  123 +
 fs/fs/src/fs_dirent.c                           |   49 +
 fs/fs/src/fs_file.c                             |   67 +
 fs/fs/src/fs_mkdir.c                            |   31 +
 fs/fs/src/fs_mount.c                            |   35 +
 fs/fs/src/fs_priv.h                             |   26 +
 fs/fs/src/fsutil.c                              |   64 +
 fs/nffs/LICENSE                                 |  202 +
 fs/nffs/README.md                               |    3 +
 fs/nffs/design.txt                              |  866 +++
 fs/nffs/egg.yml                                 |    8 +
 fs/nffs/include/nffs/nffs.h                     |   60 +
 fs/nffs/include/nffs/nffs_test.h                |   22 +
 fs/nffs/src/crc16.c                             |   99 +
 fs/nffs/src/crc16.h                             |   52 +
 fs/nffs/src/nffs.c                              |  692 ++
 fs/nffs/src/nffs_area.c                         |  109 +
 fs/nffs/src/nffs_block.c                        |  298 +
 fs/nffs/src/nffs_cache.c                        |  445 ++
 fs/nffs/src/nffs_config.c                       |   51 +
 fs/nffs/src/nffs_crc.c                          |  173 +
 fs/nffs/src/nffs_dir.c                          |  136 +
 fs/nffs/src/nffs_file.c                         |  346 +
 fs/nffs/src/nffs_flash.c                        |  174 +
 fs/nffs/src/nffs_format.c                       |  183 +
 fs/nffs/src/nffs_gc.c                           |  523 ++
 fs/nffs/src/nffs_hash.c                         |  151 +
 fs/nffs/src/nffs_inode.c                        |  906 +++
 fs/nffs/src/nffs_misc.c                         |  352 +
 fs/nffs/src/nffs_path.c                         |  337 +
 fs/nffs/src/nffs_priv.h                         |  427 ++
 fs/nffs/src/nffs_restore.c                      | 1034 +++
 fs/nffs/src/nffs_write.c                        |  397 ++
 fs/nffs/src/test/arch/cortex_m4/nffs_test.c     |   24 +
 fs/nffs/src/test/arch/sim/nffs_test.c           | 2441 +++++++
 fs/nffs/src/test/arch/sim/nffs_test_priv.h      |   39 +
 fs/nffs/src/test/arch/sim/nffs_test_system_01.c | 6534 ++++++++++++++++++
 fs/nffs/todo.txt                                |    4 +
 hw/hal/egg.yml                                  |    2 +-
 libs/bootutil/egg.yml                           |    2 +-
 libs/elua/elua_base/egg.yml                     |    2 +-
 libs/fs/egg.yml                                 |    5 -
 libs/fs/include/fs/fs.h                         |   75 -
 libs/fs/include/fs/fs_if.h                      |   55 -
 libs/fs/include/fs/fsutil.h                     |   26 -
 libs/fs/src/fs_cli.c                            |  123 -
 libs/fs/src/fs_dirent.c                         |   49 -
 libs/fs/src/fs_file.c                           |   67 -
 libs/fs/src/fs_mkdir.c                          |   31 -
 libs/fs/src/fs_mount.c                          |   35 -
 libs/fs/src/fs_priv.h                           |   26 -
 libs/fs/src/fsutil.c                            |   64 -
 libs/imgmgr/egg.yml                             |    2 +-
 libs/nffs/LICENSE                               |  202 -
 libs/nffs/README.md                             |    3 -
 libs/nffs/design.txt                            |  866 ---
 libs/nffs/egg.yml                               |    8 -
 libs/nffs/include/nffs/nffs.h                   |   60 -
 libs/nffs/include/nffs/nffs_test.h              |   22 -
 libs/nffs/src/crc16.c                           |   99 -
 libs/nffs/src/crc16.h                           |   52 -
 libs/nffs/src/nffs.c                            |  692 --
 libs/nffs/src/nffs_area.c                       |  109 -
 libs/nffs/src/nffs_block.c                      |  298 -
 libs/nffs/src/nffs_cache.c                      |  445 --
 libs/nffs/src/nffs_config.c                     |   51 -
 libs/nffs/src/nffs_crc.c                        |  173 -
 libs/nffs/src/nffs_dir.c                        |  136 -
 libs/nffs/src/nffs_file.c                       |  346 -
 libs/nffs/src/nffs_flash.c                      |  174 -
 libs/nffs/src/nffs_format.c                     |  183 -
 libs/nffs/src/nffs_gc.c                         |  523 --
 libs/nffs/src/nffs_hash.c                       |  151 -
 libs/nffs/src/nffs_inode.c                      |  906 ---
 libs/nffs/src/nffs_misc.c                       |  352 -
 libs/nffs/src/nffs_path.c                       |  337 -
 libs/nffs/src/nffs_priv.h                       |  427 --
 libs/nffs/src/nffs_restore.c                    | 1034 ---
 libs/nffs/src/nffs_write.c                      |  397 --
 libs/nffs/src/test/arch/cortex_m4/nffs_test.c   |   24 -
 libs/nffs/src/test/arch/sim/nffs_test.c         | 2441 -------
 libs/nffs/src/test/arch/sim/nffs_test_priv.h    |   39 -
 .../src/test/arch/sim/nffs_test_system_01.c     | 6534 ------------------
 libs/nffs/todo.txt                              |    4 -
 libs/testreport/egg.yml                         |    2 +-
 project/boot/boot.yml                           |    2 +-
 project/boot/egg.yml                            |    2 +-
 project/ffs2native/egg.yml                      |    6 +
 project/ffs2native/ffs2native.yml               |    2 +-
 project/luatest/luatest.yml                     |    2 +-
 project/test/egg.yml                            |    2 +-
 project/test/test.yml                           |    2 +-
 96 files changed, 17661 insertions(+), 17655 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/cf40853d/fs/fs/egg.yml
----------------------------------------------------------------------
diff --git a/fs/fs/egg.yml b/fs/fs/egg.yml
new file mode 100644
index 0000000..8f1d729
--- /dev/null
+++ b/fs/fs/egg.yml
@@ -0,0 +1,5 @@
+egg.name: fs/fs
+egg.deps.SHELL:
+    - libs/shell
+    - libs/console/full
+egg.cflags.SHELL: -DSHELL_PRESENT

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/cf40853d/fs/fs/include/fs/fs.h
----------------------------------------------------------------------
diff --git a/fs/fs/include/fs/fs.h b/fs/fs/include/fs/fs.h
new file mode 100644
index 0000000..872b863
--- /dev/null
+++ b/fs/fs/include/fs/fs.h
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __FS_H__
+#define __FS_H__
+
+#include <stddef.h>
+#include <inttypes.h>
+
+/*
+ * Common interface to access files.
+ */
+struct fs_file;
+struct fs_dir;
+struct fs_dirent;
+
+int fs_open(const char *filename, uint8_t access_flags, struct fs_file **);
+int fs_close(struct fs_file *);
+int fs_read(struct fs_file *, uint32_t len, void *out_data, uint32_t *out_len);
+int fs_write(struct fs_file *, const void *data, int len);
+int fs_seek(struct fs_file *, uint32_t offset);
+uint32_t fs_getpos(const struct fs_file *);
+int fs_filelen(const struct fs_file *, uint32_t *out_len);
+
+int fs_unlink(const char *filename);
+int fs_rename(const char *from, const char *to);
+int fs_mkdir(const char *path);
+
+int fs_opendir(const char *path, struct fs_dir **);
+int fs_readdir(struct fs_dir *, struct fs_dirent **);
+int fs_closedir(struct fs_dir *);
+int fs_dirent_name(const struct fs_dirent *, size_t max_len,
+  char *out_name, uint8_t *out_name_len);
+int fs_dirent_is_dir(const struct fs_dirent *);
+
+/*
+ * File access flags.
+ */
+#define FS_ACCESS_READ          0x01
+#define FS_ACCESS_WRITE         0x02
+#define FS_ACCESS_APPEND        0x04
+#define FS_ACCESS_TRUNCATE      0x08
+
+/*
+ * File access return codes.
+ */
+#define FS_EOK                  0       /* OK */
+#define FS_ECORRUPT             1       /* Filesystem corrupt */
+#define FS_HW_ERROR             2       /* Error access storage medium */
+#define FS_ERANGE               3
+#define FS_EINVAL               4
+#define FS_ENOMEM               5       /* out of memory */
+#define FS_ENOENT               6       /* no such file */
+#define FS_EEMPTY               7
+#define FS_EFULL                8
+#define FS_EUNEXP               9
+#define FS_EOS                  10
+#define FS_EEXIST               11
+#define FS_EACCESS              12
+#define FS_EUNINIT              13
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/cf40853d/fs/fs/include/fs/fs_if.h
----------------------------------------------------------------------
diff --git a/fs/fs/include/fs/fs_if.h b/fs/fs/include/fs/fs_if.h
new file mode 100644
index 0000000..9236cc6
--- /dev/null
+++ b/fs/fs/include/fs/fs_if.h
@@ -0,0 +1,55 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __FS_IF_H__
+#define __FS_IF_H__
+
+/*
+ * Common interface filesystem(s) provide.
+ */
+struct fs_ops {
+    int (*f_open)(const char *filename, uint8_t access_flags,
+              struct fs_file **out_file);
+    int (*f_close)(struct fs_file *file);
+    int (*f_read)(struct fs_file *file, uint32_t len, void *out_data,
+      uint32_t *out_len);
+    int (*f_write)(struct fs_file *file, const void *data, int len);
+
+    int (*f_seek)(struct fs_file *file, uint32_t offset);
+    uint32_t (*f_getpos)(const struct fs_file *file);
+    int (*f_filelen)(const struct fs_file *file, uint32_t *out_len);
+
+    int (*f_unlink)(const char *filename);
+    int (*f_rename)(const char *from, const char *to);
+    int (*f_mkdir)(const char *path);
+
+    int (*f_opendir)(const char *path, struct fs_dir **out_dir);
+    int (*f_readdir)(struct fs_dir *dir, struct fs_dirent **out_dirent);
+    int (*f_closedir)(struct fs_dir *dir);
+
+    int (*f_dirent_name)(const struct fs_dirent *dirent, size_t max_len,
+      char *out_name, uint8_t *out_name_len);
+    int (*f_dirent_is_dir)(const struct fs_dirent *dirent);
+
+    const char *f_name;
+};
+
+/*
+ * Currently allow only one type of FS, starts at root.
+ */
+int fs_register(const struct fs_ops *);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/cf40853d/fs/fs/include/fs/fsutil.h
----------------------------------------------------------------------
diff --git a/fs/fs/include/fs/fsutil.h b/fs/fs/include/fs/fsutil.h
new file mode 100644
index 0000000..59bfaf3
--- /dev/null
+++ b/fs/fs/include/fs/fsutil.h
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef H_FSUTIL_
+#define H_FSUTIL_
+
+#include <inttypes.h>
+
+int fsutil_read_file(const char *path, uint32_t offset, uint32_t len,
+                     void *dst, uint32_t *out_len);
+int fsutil_write_file(const char *path, const void *data, uint32_t len);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/cf40853d/fs/fs/src/fs_cli.c
----------------------------------------------------------------------
diff --git a/fs/fs/src/fs_cli.c b/fs/fs/src/fs_cli.c
new file mode 100644
index 0000000..e26e003
--- /dev/null
+++ b/fs/fs/src/fs_cli.c
@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef SHELL_PRESENT
+
+#include <inttypes.h>
+#include <string.h>
+
+#include <shell/shell.h>
+#include <console/console.h>
+
+#include "fs/fs.h"
+
+static struct shell_cmd fs_ls_struct;
+
+static void
+fs_ls_file(const char *name, struct fs_file *file)
+{
+    uint32_t len;
+
+    len = 0;
+    fs_filelen(file, &len);
+    console_printf("\t%6lu %s\n", (unsigned long)len, name);
+}
+
+static void
+fs_ls_dir(const char *name)
+{
+    console_printf("\t%6s %s\n", "dir", name);
+}
+
+static int
+fs_ls_cmd(int argc, char **argv)
+{
+    int rc, file_cnt = 0;
+    char *path;
+    struct fs_file *file;
+    struct fs_dir *dir;
+    struct fs_dirent *dirent;
+    char name[64];
+    int plen;
+    uint8_t namelen;
+
+    switch (argc) {
+    case 1:
+        path = "/";
+        break;
+    case 2:
+        path = argv[1];
+        break;
+    default:
+        console_printf("ls <path>\n");
+        return 1;
+    }
+
+    rc = fs_open(path, FS_ACCESS_READ, &file);
+    if (rc == 0) {
+        fs_ls_file(path, file);
+        fs_close(file);
+        file_cnt = 1;
+        goto done;
+    }
+
+    plen = strlen(path);
+    strncpy(name, path, sizeof(name) - 2);
+    if (name[plen - 1] != '/') {
+        name[plen++] = '/';
+        name[plen] = '\0';
+    }
+
+    rc = fs_opendir(path, &dir);
+    if (rc == 0) {
+        do {
+            rc = fs_readdir(dir, &dirent);
+            if (rc) {
+                break;
+            }
+            if (fs_dirent_name(dirent, sizeof(name) - plen, &name[plen],
+                &namelen)) {
+                break;
+            }
+            rc = fs_open(name, FS_ACCESS_READ, &file);
+            if (rc == 0) {
+                fs_ls_file(name, file);
+                fs_close(file);
+            } else {
+                fs_ls_dir(name);
+            }
+            file_cnt++;
+        } while (1);
+        fs_closedir(dir);
+        goto done;
+    }
+    console_printf("Error listing %s - %d\n", path, rc);
+done:
+    console_printf("%d files\n", file_cnt);
+    return 0;
+}
+
+void
+fs_cli_init(void)
+{
+    int rc;
+
+    rc = shell_cmd_register(&fs_ls_struct, "ls", fs_ls_cmd);
+    if (rc != 0) {
+        return;
+    }
+}
+#endif /* SHELL_PRESENT */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/cf40853d/fs/fs/src/fs_dirent.c
----------------------------------------------------------------------
diff --git a/fs/fs/src/fs_dirent.c b/fs/fs/src/fs_dirent.c
new file mode 100644
index 0000000..e4428de
--- /dev/null
+++ b/fs/fs/src/fs_dirent.c
@@ -0,0 +1,49 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <fs/fs.h>
+#include <fs/fs_if.h>
+#include "fs_priv.h"
+
+int
+fs_opendir(const char *path, struct fs_dir **out_dir)
+{
+    return fs_root_ops->f_opendir(path, out_dir);
+}
+
+int
+fs_readdir(struct fs_dir *dir, struct fs_dirent **out_dirent)
+{
+    return fs_root_ops->f_readdir(dir, out_dirent);
+}
+
+int
+fs_closedir(struct fs_dir *dir)
+{
+    return fs_root_ops->f_closedir(dir);
+}
+
+int
+fs_dirent_name(const struct fs_dirent *dirent, size_t max_len,
+  char *out_name, uint8_t *out_name_len)
+{
+    return fs_root_ops->f_dirent_name(dirent, max_len, out_name, out_name_len);
+}
+
+int
+fs_dirent_is_dir(const struct fs_dirent *dirent)
+{
+    return fs_root_ops->f_dirent_is_dir(dirent);
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/cf40853d/fs/fs/src/fs_file.c
----------------------------------------------------------------------
diff --git a/fs/fs/src/fs_file.c b/fs/fs/src/fs_file.c
new file mode 100644
index 0000000..ec2697b
--- /dev/null
+++ b/fs/fs/src/fs_file.c
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <fs/fs.h>
+#include <fs/fs_if.h>
+
+#include "fs_priv.h"
+
+int
+fs_open(const char *filename, uint8_t access_flags, struct fs_file **out_file)
+{
+    return fs_root_ops->f_open(filename, access_flags, out_file);
+}
+
+int
+fs_close(struct fs_file *file)
+{
+    return fs_root_ops->f_close(file);
+}
+
+int
+fs_read(struct fs_file *file, uint32_t len, void *out_data, uint32_t *out_len)
+{
+    return fs_root_ops->f_read(file, len, out_data, out_len);
+}
+
+int
+fs_write(struct fs_file *file, const void *data, int len)
+{
+    return fs_root_ops->f_write(file, data, len);
+}
+
+int
+fs_seek(struct fs_file *file, uint32_t offset)
+{
+    return fs_root_ops->f_seek(file, offset);
+}
+
+uint32_t
+fs_getpos(const struct fs_file *file)
+{
+    return fs_root_ops->f_getpos(file);
+}
+
+int
+fs_filelen(const struct fs_file *file, uint32_t *out_len)
+{
+    return fs_root_ops->f_filelen(file, out_len);
+}
+
+int
+fs_unlink(const char *filename)
+{
+    return fs_root_ops->f_unlink(filename);
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/cf40853d/fs/fs/src/fs_mkdir.c
----------------------------------------------------------------------
diff --git a/fs/fs/src/fs_mkdir.c b/fs/fs/src/fs_mkdir.c
new file mode 100644
index 0000000..4be7a0a
--- /dev/null
+++ b/fs/fs/src/fs_mkdir.c
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <fs/fs.h>
+#include <fs/fs_if.h>
+
+#include "fs_priv.h"
+
+int
+fs_rename(const char *from, const char *to)
+{
+    return fs_root_ops->f_rename(from, to);
+}
+
+int
+fs_mkdir(const char *path)
+{
+    return fs_root_ops->f_mkdir(path);
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/cf40853d/fs/fs/src/fs_mount.c
----------------------------------------------------------------------
diff --git a/fs/fs/src/fs_mount.c b/fs/fs/src/fs_mount.c
new file mode 100644
index 0000000..e452cf2
--- /dev/null
+++ b/fs/fs/src/fs_mount.c
@@ -0,0 +1,35 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <fs/fs.h>
+#include <fs/fs_if.h>
+#include "fs_priv.h"
+
+const struct fs_ops *fs_root_ops;
+
+int
+fs_register(const struct fs_ops *fops)
+{
+    if (fs_root_ops) {
+        return FS_EEXIST;
+    }
+    fs_root_ops = fops;
+
+#ifdef SHELL_PRESENT
+    fs_cli_init();
+#endif
+
+    return FS_EOK;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/cf40853d/fs/fs/src/fs_priv.h
----------------------------------------------------------------------
diff --git a/fs/fs/src/fs_priv.h b/fs/fs/src/fs_priv.h
new file mode 100644
index 0000000..c3d2ba6
--- /dev/null
+++ b/fs/fs/src/fs_priv.h
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __FS_PRIV_H__
+#define __FS_PRIV_H__
+
+struct fs_ops;
+extern const struct fs_ops *fs_root_ops;
+
+#ifdef SHELL_PRESENT
+void fs_cli_init(void);
+#endif /* SHELL_PRESENT */
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/cf40853d/fs/fs/src/fsutil.c
----------------------------------------------------------------------
diff --git a/fs/fs/src/fsutil.c b/fs/fs/src/fsutil.c
new file mode 100644
index 0000000..97fa84a
--- /dev/null
+++ b/fs/fs/src/fsutil.c
@@ -0,0 +1,64 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "fs/fs.h"
+
+int
+fsutil_read_file(const char *path, uint32_t offset, uint32_t len, void *dst,
+                 uint32_t *out_len)
+{
+    struct fs_file *file;
+    int rc;
+
+    rc = fs_open(path, FS_ACCESS_READ, &file);
+    if (rc != 0) {
+        goto done;
+    }
+
+    rc = fs_read(file, len, dst, out_len);
+    if (rc != 0) {
+        goto done;
+    }
+
+    rc = 0;
+
+done:
+    fs_close(file);
+    return rc;
+}
+
+int
+fsutil_write_file(const char *path, const void *data, uint32_t len)
+{
+    struct fs_file *file;
+    int rc;
+
+    rc = fs_open(path, FS_ACCESS_WRITE | FS_ACCESS_TRUNCATE, &file);
+    if (rc != 0) {
+        goto done;
+    }
+
+    rc = fs_write(file, data, len);
+    if (rc != 0) {
+        goto done;
+    }
+
+    rc = 0;
+
+done:
+    fs_close(file);
+    return rc;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/cf40853d/fs/nffs/LICENSE
----------------------------------------------------------------------
diff --git a/fs/nffs/LICENSE b/fs/nffs/LICENSE
new file mode 100644
index 0000000..8f71f43
--- /dev/null
+++ b/fs/nffs/LICENSE
@@ -0,0 +1,202 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "{}"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright {yyyy} {name of copyright owner}
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/cf40853d/fs/nffs/README.md
----------------------------------------------------------------------
diff --git a/fs/nffs/README.md b/fs/nffs/README.md
new file mode 100644
index 0000000..67071c5
--- /dev/null
+++ b/fs/nffs/README.md
@@ -0,0 +1,3 @@
+# ffs
+
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/cf40853d/fs/nffs/design.txt
----------------------------------------------------------------------
diff --git a/fs/nffs/design.txt b/fs/nffs/design.txt
new file mode 100644
index 0000000..76dce2c
--- /dev/null
+++ b/fs/nffs/design.txt
@@ -0,0 +1,866 @@
+***** NFFS
+
+*** HISTORY
+Rev.    Date            Changes
+6       2015/10/12      Add directory-reading API.
+5       2015/09/28      Rename to Newtron Flash File System.
+4       2015/09/08      Fix some badly-specified CRC behavior; clarification of
+                            behavior during restore of corrupt disk.
+3       2015/08/20      More cache specifics; updated nffs_read() function
+                            type.
+2       2015/08/17      Addition of crc16; clarification of sweep phase.
+1       2015/08/13
+
+
+*** SUMMARY
+
+Newtron Flash File System (nffs) is a flash file system with the following
+priorities:
+    * Minimal RAM usage
+    * Reliability
+
+
+*** DISK STRUCTURE
+
+At the top level, an nffs disk is partitioned into areas.  An area is a region
+of disk with the following properties:
+    (1) An area can be fully erased without affecting any other areas.
+    (2) A write to one area does not restrict writes to other areas.
+
+Clarification of point (2): some flash hardware divides its memory space into
+"blocks."  Writes within a block must be sequential, but writes to one block
+have no effect on what parts of other blocks can be written.  Thus, for flash
+hardware with such a restriction, each area must comprise a discrete number of
+blocks.
+
+While not strictly necessary, it is recommended that all areas have the same
+size.
+
+On disk, each area is prefixed with the following header:
+
+/** On-disk representation of an area header. */
+struct nffs_disk_area {
+    uint32_t nda_magic[4];  /* NFFS_AREA_MAGIC{0,1,2,3} */
+    uint32_t nda_length;    /* Total size of area, in bytes. */
+    uint8_t nda_ver;        /* Current nffs version: 0 */
+    uint8_t nda_gc_seq;     /* Garbage collection count. */
+    uint8_t reserved8;
+    uint8_t nda_id;         /* 0xff if scratch area. */
+};
+
+Beyond its header, an area contains a sequence of disk objects, representing
+the contents of the file system.  There are two types of objects: inodes and
+data blocks.  An inode represents a file or directory; a data block represents
+part of a file's contents.
+
+/** On-disk representation of an inode (file or directory). */
+struct nffs_disk_inode {
+    uint32_t ndi_magic;         /* NFFS_INODE_MAGIC */
+    uint32_t ndi_id;            /* Unique object ID. */
+    uint32_t ndi_seq;           /* Sequence number; greater supersedes
+                                   lesser. */
+    uint32_t ndi_parent_id;     /* Object ID of parent directory inode. */
+    uint8_t reserved8;
+    uint8_t ndi_filename_len;   /* Length of filename, in bytes. */
+    uint16_t ndi_crc16;         /* Covers rest of header and filename. */
+    /* Followed by filename. */
+};
+
+An inode filename's length cannot exceed 256 bytes.  The filename is not
+null-terminated.  The following ASCII characters are not allowed in a
+filename:
+    * /  (slash character)
+    * \0 (NUL character)
+
+/** On-disk representation of a data block. */
+struct nffs_disk_block {
+    uint32_t ndb_magic;     /* NFFS_BLOCK_MAGIC */
+    uint32_t ndb_id;        /* Unique object ID. */
+    uint32_t ndb_seq;       /* Sequence number; greater supersedes lesser. */
+    uint32_t ndb_inode_id;  /* Object ID of owning inode. */
+    uint32_t ndb_prev_id;   /* Object ID of previous block in file;
+                               NFFS_ID_NONE if this is the first block. */
+    uint16_t ndb_data_len;  /* Length of data contents, in bytes. */
+    uint16_t ndb_crc16;     /* Covers rest of header and data. */
+    /* Followed by 'ndb_data_len' bytes of data. */
+};
+
+Each data block contains the ID of the previous data block in the file.
+Together, the set of blocks in a file form a reverse singly-linked list.
+
+The maximum number of data bytes that a block can contain is determined at
+initialization-time.  The result is the greatest number which satisfies all of
+the following restrictions:
+    o No more than 2048.
+    o At least two maximum-sized blocks can fit in the smallest area.
+
+The 2048 number was chosen somewhat arbitrarily, and may change in the future.
+
+
+*** ID SPACE
+
+All disk objects have a unique 32-bit ID.  The ID space is partitioned as
+follows:
+      * 0x00000000 - 0x0fffffff: Directory inodes.
+      * 0x10000000 - 0x7fffffff: File inodes.
+      * 0x80000000 - 0xfffffffe: Data blocks.
+      * 0xffffffff             : Reserved (NFFS_ID_NONE)
+
+
+*** SCRATCH AREA
+
+A valid nffs file system must contain a single "scratch area."  The scratch
+area does not contain any objects of its own, and is only used during garbage
+collection.  The scratch area must have a size greater than or equal to each
+of the other areas in flash.
+
+
+*** RAM REPRESENTATION
+
+The file system comprises a set of objects of the following two types:
+    1) inode
+    2) data block
+
+Every object in the file system is stored in a 256-entry hash table.  An
+object's hash key is derived from its 32-bit ID.  Each list in the hash table
+is sorted by time of use; most-recently-used is at the front of the list. All
+objects are represented by the following structure:
+
+/**
+ * What gets stored in the hash table.  Each entry represents a data block or
+ * an inode.
+ */
+struct nffs_hash_entry {
+    SLIST_ENTRY(nffs_hash_entry) nhe_next;
+    uint32_t nhe_id;        /* 0 - 0x7fffffff if inode; else if block. */
+    uint32_t nhe_flash_loc; /* Upper-byte = area idx; rest = area offset. */
+};
+
+For each data block, the above structure is all that is stored in RAM.  To
+acquire more information about a data block, the block header must be read
+from flash.
+
+Inodes require a fuller RAM representation to capture the structure of the
+file system.  There are two types of inodes: files and directories.  Each
+inode hash entry is actually an instance of the following structure:
+
+/** Each inode hash entry is actually one of these. */
+struct nffs_inode_entry {
+    struct nffs_hash_entry nie_hash_entry;
+    SLIST_ENTRY(nffs_inode_entry) nie_sibling_next;
+    union {
+        struct nffs_inode_list nie_child_list;           /* If directory */
+        struct nffs_hash_entry *nie_last_block_entry;    /* If file */
+    };
+    uint8_t nie_refcnt;
+};
+
+A directory inode contains a list of its child files and directories
+(fie_child_list).  These entries are sorted alphabetically using the ASCII
+character set.
+
+A file inode contains a pointer to the last data block in the file
+(nie_last_block_entry).  For most file operations, the reversed block list must
+be walked backwards.  This introduces a number of speed inefficiencies:
+    * All data blocks must be read to determine the length of the file.
+    * Data blocks often need to be processed sequentially.  The reversed
+      nature of the block list transforms this from linear time to an O(n^2)
+      operation.
+
+Furthermore, obtaining information about any constituent data block requires a
+separate flash read.
+
+
+*** INODE CACHE AND DATA BLOCK CACHE
+The speed issues are addressed by a pair of caches.  Cached inodes entries
+contain the file length and a much more convenient doubly-linked list of
+cached data blocks.  The benefit of using caches is that the size of the
+caches need not be proportional to the size of the file system.  In other
+words, caches can address speed efficiency concerns without negatively
+impacting the file system's scalability.
+
+nffs requires both caches during normal operation, so it is not possible to
+disable them.  However, the cache sizes are configurable, and both caches can
+be configured with a size of one if RAM usage must be minimized.
+
+The following data structures are used in the inode and data block caches.
+
+/** Full data block representation; not stored permanently in RAM. */
+struct nffs_block {
+    struct nffs_hash_entry *nb_hash_entry;   /* Points to real block entry. */
+    uint32_t nb_seq;                         /* Sequence number; greater
+                                                supersedes lesser. */
+    struct nffs_inode_entry *nb_inode_entry; /* Owning inode. */
+    struct nffs_hash_entry *nb_prev;         /* Previous block in file. */
+    uint16_t nb_data_len;                    /* # of data bytes in block. */
+    uint16_t reserved16;
+};
+
+/** Represents a single cached data block. */
+struct nffs_cache_block {
+    TAILQ_ENTRY(nffs_cache_block) ncb_link; /* Next / prev cached block. */
+    struct nffs_block ncb_block;            /* Full data block. */
+    uint32_t ncb_file_offset;               /* File offset of this block. */
+};
+
+/** Full inode representation; not stored permanently in RAM. */
+struct nffs_inode {
+    struct nffs_inode_entry *ni_inode_entry; /* Points to real inode entry. */
+    uint32_t ni_seq;                         /* Sequence number; greater
+                                                supersedes lesser. */
+    struct nffs_inode_entry *ni_parent;      /* Points to parent directory. */
+    uint8_t ni_filename_len;                 /* # chars in filename. */
+    uint8_t ni_filename[NFFS_SHORT_FILENAME_LEN]; /* First 3 bytes. */
+};
+
+/** Doubly-linked tail queue of cached blocks; contained in cached inodes. */
+TAILQ_HEAD(nffs_block_cache_list, nffs_block_cache_entry);
+
+/** Represents a single cached file inode. */
+struct nffs_cache_inode {
+    TAILQ_ENTRY(nffs_cache_inode) nci_link;        /* Sorted; LRU at tail. */
+    struct nffs_inode nci_inode;                   /* Full inode. */
+    struct nffs_cache_block_list nci_block_list;   /* List of cached blocks. */
+    uint32_t nci_file_size;                        /* Total file size. */
+};
+
+Only file inodes are cached; directory inodes are never cached.
+
+Within a cached inode, all cached data blocks are contiguous.  E.g., if the
+start and end of a file are cached, then the middle must also be cached.  A
+data block is only cached if its owning file is also cached.
+
+Internally, cached inodes are stored in a singly-linked list, ordered by time
+of use.  The most-recently-used entry is the first element in the list.  If a
+new inode needs to be cached, but the inode cache is full, the
+least-recently-used entry is freed to make room for the new one.  The
+following operations cause an inode to be cached:
+    * Querying a file's length.
+    * Seeking within a file.
+    * Reading from a file.
+    * Writing to a file.
+
+The following operations cause a data block to be cached:
+    * Reading from the block.
+    * Writing to the block.
+
+If one of the above operations is applied to a data block that is not currently
+cached, nffs uses the following procedure to cache the necessary block:
+    1. If none of the owning inode's blocks are currently cached, allocate a
+       cached block entry corresponding to the requested block and insert it
+       into the inode's list.
+    2. Else if the requested file offset is less than that of the first cached
+       block, bridge the gap between the inode's sequence of cached blocks and
+       the block that now needs to be cached.  This is accomplished by caching
+       each block in the gap, finishing with the requested block.
+    3. Else (the requested offset is beyond the end of the cache),
+        a. If the requested offset belongs to the block that immediately
+           follows the end of the cache, cache the block and append it to the
+           list.
+        b. Else, clear the cache, and populate it with the single entry
+           corresponding to the requested block.
+
+If the system is unable to allocate a cached block entry at any point during
+the above procedure, the system frees up other blocks currently in the cache.
+This is accomplished as follows:
+    1. Iterate the inode cache in reverse (i.e., start with the
+       least-recently-used entry).  For each entry:
+        a. If the entry's cached block list is empty, advance to the next
+           entry.
+        b. Else, free all the cached blocks in the entry's list.
+
+Because the system imposes a minimum block cache size of one, the above
+procedure will always reclaim at least one cache block entry.  The above
+procedure may result in the freeing of the block list that belongs to the very
+inode being operated on.  This is OK, as the final block to get cached is
+always the block being requested.
+
+
+*** CONFIGURATION
+The file system is configured by populating fields in a global structure.
+Each field in the structure corresponds to a setting.  All configuration must
+be done prior to calling nffs_init().  The configuration structure is defined
+as follows:
+
+struct nffs_config {
+    /** Maximum number of inodes; default=1024. */
+    uint32_t nc_num_inodes;
+
+    /** Maximum number of data blocks; default=4096. */
+    uint32_t nc_num_blocks;
+
+    /** Maximum number of open files; default=4. */
+    uint32_t nc_num_files;
+
+    /** Inode cache size; default=4. */
+    uint32_t nc_num_cache_inodes;
+
+    /** Data block cache size; default=64. */
+    uint32_t nc_num_cache_blocks;
+};
+
+extern struct nffs_config nffs_config;
+
+Any fields that are set to 0 (or not set at all) inherit the corresponding
+default value.  This means that it is impossible to configure any setting with
+a value of zero.
+
+
+*** INITIALIZATION
+
+There are two means of initializing an nffs file system:
+    (1) Restore an existing file system via detection.
+    (2) Create a new file system via formatting.
+
+Both methods require the user to describe how the flash memory is divided into
+areas.  This is accomplished with an array of struct nffs_area_desc, defined as
+follows:
+
+struct nffs_area_desc {
+    uint32_t nad_offset;    /* Flash offset of start of area. */
+    uint32_t nad_length;    /* Size of area, in bytes. */
+};
+
+An array of area descriptors is terminated by an entry with a fad_length field
+of 0.
+
+One common initialization sequence is the following:
+
+    (1) Detect an nffs file system anywhere in flash.
+    (2) If no file system detected, format a new file system in a specific
+        region of flash.
+
+
+*** DETECTION
+
+The file system detection process consists of scanning a specified set of
+flash regions for valid nffs areas, and then populating the RAM representation
+of the file system with the detected objects.  Detection is initiated with the
+following function:
+
+/**
+ * Searches for a valid nffs file system among the specified areas.  This
+ * function succeeds if a file system is detected among any subset of the
+ * supplied areas.  If the area set does not contain a valid file system,
+ * a new one can be created via a separate call to nffs_format().
+ *
+ * @param area_descs        The area set to search.  This array must be
+ *                              terminated with a 0-length area.
+ *
+ * @return                  0 on success;
+ *                          NFFS_ECORRUPT if no valid file system was detected;
+ *                          other nonzero on error.
+ */
+int nffs_detect(const struct nffs_area_desc *area_descs);
+
+As indicated, not every area descriptor needs to reference a valid nffs area.
+Detection is successful as long as a complete file system is detected
+somewhere in the specified regions of flash.  If an application is unsure
+where a file system might be located, it can initiate detection across the
+entire flash region.
+
+A detected file system is valid if:
+    (1) At least one non-scratch area is present.
+    (2) At least one scratch area is present (only the first gets used if
+        there is more than one).
+    (3) The root directory inode is present.
+
+During detection, each indicated region of flash is checked for a valid area
+header.  The contents of each valid non-scratch area are then restored into
+the nffs RAM representation.  The following procedure is applied to each object
+in the area:
+
+    (1) Verify the object's integrity via a crc16 check.  If invalid, the
+        object is discarded and the procedure restarts on the next object in
+        the area.
+
+    (2) Convert the disk object into its corresponding RAM representation and
+        insert it into the hash table.  If the object is an inode, its
+        reference count is initialized to 1, indicating ownership by its
+        parent directory.
+
+    (3) If an object with the same ID is already present, then one supersedes
+        the other.  Accept the object with the greater sequence number and
+        discard the other.
+
+    (4) If the object references a nonexistant inode (parent directory in the
+        case of an inode; owning file in the case of a data block), insert a
+        temporary "dummy" inode into the hash table so that inter-object links
+        can be maintained until the absent inode is eventually restored.  Dummy
+        inodes are identified by a reference count of 0.
+
+    (5) If a delete record for an inode is encountered, the inode's parent
+        pointer is set to null to indicate that it should be removed from RAM.
+
+If nffs encounters an object that cannot be identified (i.e., its magic number
+is not valid), it scans the remainder of the flash area for the next valid
+magic number.  Upon encountering a valid object, nffs resumes the procedure
+described above.
+
+After all areas have been restored, a sweep is performed across the entire RAM
+representation so that invalid inodes can be deleted from memory.
+
+For each directory inode:
+    * If its reference count is 0 (i.e., it is a dummy), migrate its children
+      to the /lost+found directory, and delete it from the RAM representation.
+      This should only happen in the case of file system corruption.
+    * If its parent reference is null (i.e., it was deleted), delete it and all
+      its children from the RAM representation.
+
+For each file inode:
+    * If its reference count is 0 (i.e., it is a dummy), delete it from the RAM
+      representation.  This should only happen in the case of file system
+      corruption.  (We should try to migrate the file to the lost+found
+      directory in this case, as mentioned in the todo section).
+
+When an object is deleted during this sweep, it is only deleted from the RAM
+representation; nothing is written to disk.
+
+When objects are migrated to the lost+found directory, their parent inode
+reference is permanently updated on the disk.
+
+In addition, a single scratch area is identified during the detection process.
+The first area whose 'fda_id' value is set to 0xff is designated as the file
+system scratch area.  If no valid scratch area is found, the cause could be
+that the system was restarted while a garbage collection cycle was in progress.
+Such a condition is identified by the presence of two areas with the same ID.
+In such a case, the shorter of the two areas is erased and designated as the
+scratch area.
+
+
+*** FORMATTING
+
+A new file system is created via formatting.  Formatting is achieved via the
+following function:
+
+/**
+ * Erases all the specified areas and initializes them with a clean nffs
+ * file system.
+ *
+ * @param area_descs        The set of areas to format.
+ *
+ * @return                  0 on success;
+ *                          nonzero on failure.
+ */
+int nffs_format(const struct nffs_area_desc *area_descs);
+
+On success, an area header is written to each of the specified locations.  The
+largest area in the set is designated as the initial scratch area.
+
+
+*** FLASH WRITES
+
+The nffs implementation always writes in a strictly sequential fashion within an
+area.  For each area, the system keeps track of the current offset.  Whenever
+an object gets written to an area, it gets written to that area's current
+offset, and the offset is increased by the object's disk size.
+
+When a write needs to be performed, the nffs implementation selects the
+appropriate destination area by iterating though each area until one with
+sufficient free space is encountered.
+
+There is no write buffering.  Each call to a write function results in a write
+operation being sent to the flash hardware.
+
+
+*** NEW OBJECTS
+
+Whenever a new object is written to disk, it is assigned the following
+properties:
+    * ID: A unique value is selected from the 32-bit ID space, as appropriate
+      for the object's type.
+    * Sequence number: 0
+
+When a new file or directory is created, a corresponding inode is written to
+flash.  Likewise, a new data block also results in the writing of a
+corresponding disk object.
+
+
+*** MOVING / RENAMING FILES AND DIRECTORIES
+
+When a file or directory is moved or renamed, its corresponding inode is
+rewritten to flash with the following properties:
+    * ID: Unchanged
+    * Sequence number: Previous value plus one.
+    * Parent inode: As specified by the move / rename operation.
+    * Filename: As specified by the move / rename operation.
+
+Because the inode's ID is unchanged, all dependent objects remain valid.
+
+
+*** UNLINKING FILES AND DIRECTORIES
+
+When a file or directory is unlinked from its parent directory, a deletion
+record for the unlinked inode gets written to flash.  The deletion record is an
+inode with the following properties:
+    * ID: Unchanged
+    * Sequence number: Previous value plus one.
+    * Parent inode ID: NFFS_ID_NONE
+
+When an inode is unlinked, no deletion records need to be written for the
+inode's dependent objects (constituent data blocks or child inodes).  During
+the next file system detection, it is recognized that the objects belong to
+a deleted inode, so they are not restored into the RAM representation.
+
+If a file has an open handle at the time it gets unlinked, application code
+can continued to use the file handle to read and write data.  All files retain
+a reference count, and a file isn't deleted from the RAM representation until
+its reference code drops to 0.  Any attempt to open an unlinked file fails,
+even if the file is referenced by other file handles.
+
+
+*** WRITING TO A FILE
+
+The following procedure is used whenever the application code writes to a file.
+First, if the write operation specifies too much data to fit into a single
+block, the operation is split into several separate write operations.  Then,
+for each write operation:
+
+    (1) Determine which existing blocks the write operation overlaps
+        (n = number of overwritten blocks).
+
+    (2) If n = 0, this is an append operation.  Write a data block with the
+        following properties:
+            * ID: New unique value.
+            * Sequence number: 0.
+
+    (3) Else (n > 1), this write overlaps existing data.
+            (a) For each block in [1, 2, ... n-1], write a new block
+                containing the updated contents.  Each new block supersedes the
+                block it overwrites.  That is, each block has the following
+                properties:
+                    * ID: Unchanged
+                    * Sequence number: Previous value plus one.
+
+            (b) Write the nth block.  The nth block includes all appended data,
+                if any.  As with the other blocks, its ID is unchanged and its
+                sequence number is incremented.
+
+Appended data can only be written to the end of the file.  That is, "holes" are
+not supported.
+
+
+*** GARBAGE COLLECTION
+
+When the file system is too full to accomodate a write operation, the system
+must perform garbage collection to make room.  The garbage collection
+procedure is described below:
+
+    (1) The non-scratch area with the lowest garbage collection sequence
+        number is selected as the "source area."  If there are other areas
+        with the same sequence number, the one with the smallest flash offset
+        is selected. 
+
+    (2) The source area's ID is written to the scratch area's header,
+        transforming it into a non-scratch ID.  This former scratch area is now
+        known as the "destination area."
+
+    (3) The RAM representation is exhaustively searched for collectible
+        objects.  The following procedure is applied to each inode in the
+        system:
+
+        (a) If the inode is resident in the source area, copy the inode record
+            to the destination area.
+
+        (b) If the inode is a file inode, walk the inode's list of data blocks,
+            starting with the last block in the file.  Each block that is
+            resident in the source area is copied to the destination area.  If
+            there is a run of two or more blocks that are resident in the
+            source area, they are consolidated and copied to the destination
+            area as a single new block (subject to the maximum block size
+            restriction).
+
+    (4) The source area is reformatted as a scratch sector (i.e., is is fully
+        erased, and its header is rewritten with an ID of 0xff).  The area's
+        garbage collection sequence number is incremented prior to rewriting
+        the header.  This area is now the new scratch sector.
+
+
+*** MISC
+
+    * RAM usage:
+        o 24 bytes per inode
+        o 12 bytes per data block
+        o 36 bytes per inode cache entry
+        o 32 bytes per data block cache entry
+    * Maximum filename size: 256 characters (no null terminator required)
+    * Disallowed filename characters: '/' and '\0'
+
+
+*** FUTURE ENHANCEMENTS
+
+    * API function to traverse a directory.
+    * Migrate corrupt files to the /lost+found directory during restore, rather
+      than discarding them from RAM.
+    * Error correction.
+    * Encryption.
+    * Compression.
+
+
+*** API
+
+struct nffs_file;
+
+/**
+ * Opens a file at the specified path.  The result of opening a nonexistent
+ * file depends on the access flags specified.  All intermediate directories
+ * must already exist.
+ *
+ * The mode strings passed to fopen() map to nffs_open()'s access flags as
+ * follows:
+ *   "r"  -  NFFS_ACCESS_READ
+ *   "r+" -  NFFS_ACCESS_READ | NFFS_ACCESS_WRITE
+ *   "w"  -  NFFS_ACCESS_WRITE | NFFS_ACCESS_TRUNCATE
+ *   "w+" -  NFFS_ACCESS_READ | NFFS_ACCESS_WRITE | NFFS_ACCESS_TRUNCATE
+ *   "a"  -  NFFS_ACCESS_WRITE | NFFS_ACCESS_APPEND
+ *   "a+" -  NFFS_ACCESS_READ | NFFS_ACCESS_WRITE | NFFS_ACCESS_APPEND
+ *
+ * @param out_file          On success, a pointer to the newly-created file
+ *                              handle gets written here.
+ * @param path              The path of the file to open.
+ * @param access_flags      Flags controlling file access; see above table.
+ *
+ * @return                  0 on success; nonzero on failure.
+ */
+int nffs_open(const char *path, uint8_t access_flags,
+              struct nffs_file **out_file);
+
+
+/**
+ * Closes the specified file and invalidates the file handle.  If the file has
+ * already been unlinked, and this is the last open handle to the file, this
+ * operation causes the file to be deleted from disk.
+ *
+ * @return                  0 on success; nonzero on failure.
+ */
+int nffs_close(struct nffs_file *file);
+
+
+/**
+ * Positions a file's read and write pointer at the specified offset.  The
+ * offset is expressed as the number of bytes from the start of the file (i.e.,
+ * seeking to offset 0 places the pointer at the first byte in the file).
+ *
+ * @param file              The file to reposition.
+ * @param offset            The 0-based file offset to seek to.
+ *
+ * @return                  0 on success; nonzero on failure.
+ */
+int nffs_seek(struct nffs_file *file, uint32_t offset);
+
+
+/**
+ * Retrieves the current read and write position of the specified open file.
+ *
+ * @param file              The file to query.
+ *
+ * @return                  The file offset, in bytes.
+ */
+uint32_t nffs_getpos(const struct nffs_file *file);
+
+
+/**
+ * Retrieves the current length of the specified open file.
+ *
+ * @param file              The file to query.
+ * @param out_len           On success, the number of bytes in the file gets
+ *                              written here.
+ *
+ * @return                  0 on success; nonzero on failure.
+ */
+int nffs_file_len(const struct nffs_file *file, uint32_t *out_len)
+
+
+/**
+ * Reads data from the specified file.  If more data is requested than remains
+ * in the file, all available data is retrieved.  Note: this type of short read
+ * results in a success return code.
+ *
+ * @param file              The file to read from.
+ * @param len               The number of bytes to attempt to read.
+ * @param out_data          The destination buffer to read into.
+ * @param out_len           On success, the number of bytes actually read gets
+ *                              written here.  Pass null if you don't care.
+ *
+ * @return                  0 on success; nonzero on failure.
+ */
+int nffs_read(struct nffs_file *file, uint32_t len, void *out_data,
+              uint32_t *out_len)
+
+
+/**
+ * Writes the supplied data to the current offset of the specified file handle.
+ *
+ * @param file              The file to write to.
+ * @param data              The data to write.
+ * @param len               The number of bytes to write.
+ *
+ * @return                  0 on success; nonzero on failure.
+ */
+int nffs_write(struct nffs_file *file, const void *data, int len);
+
+
+/**
+ * Unlinks the file or directory at the specified path.  If the path refers to
+ * a directory, all the directory's descendants are recursively unlinked.  Any
+ * open file handles refering to an unlinked file remain valid, and can be
+ * read from and written to.
+ *
+ * @path                    The path of the file or directory to unlink.
+ *
+ * @return                  0 on success; nonzero on failure.
+ */
+int nffs_unlink(const char *path);
+
+
+/**
+ * Performs a rename and / or move of the specified source path to the
+ * specified destination.  The source path can refer to either a file or a
+ * directory.  All intermediate directories in the destination path must
+ * already exist.  If the source path refers to a file, the destination path
+ * must contain a full filename path, rather than just the new parent
+ * directory.  If an object already exists at the specified destination path,
+ * this function causes it to be unlinked prior to the rename (i.e., the
+ * destination gets clobbered).
+ *
+ * @param from              The source path.
+ * @param to                The destination path.
+ *
+ * @return                  0 on success;
+ *                          nonzero on failure.
+ */
+int nffs_rename(const char *from, const char *to);
+
+
+/**
+ * Creates the directory represented by the specified path.  All intermediate
+ * directories must already exist.  The specified path must start with a '/'
+ * character.
+ *
+ * @param path                  The directory to create.
+ *
+ * @return                      0 on success;
+ *                              nonzero on failure.
+ */
+int nffs_mkdir(const char *path);
+
+
+/**
+ * Erases all the specified areas and initializes them with a clean nffs
+ * file system.
+ *
+ * @param area_descs        The set of areas to format.
+ *
+ * @return                  0 on success;
+ *                          nonzero on failure.
+ */
+int nffs_format(const struct nffs_area_desc *area_descs);
+
+
+/**
+ * Opens the directory at the specified path.  The directory's contents can be
+ * read with subsequent calls to nffs_readdir().  When you are done with the
+ * directory handle, close it with nffs_closedir().
+ *
+ * Unlinking files from the directory while it is open may result in
+ * unpredictable behavior.  New files can be created inside the directory.
+ *
+ * @param path                  The directory to open.
+ * @param out_dir               On success, points to the directory handle.
+ *
+ * @return                      0 on success;
+ *                              NFFS_ENOENT if the specified directory does not
+ *                                  exist;
+ *                              other nonzero on error.
+ */
+int nffs_opendir(const char *path, struct nffs_dir **out_dir);
+
+
+/**
+ * Reads the next entry in an open directory.
+ *
+ * @param dir                   The directory handle to read from.
+ * @param out_dirent            On success, points to the next child entry in
+ *                                  the specified directory.
+ *
+ * @return                      0 on success;
+ *                              NFFS_ENOENT if there are no more entries in the
+ *                                  parent directory;
+ *                              other nonzero on error.
+ */
+int nffs_readdir(struct nffs_dir *dir, struct nffs_dirent **out_dirent);
+
+
+/**
+ * Closes the specified directory handle.
+ *
+ * @param dir                   The directory to close.
+ *
+ * @return                      0 on success; nonzero on failure.
+ */
+int nffs_closedir(struct nffs_dir *dir);
+
+
+/**
+ * Retrieves the filename of the specified directory entry.  The retrieved
+ * filename is always null-terminated.  To ensure enough space to hold the full
+ * filename plus a null-termintor, a destination buffer of size
+ * (NFFS_FILENAME_MAX_LEN + 1) should be used.
+ *
+ * @param dirent                The directory entry to query.
+ * @param max_len               The size of the "out_name" character buffer.
+ * @param out_name              On success, the entry's filename is written
+ *                                  here; always null-terminated.
+ * @param out_name_len          On success, contains the actual length of the
+ *                                  filename, NOT including the
+ *                                  null-terminator.
+ *
+ * @return                      0 on success; nonzero on failure.
+ */
+int nffs_dirent_name(struct nffs_dirent *dirent, size_t max_len,
+                     char *out_name, uint8_t *out_name_len);
+
+
+/**
+ * Tells you whether the specified directory entry is a sub-directory or a
+ * regular file.
+ *
+ * @param dirent                The directory entry to query.
+ *
+ * @return                      1: The entry is a directory;
+ *                              0: The entry is a regular file.
+ */
+int nffs_dirent_is_dir(const struct nffs_dirent *dirent);
+
+/**
+ * Searches for a valid nffs file system among the specified areas.  This
+ * function succeeds if a file system is detected among any subset of the
+ * supplied areas.  If the area set does not contain a valid file system,
+ * a new one can be created via a call to nffs_format().
+ *
+ * @param area_descs        The area set to search.  This array must be
+ *                              terminated with a 0-length area.
+ *
+ * @return                  0 on success;
+ *                          NFFS_ECORRUPT if no valid file system was detected;
+ *                          other nonzero on error.
+ */
+int nffs_detect(const struct nffs_area_desc *area_descs);
+
+
+/**
+ * Indicates whether a valid filesystem has been initialized, either via
+ * detection or formatting.
+ *
+ * @return                  1 if a file system is present; 0 otherwise.
+ */
+int nffs_ready(void);
+
+
+/**
+ * Initializes the nffs memory and data structures.  This must be called before
+ * any nffs operations are attempted.
+ *
+ * @return                  0 on success; nonzero on error.
+ */
+int nffs_init(void);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/cf40853d/fs/nffs/egg.yml
----------------------------------------------------------------------
diff --git a/fs/nffs/egg.yml b/fs/nffs/egg.yml
new file mode 100644
index 0000000..6019839
--- /dev/null
+++ b/fs/nffs/egg.yml
@@ -0,0 +1,8 @@
+egg.name: fs/nffs
+egg.vers: 0.1
+egg.identities: NFFS
+egg.deps:
+    - fs/fs
+    - libs/os
+    - libs/testutil
+    - hw/hal

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/cf40853d/fs/nffs/include/nffs/nffs.h
----------------------------------------------------------------------
diff --git a/fs/nffs/include/nffs/nffs.h b/fs/nffs/include/nffs/nffs.h
new file mode 100644
index 0000000..9854bc8
--- /dev/null
+++ b/fs/nffs/include/nffs/nffs.h
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef H_NFFS_
+#define H_NFFS_
+
+#include <stddef.h>
+#include <inttypes.h>
+
+#define NFFS_FILENAME_MAX_LEN   256  /* Does not require null terminator. */
+#define NFFS_MAX_AREAS          256
+
+struct nffs_config {
+    /** Maximum number of inodes; default=1024. */
+    uint32_t nc_num_inodes;
+
+    /** Maximum number of data blocks; default=4096. */
+    uint32_t nc_num_blocks;
+
+    /** Maximum number of open files; default=4. */
+    uint32_t nc_num_files;
+
+    /** Maximum number of open directories; default=4. */
+    uint32_t nc_num_dirs;
+
+    /** Inode cache size; default=4. */
+    uint32_t nc_num_cache_inodes;
+
+    /** Data block cache size; default=64. */
+    uint32_t nc_num_cache_blocks;
+};
+
+extern struct nffs_config nffs_config;
+
+struct nffs_area_desc {
+    uint32_t nad_offset;    /* Flash offset of start of area. */
+    uint32_t nad_length;    /* Size of area, in bytes. */
+    uint8_t nad_flash_id;   /* Logical flash id */
+};
+
+int nffs_init(void);
+int nffs_detect(const struct nffs_area_desc *area_descs);
+int nffs_format(const struct nffs_area_desc *area_descs);
+int nffs_ready(void);
+
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/cf40853d/fs/nffs/include/nffs/nffs_test.h
----------------------------------------------------------------------
diff --git a/fs/nffs/include/nffs/nffs_test.h b/fs/nffs/include/nffs/nffs_test.h
new file mode 100644
index 0000000..12d2ea4
--- /dev/null
+++ b/fs/nffs/include/nffs/nffs_test.h
@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef H_NFFS_TEST_
+#define H_NFFS_TEST_
+
+int nffs_test_all(void);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/cf40853d/fs/nffs/src/crc16.c
----------------------------------------------------------------------
diff --git a/fs/nffs/src/crc16.c b/fs/nffs/src/crc16.c
new file mode 100644
index 0000000..85995c4
--- /dev/null
+++ b/fs/nffs/src/crc16.c
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*    
+ * Copyright 2001-2010 Georges Menie (www.menie.org)
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of the University of California, Berkeley 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 REGENTS 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 REGENTS AND 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.
+ */
+
+#include <inttypes.h>
+#include "crc16.h"
+
+/* CRC16 implementation acording to CCITT standards */
+
+static const uint16_t crc16tab[256]= {
+    0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
+    0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
+    0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,
+    0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,
+    0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,
+    0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,
+    0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,
+    0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,
+    0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,
+    0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,
+    0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,
+    0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,
+    0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,
+    0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,
+    0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,
+    0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,
+    0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,
+    0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,
+    0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,
+    0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,
+    0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,
+    0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,
+    0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,
+    0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,
+    0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,
+    0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,
+    0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,
+    0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,
+    0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,
+    0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,
+    0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,
+    0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0
+};
+  
+uint16_t
+crc16_ccitt(uint16_t initial_crc, const void *buf, int len)
+{
+    const uint8_t *ptr;
+    uint16_t crc;
+    int counter;
+
+    crc = initial_crc;
+    ptr = buf;
+
+    for (counter = 0; counter < len; counter++) {
+        crc = (crc<<8) ^ crc16tab[((crc>>8) ^ *ptr++)&0x00FF];
+    }
+
+    return crc;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/cf40853d/fs/nffs/src/crc16.h
----------------------------------------------------------------------
diff --git a/fs/nffs/src/crc16.h b/fs/nffs/src/crc16.h
new file mode 100644
index 0000000..f0937ca
--- /dev/null
+++ b/fs/nffs/src/crc16.h
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/*	
+ * Copyright 2001-2010 Georges Menie (www.menie.org)
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of the University of California, Berkeley 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 REGENTS 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 REGENTS AND 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 _CRC16_H_
+#define _CRC16_H_
+
+#include <inttypes.h>
+
+unsigned short crc16_ccitt(uint16_t initial_crc, const void *buf, int len);
+
+#endif /* _CRC16_H_ */