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_ */