Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 5CB40200C01 for ; Thu, 19 Jan 2017 18:36:24 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 5B304160B57; Thu, 19 Jan 2017 17:36:24 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 04865160B3A for ; Thu, 19 Jan 2017 18:36:22 +0100 (CET) Received: (qmail 50020 invoked by uid 500); 19 Jan 2017 17:36:22 -0000 Mailing-List: contact commits-help@mynewt.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@mynewt.incubator.apache.org Delivered-To: mailing list commits@mynewt.incubator.apache.org Received: (qmail 50010 invoked by uid 99); 19 Jan 2017 17:36:22 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd2-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 19 Jan 2017 17:36:22 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd2-us-west.apache.org (ASF Mail Server at spamd2-us-west.apache.org) with ESMTP id A57301A0235 for ; Thu, 19 Jan 2017 17:36:21 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd2-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -6.219 X-Spam-Level: X-Spam-Status: No, score=-6.219 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-2.999] autolearn=disabled Received: from mx1-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd2-us-west.apache.org [10.40.0.9]) (amavisd-new, port 10024) with ESMTP id bcZM9YIvIa0V for ; Thu, 19 Jan 2017 17:36:16 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx1-lw-eu.apache.org (ASF Mail Server at mx1-lw-eu.apache.org) with SMTP id 9ACA15FDA2 for ; Thu, 19 Jan 2017 17:36:13 +0000 (UTC) Received: (qmail 48510 invoked by uid 99); 19 Jan 2017 17:36:12 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 19 Jan 2017 17:36:12 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 93336DFDF1; Thu, 19 Jan 2017 17:36:12 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: ccollins@apache.org To: commits@mynewt.incubator.apache.org Date: Thu, 19 Jan 2017 17:36:16 -0000 Message-Id: <8d2a1944b124441aa92694c5445844ad@git.apache.org> In-Reply-To: <5c09a86c1d4d4c5baa1048813ea5dbda@git.apache.org> References: <5c09a86c1d4d4c5baa1048813ea5dbda@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [05/19] incubator-mynewt-core git commit: Save multi-disk support WIP archived-at: Thu, 19 Jan 2017 17:36:24 -0000 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 Authored: Wed Dec 14 16:39:52 2016 -0200 Committer: Fabio Utzig 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 #include #include +#include #include #include #include @@ -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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +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 +#include #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 +#include +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 + 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 +#include + +#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 " +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 + +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; +}