diff --git a/demos/STM32/RT-VFS-FATFS/cfg/stm32g474re_nucleo64/vfsconf.h b/demos/STM32/RT-VFS-FATFS/cfg/stm32g474re_nucleo64/vfsconf.h index 07e8dbd5c..aee43bf70 100644 --- a/demos/STM32/RT-VFS-FATFS/cfg/stm32g474re_nucleo64/vfsconf.h +++ b/demos/STM32/RT-VFS-FATFS/cfg/stm32g474re_nucleo64/vfsconf.h @@ -38,8 +38,22 @@ /** * @brief Maximum filename length. */ -#if !defined(VFS_CFG_MAX_NAMELEN) || defined(__DOXYGEN__) -#define VFS_CFG_MAX_NAMELEN 15 +#if !defined(VFS_CFG_NAMELEN_MAX) || defined(__DOXYGEN__) +#define VFS_CFG_NAMELEN_MAX 15 +#endif + +/** + * @brief Maximum paths length. + */ +#if !defined(VFS_CFG_PATHLEN_MAX) || defined(__DOXYGEN__) +#define VFS_CFG_PATHLEN_MAX 1023 +#endif + +/** + * @brief Number of shared path buffers. + */ +#if !defined(VFS_CFG_PATHBUFS_NUM) || defined(__DOXYGEN__) +#define VFS_CFG_PATHBUFS_NUM 1 #endif /** @} */ diff --git a/demos/STM32/RT-VFS-FATFS/cfg/stm32l4r9ai_discovery/vfsconf.h b/demos/STM32/RT-VFS-FATFS/cfg/stm32l4r9ai_discovery/vfsconf.h index db4824c55..c11cc733f 100644 --- a/demos/STM32/RT-VFS-FATFS/cfg/stm32l4r9ai_discovery/vfsconf.h +++ b/demos/STM32/RT-VFS-FATFS/cfg/stm32l4r9ai_discovery/vfsconf.h @@ -38,8 +38,22 @@ /** * @brief Maximum filename length. */ -#if !defined(VFS_CFG_MAX_NAMELEN) || defined(__DOXYGEN__) -#define VFS_CFG_MAX_NAMELEN 15 +#if !defined(VFS_CFG_NAMELEN_MAX) || defined(__DOXYGEN__) +#define VFS_CFG_NAMELEN_MAX 15 +#endif + +/** + * @brief Maximum paths length. + */ +#if !defined(VFS_CFG_PATHLEN_MAX) || defined(__DOXYGEN__) +#define VFS_CFG_PATHLEN_MAX 1023 +#endif + +/** + * @brief Number of shared path buffers. + */ +#if !defined(VFS_CFG_PATHBUFS_NUM) || defined(__DOXYGEN__) +#define VFS_CFG_PATHBUFS_NUM 1 #endif /** @} */ diff --git a/demos/STM32/RT-VFS-FATFS/main.c b/demos/STM32/RT-VFS-FATFS/main.c index 1bb01d9bc..01da2b8ad 100644 --- a/demos/STM32/RT-VFS-FATFS/main.c +++ b/demos/STM32/RT-VFS-FATFS/main.c @@ -274,11 +274,13 @@ int main(void) { /* Initializing an overlay VFS object overlaying a FatFS driver, no need for names, both are root.*/ drvOverlayObjectInit(&root_overlay_driver, - drvFatFSObjectInit(&root_driver, ""), ""); + drvFatFSObjectInit(&root_driver, ""), + NULL, + ""); #else /* Initializing an overlay VFS object as a root, no overlaid driver, no need for a name.*/ - drvOverlayObjectInit(&root_overlay_driver, NULL, ""); + drvOverlayObjectInit(&root_overlay_driver, NULL, NULL, ""); #endif /* Registering a streams VFS driver on the VFS overlay root as "/dev".*/ diff --git a/os/vfs/drivers/fatfs/drvfatfs.c b/os/vfs/drivers/fatfs/drvfatfs.c index 0a1b87559..a2381c8b7 100644 --- a/os/vfs/drivers/fatfs/drvfatfs.c +++ b/os/vfs/drivers/fatfs/drvfatfs.c @@ -325,8 +325,8 @@ static msg_t node_dir_next(void *instance, vfs_node_info_t *nip) { else { nip->attr = (vfs_nodeattr_t)fip->fattrib; nip->size = (vfs_offset_t)fip->fsize; - strncpy(nip->name, fip->fname, VFS_CFG_MAX_NAMELEN); - nip->name[VFS_CFG_MAX_NAMELEN] = '\0'; + strncpy(nip->name, fip->fname, VFS_CFG_NAMELEN_MAX); + nip->name[VFS_CFG_NAMELEN_MAX] = '\0'; err = VFS_RET_SUCCESS; } } diff --git a/os/vfs/drivers/overlay/drvoverlay.c b/os/vfs/drivers/overlay/drvoverlay.c index 6b6318432..62c8aa083 100644 --- a/os/vfs/drivers/overlay/drvoverlay.c +++ b/os/vfs/drivers/overlay/drvoverlay.c @@ -91,7 +91,7 @@ static struct { static msg_t match_driver(vfs_overlay_driver_c *odp, const char **pathp, vfs_driver_c **vdpp) { - char fname[VFS_CFG_MAX_NAMELEN + 1]; + char fname[VFS_CFG_NAMELEN_MAX + 1]; msg_t err; vfs_driver_c **pp; @@ -102,7 +102,7 @@ static msg_t match_driver(vfs_overlay_driver_c *odp, /* Searching among registered drivers.*/ pp = &odp->drivers[0]; while (pp < &odp->drivers[odp->next_driver]) { - if (strncmp(fname, (*pp)->rootname, VFS_CFG_MAX_NAMELEN) == 0) { + if (strncmp(fname, (*pp)->rootname, VFS_CFG_NAMELEN_MAX) == 0) { *vdpp = *pp; return VFS_RET_SUCCESS; } @@ -300,6 +300,7 @@ void __drv_overlay_init(void) { * * @param[out] vodp pointer to a @p vfs_overlay_driver_c structure * @param[out] overlaid_drv pointer to a driver to be overlaid + * @param[out] path_prefix prefix to be added to the paths or @p NULL * @param[in] rootname name to be attributed to this object * @return A pointer to this initialized object. * @@ -307,11 +308,13 @@ void __drv_overlay_init(void) { */ vfs_driver_c *drvOverlayObjectInit(vfs_overlay_driver_c *vodp, vfs_driver_c *overlaid_drv, + const char *path_prefix, const char *rootname) { __base_object_objinit_impl(vodp, &driver_vmt); vodp->rootname = rootname; vodp->overlaid_drv = overlaid_drv; + vodp->path_prefix = path_prefix; vodp->next_driver = 0U; return (vfs_driver_c *)vodp; @@ -320,8 +323,8 @@ vfs_driver_c *drvOverlayObjectInit(vfs_overlay_driver_c *vodp, /** * @brief Registers a VFS driver as an overlay. * - * @param[in] vodp pointer to a @p vfs_overlay_driver_c structure - * @return The operation result. + * @param[in] vodp pointer to a @p vfs_overlay_driver_c structure + * @return The operation result. * * @api */ diff --git a/os/vfs/drivers/overlay/drvoverlay.h b/os/vfs/drivers/overlay/drvoverlay.h index 352bf281a..21f083acc 100644 --- a/os/vfs/drivers/overlay/drvoverlay.h +++ b/os/vfs/drivers/overlay/drvoverlay.h @@ -109,6 +109,8 @@ typedef struct vfs_overlay_dir_node { __vfs_driver_data \ /* Driver to be overlaid or NULL.*/ \ vfs_driver_c *overlaid_drv; \ + /* Path prefix for the overlaid driver or NULL.*/ \ + const char *path_prefix ; \ /* Next registration slot.*/ \ unsigned next_driver; \ /* Registration slots.*/ \ @@ -146,6 +148,7 @@ extern "C" { void __drv_overlay_init(void); vfs_driver_c *drvOverlayObjectInit(vfs_overlay_driver_c *vodp, vfs_driver_c *overlaid_drv, + const char *path_prefix, const char *rootname); msg_t drvOverlayRegisterDriver(vfs_overlay_driver_c *vodp, vfs_driver_c *vdp); diff --git a/os/vfs/drivers/streams/drvstreams.c b/os/vfs/drivers/streams/drvstreams.c index 7a08ed669..d095d1d13 100644 --- a/os/vfs/drivers/streams/drvstreams.c +++ b/os/vfs/drivers/streams/drvstreams.c @@ -159,7 +159,7 @@ static msg_t drv_open_file(void *instance, (void)oflag; do { - char fname[VFS_CFG_MAX_NAMELEN + 1]; + char fname[VFS_CFG_NAMELEN_MAX + 1]; err = vfs_parse_match_separator(&path); VFS_BREAK_ON_ERROR(err); @@ -172,7 +172,7 @@ static msg_t drv_open_file(void *instance, dsep = &drvp->streams[0]; while (dsep->name != NULL) { - if (strncmp(fname, dsep->name, VFS_CFG_MAX_NAMELEN) == 0) { + if (strncmp(fname, dsep->name, VFS_CFG_NAMELEN_MAX) == 0) { vfs_streams_file_node_c *sfnp; sfnp = chPoolAlloc(&vfs_streams_driver_static.file_nodes_pool); diff --git a/os/vfs/include/vfs.h b/os/vfs/include/vfs.h index 1de27f0d3..adf9e7bae 100644 --- a/os/vfs/include/vfs.h +++ b/os/vfs/include/vfs.h @@ -67,7 +67,7 @@ #include /* Dependencies.*/ -#include "osal.h" +#include "ch.h" #include "oop_base_object.h" #include "oop_referenced_object.h" #include "oop_synchronized_object.h" @@ -84,6 +84,7 @@ /* Base VFS headers.*/ #include "vfserrors.h" #include "vfsparser.h" +#include "vfsbuffers.h" #include "vfsnodes.h" #include "vfsdrivers.h" diff --git a/os/vfs/include/vfsbuffers.h b/os/vfs/include/vfsbuffers.h new file mode 100644 index 000000000..0f6c90795 --- /dev/null +++ b/os/vfs/include/vfsbuffers.h @@ -0,0 +1,72 @@ +/* + 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/include/vfsbuffers.h + * @brief VFS header file. + * @details VFS shared path buffers header file. + * + * @addtogroup VFS_BUFFERS + * @{ + */ + +#ifndef VFS_BUFFERS_H +#define VFS_BUFFERS_H + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void __vfs_buffers_init(void); + char *vfs_buffer_take(void); + void vfs_buffer_release(char *buf); +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +#endif /* VFS_BUFFERS_H */ + +/** @} */ diff --git a/os/vfs/include/vfschecks.h b/os/vfs/include/vfschecks.h index 86d662258..644dcc6ef 100644 --- a/os/vfs/include/vfschecks.h +++ b/os/vfs/include/vfschecks.h @@ -49,12 +49,28 @@ #endif /* Configuration options checks.*/ -#if !defined(VFS_CFG_MAX_NAMELEN) -#error "VFS_CFG_MAX_NAMELEN not defined in vfsconf.h" +#if !defined(VFS_CFG_NAMELEN_MAX) +#error "VFS_CFG_NAMELEN_MAX not defined in vfsconf.h" #endif -#if VFS_CFG_MAX_NAMELEN < 12 -#error "invalid value for VFS_CFG_MAX_NAMELEN" +#if VFS_CFG_NAMELEN_MAX < 12 +#error "invalid value for VFS_CFG_NAMELEN_MAX" +#endif + +#if !defined(VFS_CFG_PATHLEN_MAX) +#error "VFS_CFG_PATHLEN_MAX not defined in vfsconf.h" +#endif + +#if VFS_CFG_PATHLEN_MAX < 63 +#error "invalid value for VFS_CFG_PATHLEN_MAX" +#endif + +#if !defined(VFS_CFG_PATHBUFS_NUM) +#error "VFS_CFG_PATHBUFS_NUM not defined in vfsconf.h" +#endif + +#if VFS_CFG_PATHBUFS_NUM < 1 +#error "invalid value for VFS_CFG_PATHBUFS_NUM" #endif #if !defined(VFS_CFG_ENABLE_DRV_OVERLAY) diff --git a/os/vfs/include/vfsnodes.h b/os/vfs/include/vfsnodes.h index 589713a59..1523803b3 100644 --- a/os/vfs/include/vfsnodes.h +++ b/os/vfs/include/vfsnodes.h @@ -85,7 +85,7 @@ typedef struct vfs_node_info { /** * @brief Name of the node. */ - char name[VFS_CFG_MAX_NAMELEN + 1]; + char name[VFS_CFG_NAMELEN_MAX + 1]; } vfs_node_info_t; /** diff --git a/os/vfs/src/vfs.c b/os/vfs/src/vfs.c index 91840995d..cd3b2eb67 100644 --- a/os/vfs/src/vfs.c +++ b/os/vfs/src/vfs.c @@ -60,6 +60,9 @@ */ void vfsInit(void) { + /* Shared buffers manager initialization.*/ + __vfs_buffers_init(); + #if VFS_CFG_ENABLE_DRV_OVERLAY == TRUE __drv_overlay_init(); #endif diff --git a/os/vfs/src/vfsbuffers.c b/os/vfs/src/vfsbuffers.c new file mode 100644 index 000000000..e534c637e --- /dev/null +++ b/os/vfs/src/vfsbuffers.c @@ -0,0 +1,104 @@ +/* + 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/src/vfsbuffers.c + * @brief VFS shared path buffers code. + * + * @addtogroup VFS_BUFFERS + * @{ + */ + +#include "vfs.h" + +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +/** + * @brief VFS static data. + */ +static struct { + /** + * @brief Guarded pool of path buffers. + */ + guarded_memory_pool_t path_buffers_pool; + /** + * @brief Shared path buffers. + */ + char path_buffers[VFS_CFG_PATHBUFS_NUM] + [VFS_CFG_PATHLEN_MAX + 1]; +} vfs_buffers_static; + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +/** + * @brief VFS initialization. + * + * @init + */ +void __vfs_buffers_init(void) { + + chGuardedPoolObjectInit(&vfs_buffers_static.path_buffers_pool, + VFS_CFG_PATHLEN_MAX + 1); + chGuardedPoolLoadArray(&vfs_buffers_static.path_buffers_pool, + &vfs_buffers_static.path_buffers[0], + VFS_CFG_PATHBUFS_NUM); +} + +/** + * @brief Claims a path buffer, waiting if not available. + * + * @return Pointer to the taken buffer. + */ +char *vfs_buffer_take(void) { + + return (char *)chGuardedPoolAllocTimeout(&vfs_buffers_static.path_buffers_pool, + TIME_INFINITE); +} + +/** + * @brief Releases a path buffer. + * + * @param[in] buf Buffer to be released. + */ +void vfs_buffer_release(char *buf) { + + chGuardedPoolFree(&vfs_buffers_static.path_buffers_pool, (void *)buf); +} + +/** @} */ diff --git a/os/vfs/src/vfsparser.c b/os/vfs/src/vfsparser.c index 0e164dcd1..0143b3ac4 100644 --- a/os/vfs/src/vfsparser.c +++ b/os/vfs/src/vfsparser.c @@ -128,7 +128,7 @@ msg_t vfs_parse_filename(const char **pathp, char *fname) { return VFS_RET_ENOENT; } - if (n > VFS_CFG_MAX_NAMELEN) { + if (n > VFS_CFG_NAMELEN_MAX) { return VFS_RET_ENOENT; } diff --git a/os/vfs/templates/vfsconf.h b/os/vfs/templates/vfsconf.h index db4824c55..c11cc733f 100644 --- a/os/vfs/templates/vfsconf.h +++ b/os/vfs/templates/vfsconf.h @@ -38,8 +38,22 @@ /** * @brief Maximum filename length. */ -#if !defined(VFS_CFG_MAX_NAMELEN) || defined(__DOXYGEN__) -#define VFS_CFG_MAX_NAMELEN 15 +#if !defined(VFS_CFG_NAMELEN_MAX) || defined(__DOXYGEN__) +#define VFS_CFG_NAMELEN_MAX 15 +#endif + +/** + * @brief Maximum paths length. + */ +#if !defined(VFS_CFG_PATHLEN_MAX) || defined(__DOXYGEN__) +#define VFS_CFG_PATHLEN_MAX 1023 +#endif + +/** + * @brief Number of shared path buffers. + */ +#if !defined(VFS_CFG_PATHBUFS_NUM) || defined(__DOXYGEN__) +#define VFS_CFG_PATHBUFS_NUM 1 #endif /** @} */ diff --git a/os/vfs/vfs.mk b/os/vfs/vfs.mk index 34246b3a8..403cd70c7 100644 --- a/os/vfs/vfs.mk +++ b/os/vfs/vfs.mk @@ -1,5 +1,6 @@ # List of all the ChibiOS/VFS files. VFSSRC := $(CHIBIOS)/os/vfs/src/vfsparser.c \ + $(CHIBIOS)/os/vfs/src/vfsbuffers.c \ $(CHIBIOS)/os/vfs/src/vfs.c \ $(CHIBIOS)/os/vfs/drivers/fatfs/drvfatfs.c \ $(CHIBIOS)/os/vfs/drivers/overlay/drvoverlay.c \