Save multi-disk support WIP
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/1a029621
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/1a029621
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/1a029621
Branch: refs/heads/develop
Commit: 1a029621576f068a361d322d9dfb789a7f34d54d
Parents: 0845466
Author: Fabio Utzig <utzig@utzig.org>
Authored: Wed Dec 14 16:39:52 2016 -0200
Committer: Fabio Utzig <utzig@utzig.org>
Committed: Thu Jan 12 10:51:46 2017 -0200
----------------------------------------------------------------------
fs/fatfs/src/mynewt_glue.c | 24 +-
fs/fatfs/src/mynewt_glue_2.c | 410 +++++++++++++++++++++++++
fs/fs/include/fs/fs_if.h | 21 +-
fs/fs/src/fs_dirent.c | 15 +-
fs/fs/src/fs_file.c | 62 +++-
fs/fs/src/fs_mkdir.c | 6 +-
fs/fs/src/fs_mount.c | 32 +-
fs/fs/src/fs_priv.h | 3 +-
hw/bsp/stm32f4discovery/include/bsp/bsp.h | 2 +-
hw/drivers/mmc/include/mmc/mmc.h | 3 +
hw/drivers/mmc/src/mmc.c | 17 +
hw/hal/include/hal/hal_flash.h | 5 +-
hw/hal/src/hal_flash.c | 14 +
sys/diskio/include/diskio/diskio.h | 51 +++
sys/diskio/pkg.yml | 27 ++
sys/diskio/src/diskio.c | 57 ++++
16 files changed, 721 insertions(+), 28 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1a029621/fs/fatfs/src/mynewt_glue.c
----------------------------------------------------------------------
diff --git a/fs/fatfs/src/mynewt_glue.c b/fs/fatfs/src/mynewt_glue.c
index 0f45cfb..f2382f8 100644
--- a/fs/fatfs/src/mynewt_glue.c
+++ b/fs/fatfs/src/mynewt_glue.c
@@ -1,6 +1,7 @@
#include <assert.h>
#include <sysinit/sysinit.h>
#include <hal/hal_flash.h>
+#include <mmc/mmc.h>
#include <flash_map/flash_map.h>
#include <stdio.h>
#include <stdlib.h>
@@ -348,17 +349,29 @@ disk_status(BYTE pdrv)
return RES_OK;
}
+static struct disk_ops *disk_ops_from_handle(BYTE pdrv)
+{
+ return &mmc_ops;
+}
+
DRESULT
disk_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count)
{
int rc;
uint32_t address;
uint32_t num_bytes;
+ struct disk_ops *dops;
/* NOTE: safe to assume sector size as 512 for now, see ffconf.h */
address = (uint32_t) sector * 512;
num_bytes = (uint32_t) count * 512;
- rc = hal_flash_read(pdrv, address, (void *) buff, num_bytes);
+
+ dops = disk_ops_from_handle(pdrv);
+ if (dops == NULL) {
+ return STA_NOINIT;
+ }
+
+ rc = dops->read(pdrv, address, (void *) buff, num_bytes);
if (rc < 0) {
return STA_NOINIT;
}
@@ -372,11 +385,18 @@ disk_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count)
int rc;
uint32_t address;
uint32_t num_bytes;
+ struct disk_ops *dops;
/* NOTE: safe to assume sector size as 512 for now, see ffconf.h */
address = (uint32_t) sector * 512;
num_bytes = (uint32_t) count * 512;
- rc = hal_flash_write(pdrv, address, (const void *) buff, num_bytes);
+
+ dops = disk_ops_from_handle(pdrv);
+ if (dops == NULL) {
+ return STA_NOINIT;
+ }
+
+ rc = dops->write(pdrv, address, (const void *) buff, num_bytes);
if (rc < 0) {
return STA_NOINIT;
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1a029621/fs/fatfs/src/mynewt_glue_2.c
----------------------------------------------------------------------
diff --git a/fs/fatfs/src/mynewt_glue_2.c b/fs/fatfs/src/mynewt_glue_2.c
new file mode 100644
index 0000000..8be7265
--- /dev/null
+++ b/fs/fatfs/src/mynewt_glue_2.c
@@ -0,0 +1,410 @@
+#include <assert.h>
+#include <sysinit/sysinit.h>
+#include <hal/hal_flash.h>
+#include <flash_map/flash_map.h>
+#include <mmc/mmc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <fatfs/ff.h>
+#include <fatfs/diskio.h>
+
+#include <fs/fs.h>
+#include <fs/fs_if.h>
+
+static int fatfs_open(const char *path, uint8_t access_flags,
+ struct fs_file **out_file);
+static int fatfs_close(struct fs_file *fs_file);
+static int fatfs_read(struct fs_file *fs_file, uint32_t len, void *out_data,
+ uint32_t *out_len);
+static int fatfs_write(struct fs_file *fs_file, const void *data, int len);
+static int fatfs_seek(struct fs_file *fs_file, uint32_t offset);
+static uint32_t fatfs_getpos(const struct fs_file *fs_file);
+static int fatfs_file_len(const struct fs_file *fs_file, uint32_t *out_len);
+static int fatfs_unlink(const char *path);
+static int fatfs_rename(const char *from, const char *to);
+static int fatfs_mkdir(const char *path);
+static int fatfs_opendir(const char *path, struct fs_dir **out_fs_dir);
+static int fatfs_readdir(struct fs_dir *dir, struct fs_dirent **out_dirent);
+static int fatfs_closedir(struct fs_dir *dir);
+static int fatfs_dirent_name(const struct fs_dirent *fs_dirent, size_t max_len,
+ char *out_name, uint8_t *out_name_len);
+static int fatfs_dirent_is_dir(const struct fs_dirent *fs_dirent);
+
+/* NOTE: to ease memory management of dirent structs, this single static
+ * variable holds the latest entry found by readdir. This limits FAT to
+ * working on a single thread, single opendir -> closedir cycle.
+ */
+static FILINFO filinfo;
+
+static const struct fs_ops fatfs_ops = {
+ .f_open = fatfs_open,
+ .f_close = fatfs_close,
+ .f_read = fatfs_read,
+ .f_write = fatfs_write,
+
+ .f_seek = fatfs_seek,
+ .f_getpos = fatfs_getpos,
+ .f_filelen = fatfs_file_len,
+
+ .f_unlink = fatfs_unlink,
+ .f_rename = fatfs_rename,
+ .f_mkdir = fatfs_mkdir,
+
+ .f_opendir = fatfs_opendir,
+ .f_readdir = fatfs_readdir,
+ .f_closedir = fatfs_closedir,
+
+ .f_dirent_name = fatfs_dirent_name,
+ .f_dirent_is_dir = fatfs_dirent_is_dir,
+
+ .f_name = "fatfs"
+};
+
+int fatfs_to_vfs_error(FRESULT res)
+{
+ int rc = FS_EOS;
+
+ switch (res) {
+ case FR_OK:
+ rc = FS_EOK;
+ break;
+ case FR_DISK_ERR: /* (1) A hard error occurred in the low level disk I/O
layer */
+ rc = FS_EHW;
+ break;
+ case FR_INT_ERR: /* (2) Assertion failed */
+ rc = FS_EOS;
+ break;
+ case FR_NOT_READY: /* (3) The physical drive cannot work */
+ rc = FS_ECORRUPT;
+ break;
+ case FR_NO_FILE: /* (4) Could not find the file */
+ /* passthrough */
+ case FR_NO_PATH: /* (5) Could not find the path */
+ rc = FS_ENOENT;
+ break;
+ case FR_INVALID_NAME: /* (6) The path name format is invalid */
+ rc = FS_EINVAL;
+ break;
+ case FR_DENIED: /* (7) Access denied due to prohibited access or directory
full */
+ rc = FS_EACCESS;
+ break;
+ case FR_EXIST: /* (8) Access denied due to prohibited access */
+ rc = FS_EEXIST;
+ break;
+ case FR_INVALID_OBJECT: /* (9) The file/directory object is invalid */
+ rc = FS_EINVAL;
+ break;
+ case FR_WRITE_PROTECTED: /* (10) The physical drive is write protected */
+ /* TODO: assign correct error */
+ break;
+ case FR_INVALID_DRIVE: /* (11) The logical drive number is invalid */
+ rc = FS_EHW;
+ break;
+ case FR_NOT_ENABLED: /* (12) The volume has no work area */
+ rc = FS_EUNEXP;
+ break;
+ case FR_NO_FILESYSTEM: /* (13) There is no valid FAT volume */
+ rc = FS_EUNINIT;
+ break;
+ case FR_MKFS_ABORTED: /* (14) The f_mkfs() aborted due to any problem */
+ /* TODO: assign correct error */
+ break;
+ case FR_TIMEOUT: /* (15) Could not get a grant to access the volume within
defined period */
+ /* TODO: assign correct error */
+ break;
+ case FR_LOCKED: /* (16) The operation is rejected according to the file
sharing policy */
+ /* TODO: assign correct error */
+ break;
+ case FR_NOT_ENOUGH_CORE: /* (17) LFN working buffer could not be allocated */
+ rc = FS_ENOMEM;
+ break;
+ case FR_TOO_MANY_OPEN_FILES: /* (18) Number of open files > _FS_LOCK */
+ /* TODO: assign correct error */
+ break;
+ case FR_INVALID_PARAMETER: /* (19) Given parameter is invalid */
+ rc = FS_EINVAL;
+ break;
+ }
+
+ return rc;
+}
+
+static int
+fatfs_open(const char *path, uint8_t access_flags, struct fs_file **out_fs_file)
+{
+ FRESULT res;
+ FIL *out_file;
+ BYTE mode;
+
+ out_file = malloc(sizeof(FIL));
+ if (!out_file) {
+ return FS_ENOMEM;
+ }
+
+ mode = FA_OPEN_EXISTING;
+ if (access_flags & FS_ACCESS_READ) {
+ mode |= FA_READ;
+ }
+ if (access_flags & FS_ACCESS_WRITE) {
+ mode |= FA_WRITE;
+ }
+ if (access_flags & FS_ACCESS_APPEND) {
+ mode |= FA_OPEN_APPEND;
+ }
+ if (access_flags & FS_ACCESS_TRUNCATE) {
+ mode &= ~FA_OPEN_EXISTING;
+ mode |= FA_CREATE_ALWAYS;
+ }
+
+ res = f_open(out_file, path, mode);
+ if (res != FR_OK) {
+ free(out_file);
+ return fatfs_to_vfs_error(res);
+ }
+ *out_fs_file = (struct fs_file *)out_file;
+ return FS_EOK;
+}
+
+static int
+fatfs_close(struct fs_file *fs_file)
+{
+ FRESULT res;
+ FIL *file = (FIL *)fs_file;
+
+ if (file == NULL) {
+ return FS_EOK;
+ }
+
+ res = f_close(file);
+ free(file);
+ return fatfs_to_vfs_error(res);
+}
+
+static int
+fatfs_seek(struct fs_file *fs_file, uint32_t offset)
+{
+ FRESULT res;
+ FIL *file = (FIL *)fs_file;
+
+ res = f_lseek(file, offset);
+ return fatfs_to_vfs_error(res);
+}
+
+static uint32_t
+fatfs_getpos(const struct fs_file *fs_file)
+{
+ uint32_t offset;
+ FIL *file = (FIL *)fs_file;
+
+ offset = (uint32_t) f_tell(file);
+ return offset;
+}
+
+static int
+fatfs_file_len(const struct fs_file *fs_file, uint32_t *out_len)
+{
+ uint32_t offset;
+ FIL *file = (FIL *)fs_file;
+
+ offset = (uint32_t) f_size(file);
+ return offset;
+}
+
+static int
+fatfs_read(struct fs_file *fs_file, uint32_t len, void *out_data,
+ uint32_t *out_len)
+{
+ FRESULT res;
+ FIL *file = (FIL *)fs_file;
+
+ res = f_read(file, out_data, len, (UINT *)out_len);
+ return fatfs_to_vfs_error(res);
+}
+
+static int
+fatfs_write(struct fs_file *fs_file, const void *data, int len)
+{
+ FRESULT res;
+ UINT out_len;
+ FIL *file = (FIL *)fs_file;
+
+ res = f_write(file, data, len, &out_len);
+ if (len != out_len) {
+ return FS_EFULL;
+ }
+ return fatfs_to_vfs_error(res);
+}
+
+static int
+fatfs_unlink(const char *path)
+{
+ FRESULT res;
+
+ res = f_unlink(path);
+ return fatfs_to_vfs_error(res);
+}
+
+static int
+fatfs_rename(const char *from, const char *to)
+{
+ FRESULT res;
+
+ res = f_rename(from, to);
+ return fatfs_to_vfs_error(res);
+}
+
+static int
+fatfs_mkdir(const char *path)
+{
+ FRESULT res;
+
+ res = f_mkdir(path);
+ return fatfs_to_vfs_error(res);
+}
+
+static int
+fatfs_opendir(const char *path, struct fs_dir **out_fs_dir)
+{
+ FRESULT res;
+ FATFS_DIR *out_dir;
+
+ out_dir = malloc(sizeof(FATFS_DIR));
+ if (!out_dir) {
+ return FS_ENOMEM;
+ }
+
+ res = f_opendir(out_dir, path);
+ if (res != FR_OK) {
+ return fatfs_to_vfs_error(res);
+ }
+ *out_fs_dir = (struct fs_dir *)out_dir;
+ return FS_EOK;
+}
+
+static int
+fatfs_readdir(struct fs_dir *fs_dir, struct fs_dirent **out_fs_dirent)
+{
+ FRESULT res;
+ FATFS_DIR *dir = (FATFS_DIR *)fs_dir;
+
+ res = f_readdir(dir, &filinfo);
+ if (res != FR_OK) {
+ return fatfs_to_vfs_error(res);
+ }
+
+ *out_fs_dirent = (struct fs_dirent *)&filinfo;
+ if (!filinfo.fname[0]) {
+ return FS_ENOENT;
+ }
+ return FS_EOK;
+}
+
+static int
+fatfs_closedir(struct fs_dir *fs_dir)
+{
+ FRESULT res;
+ FATFS_DIR *dir = (FATFS_DIR *)fs_dir;
+
+ res = f_closedir(dir);
+ free(dir);
+ return fatfs_to_vfs_error(res);
+}
+
+static int
+fatfs_dirent_name(const struct fs_dirent *fs_dirent, size_t max_len,
+ char *out_name, uint8_t *out_name_len)
+{
+ const FILINFO *dirent = (const FILINFO *)fs_dirent;
+ size_t out_len;
+
+ assert(dirent != NULL);
+ out_len = max_len < sizeof(dirent->fname) ? max_len : sizeof(dirent->fname);
+ memcpy(out_name, dirent->fname, out_len);
+ *out_name_len = out_len;
+ return FS_EOK;
+}
+
+static int
+fatfs_dirent_is_dir(const struct fs_dirent *fs_dirent)
+{
+ const FILINFO *dirent = (const FILINFO *)fs_dirent;
+
+ assert(dirent != NULL);
+ return dirent->fattrib & AM_DIR;
+}
+
+DSTATUS
+disk_initialize(BYTE pdrv)
+{
+ /* Don't need to do anything while using hal_flash */
+ return RES_OK;
+}
+
+DSTATUS
+disk_status(BYTE pdrv)
+{
+ /* Always OK on native emulated flash */
+ return RES_OK;
+}
+
+DRESULT
+disk_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count)
+{
+ int rc;
+ uint32_t address;
+ uint32_t num_bytes;
+
+ /* NOTE: safe to assume sector size as 512 for now, see ffconf.h */
+ address = (uint32_t) sector * 512;
+ num_bytes = (uint32_t) count * 512;
+ //rc = hal_flash_read(pdrv, address, (void *) buff, num_bytes);
+ rc = mmc_read(pdrv, address, (void *) buff, num_bytes);
+ if (rc < 0) {
+ return STA_NOINIT;
+ }
+
+ return RES_OK;
+}
+
+DRESULT
+disk_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count)
+{
+ int rc;
+ uint32_t address;
+ uint32_t num_bytes;
+
+ /* NOTE: safe to assume sector size as 512 for now, see ffconf.h */
+ address = (uint32_t) sector * 512;
+ num_bytes = (uint32_t) count * 512;
+ //rc = hal_flash_write(pdrv, address, (const void *) buff, num_bytes);
+ rc = mmc_write(pdrv, address, (const void *) buff, num_bytes);
+ if (rc < 0) {
+ return STA_NOINIT;
+ }
+
+ return RES_OK;
+}
+
+DRESULT
+disk_ioctl(BYTE pdrv, BYTE cmd, void* buff)
+{
+ return RES_OK;
+}
+
+/* FIXME: _FS_NORTC=1 because there is not hal_rtc interface */
+DWORD
+get_fattime(void)
+{
+ return 0;
+}
+
+void
+fatfs_pkg_init(void)
+{
+ /* Ensure this function only gets called by sysinit. */
+ SYSINIT_ASSERT_ACTIVE();
+
+ fs_register(&fatfs_ops);
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1a029621/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
index 5d71f1b..842f070 100644
--- a/fs/fs/include/fs/fs_if.h
+++ b/fs/fs/include/fs/fs_if.h
@@ -52,12 +52,27 @@ struct fs_ops {
int (*f_dirent_is_dir)(const struct fs_dirent *dirent);
const char *f_name;
+
+ SLIST_ENTRY(fs_ops) sc_next;
};
-/*
- * Currently allow only one type of FS, starts at root.
+/**
+ * Registers a new filesystem interface
+ *
+ * @param fops filesystem operations table
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int fs_register(const struct fs_ops *fops);
+
+/**
+ * Retrieve a filesystem's operations table
+ *
+ * @param name Name of the filesystem to retrieve fs_ops for
+ *
+ * @return valid pointer on success, NULL on failure
*/
-int fs_register(const struct fs_ops *);
+struct fs_ops *fs_ops_for(const char *name);
#ifdef __cplusplus
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1a029621/fs/fs/src/fs_dirent.c
----------------------------------------------------------------------
diff --git a/fs/fs/src/fs_dirent.c b/fs/fs/src/fs_dirent.c
index bc526f2..b5fd6c5 100644
--- a/fs/fs/src/fs_dirent.c
+++ b/fs/fs/src/fs_dirent.c
@@ -23,30 +23,35 @@
int
fs_opendir(const char *path, struct fs_dir **out_dir)
{
- return fs_root_ops->f_opendir(path, out_dir);
+ struct fs_ops *fops = safe_fs_ops_for("fatfs");
+ return fops->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);
+ struct fs_ops *fops = safe_fs_ops_for("fatfs");
+ return fops->f_readdir(dir, out_dirent);
}
int
fs_closedir(struct fs_dir *dir)
{
- return fs_root_ops->f_closedir(dir);
+ struct fs_ops *fops = safe_fs_ops_for("fatfs");
+ return fops->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);
+ struct fs_ops *fops = safe_fs_ops_for("fatfs");
+ return fops->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);
+ struct fs_ops *fops = safe_fs_ops_for("fatfs");
+ return fops->f_dirent_is_dir(dirent);
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1a029621/fs/fs/src/fs_file.c
----------------------------------------------------------------------
diff --git a/fs/fs/src/fs_file.c b/fs/fs/src/fs_file.c
index fcc2e2c..fdcecda 100644
--- a/fs/fs/src/fs_file.c
+++ b/fs/fs/src/fs_file.c
@@ -21,50 +21,96 @@
#include "fs_priv.h"
+static int
+not_initialized(const void *v, ...)
+{
+ return FS_EUNINIT;
+}
+
+static struct fs_ops not_initialized_ops = {
+ .f_open = not_initialized,
+ .f_close = not_initialized,
+ .f_read = not_initialized,
+ .f_write = not_initialized,
+ .f_seek = not_initialized,
+ .f_getpos = not_initialized,
+ .f_filelen = not_initialized,
+ .f_unlink = not_initialized,
+ .f_rename = not_initialized,
+ .f_mkdir = not_initialized,
+ .f_opendir = not_initialized,
+ .f_readdir = not_initialized,
+ .f_closedir = not_initialized,
+ .f_dirent_name = not_initialized,
+ .f_dirent_is_dir = not_initialized,
+ .f_name = "fakefs",
+};
+
+struct fs_ops *
+safe_fs_ops_for(const char *fs_name)
+{
+ struct fs_ops *fops;
+
+ fops = fs_ops_for("fatfs");
+ if (fops == NULL) {
+ fops = ¬_initialized_ops;
+ }
+
+ return fops;
+}
+
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);
+ struct fs_ops *fops = safe_fs_ops_for("fatfs");
+ return fops->f_open(filename, access_flags, out_file);
}
int
fs_close(struct fs_file *file)
{
- return fs_root_ops->f_close(file);
+ struct fs_ops *fops = safe_fs_ops_for("fatfs");
+ return fops->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);
+ struct fs_ops *fops = safe_fs_ops_for("fatfs");
+ return fops->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);
+ struct fs_ops *fops = safe_fs_ops_for("fatfs");
+ return fops->f_write(file, data, len);
}
int
fs_seek(struct fs_file *file, uint32_t offset)
{
- return fs_root_ops->f_seek(file, offset);
+ struct fs_ops *fops = safe_fs_ops_for("fatfs");
+ return fops->f_seek(file, offset);
}
uint32_t
fs_getpos(const struct fs_file *file)
{
- return fs_root_ops->f_getpos(file);
+ struct fs_ops *fops = safe_fs_ops_for("fatfs");
+ return fops->f_getpos(file);
}
int
fs_filelen(const struct fs_file *file, uint32_t *out_len)
{
- return fs_root_ops->f_filelen(file, out_len);
+ struct fs_ops *fops = safe_fs_ops_for("fatfs");
+ return fops->f_filelen(file, out_len);
}
int
fs_unlink(const char *filename)
{
- return fs_root_ops->f_unlink(filename);
+ struct fs_ops *fops = safe_fs_ops_for("fatfs");
+ return fops->f_unlink(filename);
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1a029621/fs/fs/src/fs_mkdir.c
----------------------------------------------------------------------
diff --git a/fs/fs/src/fs_mkdir.c b/fs/fs/src/fs_mkdir.c
index 2072229..546736f 100644
--- a/fs/fs/src/fs_mkdir.c
+++ b/fs/fs/src/fs_mkdir.c
@@ -24,11 +24,13 @@
int
fs_rename(const char *from, const char *to)
{
- return fs_root_ops->f_rename(from, to);
+ struct fs_ops *fops = safe_fs_ops_for("fatfs");
+ return fops->f_rename(from, to);
}
int
fs_mkdir(const char *path)
{
- return fs_root_ops->f_mkdir(path);
+ struct fs_ops *fops = safe_fs_ops_for("fatfs");
+ return fops->f_mkdir(path);
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1a029621/fs/fs/src/fs_mount.c
----------------------------------------------------------------------
diff --git a/fs/fs/src/fs_mount.c b/fs/fs/src/fs_mount.c
index 9645d1a..174fac8 100644
--- a/fs/fs/src/fs_mount.c
+++ b/fs/fs/src/fs_mount.c
@@ -22,19 +22,41 @@
#include "fs/fs_if.h"
#include "fs_priv.h"
-const struct fs_ops *fs_root_ops = NULL;
+static SLIST_HEAD(, fs_ops) root_fops = SLIST_HEAD_INITIALIZER();
+static bool g_cli_initialized = false;
int
fs_register(const struct fs_ops *fops)
{
- if (fs_root_ops) {
- return FS_EEXIST;
+ SLIST_FOREACH(sc, &root_fops, sc_next) {
+ if (strcmp(sc->f_name, fops->f_name) == 0) {
+ return FS_EEXIST;
+ }
}
- fs_root_ops = fops;
+
+ SLIST_INSERT_HEAD(&root_fops, fops, sc_next);
#if MYNEWT_VAL(FS_CLI)
- fs_cli_init();
+ if (!g_cli_initialized) {
+ fs_cli_init();
+ g_cli_initialized = true;
+ }
#endif
return FS_EOK;
}
+
+struct fs_ops *
+fs_ops_for(const char *fs_name)
+{
+ struct fs_ops *fops = NULL;
+
+ SLIST_FOREACH(sc, &root_fops, sc_next) {
+ if (strcmp(sc->f_name, fs_name) == 0) {
+ fops = sc;
+ break;
+ }
+ }
+
+ return fops;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1a029621/fs/fs/src/fs_priv.h
----------------------------------------------------------------------
diff --git a/fs/fs/src/fs_priv.h b/fs/fs/src/fs_priv.h
index 5733733..d9cbd2d 100644
--- a/fs/fs/src/fs_priv.h
+++ b/fs/fs/src/fs_priv.h
@@ -26,7 +26,8 @@ extern "C" {
#endif
struct fs_ops;
-extern const struct fs_ops *fs_root_ops;
+struct fs_ops *fs_ops_for(const char *fs_name);
+struct fs_ops *safe_fs_ops_for(const char *fs_name);
#if MYNEWT_VAL(FS_CLI)
void fs_cli_init(void);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1a029621/hw/bsp/stm32f4discovery/include/bsp/bsp.h
----------------------------------------------------------------------
diff --git a/hw/bsp/stm32f4discovery/include/bsp/bsp.h b/hw/bsp/stm32f4discovery/include/bsp/bsp.h
index dd038e9..ca8a92c 100644
--- a/hw/bsp/stm32f4discovery/include/bsp/bsp.h
+++ b/hw/bsp/stm32f4discovery/include/bsp/bsp.h
@@ -41,7 +41,7 @@ extern uint8_t _ccram_start;
#define CCRAM_SIZE (64 * 1024)
/* LED pins */
-#define LED_BLINK_PIN MCU_GPIO_PORTD(12)
+#define LED_BLINK_PIN MCU_GPIO_PORTD(13)
/* UART */
#define UART_CNT 1
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1a029621/hw/drivers/mmc/include/mmc/mmc.h
----------------------------------------------------------------------
diff --git a/hw/drivers/mmc/include/mmc/mmc.h b/hw/drivers/mmc/include/mmc/mmc.h
index d65363d..a13b682 100644
--- a/hw/drivers/mmc/include/mmc/mmc.h
+++ b/hw/drivers/mmc/include/mmc/mmc.h
@@ -21,6 +21,7 @@
#define __MMC_H__
#include <os/os_dev.h>
+#include <diskio/diskio.h>
#ifdef __cplusplus
extern "C" {
@@ -43,6 +44,8 @@ extern "C" {
#define MMC_ERASE_ERROR (-11)
#define MMC_ADDR_ERROR (-12)
+extern struct disk_ops mmc_ops;
+
/**
* Initialize the MMC driver
*
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1a029621/hw/drivers/mmc/src/mmc.c
----------------------------------------------------------------------
diff --git a/hw/drivers/mmc/src/mmc.c b/hw/drivers/mmc/src/mmc.c
index ca89434..0b2aa98 100644
--- a/hw/drivers/mmc/src/mmc.c
+++ b/hw/drivers/mmc/src/mmc.c
@@ -583,3 +583,20 @@ out:
hal_gpio_write(mmc->ss_pin, 1);
return (rc);
}
+
+/*
+ *
+ */
+int mmc_ioctl(int cmd, void *arg)
+{
+ return 0;
+}
+
+/*
+ *
+ */
+struct disk_ops mmc_ops = {
+ .read = mmc_read,
+ .write = mmc_write,
+ .ioctl = mmc_ioctl,
+};
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1a029621/hw/hal/include/hal/hal_flash.h
----------------------------------------------------------------------
diff --git a/hw/hal/include/hal/hal_flash.h b/hw/hal/include/hal/hal_flash.h
index 2895479..1fdc91e 100644
--- a/hw/hal/include/hal/hal_flash.h
+++ b/hw/hal/include/hal/hal_flash.h
@@ -25,7 +25,11 @@ extern "C" {
#endif
#include <inttypes.h>
+#include <diskio/diskio.h>
+extern struct disk_ops hal_flash_ops;
+
+int hal_flash_ioctl(uint8_t flash_id, uint32_t cmd, void *args);
int hal_flash_read(uint8_t flash_id, uint32_t address, void *dst,
uint32_t num_bytes);
int hal_flash_write(uint8_t flash_id, uint32_t address, const void *src,
@@ -35,7 +39,6 @@ int hal_flash_erase(uint8_t flash_id, uint32_t address, uint32_t num_bytes);
uint8_t hal_flash_align(uint8_t flash_id);
int hal_flash_init(void);
-
#ifdef __cplusplus
}
#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1a029621/hw/hal/src/hal_flash.c
----------------------------------------------------------------------
diff --git a/hw/hal/src/hal_flash.c b/hw/hal/src/hal_flash.c
index ba51f8a..a95b57b 100644
--- a/hw/hal/src/hal_flash.c
+++ b/hw/hal/src/hal_flash.c
@@ -24,6 +24,8 @@
#include "hal/hal_flash.h"
#include "hal/hal_flash_int.h"
+#include <diskio/diskio.h>
+
int
hal_flash_init(void)
{
@@ -167,3 +169,15 @@ hal_flash_erase(uint8_t id, uint32_t address, uint32_t num_bytes)
}
return 0;
}
+
+int
+hal_flash_ioctl(uint8_t id, uint32_t cmd, void *args)
+{
+ return 0;
+}
+
+static struct disk_ops hal_flash_ops = {
+ .read = hal_flash_read,
+ .write = hal_flash_write,
+ .ioctl = hal_flash_ioctl,
+};
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1a029621/sys/diskio/include/diskio/diskio.h
----------------------------------------------------------------------
diff --git a/sys/diskio/include/diskio/diskio.h b/sys/diskio/include/diskio/diskio.h
new file mode 100644
index 0000000..a0a68f6
--- /dev/null
+++ b/sys/diskio/include/diskio/diskio.h
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 __DISKIO_H__
+#define __DISKIO_H__
+
+#include <stddef.h>
+#include <inttypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DISKIO_EOK 0 /* Success */
+#define DISKIO_EHW 1 /* Error accessing storage medium */
+#define DISKIO_ENOMEM 2 /* Insufficient memory */
+#define DISKIO_ENOENT 3 /* No such file or directory */
+#define DISKIO_EOS 4 /* OS error */
+#define DISKIO_EUNINIT 5 /* File system not initialized */
+
+struct disk_ops {
+ int (*read)(int, uint32_t, void *, uint32_t);
+ int (*write)(int, uint32_t, const void *, uint32_t);
+ int (*ioctl)(int, uint32_t, const void *);
+
+ SLIST_ENTRY(disk_ops) sc_next;
+};
+
+int diskio_register(const char *disk_name, const char *fs_name, struct disk_ops *dops);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1a029621/sys/diskio/pkg.yml
----------------------------------------------------------------------
diff --git a/sys/diskio/pkg.yml b/sys/diskio/pkg.yml
new file mode 100644
index 0000000..8981937
--- /dev/null
+++ b/sys/diskio/pkg.yml
@@ -0,0 +1,27 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+#
+
+pkg.name: sys/diskio
+pkg.description: Disk IO layer to glue filesystems to disk devices.
+pkg.author: "Apache Mynewt <dev@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+ - kernel/os
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1a029621/sys/diskio/src/diskio.c
----------------------------------------------------------------------
diff --git a/sys/diskio/src/diskio.c b/sys/diskio/src/diskio.c
new file mode 100644
index 0000000..e74eae3
--- /dev/null
+++ b/sys/diskio/src/diskio.c
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 "syscfg/syscfg.h"
+#include "fs/fs.h"
+#include <diskio/diskio.h>
+
+static struct disk_info {
+ char *disk_name;
+ char *fs_name;
+ struct disk_ops *dops;
+};
+
+static SLIST_HEAD(, disk_info) disks = SLIST_HEAD_INITIALIZER();
+
+/**
+ *
+ */
+int diskio_register(const char *disk_name, const char *fs_name, struct disk_ops *dops)
+{
+ struct disk_info *info = NULL;
+
+ SLIST_FOREACH(sc, &disks, sc_next) {
+ if (strcmp(sc->disk_name, disk_name) == 0) {
+ return DISKIO_EEXIST;
+ }
+ }
+
+ info = malloc(sizeof(struct disk_info));
+ if (!info) {
+ return DISKIO_ENOMEM;
+ }
+
+ info.disk_name = disk_name;
+ info.fs_name = fs_name;
+ info.dops = dops;
+
+ SLIST_INSERT_HEAD(&disks, info, sc_next);
+
+ return 0;
+}
|