aboutsummaryrefslogtreecommitdiff
path: root/libiot/ramfs/ramfs.h
diff options
context:
space:
mode:
Diffstat (limited to 'libiot/ramfs/ramfs.h')
-rw-r--r--libiot/ramfs/ramfs.h274
1 files changed, 274 insertions, 0 deletions
diff --git a/libiot/ramfs/ramfs.h b/libiot/ramfs/ramfs.h
new file mode 100644
index 0000000..cde76cf
--- /dev/null
+++ b/libiot/ramfs/ramfs.h
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2015 - 2018, IBEROXARXA SERVICIOS INTEGRALES, S.L.
+ * Copyright (C) 2015 - 2018, Jaume Olivé Petrus (jolive@whitecatboard.org)
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of the <organization> nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ * * The WHITECAT logotype cannot be changed, you can remove it, but you
+ * cannot change it in any way. The WHITECAT logotype is:
+ *
+ * /\ /\
+ * / \_____/ \
+ * /_____________\
+ * W H I T E C A T
+ *
+ * * Redistributions in binary form must retain all copyright notices printed
+ * to any local or remote output device. This include any reference to
+ * Lua RTOS, whitecatboard.org, Lua, and other copyright notices that may
+ * appear in the future.
+ *
+ * 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 <COPYRIGHT HOLDER> 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.
+ *
+ * Lua RTOS, RAM file system
+ *
+ */
+
+/**
+ * @brief RAM file system (RAMFS)
+ *
+ * The RAMFS is a POSIX-compliance file system entirely stored in RAM, without
+ * persistence, which means that all the data stored in the file system is
+ * lost on each reboot.
+ *
+ * In RAMFS, the file system is stored in a tree structure, in which there are
+ * 2 types of nodes (entries): directories, and files.
+ *
+ * RAMFS structure overview:
+ *
+ * ----------
+ * - RAMFS -
+ * ----------
+ * |
+ * | child
+ * \|/
+ * ---------------- next ---------------- next ----------------
+ * - directory or - ------> - file - ------> - directory -
+ * - file entry - - entry - - entry -
+ * ---------------- ---------------- ----------------
+ * | |
+ * | header | child
+ * \|/ \|/
+ * --------------- ----------------
+ * - file header - - directory or -
+ * --------------- - file entry -
+ * | ----------------
+ * |
+ * \|/
+ * --------- next ---------
+ * - block - ----> - block -
+ * --------- ---------
+ */
+
+#ifndef _RAMFS_H_
+#define _RAMFS_H_
+
+#include <stdint.h>
+#include <stddef.h>
+#include <limits.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/mutex.h>
+
+#if PATH_MAX > 64
+#error "ramfs, PATH_MAX must be <= 64"
+#endif
+
+/*
+ * To use the file system in a multi-threaded environment,
+ * define the lock type (mutex) used in your platform.
+ */
+#define ramfs_lock_t struct mtx
+
+/*
+ * If ramfs_lock_t is defined, define the following macros:
+ *
+ * ramfs_lock_init(l): initialize / create the lock
+ * ramfs_lock_destroy(l): destroy the lock
+ * ramfs_lock(l): obtain the lock
+ * ramfs_unlock(l): release the lock
+ */
+#ifdef ramfs_lock_t
+#define ramfs_lock_init(l) \
+ mtx_init(&l, NULL, NULL, 0);
+
+#define ramfs_lock_destroy(l) \
+ mtx_destroy(&l);
+
+#define ramfs_lock(l) \
+ mtx_lock(&l);
+
+#define ramfs_unlock(l) \
+ mtx_unlock(&l);
+#else
+#define ramfs_lock_init()
+#define ramfs_lock_destroy()
+#define ramfs_lock()
+#define ramfs_unlock()
+#endif
+
+typedef int32_t ramfs_off_t;
+typedef int32_t ramfs_size_t;
+
+/**
+ * @brief File system entry flags.
+ *
+ * bit0..bit0: entry type
+ * bit1..bit6: length of the name of the entry
+ * bit7..bit7: entry is deleted from the file system, but not still removed
+ *
+ */
+typedef uint8_t ramfs_entry_flags_t;
+
+#define RAMFS_ENTRY_TYPE_MSK 0b00000001
+#define RAMFS_ENTRY_NAME_LEN_MSK 0b01111110
+#define RAMFS_ENTRY_NAME_LEN_POS 1
+#define RAMFS_ENTRY_RM_LEN_MSK 0b10000000
+
+typedef enum {
+ RAMFS_DIR = 0,
+ RAMFS_FILE = 1
+} ramfs_entry_type_t;
+
+typedef enum {
+ RAMFS_ERR_OK = 0,
+ RAMFS_ERR_NOMEM = -1,
+ RAMFS_ERR_NOENT = -2,
+ RAMFS_ERR_EXIST = -3,
+ RAMFS_ERR_NOTDIR = -4,
+ RAMFS_ERR_BADF = -5,
+ RAMFS_ERR_ACCESS = -6,
+ RAMFS_ERR_NOSPC = -7,
+ RAMFS_ERR_INVAL = -8,
+ RAMFS_ERR_ISDIR = -9,
+ RAMFS_ERR_NOTEMPTY = -10,
+ RAMFS_ERR_BUSY = -11,
+ RAMFS_ERR_PERM = -12,
+ RAMFS_ERR_NAMETOOLONG = -13,
+} ramfs_error_t;
+
+typedef enum {
+ RAMFS_O_RDONLY = 1, // Open a file as read only
+ RAMFS_O_WRONLY = 2, // Open a file as write only
+ RAMFS_O_RDWR = 3, // Open a file as read and write
+ RAMFS_O_CREAT = 0x0100, // Create a file if it does not exist
+ RAMFS_O_EXCL = 0x0200, // Fail if a file already exists
+ RAMFS_O_TRUNC = 0x0400, // Truncate the existing file to zero size
+ RAMFS_O_APPEND = 0x0800, // Move to end of file on every write
+} ramfs_flags_t;
+
+#define RAMFS_ACCMODE (RAMFS_O_RDONLY | RAMFS_O_WRONLY | RAMFS_O_RDWR)
+
+typedef enum {
+ RAMFS_SEEK_SET = 1,
+ RAMFS_SEEK_CUR = 2,
+ RAMFS_SEEK_END = 3,
+} ramfs_whence_t;
+
+typedef struct ramfs_block {
+ struct ramfs_block *next; /*!< Next block in chain */
+ uint8_t data[1]; /*!< Block data */
+} ramfs_block_t;
+
+typedef struct ram_file_header {
+ ramfs_block_t *head; /*!< File head */
+ ramfs_block_t *tail; /*!< File tail */
+ ramfs_size_t size; /*!< File size */
+} ram_file_header_t;
+
+typedef struct ramfs_entry {
+ ramfs_entry_flags_t flags; /*!< Entry flags */
+ struct ramfs_entry *next; /*!< Next entry */
+ union {
+ struct {
+ struct ram_file_header *header; /*!< File header */
+ } file;
+ struct {
+ struct ramfs_entry *child; /*!< Entry type */
+ } dir;
+ };
+ char name[1]; /*!< Entry name */
+} ramfs_entry_t;
+
+typedef struct {
+ ramfs_off_t offset; /*!< Current seek offset */
+ ramfs_entry_t *entry; /*!< Directory entry */
+ ramfs_entry_t *child; /*!< Directory child chain */
+} ramfs_dir_t;
+
+typedef struct {
+ ramfs_entry_t *entry; /*!< File entry reference */
+ uint32_t flags; /*!< Open flags */
+ ramfs_off_t offset; /*!< Current seek offset */
+ ramfs_block_t *block; /*!< Current read/write block */
+ uint8_t *ptr; /*!< Current read/write pointer into current block */
+} ramfs_file_t;
+
+typedef struct {
+ char name[PATH_MAX + 1];
+ ramfs_entry_type_t type;
+ ramfs_size_t size;
+} ramfs_info_t;
+
+typedef struct ramfs_entry_ref {
+ ramfs_entry_t *entry;
+ uint8_t uses;
+ struct ramfs_entry_ref *next;
+} ramfs_entry_ref_t;
+
+typedef struct {
+ ramfs_entry_t *child; /*!< Root directory child chain */
+ ramfs_entry_ref_t *ref; /*< Open references to file system entries */
+ ramfs_size_t size;
+ ramfs_size_t current_size;
+ ramfs_size_t block_size;
+#ifdef ramfs_lock_t
+ ramfs_lock_t lock;
+#endif
+} ramfs_t;
+
+typedef struct {
+ ramfs_size_t size;
+ ramfs_size_t block_size;
+} ramfs_config_t;
+
+int ramfs_mount(ramfs_t *fs, ramfs_config_t *config);
+int ramfs_umount(ramfs_t *fs);
+int ramfs_mkdir(ramfs_t *fs, const char *path);
+int ramfs_dir_open(ramfs_t *fs, ramfs_dir_t *dir, const char *path);
+int ramfs_dir_read(ramfs_t *fs, ramfs_dir_t *dir, ramfs_info_t *info);
+int ramfs_dir_close(ramfs_t *fs, ramfs_dir_t *dir);
+int ramfs_stat(ramfs_t *fs, const char *path, ramfs_info_t *info);
+int ramfs_file_open(ramfs_t *fs, ramfs_file_t *file, const char *path, int flags);
+int ramfs_file_sync(ramfs_t *fs, ramfs_file_t *file);
+ramfs_size_t ramfs_file_read(ramfs_t *fs, ramfs_file_t *file, void *buffer, ramfs_size_t size);
+ramfs_size_t ramfs_file_write(ramfs_t *fs, ramfs_file_t *file, const void *buffer, ramfs_size_t size);
+int ramfs_file_close(ramfs_t *fs, ramfs_file_t *file);
+ramfs_off_t ramfs_file_seek(ramfs_t *fs, ramfs_file_t *file, ramfs_off_t offset, ramfs_whence_t whence);
+int ramfs_rename(ramfs_t *fs, const char *oldpath, const char *newpath);
+int ramfs_rmdir(ramfs_t *fs, const char *path);
+int ramfs_unlink(ramfs_t *fs, const char *pathname);
+ramfs_off_t ramfs_telldir(ramfs_t *fs, ramfs_dir_t *dir);
+int ramfs_file_truncate(ramfs_t *fs, ramfs_file_t *file, ramfs_off_t size);
+int ramfs_file_stat(ramfs_t *fs, ramfs_file_t *file, ramfs_info_t *info);
+
+#endif /* _RAMFS_H_ */