diff --git a/os/vfs/drivers/sfs/drvsfs.c b/os/vfs/drivers/sfs/drvsfs.c index 2747a8c73..6b7d72678 100644 --- a/os/vfs/drivers/sfs/drvsfs.c +++ b/os/vfs/drivers/sfs/drvsfs.c @@ -19,7 +19,7 @@ /** * @file vfs/drivers/drvsfs.c - * @brief HAL FatFS VFS driver code. + * @brief SimpleFS VFS driver code. * * @addtogroup VFS_DRV_SFS * @{ @@ -354,7 +354,7 @@ void __drv_sfs_init(void) { } /** - * @brief VFS FatFS object initialization. + * @brief VFS SimpleFS object initialization. * * @param[out] drvp pointer to a @p vfs_sfs_driver_c structure * @param[in] rootname name to be attributed to this object diff --git a/os/vfs/drivers/sfs/drvsfs.h b/os/vfs/drivers/sfs/drvsfs.h index 14e6214ae..9f1c9d2d7 100644 --- a/os/vfs/drivers/sfs/drvsfs.h +++ b/os/vfs/drivers/sfs/drvsfs.h @@ -83,7 +83,7 @@ struct vfs_sfs_dir_node_vmt { }; /** - * @brief Type of a FatFS directory VFS node class. + * @brief Type of a SimpleFS directory VFS node class. */ typedef struct vfs_sfs_dir_node { /** @@ -114,7 +114,7 @@ struct vfs_sfs_file_node_vmt { }; /** - * @brief Type of a FatFS file VFS node class. + * @brief Type of a SimpleFS file VFS node class. */ typedef struct vfs_sfs_file_node { /** @@ -144,7 +144,7 @@ struct vfs_sfs_driver_vmt { }; /** - * @brief Type of a VFS FatFS driver class. + * @brief Type of a VFS SimpleFS driver class. */ typedef struct vfs_sfs_driver { /** diff --git a/os/vfs/drivers/template/drvtemplate.c b/os/vfs/drivers/template/drvtemplate.c new file mode 100644 index 000000000..2467db6de --- /dev/null +++ b/os/vfs/drivers/template/drvtemplate.c @@ -0,0 +1,376 @@ +/* + ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014, + 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation version 3 of the License. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file vfs/drivers/drvtemplate.c + * @brief HAL Template VFS driver code. + * + * @addtogroup VFS_DRV_TEMPLATE + * @{ + */ + +#include "vfs.h" + +#if (VFS_CFG_ENABLE_DRV_TEMPLATE == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +static msg_t drv_open_dir(void *instance, + const char *path, + vfs_directory_node_c **vdnpp); +static msg_t drv_open_file(void *instance, + const char *path, + int oflag, + vfs_file_node_c **vfnpp); + +static const struct vfs_template_driver_vmt driver_vmt = { + .open_dir = drv_open_dir, + .open_file = drv_open_file +}; + +static void node_dir_release(void *instance); +static msg_t node_dir_first(void *instance, vfs_node_info_t *nip); +static msg_t node_dir_next(void *instance, vfs_node_info_t *nip); + +static const struct vfs_template_dir_node_vmt dir_node_vmt = { + .release = node_dir_release, + .dir_first = node_dir_first, + .dir_next = node_dir_next +}; + +static void node_file_release(void *instance); +static BaseSequentialStream *node_file_get_stream(void *instance); +static ssize_t node_file_read(void *instance, uint8_t *buf, size_t n); +static ssize_t node_file_write(void *instance, const uint8_t *buf, size_t n); +static msg_t node_file_setpos(void *instance, vfs_offset_t offset); +static vfs_offset_t node_file_getpos(void *instance); +static vfs_offset_t node_file_getsize(void *instance); + +static const struct vfs_template_file_node_vmt file_node_vmt = { + .release = node_file_release, + .file_get_stream = node_file_get_stream, + .file_read = node_file_read, + .file_write = node_file_write, + .file_setpos = node_file_setpos, + .file_getpos = node_file_getpos, + .file_getsize = node_file_getsize +}; + +static size_t file_stream_write(void *instance, const uint8_t *bp, size_t n); +static size_t file_stream_read(void *instance, uint8_t *bp, size_t n); +static msg_t file_stream_put(void *instance, uint8_t b); +static msg_t file_stream_get(void *instance); + +static const struct BaseSequentialStreamVMT file_stream_vmt = { + .instance_offset = __CH_OFFSETOF(vfs_template_file_node_c, stream.vmt), + .write = file_stream_write, + .read = file_stream_read, + .put = file_stream_put, + .get = file_stream_get +}; + +/** + * @brief Static members of @p vfs_template_driver_c. + */ +static struct { + /** + * @brief Pool of file system objects. + */ + memory_pool_t fs_nodes_pool; + /** + * @brief Pool of file info objects. + */ + memory_pool_t info_nodes_pool; + /** + * @brief Pool of directory nodes. + */ + memory_pool_t dir_nodes_pool; + /** + * @brief Pool of file nodes. + */ + memory_pool_t file_nodes_pool; + /** + * @brief Static storage of directory nodes. + */ + vfs_template_dir_node_c dir_nodes[DRV_CFG_TEMPLATE_DIR_NODES_NUM]; + /** + * @brief Static storage of file nodes. + */ + vfs_template_file_node_c file_nodes[DRV_CFG_TEMPLATE_FILE_NODES_NUM]; +} vfs_template_driver_static; + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +static msg_t drv_open_dir(void *instance, + const char *path, + vfs_directory_node_c **vdnpp) { + msg_t err = VFS_RET_SUCCESS; + + do { + vfs_template_driver_c *drvp = (vfs_template_driver_c *)instance; + + (void)drvp; + (void)path; + (void)vdnpp; + + } + while (false); + + return err; +} + +static msg_t drv_open_file(void *instance, + const char *path, + int oflag, + vfs_file_node_c **vfnpp) { + msg_t err = VFS_RET_SUCCESS; + + do { + vfs_template_driver_c *drvp = (vfs_template_driver_c *)instance; + + (void)drvp; + (void)path; + (void)oflag; + (void)vfnpp; + + } + while (false); + + return err; +} + +static void node_dir_release(void *instance) { + vfs_template_dir_node_c *dnp = (vfs_template_dir_node_c *)instance; + + __referenced_object_release_impl(instance); + if (__referenced_object_getref_impl(instance) == 0U) { + + chPoolFree(&vfs_template_driver_static.dir_nodes_pool, (void *)dnp); + } +} + +static msg_t node_dir_first(void *instance, vfs_node_info_t *nip) { + vfs_template_dir_node_c *dnp = (vfs_template_dir_node_c *)instance; + msg_t err = VFS_RET_SUCCESS;; + + (void)dnp; + + /* TODO rewind */ + err = node_dir_next(instance, nip); + + return err; +} + +static msg_t node_dir_next(void *instance, vfs_node_info_t *nip) { + msg_t err = VFS_RET_SUCCESS; + + do { + vfs_template_dir_node_c *dnp = (vfs_template_dir_node_c *)instance; + + (void)dnp; + (void)nip; + } + while (false); + + return err; +} + +static void node_file_release(void *instance) { + vfs_template_file_node_c *fnp = (vfs_template_file_node_c *)instance; + + __referenced_object_release_impl(instance); + if (__referenced_object_getref_impl(instance) == 0U) { + + chPoolFree(&vfs_template_driver_static.file_nodes_pool, (void *)fnp); + } +} + +static BaseSequentialStream *node_file_get_stream(void *instance) { + vfs_template_file_node_c *fnp = (vfs_template_file_node_c *)instance; + + return &fnp->stream; +} + +static ssize_t node_file_read(void *instance, uint8_t *buf, size_t n) { + vfs_template_file_node_c *fnp = (vfs_template_file_node_c *)instance; + + (void)fnp; + (void)buf; + (void)n; + + return (ssize_t)0; +} + +static ssize_t node_file_write(void *instance, const uint8_t *buf, size_t n) { + vfs_template_file_node_c *fnp = (vfs_template_file_node_c *)instance; + + (void)fnp; + (void)buf; + (void)n; + + return (ssize_t)0; +} + +static msg_t node_file_setpos(void *instance, vfs_offset_t offset) { + vfs_template_file_node_c *fnp = (vfs_template_file_node_c *)instance; + + (void)fnp; + (void)offset; + + return VFS_RET_SUCCESS; +} + +static vfs_offset_t node_file_getpos(void *instance) { + vfs_template_file_node_c *fnp = (vfs_template_file_node_c *)instance; + + (void)fnp; + + return (vfs_offset_t)0; +} + +static vfs_offset_t node_file_getsize(void *instance) { + vfs_template_file_node_c *fnp = (vfs_template_file_node_c *)instance; + + (void)fnp; + + return (vfs_offset_t)0; +} + +static size_t file_stream_write(void *instance, const uint8_t *bp, size_t n) { + vfs_template_file_node_c *fnp = objGetInstance(vfs_template_file_node_c *, + (BaseSequentialStream *)instance); + msg_t msg; + + msg = fnp->vmt->file_write((void *)fnp, bp, n); + if (msg < VFS_RET_SUCCESS) { + + return (size_t)0; + } + + return (size_t)msg; +} + +static size_t file_stream_read(void *instance, uint8_t *bp, size_t n) { + vfs_template_file_node_c *fnp = objGetInstance(vfs_template_file_node_c *, + (BaseSequentialStream *)instance); + msg_t msg; + + msg = fnp->vmt->file_read((void *)fnp, bp, n); + if (msg < VFS_RET_SUCCESS) { + + return (size_t)0; + } + + return (size_t)msg; +} + +static msg_t file_stream_put(void *instance, uint8_t b) { + vfs_template_file_node_c *fnp = objGetInstance(vfs_template_file_node_c *, + (BaseSequentialStream *)instance); + msg_t msg; + + msg = fnp->vmt->file_write((void *)fnp, &b, (size_t)1); + if (msg < VFS_RET_SUCCESS) { + + return STM_TIMEOUT; + } + + return msg; +} + +static msg_t file_stream_get(void *instance) { + vfs_template_file_node_c *fnp = objGetInstance(vfs_template_file_node_c *, + (BaseSequentialStream *)instance); + msg_t msg; + uint8_t b; + + msg = fnp->vmt->file_read((void *)fnp, &b, (size_t)1); + if (msg < VFS_RET_SUCCESS) { + + return STM_TIMEOUT; + } + + return (msg_t)b; +} + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +/** + * @brief Module initialization. + * + * @notapi + */ +void __drv_template_init(void) { + + /* Initializing pools.*/ + chPoolObjectInit(&vfs_template_driver_static.dir_nodes_pool, + sizeof (vfs_template_dir_node_c), + chCoreAllocAlignedI); + chPoolObjectInit(&vfs_template_driver_static.file_nodes_pool, + sizeof (vfs_template_file_node_c), + chCoreAllocAlignedI); + + /* Preloading pools.*/ + chPoolLoadArray(&vfs_template_driver_static.dir_nodes_pool, + &vfs_template_driver_static.dir_nodes[0], + DRV_CFG_TEMPLATE_DIR_NODES_NUM); + chPoolLoadArray(&vfs_template_driver_static.file_nodes_pool, + &vfs_template_driver_static.file_nodes[0], + DRV_CFG_TEMPLATE_FILE_NODES_NUM); +} + +/** + * @brief VFS Template object initialization. + * + * @param[out] drvp pointer to a @p vfs_template_driver_c structure + * @param[in] rootname name to be attributed to this object + * @return A pointer to this initialized object. + * + * @api + */ +vfs_driver_c *drvTEMPLATEObjectInit(vfs_template_driver_c *drvp, + const char *rootname) { + + __base_object_objinit_impl(drvp, &driver_vmt); + drvp->rootname = rootname; + + return (vfs_driver_c *)drvp; +} + +#endif /* VFS_CFG_ENABLE_DRV_TEMPLATE == TRUE */ + +/** @} */ diff --git a/os/vfs/drivers/template/drvtemplate.h b/os/vfs/drivers/template/drvtemplate.h new file mode 100644 index 000000000..7f2cd2497 --- /dev/null +++ b/os/vfs/drivers/template/drvtemplate.h @@ -0,0 +1,183 @@ +/* + ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014, + 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation version 3 of the License. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +/** + * @file vfs/drivers/drvtemplate.h + * @brief SimpleFS VFS driver header. + * + * @addtogroup VFS_DRV_TEMPLATE + * @details Simple FS for VFS. + * @{ + */ + +#ifndef DRVTEMPLATE_H +#define DRVTEMPLATE_H + +#if (VFS_CFG_ENABLE_DRV_TEMPLATE == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* Configuration options checks.*/ +#if !defined(DRV_CFG_TEMPLATE_DIR_NODES_NUM) +#error "DRV_CFG_TEMPLATE_DIR_NODES_NUM not defined in vfsconf.h" +#endif + +#if !defined(DRV_CFG_TEMPLATE_FILE_NODES_NUM) +#error "DRV_CFG_TEMPLATE_FILE_NODES_NUM not defined in vfsconf.h" +#endif + +#if DRV_CFG_TEMPLATE_DIR_NODES_NUM < 1 +#error "invalid value for DRV_CFG_TEMPLATE_DIR_NODES_NUM" +#endif + +#if DRV_CFG_TEMPLATE_FILE_NODES_NUM < 1 +#error "invalid value for DRV_CFG_TEMPLATE_FILE_NODES_NUM" +#endif + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/** + * @brief @p vfs_template_dir_node_c specific methods. + */ +#define __vfs_template_dir_node_methods \ + __vfs_directory_node_methods + +/** + * @brief @p vfs_template_dir_node_c specific data. + */ +#define __vfs_template_dir_node_data \ + __vfs_directory_node_data + +/** + * @brief @p vfs_template_dir_node_c virtual methods table. + */ +struct vfs_template_dir_node_vmt { + __vfs_template_dir_node_methods +}; + +/** + * @brief Type of a Template directory VFS node class. + */ +typedef struct vfs_template_dir_node { + /** + * @brief Virtual Methods Table. + */ + const struct vfs_template_dir_node_vmt *vmt; + __vfs_template_dir_node_data +} vfs_template_dir_node_c; + +/** + * @brief @p vfs_template_file_node_c specific methods. + */ +#define __vfs_template_file_node_methods \ + __vfs_file_node_methods + +/** + * @brief @p vfs_template_file_node_c specific data. + */ +#define __vfs_template_file_node_data \ + __vfs_file_node_data \ + BaseSequentialStream stream; + +/** + * @brief @p vfs_template_file_node_c virtual methods table. + */ +struct vfs_template_file_node_vmt { + __vfs_template_file_node_methods +}; + +/** + * @brief Type of a Template file VFS node class. + */ +typedef struct vfs_template_file_node { + /** + * @brief Virtual Methods Table. + */ + const struct vfs_template_file_node_vmt *vmt; + __vfs_template_file_node_data +} vfs_template_file_node_c; + +/** + * @brief @p vfs_template_driver_c specific methods. + */ +#define __vfs_template_driver_methods \ + __vfs_driver_methods + +/** + * @brief @p vfs_template_driver_c specific data. + */ +#define __vfs_template_driver_data \ + __vfs_driver_data + +/** + * @brief @p vfs_template_driver_c virtual methods table. + */ +struct vfs_template_driver_vmt { + __vfs_template_driver_methods +}; + +/** + * @brief Type of a VFS Template driver class. + */ +typedef struct vfs_template_driver { + /** + * @brief Virtual Methods Table. + */ + const struct vfs_template_driver_vmt *vmt; + __vfs_template_driver_data +} vfs_template_driver_c; + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void __drv_template_init(void); + vfs_driver_c *drvTEMPLATEObjectInit(vfs_template_driver_c *drvp, + const char *rootname); +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +#endif /* VFS_CFG_ENABLE_DRV_TEMPLATE == TRUE */ + +#endif /* DRVTEMPLATE_H */ + +/** @} */ diff --git a/os/vfs/include/vfs.h b/os/vfs/include/vfs.h index 578594035..8410f63cd 100644 --- a/os/vfs/include/vfs.h +++ b/os/vfs/include/vfs.h @@ -105,13 +105,21 @@ #endif /* TODO temporary */ -#define DRV_CFG_SFS_DIR_NODES_NUM 1 -#define DRV_CFG_SFS_FILE_NODES_NUM 1 -#define VFS_CFG_ENABLE_DRV_SFS FALSE +#define VFS_CFG_ENABLE_DRV_SFS FALSE +#define DRV_CFG_SFS_DIR_NODES_NUM 1 +#define DRV_CFG_SFS_FILE_NODES_NUM 1 #if VFS_CFG_ENABLE_DRV_SFS == TRUE #include "drvsfs.h" #endif +/* Only for testing, not a real driver.*/ +#define VFS_CFG_ENABLE_DRV_TEMPLATE FALSE +#define DRV_CFG_TEMPLATE_DIR_NODES_NUM 1 +#define DRV_CFG_TEMPLATE_FILE_NODES_NUM 1 +#if VFS_CFG_ENABLE_DRV_TEMPLATE == TRUE +#include "drvtemplate.h" +#endif + /* Application code is supposed to export this symbol, it is expected to exists.*/ extern vfs_driver_c *vfs_root; diff --git a/os/vfs/vfs.mk b/os/vfs/vfs.mk index a67ca80e4..e560199b7 100644 --- a/os/vfs/vfs.mk +++ b/os/vfs/vfs.mk @@ -3,6 +3,7 @@ VFSSRC := $(CHIBIOS)/os/vfs/src/vfsparser.c \ $(CHIBIOS)/os/vfs/src/vfspaths.c \ $(CHIBIOS)/os/vfs/src/vfsbuffers.c \ $(CHIBIOS)/os/vfs/src/vfs.c \ + $(CHIBIOS)/os/vfs/drivers/template/drvtemplate.c \ $(CHIBIOS)/os/vfs/drivers/sfs/drvsfs.c \ $(CHIBIOS)/os/vfs/drivers/fatfs/drvfatfs.c \ $(CHIBIOS)/os/vfs/drivers/overlay/drvoverlay.c \ @@ -10,6 +11,7 @@ VFSSRC := $(CHIBIOS)/os/vfs/src/vfsparser.c \ # Required include directories VFSINC := $(CHIBIOS)/os/vfs/include \ + $(CHIBIOS)/os/vfs/drivers/template \ $(CHIBIOS)/os/vfs/drivers/sfs \ $(CHIBIOS)/os/vfs/drivers/fatfs \ $(CHIBIOS)/os/vfs/drivers/overlay \