From 6db77dc8bbae32ee15a17e7a5caa90f7e6191b2c Mon Sep 17 00:00:00 2001 From: Mark Charlebois Date: Wed, 6 May 2015 22:12:45 -0700 Subject: [PATCH] Experimental virtual file support QuRT does not have a filesystem, so creating a virtual filesystem that could be implemented as an in-memory file or a remote file over fastRPC. Signed-off-by: Mark Charlebois --- Tools/posix_apps.py | 7 +++ src/drivers/device/module.mk | 1 + src/drivers/device/vdev.cpp | 18 +++++++- src/drivers/device/vdev.h | 2 + src/drivers/device/vdev_posix.cpp | 32 +++++++++++-- src/drivers/device/vfile.cpp | 65 +++++++++++++++++++++++++++ src/drivers/device/vfile.h | 58 ++++++++++++++++++++++++ src/modules/systemlib/bson/tinybson.c | 7 +-- src/modules/systemlib/param/param.c | 10 +++-- src/platforms/px4_posix.h | 16 ++++--- src/systemcmds/param/param.c | 13 +++--- 11 files changed, 206 insertions(+), 23 deletions(-) create mode 100644 src/drivers/device/vfile.cpp create mode 100644 src/drivers/device/vfile.h diff --git a/Tools/posix_apps.py b/Tools/posix_apps.py index fe457e778e..375e71fc2d 100755 --- a/Tools/posix_apps.py +++ b/Tools/posix_apps.py @@ -61,6 +61,7 @@ for app in apps: print """ static int shutdown_main(int argc, char *argv[]); static int list_tasks_main(int argc, char *argv[]); +static int list_files_main(int argc, char *argv[]); static int list_devices_main(int argc, char *argv[]); static int list_topics_main(int argc, char *argv[]); } @@ -77,6 +78,7 @@ for app in apps: print '\tapps["shutdown"] = shutdown_main;' print '\tapps["list_tasks"] = list_tasks_main;' +print '\tapps["list_files"] = list_files_main;' print '\tapps["list_devices"] = list_devices_main;' print '\tapps["list_topics"] = list_topics_main;' print """ @@ -115,5 +117,10 @@ static int list_topics_main(int argc, char *argv[]) px4_show_topics(); return 0; } +static int list_files_main(int argc, char *argv[]) +{ + px4_show_files(); + return 0; +} """ diff --git a/src/drivers/device/module.mk b/src/drivers/device/module.mk index 22e7b15622..c206a5037c 100644 --- a/src/drivers/device/module.mk +++ b/src/drivers/device/module.mk @@ -47,6 +47,7 @@ else SRCS = \ device_posix.cpp \ vdev.cpp \ + vfile.cpp \ vdev_posix.cpp \ i2c_posix.cpp \ sim.cpp \ diff --git a/src/drivers/device/vdev.cpp b/src/drivers/device/vdev.cpp index 699bc817b1..25a5253cc0 100644 --- a/src/drivers/device/vdev.cpp +++ b/src/drivers/device/vdev.cpp @@ -64,7 +64,7 @@ private: px4_dev_t() {} }; -#define PX4_MAX_DEV 100 +#define PX4_MAX_DEV 30 static px4_dev_t *devmap[PX4_MAX_DEV]; /* @@ -448,8 +448,12 @@ VDev::remove_poll_waiter(px4_pollfd_struct_t *fds) VDev *VDev::getDev(const char *path) { + printf("VDev::getDev\n"); int i=0; for (; iname, path); + } if (devmap[i] && (strcmp(devmap[i]->name, path) == 0)) { return (VDev *)(devmap[i]->cdev); } @@ -479,6 +483,18 @@ void VDev::showTopics() } } +void VDev::showFiles() +{ + int i=0; + printf("Files:\n"); + for (; iname, "/obj/", 5) != 0 && + strncmp(devmap[i]->name, "/dev/", 5) != 0) { + printf(" %s\n", devmap[i]->name); + } + } +} + const char *VDev::topicList(unsigned int *next) { for (;*next #include #include "device.h" +#include "vfile.h" #include #include @@ -85,16 +86,26 @@ inline bool valid_fd(int fd) return (fd < PX4_MAX_FD && fd >= 0 && filemap[fd] != NULL); } -int px4_open(const char *path, int flags) +int px4_open(const char *path, int flags, ...) { + printf("px4_open\n"); VDev *dev = VDev::getDev(path); int ret = 0; int i; + mode_t mode; - if (!dev) { - ret = -EINVAL; + if (!dev && (flags & (PX4_F_WRONLY|PX4_F_CREAT)) != 0) + { + va_list p; + va_start(p, flags); + mode = va_arg(p, mode_t); + va_end(p); + + // Create the file + warnx("Creating virtual file %s\n", path); + dev = VFile::createFile(path, mode); } - else { + if (dev) { for (i=0; i + */ + +#include "vfile.h" +#include + +using namespace device; + +VFile::VFile(const char *fname, mode_t mode) : + VDev("vfile", fname) +{ +} + +VFile * VFile::createFile(const char *fname, mode_t mode) +{ + VFile *me = new VFile(fname, mode); + me->register_driver(fname, me); + return me; +} + +ssize_t VFile::write(device::file_t *handlep, const char *buffer, size_t buflen) +{ + // ignore what was written, but let pollers know something was written + poll_notify(POLLIN); + + return buflen; +} + diff --git a/src/drivers/device/vfile.h b/src/drivers/device/vfile.h new file mode 100644 index 0000000000..d7c5e15d7f --- /dev/null +++ b/src/drivers/device/vfile.h @@ -0,0 +1,58 @@ +/**************************************************************************** + * + * Copyright (C) 2015 Mark Charlebois. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file vfile.cpp + * Virtual file + * + * @author Mark Charlebois + */ + +#include +#include +#include "device.h" +#include +#include + +class VFile : public device::VDev { +public: + + static VFile *createFile(const char *fname, mode_t mode); + ~VFile() {} + + virtual ssize_t write(device::file_t *handlep, const char *buffer, size_t buflen); + +private: + VFile(const char *fname, mode_t mode); + VFile(const VFile &); +}; diff --git a/src/modules/systemlib/bson/tinybson.c b/src/modules/systemlib/bson/tinybson.c index 49403c98bd..5908ace6c7 100644 --- a/src/modules/systemlib/bson/tinybson.c +++ b/src/modules/systemlib/bson/tinybson.c @@ -37,6 +37,7 @@ * A simple subset SAX-style BSON parser and generator. */ +#include #include #include #include @@ -59,7 +60,7 @@ read_x(bson_decoder_t decoder, void *p, size_t s) CODER_CHECK(decoder); if (decoder->fd > -1) - return (read(decoder->fd, p, s) == (int)s) ? 0 : -1; + return (px4_read(decoder->fd, p, s) == (int)s) ? 0 : -1; if (decoder->buf != NULL) { /* staged operations to avoid integer overflow for corrupt data */ @@ -301,7 +302,7 @@ write_x(bson_encoder_t encoder, const void *p, size_t s) CODER_CHECK(encoder); if (encoder->fd > -1) - return (write(encoder->fd, p, s) == (int)s) ? 0 : -1; + return (px4_write(encoder->fd, p, s) == (int)s) ? 0 : -1; /* do we need to extend the buffer? */ while ((encoder->bufpos + s) > encoder->bufsize) { @@ -408,7 +409,7 @@ bson_encoder_fini(bson_encoder_t encoder) } /* sync file */ - fsync(encoder->fd); + px4_fsync(encoder->fd); return 0; } diff --git a/src/modules/systemlib/param/param.c b/src/modules/systemlib/param/param.c index 2b9a09b712..19e91b4b2f 100644 --- a/src/modules/systemlib/param/param.c +++ b/src/modules/systemlib/param/param.c @@ -43,6 +43,7 @@ //#include #include +#include #include #include #include @@ -684,7 +685,7 @@ param_save_default(void) const char *filename = param_get_default_file(); /* write parameters to temp file */ - fd = open(filename, O_WRONLY | O_CREAT, 0x777); + fd = px4_open(filename, O_WRONLY | O_CREAT, 0x777); if (fd < 0) { warn("failed to open param file: %s", filename); @@ -697,7 +698,7 @@ param_save_default(void) warnx("failed to write parameters to file: %s", filename); } - close(fd); + px4_close(fd); return res; } @@ -708,7 +709,8 @@ param_save_default(void) int param_load_default(void) { - int fd_load = open(param_get_default_file(), O_RDONLY); + warnx("param_load_default\n"); + int fd_load = px4_open(param_get_default_file(), O_RDONLY); if (fd_load < 0) { /* no parameter file is OK, otherwise this is an error */ @@ -720,7 +722,7 @@ param_load_default(void) } int result = param_load(fd_load); - close(fd_load); + px4_close(fd_load); if (result != 0) { warn("error reading parameters from '%s'", param_get_default_file()); diff --git a/src/platforms/px4_posix.h b/src/platforms/px4_posix.h index b891ab9982..67c9a47963 100644 --- a/src/platforms/px4_posix.h +++ b/src/platforms/px4_posix.h @@ -43,14 +43,16 @@ #include #include #include +#include #include #include -#define PX4_F_RDONLY 1 -#define PX4_F_WRONLY 2 #ifdef __PX4_NUTTX +#define PX4_F_RDONLY 1 +#define PX4_F_WRONLY 2 + typedef struct pollfd px4_pollfd_struct_t; #if defined(__cplusplus) @@ -64,11 +66,13 @@ typedef struct pollfd px4_pollfd_struct_t; #define px4_write _GLOBAL write #define px4_read _GLOBAL read #define px4_poll _GLOBAL poll +#define px4_fsync _GLOBAL fsync #elif defined(__PX4_POSIX) -#define PX4_F_RDONLY 1 -#define PX4_F_WRONLY 2 +#define PX4_F_RDONLY O_RDONLY +#define PX4_F_WRONLY O_WRONLY +#define PX4_F_CREAT O_CREAT typedef short pollevent_t; @@ -85,12 +89,13 @@ typedef struct { __BEGIN_DECLS -__EXPORT int px4_open(const char *path, int flags); +__EXPORT int px4_open(const char *path, int flags, ...); __EXPORT int px4_close(int fd); __EXPORT ssize_t px4_read(int fd, void *buffer, size_t buflen); __EXPORT ssize_t px4_write(int fd, const void *buffer, size_t buflen); __EXPORT int px4_ioctl(int fd, int cmd, unsigned long arg); __EXPORT int px4_poll(px4_pollfd_struct_t *fds, nfds_t nfds, int timeout); +__EXPORT int px4_fsync(int fd); __END_DECLS #else @@ -101,6 +106,7 @@ __BEGIN_DECLS extern int px4_errno; __EXPORT void px4_show_devices(void); +__EXPORT void px4_show_files(void); __EXPORT const char * px4_get_device_names(unsigned int *handle); __EXPORT void px4_show_topics(void); diff --git a/src/systemcmds/param/param.c b/src/systemcmds/param/param.c index 716a5b2d0b..20de5fd7a7 100644 --- a/src/systemcmds/param/param.c +++ b/src/systemcmds/param/param.c @@ -40,6 +40,7 @@ */ #include +#include #include #include @@ -182,7 +183,7 @@ static int do_save(const char *param_file_name) { /* create the file */ - int fd = open(param_file_name, O_WRONLY | O_CREAT, 0x777); + int fd = px4_open(param_file_name, O_WRONLY | O_CREAT, 0x777); if (fd < 0) { warn("opening '%s' failed", param_file_name); @@ -190,7 +191,7 @@ do_save(const char *param_file_name) } int result = param_export(fd, false); - close(fd); + px4_close(fd); if (result < 0) { (void)unlink(param_file_name); @@ -204,7 +205,7 @@ do_save(const char *param_file_name) static int do_load(const char *param_file_name) { - int fd = open(param_file_name, O_RDONLY); + int fd = px4_open(param_file_name, O_RDONLY); if (fd < 0) { warn("open '%s'", param_file_name); @@ -212,7 +213,7 @@ do_load(const char *param_file_name) } int result = param_load(fd); - close(fd); + px4_close(fd); if (result < 0) { warnx("error importing from '%s'", param_file_name); @@ -225,7 +226,7 @@ do_load(const char *param_file_name) static int do_import(const char *param_file_name) { - int fd = open(param_file_name, O_RDONLY); + int fd = px4_open(param_file_name, O_RDONLY); if (fd < 0) { warn("open '%s'", param_file_name); @@ -233,7 +234,7 @@ do_import(const char *param_file_name) } int result = param_import(fd); - close(fd); + px4_close(fd); if (result < 0) { warnx("error importing from '%s'", param_file_name);