git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15129 27425a3e-05d8-49a3-a47f-9c15f0e5edd8

This commit is contained in:
Giovanni Di Sirio 2021-11-23 08:19:39 +00:00
parent 09747ca593
commit fc29bee998
7 changed files with 220 additions and 53 deletions

View File

@ -0,0 +1,161 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
/**
* @file vfs/drivers/drvstreams.c
* @brief HAL streams VFS driver code.
*
* @addtogroup VFS_DRV_STREAMS
* @{
*/
#include <string.h>
#include "vfs.h"
#include "drvstreams.h"
/*===========================================================================*/
/* Module local definitions. */
/*===========================================================================*/
/**
* @brief @p vfs_drv_streams_t specific methods.
*/
#define __vfs_drv_streams_methods \
__vfs_driver_methods
/**
* @brief @p vfs_drv_streams_t specific data.
*/
#define __vfs_drv_streams_data \
__vfs_driver_data \
const drv_stream_element_t *streams;
/*===========================================================================*/
/* Module exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local types. */
/*===========================================================================*/
/**
* @brief @p vfs_drv_streams_t virtual methods table.
*/
struct vfs_drv_streams_vmt {
__vfs_drv_streams_methods
};
/**
* @brief Type of a structure representing a VFS streams driver.
*/
typedef struct vfs_drv_streams {
/**
* @brief Virtual Methods Table.
*/
const struct vfs_drv_streams_vmt *vmt;
__vfs_drv_streams_data
} vfs_drv_streams_t;
/*===========================================================================*/
/* Module local variables. */
/*===========================================================================*/
static msg_t drv_open_dir(void *instance,
const char *path,
vfs_directory_node_t **vdnpp);
static msg_t drv_open_file(void *instance,
const char *path,
vfs_file_node_t **vfnpp);
static const struct vfs_drv_streams_vmt vmt = {
.open_dir = drv_open_dir,
.open_file = drv_open_file
};
static vfs_drv_streams_t drv_streams;
/*===========================================================================*/
/* Module local functions. */
/*===========================================================================*/
static msg_t drv_open_dir(void *instance,
const char *path,
vfs_directory_node_t **vdnpp) {
(void)instance;
(void)path;
(void)vdnpp;
return VFS_RET_NOT_FOUND;
}
static msg_t drv_open_file(void *instance,
const char *path,
vfs_file_node_t **vfnpp) {
vfs_drv_streams_t *drvp = (vfs_drv_streams_t *)instance;
const drv_stream_element_t *dsep;
msg_t err;
do {
char fname[VFS_CFG_MAX_NAMELEN + 1];
err = vfs_parse_match_separator(&path);
VFS_BREAK_ON_ERROR(err);
err = vfs_parse_filename(&path, fname);
VFS_BREAK_ON_ERROR(err);
err = vfs_parse_match_end(&path);
VFS_BREAK_ON_ERROR(err);
dsep = &drvp->streams[0];
while (dsep->name != NULL) {
if (strncmp(fname, dsep->name, VFS_CFG_MAX_NAMELEN) == 0) {
*vfnpp = NULL;
return VFS_RET_SUCCESS;
}
dsep++;
}
err = VFS_RET_NOT_FOUND;
}
while (false);
return err;
}
/*===========================================================================*/
/* Module exported functions. */
/*===========================================================================*/
vfs_driver_t *drvStreamsInit(const char *rootname,
const drv_stream_element_t *streams) {
drv_streams.vmt = &vmt;
drv_streams.rootname = rootname;
drv_streams.streams = streams;
return (vfs_driver_t *)&drv_streams;
}
/** @} */

View File

@ -47,39 +47,18 @@
/*===========================================================================*/
/**
* @brief Type of a structure representing a VFS driver.
* @brief Type of a stream association structure.
*/
typedef struct vfs_drv_streams vfs_drv_streams_t;
/**
* @brief @p vfs_node_t specific methods.
*/
#define __vfs_drv_streams_methods \
__vfs_driver_methods
/**
* @brief @p vfs_node_t specific data.
*/
#define __vfs_drv_streams_data \
__vfs_driver_data
/**
* @brief @p vfs_node_t virtual methods table.
*/
struct vfs_drv_stream_vmt {
__vfs_drv_streams_methods
};
/**
* @brief TStructure representing a VFS driver.
*/
struct vfs_drv_streams {
typedef struct drv_stream_element {
/**
* @brief Virtual Methods Table.
* @brief Filename for the stream.
*/
const struct vfs_drv_streams_vmt *vmt;
__vfs_drv_streams_data
};
char *name;
/**
* @brief Pointer to the stream.
*/
BaseSequentialStream *stream;
} drv_stream_element_t;
/*===========================================================================*/
/* Module macros. */

View File

@ -0,0 +1,9 @@
# List of all the streams VFS driver files.
DRVSTREAMSSRC := $(CHIBIOS)/os/vfs/drivers/streams/drvstreams.c
# Required include directories
DRVSTREAMSINC := $(CHIBIOS)/os/vfs/drivers/streams
# Shared variables
ALLCSRC += $(DRVSTREAMSSRC)
ALLINC += $(DRVSTREAMSINC)

View File

@ -45,43 +45,41 @@
/*===========================================================================*/
/**
* @brief Type of a structure representing a VFS driver.
*/
typedef struct vfs_driver vfs_driver_t;
/**
* @brief @p vfs_node_t specific methods.
* @brief @p vfs_driver_t specific methods.
*/
#define __vfs_driver_methods \
_base_object_methods \
/* Returns a pointer to the driver name constant.*/ \
const char *(*get_name)(void); \
msg_t (*open_dir)(const char *path, vfs_directory_node_t **vdnpp); \
msg_t (*open_file)(const char *path, vfs_file_node_t **vfnpp);
msg_t (*open_dir)(void *instance, \
const char *path, \
vfs_directory_node_t **vdnpp); \
msg_t (*open_file)(void *instance, \
const char *path, \
vfs_file_node_t **vfnpp);
/**
* @brief @p vfs_node_t specific data.
* @brief @p vfs_driver_t specific data.
*/
#define __vfs_driver_data \
_base_object_data
_base_object_data \
const char *rootname;
/**
* @brief @p vfs_node_t virtual methods table.
* @brief @p vfs_driver_t virtual methods table.
*/
struct vfs_driver_vmt {
__vfs_driver_methods
};
/**
* @brief TStructure representing a VFS driver.
* @brief Type of a structure representing a VFS driver.
*/
struct vfs_driver {
typedef struct vfs_driver {
/**
* @brief Virtual Methods Table.
*/
const struct vfs_driver_vmt *vmt;
__vfs_driver_data
};
} vfs_driver_t;
/*===========================================================================*/
/* Module macros. */

View File

@ -55,7 +55,8 @@
#ifdef __cplusplus
extern "C" {
#endif
msg_t vfs_parse_separator(const char **pathp);
msg_t vfs_parse_match_separator(const char **pathp);
msg_t vfs_parse_match_end(const char **pathp);
msg_t vfs_parse_filename(const char **pathp, char *fname);
#ifdef __cplusplus
}

View File

@ -26,6 +26,7 @@
*/
#include <string.h>
#include <ctype.h>
#include "vfs.h"
@ -54,11 +55,11 @@
/*===========================================================================*/
/**
* @brief Parses a path separator.
* @brief Matches a path separator.
*
* @param[in, out] pathp pointer to the path under parsing
*/
msg_t vfs_parse_separator(const char **pathp) {
msg_t vfs_parse_match_separator(const char **pathp) {
msg_t err;
const char *p = *pathp;
@ -73,6 +74,24 @@ msg_t vfs_parse_separator(const char **pathp) {
return err;
}
/**
* @brief Matches a string end.
*
* @param[in, out] pathp pointer to the path under parsing
*/
msg_t vfs_parse_match_end(const char **pathp) {
msg_t err;
if (**pathp != '\0') {
err = VFS_RET_INVALID_PATH;
}
else {
err = VFS_RET_SUCCESS;
}
return err;
}
/**
* @brief Parses a filename element using the restricted Posix set.
* @note Consumes the next path separator, if any.

View File

@ -60,7 +60,7 @@ msg_t match_driver(const char **pathp, vfs_driver_t **vdpp) {
vfs_driver_t **pp;
do {
err = vfs_parse_separator(pathp);
err = vfs_parse_match_separator(pathp);
VFS_BREAK_ON_ERROR(err);
err = vfs_parse_filename(pathp, fname);
@ -69,7 +69,7 @@ msg_t match_driver(const char **pathp, vfs_driver_t **vdpp) {
/* Searching among registered drivers.*/
pp = &vfs.drivers[0];
while (pp < vfs.next_driver) {
if (strncmp(fname, (*pp)->vmt->get_name(), VFS_CFG_MAX_NAMELEN) == 0) {
if (strncmp(fname, (*pp)->rootname, VFS_CFG_MAX_NAMELEN) == 0) {
*vdpp = *pp;
return VFS_RET_SUCCESS;
}
@ -147,7 +147,7 @@ msg_t vfsOpenDirectory(const char *path, vfs_directory_node_t **vdnpp) {
err = match_driver(&path, &dp);
VFS_BREAK_ON_ERROR(err);
err = dp->vmt->open_dir(path, vdnpp);
err = dp->vmt->open_dir((void *)dp, path, vdnpp);
}
while (false);
@ -217,7 +217,7 @@ msg_t vfsOpenFile(const char *path, vfs_file_node_t **vfnpp) {
err = match_driver(&path, &dp);
VFS_BREAK_ON_ERROR(err);
err = dp->vmt->open_file(path, vfnpp);
err = dp->vmt->open_file((void *)dp, path, vfnpp);
}
while (false);