Reworked error codes to be more HAL-like. Added a separate parser module.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15124 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2021-11-21 18:32:41 +00:00
parent 6bd121bd45
commit a61f93feb3
9 changed files with 248 additions and 99 deletions

View File

@ -79,6 +79,7 @@
/* Base VFS headers.*/
#include "vfserrors.h"
#include "vfsparser.h"
#include "vfsnodes.h"
#include "vfsdrivers.h"
#include "vfssystem.h"

View File

@ -56,8 +56,8 @@ typedef struct vfs_driver vfs_driver_t;
_base_object_methods \
/* Returns a pointer to the driver name constant.*/ \
const char *(*get_name)(void); \
vfserr_t (*open_dir)(const char *path, vfs_directory_node_t **vdnpp); \
vfserr_t (*open_file)(const char *path, vfs_file_node_t **vfnpp);
msg_t (*open_dir)(const char *path, vfs_directory_node_t **vdnpp); \
msg_t (*open_file)(const char *path, vfs_file_node_t **vfnpp);
/**
* @brief @p vfs_node_t specific data.

View File

@ -32,6 +32,18 @@
/* Module constants. */
/*===========================================================================*/
/**
* @brief Error codes compatible with @p msg_t
* @{
*/
#define VFS_RET_SUCCESS MSG_OK
#define VFS_RET_NO_RESOURCE (msg_t)-3
#define VFS_RET_NO_DRIVER (msg_t)-4
#define VFS_RET_INVALID_PATH (msg_t)-5
#define VFS_RET_NOT_FOUND (msg_t)-6
#define VFS_RET_EOF (msg_t)-7
/** @} */
/*===========================================================================*/
/* Module pre-compile time settings. */
/*===========================================================================*/
@ -44,22 +56,13 @@
/* Module data structures and types. */
/*===========================================================================*/
/**
* @brief Type of a VFS error code.
*/
typedef enum {
VFS_RET_SUCCESS = 0,
VFS_RET_NO_RESOURCE = -3,
VFS_RET_NO_DRIVER = -4,
VFS_RET_INVALID_PATH = -5,
VFS_RET_NOT_FOUND = -6,
VFS_RET_EOF = -7
} vfserr_t;
/*===========================================================================*/
/* Module macros. */
/*===========================================================================*/
#define VFS_BREAK_ON_ERROR(err) \
if ((err) < VFS_RET_SUCCESS) break
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/

View File

@ -87,7 +87,6 @@ typedef struct vfs_node_info {
char name[VFS_CFG_MAX_NAMELEN + 1];
} vfs_node_info_t;
/**
* @brief Type of a structure representing a generic VFS node.
*/
@ -151,8 +150,8 @@ typedef struct vfs_directory_node vfs_directory_node_t;
*/
struct vfs_directory_node_vmt {
__vfs_directory_node_methods \
vfserr_t (*dir_first)(void *instance); \
vfserr_t (*dir_next)(void *instance);
msg_t (*dir_first)(void *instance); \
msg_t (*dir_next)(void *instance);
};
/**
@ -176,9 +175,9 @@ typedef struct vfs_file_node vfs_file_node_t;
*/
#define __vfs_file_node_methods \
__vfs_node_methods \
vfserr_t (*file_read)(void *instance, char *buf, size_t n); \
vfserr_t (*file_write)(void *instance, const char *buf, size_t n); \
vfserr_t (*file_setpos)(void *instance, vfs_offset_t offset); \
msg_t (*file_read)(void *instance, uint8_t *buf, size_t n); \
msg_t (*file_write)(void *instance, const uint8_t *buf, size_t n); \
msg_t (*file_setpos)(void *instance, vfs_offset_t offset); \
vfs_offset_t (*file_getpos)(void *instance); \
vfs_offset_t (*file_getsize)(void *instance);

View File

@ -0,0 +1,66 @@
/*
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/include/vfsparser.h
* @brief VFS parser utilities header file.
*
* @addtogroup VFS_PARSE
* @{
*/
#ifndef VFSPARSE_H
#define VFSPARSE_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
msg_t vfs_parse_separator(const char **pathp);
msg_t vfs_parse_filename(const char **pathp, char *fname);
#ifdef __cplusplus
}
#endif
#endif /* VFSPARSE_H */
/** @} */

View File

@ -116,14 +116,14 @@ extern vfs_system_t vfs;
extern "C" {
#endif
void vfsInit(void);
vfserr_t vfsRegisterDriver(vfs_driver_t *vdp);
vfserr_t vfsOpenDirectory(const char *name, vfs_directory_node_t **vdnpp);
msg_t vfsRegisterDriver(vfs_driver_t *vdp);
msg_t vfsOpenDirectory(const char *name, vfs_directory_node_t **vdnpp);
void vfsCloseDirectory(vfs_directory_node_t *vdnp);
vfserr_t vfsOpenFile(const char *name, vfs_file_node_t **vfnpp);
msg_t vfsOpenFile(const char *name, vfs_file_node_t **vfnpp);
void vfsCloseFile(vfs_file_node_t *vfnp);
vfserr_t vfsReadFile(vfs_file_node_t *vfnp, char *buf, size_t n);
vfserr_t vfsWriteFile(vfs_file_node_t *vfnp, const char *buf, size_t n);
vfserr_t vfsSetFilePosition(vfs_file_node_t *vfnp, vfs_offset_t offset);
msg_t vfsReadFile(vfs_file_node_t *vfnp, uint8_t *buf, size_t n);
msg_t vfsWriteFile(vfs_file_node_t *vfnp, const uint8_t *buf, size_t n);
msg_t vfsSetFilePosition(vfs_file_node_t *vfnp, vfs_offset_t offset);
vfs_offset_t vfsGetFilePosition(vfs_file_node_t *vfnp);
vfs_offset_t vfsGetFileSize(vfs_file_node_t *vfnp);
#ifdef __cplusplus

99
os/vfs/src/vfsparser.c Normal file
View File

@ -0,0 +1,99 @@
/*
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/src/chparser.c
* @brief VFS parser utilities code.
*
* @addtogroup VFS_PARSE
* @{
*/
#include <string.h>
#include "vfs.h"
/*===========================================================================*/
/* Module local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Module exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local types. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Module exported functions. */
/*===========================================================================*/
msg_t vfs_parse_separator(const char **pathp) {
msg_t err;
const char *p = *pathp;
if (*p++ != '/') {
err = VFS_RET_INVALID_PATH;
}
else {
err = VFS_RET_SUCCESS;
*pathp = p;
}
return err;
}
msg_t vfs_parse_filename(const char **pathp, char *fname) {
msg_t err;
size_t n;
const char *p = *pathp;
n = 0U;
while (true) {
char c = *p++;
if ((c == '\0') || (c == '/')) {
*pathp = p;
*fname = '\0';
err = VFS_RET_SUCCESS;
break;
}
if (n > VFS_CFG_MAX_NAMELEN) {
err = VFS_RET_INVALID_PATH;
break;
}
*fname++ = c;
n++;
}
return err;
}
/** @} */

View File

@ -33,9 +33,6 @@
/* Module local definitions. */
/*===========================================================================*/
#define BREAK_ON_ERROR(err) \
if ((err) < VFS_RET_SUCCESS) break
/*===========================================================================*/
/* Module exported variables. */
/*===========================================================================*/
@ -57,60 +54,17 @@ vfs_system_t vfs;
/* Module local functions. */
/*===========================================================================*/
vfserr_t vfs_match_separator(const char **pathp) {
vfserr_t err;
const char *p = *pathp;
if (*p++ != '/') {
err = VFS_RET_INVALID_PATH;
}
else {
err = VFS_RET_SUCCESS;
*pathp = p;
}
return err;
}
vfserr_t vfs_match_filename(const char **pathp, char *fname) {
vfserr_t err;
size_t n;
const char *p = *pathp;
n = 0U;
while (true) {
char c = *p++;
if ((c == '\0') || (c == '/')) {
*pathp = p;
*fname = '\0';
err = VFS_RET_SUCCESS;
break;
}
if (n > VFS_CFG_MAX_NAMELEN) {
err = VFS_RET_INVALID_PATH;
break;
}
*fname++ = c;
n++;
}
return err;
}
vfserr_t vfs_match_driver(const char **pathp, vfs_driver_t **vdpp) {
msg_t match_driver(const char **pathp, vfs_driver_t **vdpp) {
char fname[VFS_CFG_MAX_NAMELEN + 1];
vfserr_t err;
msg_t err;
vfs_driver_t **pp;
do {
err = vfs_match_separator(pathp);
BREAK_ON_ERROR(err);
err = vfs_parse_separator(pathp);
VFS_BREAK_ON_ERROR(err);
err = vfs_match_filename(pathp, fname);
BREAK_ON_ERROR(err);
err = vfs_parse_filename(pathp, fname);
VFS_BREAK_ON_ERROR(err);
/* Searching among registered drivers.*/
pp = &vfs.drivers[0];
@ -154,9 +108,11 @@ void vfsInit(void) {
*
* @param[in] vdp pointer to a @p vfs_driver_t structure
* @return The operation result.
*
* @api
*/
vfserr_t vfsRegisterDriver(vfs_driver_t *vdp) {
vfserr_t err;
msg_t vfsRegisterDriver(vfs_driver_t *vdp) {
msg_t err;
VFS_LOCK();
@ -180,14 +136,16 @@ vfserr_t vfsRegisterDriver(vfs_driver_t *vdp) {
* @param[out] vdnpp pointer to the pointer to the instantiated
* @p vfs_directory_node_t object
* @return The operation result.
*
* @api
*/
vfserr_t vfsOpenDirectory(const char *path, vfs_directory_node_t **vdnpp) {
vfserr_t err;
msg_t vfsOpenDirectory(const char *path, vfs_directory_node_t **vdnpp) {
msg_t err;
vfs_driver_t *dp;
do {
err = vfs_match_driver(&path, &dp);
BREAK_ON_ERROR(err);
err = match_driver(&path, &dp);
VFS_BREAK_ON_ERROR(err);
err = dp->vmt->open_dir(path, vdnpp);
}
@ -201,22 +159,40 @@ vfserr_t vfsOpenDirectory(const char *path, vfs_directory_node_t **vdnpp) {
*
* @param[in] vdnp the pointer to the @p vfs_directory_node_t object
* to be released
*
* @api
*/
void vfsCloseDirectory(vfs_directory_node_t *vdnp) {
vdnp->vmt->release((void *)vdnp);
}
vfserr_t vfsGetDirectoryFirst(vfs_directory_node_t *vdnp) {
vfserr_t err = VFS_RET_EOF;
/**
* @brief First directory entry.
*
* @param[in] vdnp the pointer to the @p vfs_directory_node_t object
* @return The operation result.
*
* @api
*/
msg_t vfsGetDirectoryFirst(vfs_directory_node_t *vdnp) {
msg_t err = VFS_RET_EOF;
(void)vdnp;
return err;
}
vfserr_t vfsGetDirectoryNext(vfs_directory_node_t *vdnp) {
vfserr_t err = VFS_RET_EOF;
/**
* @brief Next directory entry.
*
* @param[in] vdnp the pointer to the @p vfs_directory_node_t object
* @return The operation result.
*
* @api
*/
msg_t vfsGetDirectoryNext(vfs_directory_node_t *vdnp) {
msg_t err = VFS_RET_EOF;
(void)vdnp;
@ -230,14 +206,16 @@ vfserr_t vfsGetDirectoryNext(vfs_directory_node_t *vdnp) {
* @param[out] vdnpp pointer to the pointer to the instantiated
* @p vfs_file_node_t object
* @return The operation result.
*
* @api
*/
vfserr_t vfsOpenFile(const char *path, vfs_file_node_t **vfnpp) {
vfserr_t err;
msg_t vfsOpenFile(const char *path, vfs_file_node_t **vfnpp) {
msg_t err;
vfs_driver_t *dp;
do {
err = vfs_match_driver(&path, &dp);
BREAK_ON_ERROR(err);
err = match_driver(&path, &dp);
VFS_BREAK_ON_ERROR(err);
err = dp->vmt->open_file(path, vfnpp);
}
@ -251,6 +229,8 @@ vfserr_t vfsOpenFile(const char *path, vfs_file_node_t **vfnpp) {
*
* @param[in] vfnp the pointer to the @p vfs_file_node_t object
* to be released
*
* @api
*/
void vfsCloseFile(vfs_file_node_t *vfnp) {
@ -268,8 +248,8 @@ void vfsCloseFile(vfs_file_node_t *vfnp) {
*
* @api
*/
vfserr_t vfsReadFile(vfs_file_node_t *vfnp, char *buf, size_t n) {
vfserr_t err = VFS_RET_SUCCESS;
msg_t vfsReadFile(vfs_file_node_t *vfnp, uint8_t *buf, size_t n) {
msg_t err = VFS_RET_SUCCESS;
(void)vfnp;
(void)buf;
@ -289,8 +269,8 @@ vfserr_t vfsReadFile(vfs_file_node_t *vfnp, char *buf, size_t n) {
*
* @api
*/
vfserr_t vfsWriteFile(vfs_file_node_t *vfnp, const char *buf, size_t n) {
vfserr_t err = VFS_RET_SUCCESS;
msg_t vfsWriteFile(vfs_file_node_t *vfnp, const uint8_t *buf, size_t n) {
msg_t err = VFS_RET_SUCCESS;
(void)vfnp;
(void)buf;
@ -308,8 +288,8 @@ vfserr_t vfsWriteFile(vfs_file_node_t *vfnp, const char *buf, size_t n) {
*
* @api
*/
vfserr_t vfsSetFilePosition(vfs_file_node_t *vfnp, vfs_offset_t offset) {
vfserr_t err = VFS_RET_SUCCESS;
msg_t vfsSetFilePosition(vfs_file_node_t *vfnp, vfs_offset_t offset) {
msg_t err = VFS_RET_SUCCESS;
(void)vfnp;
(void)offset;

View File

@ -1,5 +1,6 @@
# List of all the ChibiOS/VFS files.
VFSSRC := $(CHIBIOS)/os/vfs/src/vfssystem.c
VFSSRC := $(CHIBIOS)/os/vfs/src/vfsparser.c \
$(CHIBIOS)/os/vfs/src/vfssystem.c
# Required include directories
VFSINC := $(CHIBIOS)/os/vfs/include