mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-12-27 10:34:08 +08:00
880 lines
32 KiB
C
880 lines
32 KiB
C
//-----------------------------------------------------------------------------
|
|
// Borrowed initially from https://github.com/pellepl/spiffs
|
|
// Copyright (c) 2013-2017 Peter Andersson (pelleplutt1976 at gmail.com)
|
|
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
|
|
//
|
|
// This program 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, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program 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.
|
|
//
|
|
// See LICENSE.txt for the text of the license.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#ifndef SPIFFS_H_
|
|
#define SPIFFS_H_
|
|
#if defined(__cplusplus)
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include "spiffs_config.h"
|
|
|
|
typedef enum spiffs_safety_level {
|
|
RDV40_SPIFFS_SAFETY_NORMAL,
|
|
RDV40_SPIFFS_SAFETY_LAZY,
|
|
RDV40_SPIFFS_SAFETY_SAFE
|
|
} RDV40SpiFFSSafetyLevel;
|
|
|
|
typedef enum spiffs_file_type {
|
|
RDV40_SPIFFS_FILETYPE_REAL,
|
|
RDV40_SPIFFS_FILETYPE_SYMLINK,
|
|
RDV40_SPIFFS_FILETYPE_BOTH,
|
|
RDV40_SPIFFS_FILETYPE_UNKNOWN
|
|
} RDV40SpiFFSFileType;
|
|
|
|
typedef struct rdv40_spiffs_fsinfo {
|
|
uint32_t blockSize;
|
|
uint32_t pageSize;
|
|
uint32_t maxOpenFiles;
|
|
uint32_t maxPathLength;
|
|
uint32_t totalBytes, usedBytes, freeBytes;
|
|
uint32_t usedPercent, freePercent;
|
|
} rdv40_spiffs_fsinfo;
|
|
|
|
int rdv40_spiffs_read_as_filetype(const char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level);
|
|
|
|
int rdv40_spiffs_check(void);
|
|
int rdv40_spiffs_lazy_unmount(void);
|
|
int rdv40_spiffs_lazy_mount(void);
|
|
int rdv40_spiffs_lazy_mount_rollback(int changed);
|
|
int rdv40_spiffs_write(const char *filename, const uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level);
|
|
int rdv40_spiffs_read(const char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level);
|
|
int rdv40_spiffs_rename(const char *old_filename, const char *new_filename, RDV40SpiFFSSafetyLevel level);
|
|
int rdv40_spiffs_remove(const char *filename, RDV40SpiFFSSafetyLevel level);
|
|
int rdv40_spiffs_read_as_symlink(const char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level);
|
|
void write_to_spiffs(const char *filename, const uint8_t *src, uint32_t size);
|
|
void read_from_spiffs(const char *filename, uint8_t *dst, uint32_t size);
|
|
void test_spiffs(void);
|
|
void rdv40_spiffs_safe_print_tree(void);
|
|
int rdv40_spiffs_unmount(void);
|
|
int rdv40_spiffs_mount(void);
|
|
int rdv40_spiffs_is_symlink(const char *s);
|
|
void rdv40_spiffs_safe_print_fsinfo(void);
|
|
int rdv40_spiffs_make_symlink(const char *linkdest, const char *filename, RDV40SpiFFSSafetyLevel level);
|
|
void append_to_spiffs(const char *filename, const uint8_t *src, uint32_t size);
|
|
int rdv40_spiffs_copy(const char *src_filename, const char *dst_filename, RDV40SpiFFSSafetyLevel level);
|
|
int rdv40_spiffs_append(const char *filename, const uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level);
|
|
int rdv40_spiffs_stat(const char *filename, uint32_t *size_in_bytes, RDV40SpiFFSSafetyLevel level);
|
|
uint32_t size_in_spiffs(const char *filename);
|
|
int exists_in_spiffs(const char *filename);
|
|
|
|
void rdv40_spiffs_safe_wipe(void);
|
|
|
|
#define SPIFFS_OK 0
|
|
#define SPIFFS_ERR_NOT_MOUNTED -10000
|
|
#define SPIFFS_ERR_FULL -10001
|
|
#define SPIFFS_ERR_NOT_FOUND -10002
|
|
#define SPIFFS_ERR_END_OF_OBJECT -10003
|
|
#define SPIFFS_ERR_DELETED -10004
|
|
#define SPIFFS_ERR_NOT_FINALIZED -10005
|
|
#define SPIFFS_ERR_NOT_INDEX -10006
|
|
#define SPIFFS_ERR_OUT_OF_FILE_DESCS -10007
|
|
#define SPIFFS_ERR_FILE_CLOSED -10008
|
|
#define SPIFFS_ERR_FILE_DELETED -10009
|
|
#define SPIFFS_ERR_BAD_DESCRIPTOR -10010
|
|
#define SPIFFS_ERR_IS_INDEX -10011
|
|
#define SPIFFS_ERR_IS_FREE -10012
|
|
#define SPIFFS_ERR_INDEX_SPAN_MISMATCH -10013
|
|
#define SPIFFS_ERR_DATA_SPAN_MISMATCH -10014
|
|
#define SPIFFS_ERR_INDEX_REF_FREE -10015
|
|
#define SPIFFS_ERR_INDEX_REF_LU -10016
|
|
#define SPIFFS_ERR_INDEX_REF_INVALID -10017
|
|
#define SPIFFS_ERR_INDEX_FREE -10018
|
|
#define SPIFFS_ERR_INDEX_LU -10019
|
|
#define SPIFFS_ERR_INDEX_INVALID -10020
|
|
#define SPIFFS_ERR_NOT_WRITABLE -10021
|
|
#define SPIFFS_ERR_NOT_READABLE -10022
|
|
#define SPIFFS_ERR_CONFLICTING_NAME -10023
|
|
#define SPIFFS_ERR_NOT_CONFIGURED -10024
|
|
|
|
#define SPIFFS_ERR_NOT_A_FS -10025
|
|
#define SPIFFS_ERR_MOUNTED -10026
|
|
#define SPIFFS_ERR_ERASE_FAIL -10027
|
|
#define SPIFFS_ERR_MAGIC_NOT_POSSIBLE -10028
|
|
|
|
#define SPIFFS_ERR_NO_DELETED_BLOCKS -10029
|
|
|
|
#define SPIFFS_ERR_FILE_EXISTS -10030
|
|
|
|
#define SPIFFS_ERR_NOT_A_FILE -10031
|
|
#define SPIFFS_ERR_RO_NOT_IMPL -10032
|
|
#define SPIFFS_ERR_RO_ABORTED_OPERATION -10033
|
|
#define SPIFFS_ERR_PROBE_TOO_FEW_BLOCKS -10034
|
|
#define SPIFFS_ERR_PROBE_NOT_A_FS -10035
|
|
#define SPIFFS_ERR_NAME_TOO_LONG -10036
|
|
|
|
#define SPIFFS_ERR_IX_MAP_UNMAPPED -10037
|
|
#define SPIFFS_ERR_IX_MAP_MAPPED -10038
|
|
#define SPIFFS_ERR_IX_MAP_BAD_RANGE -10039
|
|
|
|
#define SPIFFS_ERR_SEEK_BOUNDS -10040
|
|
|
|
|
|
#define SPIFFS_ERR_INTERNAL -10050
|
|
|
|
#define SPIFFS_ERR_TEST -10100
|
|
|
|
// Amount of data to write/append to a file in one go.
|
|
#define SPIFFS_WRITE_CHUNK_SIZE 8192
|
|
|
|
// spiffs file descriptor index type. must be signed
|
|
typedef s16_t spiffs_file;
|
|
// spiffs file descriptor flags
|
|
typedef u16_t spiffs_flags;
|
|
// spiffs file mode
|
|
typedef u16_t spiffs_mode;
|
|
// object type
|
|
typedef u8_t spiffs_obj_type;
|
|
|
|
struct spiffs_t;
|
|
|
|
#if SPIFFS_HAL_CALLBACK_EXTRA
|
|
|
|
/* spi read call function type */
|
|
typedef s32_t (*spiffs_read)(struct spiffs_t *fs, u32_t addr, u32_t size, u8_t *dst);
|
|
/* spi write call function type */
|
|
typedef s32_t (*spiffs_write)(struct spiffs_t *fs, u32_t addr, u32_t size, u8_t *src);
|
|
/* spi erase call function type */
|
|
typedef s32_t (*spiffs_erase)(struct spiffs_t *fs, u32_t addr, u32_t size);
|
|
|
|
#else // SPIFFS_HAL_CALLBACK_EXTRA
|
|
|
|
/* spi read call function type */
|
|
typedef s32_t (*spiffs_read)(u32_t addr, u32_t size, u8_t *dst);
|
|
/* spi write call function type */
|
|
typedef s32_t (*spiffs_write)(u32_t addr, u32_t size, u8_t *src);
|
|
/* spi erase call function type */
|
|
typedef s32_t (*spiffs_erase)(u32_t addr, u32_t size);
|
|
#endif // SPIFFS_HAL_CALLBACK_EXTRA
|
|
|
|
/* file system check callback report operation */
|
|
typedef enum {
|
|
SPIFFS_CHECK_LOOKUP = 0,
|
|
SPIFFS_CHECK_INDEX,
|
|
SPIFFS_CHECK_PAGE
|
|
} spiffs_check_type;
|
|
|
|
/* file system check callback report type */
|
|
typedef enum {
|
|
SPIFFS_CHECK_PROGRESS = 0,
|
|
SPIFFS_CHECK_ERROR,
|
|
SPIFFS_CHECK_FIX_INDEX,
|
|
SPIFFS_CHECK_FIX_LOOKUP,
|
|
SPIFFS_CHECK_DELETE_ORPHANED_INDEX,
|
|
SPIFFS_CHECK_DELETE_PAGE,
|
|
SPIFFS_CHECK_DELETE_BAD_FILE
|
|
} spiffs_check_report;
|
|
|
|
/* file system check callback function */
|
|
#if SPIFFS_HAL_CALLBACK_EXTRA
|
|
typedef void (*spiffs_check_callback)(struct spiffs_t *fs, spiffs_check_type type, spiffs_check_report report,
|
|
u32_t arg1, u32_t arg2);
|
|
#else // SPIFFS_HAL_CALLBACK_EXTRA
|
|
typedef void (*spiffs_check_callback)(spiffs_check_type type, spiffs_check_report report,
|
|
u32_t arg1, u32_t arg2);
|
|
#endif // SPIFFS_HAL_CALLBACK_EXTRA
|
|
|
|
/* file system listener callback operation */
|
|
typedef enum {
|
|
/* the file has been created */
|
|
SPIFFS_CB_CREATED = 0,
|
|
/* the file has been updated or moved to another page */
|
|
SPIFFS_CB_UPDATED,
|
|
/* the file has been deleted */
|
|
SPIFFS_CB_DELETED
|
|
} spiffs_fileop_type;
|
|
|
|
/* file system listener callback function */
|
|
typedef void (*spiffs_file_callback)(struct spiffs_t *fs, spiffs_fileop_type op, spiffs_obj_id obj_id, spiffs_page_ix pix);
|
|
|
|
#ifndef SPIFFS_DBG
|
|
#define SPIFFS_DBG(...) \
|
|
Dbprintf(__VA_ARGS__)
|
|
#endif
|
|
#ifndef SPIFFS_GC_DBG
|
|
#define SPIFFS_GC_DBG(...) Dbprintf(__VA_ARGS__)
|
|
#endif
|
|
#ifndef SPIFFS_CACHE_DBG
|
|
#define SPIFFS_CACHE_DBG(...) Dbprintf(__VA_ARGS__)
|
|
#endif
|
|
#ifndef SPIFFS_CHECK_DBG
|
|
#define SPIFFS_CHECK_DBG(...) Dbprintf(__VA_ARGS__)
|
|
#endif
|
|
|
|
/* Any write to the filehandle is appended to end of the file */
|
|
#define SPIFFS_APPEND (1<<0)
|
|
#define SPIFFS_O_APPEND SPIFFS_APPEND
|
|
/* If the opened file exists, it will be truncated to zero length before opened */
|
|
#define SPIFFS_TRUNC (1<<1)
|
|
#define SPIFFS_O_TRUNC SPIFFS_TRUNC
|
|
/* If the opened file does not exist, it will be created before opened */
|
|
#define SPIFFS_CREAT (1<<2)
|
|
#define SPIFFS_O_CREAT SPIFFS_CREAT
|
|
/* The opened file may only be read */
|
|
#define SPIFFS_RDONLY (1<<3)
|
|
#define SPIFFS_O_RDONLY SPIFFS_RDONLY
|
|
/* The opened file may only be written */
|
|
#define SPIFFS_WRONLY (1<<4)
|
|
#define SPIFFS_O_WRONLY SPIFFS_WRONLY
|
|
/* The opened file may be both read and written */
|
|
#define SPIFFS_RDWR (SPIFFS_RDONLY | SPIFFS_WRONLY)
|
|
#define SPIFFS_O_RDWR SPIFFS_RDWR
|
|
/* Any writes to the filehandle will never be cached but flushed directly */
|
|
#define SPIFFS_DIRECT (1<<5)
|
|
#define SPIFFS_O_DIRECT SPIFFS_DIRECT
|
|
/* If SPIFFS_O_CREAT and SPIFFS_O_EXCL are set, SPIFFS_open() shall fail if the file exists */
|
|
#define SPIFFS_EXCL (1<<6)
|
|
#define SPIFFS_O_EXCL SPIFFS_EXCL
|
|
|
|
#define SPIFFS_SEEK_SET (0)
|
|
#define SPIFFS_SEEK_CUR (1)
|
|
#define SPIFFS_SEEK_END (2)
|
|
|
|
#define SPIFFS_TYPE_FILE (1)
|
|
#define SPIFFS_TYPE_DIR (2)
|
|
#define SPIFFS_TYPE_HARD_LINK (3)
|
|
#define SPIFFS_TYPE_SOFT_LINK (4)
|
|
|
|
#ifndef SPIFFS_LOCK
|
|
#define SPIFFS_LOCK(fs)
|
|
#endif
|
|
|
|
#ifndef SPIFFS_UNLOCK
|
|
#define SPIFFS_UNLOCK(fs)
|
|
#endif
|
|
|
|
// phys structs
|
|
|
|
// spiffs spi configuration struct
|
|
typedef struct {
|
|
// physical read function
|
|
spiffs_read hal_read_f;
|
|
// physical write function
|
|
spiffs_write hal_write_f;
|
|
// physical erase function
|
|
spiffs_erase hal_erase_f;
|
|
#if SPIFFS_SINGLETON == 0
|
|
// physical size of the spi flash
|
|
u32_t phys_size;
|
|
// physical offset in spi flash used for spiffs,
|
|
// must be on block boundary
|
|
u32_t phys_addr;
|
|
// physical size when erasing a block
|
|
u32_t phys_erase_block;
|
|
|
|
// logical size of a block, must be on physical
|
|
// block size boundary and must never be less than
|
|
// a physical block
|
|
u32_t log_block_size;
|
|
// logical size of a page, must be at least
|
|
// log_block_size / 8
|
|
u32_t log_page_size;
|
|
|
|
#endif
|
|
#if SPIFFS_FILEHDL_OFFSET
|
|
// an integer offset added to each file handle
|
|
u16_t fh_ix_offset;
|
|
#endif
|
|
} spiffs_config;
|
|
|
|
typedef struct spiffs_t {
|
|
// file system configuration
|
|
spiffs_config cfg;
|
|
// number of logical blocks
|
|
u32_t block_count;
|
|
|
|
// cursor for free blocks, block index
|
|
spiffs_block_ix free_cursor_block_ix;
|
|
// cursor for free blocks, entry index
|
|
int free_cursor_obj_lu_entry;
|
|
// cursor when searching, block index
|
|
spiffs_block_ix cursor_block_ix;
|
|
// cursor when searching, entry index
|
|
int cursor_obj_lu_entry;
|
|
|
|
// primary work buffer, size of a logical page
|
|
u8_t *lu_work;
|
|
// secondary work buffer, size of a logical page
|
|
u8_t *work;
|
|
// file descriptor memory area
|
|
u8_t *fd_space;
|
|
// available file descriptors
|
|
u32_t fd_count;
|
|
|
|
// last error
|
|
s32_t err_code;
|
|
|
|
// current number of free blocks
|
|
u32_t free_blocks;
|
|
// current number of busy pages
|
|
u32_t stats_p_allocated;
|
|
// current number of deleted pages
|
|
u32_t stats_p_deleted;
|
|
// flag indicating that garbage collector is cleaning
|
|
u8_t cleaning;
|
|
// max erase count amongst all blocks
|
|
spiffs_obj_id max_erase_count;
|
|
|
|
#if SPIFFS_GC_STATS
|
|
u32_t stats_gc_runs;
|
|
#endif
|
|
|
|
#if SPIFFS_CACHE
|
|
// cache memory
|
|
void *cache;
|
|
// cache size
|
|
u32_t cache_size;
|
|
#if SPIFFS_CACHE_STATS
|
|
u32_t cache_hits;
|
|
u32_t cache_misses;
|
|
#endif
|
|
#endif
|
|
|
|
// check callback function
|
|
spiffs_check_callback check_cb_f;
|
|
// file callback function
|
|
spiffs_file_callback file_cb_f;
|
|
// mounted flag
|
|
u8_t mounted;
|
|
// user data
|
|
void *user_data;
|
|
// config magic
|
|
u32_t config_magic;
|
|
} spiffs;
|
|
|
|
/* spiffs file status struct */
|
|
typedef struct {
|
|
spiffs_obj_id obj_id;
|
|
u32_t size;
|
|
spiffs_obj_type type;
|
|
spiffs_page_ix pix;
|
|
u8_t name[SPIFFS_OBJ_NAME_LEN];
|
|
#if SPIFFS_OBJ_META_LEN
|
|
u8_t meta[SPIFFS_OBJ_META_LEN];
|
|
#endif
|
|
} spiffs_stat;
|
|
|
|
struct spiffs_dirent {
|
|
spiffs_obj_id obj_id;
|
|
u8_t name[SPIFFS_OBJ_NAME_LEN];
|
|
spiffs_obj_type type;
|
|
u32_t size;
|
|
spiffs_page_ix pix;
|
|
#if SPIFFS_OBJ_META_LEN
|
|
u8_t meta[SPIFFS_OBJ_META_LEN];
|
|
#endif
|
|
};
|
|
|
|
typedef struct {
|
|
spiffs *fs;
|
|
spiffs_block_ix block;
|
|
int entry;
|
|
} spiffs_DIR;
|
|
|
|
#if SPIFFS_IX_MAP
|
|
|
|
typedef struct {
|
|
// buffer with looked up data pixes
|
|
spiffs_page_ix *map_buf;
|
|
// precise file byte offset
|
|
u32_t offset;
|
|
// start data span index of lookup buffer
|
|
spiffs_span_ix start_spix;
|
|
// end data span index of lookup buffer
|
|
spiffs_span_ix end_spix;
|
|
} spiffs_ix_map;
|
|
|
|
#endif
|
|
|
|
// functions
|
|
|
|
#if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0
|
|
/**
|
|
* Special function. This takes a spiffs config struct and returns the number
|
|
* of blocks this file system was formatted with. This function relies on
|
|
* that following info is set correctly in given config struct:
|
|
*
|
|
* phys_addr, log_page_size, and log_block_size.
|
|
*
|
|
* Also, hal_read_f must be set in the config struct.
|
|
*
|
|
* One must be sure of the correct page size and that the physical address is
|
|
* correct in the probed file system when calling this function. It is not
|
|
* checked if the phys_addr actually points to the start of the file system,
|
|
* so one might get a false positive if entering a phys_addr somewhere in the
|
|
* middle of the file system at block boundary. In addition, it is not checked
|
|
* if the page size is actually correct. If it is not, weird file system sizes
|
|
* will be returned.
|
|
*
|
|
* If this function detects a file system it returns the assumed file system
|
|
* size, which can be used to set the phys_size.
|
|
*
|
|
* Otherwise, it returns an error indicating why it is not regarded as a file
|
|
* system.
|
|
*
|
|
* Note: this function is not protected with SPIFFS_LOCK and SPIFFS_UNLOCK
|
|
* macros. It returns the error code directly, instead of as read by
|
|
* SPIFFS_errno.
|
|
*
|
|
* @param config essential parts of the physical and logical
|
|
* configuration of the file system.
|
|
*/
|
|
s32_t SPIFFS_probe_fs(spiffs_config *config);
|
|
#endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0
|
|
|
|
/**
|
|
* Initializes the file system dynamic parameters and mounts the filesystem.
|
|
* If SPIFFS_USE_MAGIC is enabled the mounting may fail with SPIFFS_ERR_NOT_A_FS
|
|
* if the flash does not contain a recognizable file system.
|
|
* In this case, SPIFFS_format must be called prior to remounting.
|
|
* @param fs the file system struct
|
|
* @param config the physical and logical configuration of the file system
|
|
* @param work a memory work buffer comprising 2*config->log_page_size
|
|
* bytes used throughout all file system operations
|
|
* @param fd_space memory for file descriptors
|
|
* @param fd_space_size memory size of file descriptors
|
|
* @param cache memory for cache, may be null
|
|
* @param cache_size memory size of cache
|
|
* @param check_cb_f callback function for reporting during consistency checks
|
|
*/
|
|
s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work,
|
|
u8_t *fd_space, u32_t fd_space_size,
|
|
void *cache, u32_t cache_size,
|
|
spiffs_check_callback check_cb_f);
|
|
|
|
/**
|
|
* Unmounts the file system. All file handles will be flushed of any
|
|
* cached writes and closed.
|
|
* @param fs the file system struct
|
|
*/
|
|
void SPIFFS_unmount(spiffs *fs);
|
|
|
|
/**
|
|
* Creates a new file.
|
|
* @param fs the file system struct
|
|
* @param path the path of the new file
|
|
* @param mode ignored, for posix compliance
|
|
*/
|
|
s32_t SPIFFS_creat(spiffs *fs, const char *path, spiffs_mode mode);
|
|
|
|
/**
|
|
* Opens/creates a file.
|
|
* @param fs the file system struct
|
|
* @param path the path of the new file
|
|
* @param flags the flags for the open command, can be combinations of
|
|
* SPIFFS_O_APPEND, SPIFFS_O_TRUNC, SPIFFS_O_CREAT, SPIFFS_O_RDONLY,
|
|
* SPIFFS_O_WRONLY, SPIFFS_O_RDWR, SPIFFS_O_DIRECT, SPIFFS_O_EXCL
|
|
* @param mode ignored, for posix compliance
|
|
*/
|
|
spiffs_file SPIFFS_open(spiffs *fs, const char *path, spiffs_flags flags, spiffs_mode mode);
|
|
|
|
/**
|
|
* Opens a file by given dir entry.
|
|
* Optimization purposes, when traversing a file system with SPIFFS_readdir
|
|
* a normal SPIFFS_open would need to traverse the filesystem again to find
|
|
* the file, whilst SPIFFS_open_by_dirent already knows where the file resides.
|
|
* @param fs the file system struct
|
|
* @param e the dir entry to the file
|
|
* @param flags the flags for the open command, can be combinations of
|
|
* SPIFFS_APPEND, SPIFFS_TRUNC, SPIFFS_CREAT, SPIFFS_RD_ONLY,
|
|
* SPIFFS_WR_ONLY, SPIFFS_RDWR, SPIFFS_DIRECT.
|
|
* SPIFFS_CREAT will have no effect in this case.
|
|
* @param mode ignored, for posix compliance
|
|
*/
|
|
spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_flags flags, spiffs_mode mode);
|
|
|
|
/**
|
|
* Opens a file by given page index.
|
|
* Optimization purposes, opens a file by directly pointing to the page
|
|
* index in the spi flash.
|
|
* If the page index does not point to a file header SPIFFS_ERR_NOT_A_FILE
|
|
* is returned.
|
|
* @param fs the file system struct
|
|
* @param page_ix the page index
|
|
* @param flags the flags for the open command, can be combinations of
|
|
* SPIFFS_APPEND, SPIFFS_TRUNC, SPIFFS_CREAT, SPIFFS_RD_ONLY,
|
|
* SPIFFS_WR_ONLY, SPIFFS_RDWR, SPIFFS_DIRECT.
|
|
* SPIFFS_CREAT will have no effect in this case.
|
|
* @param mode ignored, for posix compliance
|
|
*/
|
|
spiffs_file SPIFFS_open_by_page(spiffs *fs, spiffs_page_ix page_ix, spiffs_flags flags, spiffs_mode mode);
|
|
|
|
/**
|
|
* Reads from given filehandle.
|
|
* @param fs the file system struct
|
|
* @param fh the filehandle
|
|
* @param buf where to put read data
|
|
* @param len how much to read
|
|
* @returns number of bytes read, or -1 if error
|
|
*/
|
|
s32_t SPIFFS_read(spiffs *fs, spiffs_file fh, void *buf, s32_t len);
|
|
|
|
/**
|
|
* Writes to given filehandle.
|
|
* @param fs the file system struct
|
|
* @param fh the filehandle
|
|
* @param buf the data to write
|
|
* @param len how much to write
|
|
* @returns number of bytes written, or -1 if error
|
|
*/
|
|
s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len);
|
|
|
|
/**
|
|
* Moves the read/write file offset. Resulting offset is returned or negative if error.
|
|
* lseek(fs, fd, 0, SPIFFS_SEEK_CUR) will thus return current offset.
|
|
* @param fs the file system struct
|
|
* @param fh the filehandle
|
|
* @param offs how much/where to move the offset
|
|
* @param whence if SPIFFS_SEEK_SET, the file offset shall be set to offset bytes
|
|
* if SPIFFS_SEEK_CUR, the file offset shall be set to its current location plus offset
|
|
* if SPIFFS_SEEK_END, the file offset shall be set to the size of the file plus offse, which should be negative
|
|
*/
|
|
s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence);
|
|
|
|
/**
|
|
* Removes a file by path
|
|
* @param fs the file system struct
|
|
* @param path the path of the file to remove
|
|
*/
|
|
s32_t SPIFFS_remove(spiffs *fs, const char *path);
|
|
|
|
/**
|
|
* Removes a file by filehandle
|
|
* @param fs the file system struct
|
|
* @param fh the filehandle of the file to remove
|
|
*/
|
|
s32_t SPIFFS_fremove(spiffs *fs, spiffs_file fh);
|
|
|
|
/**
|
|
* Gets file status by path
|
|
* @param fs the file system struct
|
|
* @param path the path of the file to stat
|
|
* @param s the stat struct to populate
|
|
*/
|
|
s32_t SPIFFS_stat(spiffs *fs, const char *path, spiffs_stat *s);
|
|
|
|
/**
|
|
* Gets file status by filehandle
|
|
* @param fs the file system struct
|
|
* @param fh the filehandle of the file to stat
|
|
* @param s the stat struct to populate
|
|
*/
|
|
s32_t SPIFFS_fstat(spiffs *fs, spiffs_file fh, spiffs_stat *s);
|
|
|
|
/**
|
|
* Flushes all pending write operations from cache for given file
|
|
* @param fs the file system struct
|
|
* @param fh the filehandle of the file to flush
|
|
*/
|
|
s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh);
|
|
|
|
/**
|
|
* Closes a filehandle. If there are pending write operations, these are finalized before closing.
|
|
* @param fs the file system struct
|
|
* @param fh the filehandle of the file to close
|
|
*/
|
|
s32_t SPIFFS_close(spiffs *fs, spiffs_file fh);
|
|
|
|
/**
|
|
* Renames a file
|
|
* @param fs the file system struct
|
|
* @param old path of file to rename
|
|
* @param newPath new path of file
|
|
*/
|
|
s32_t SPIFFS_rename(spiffs *fs, const char *old_path, const char *new_path);
|
|
|
|
#if SPIFFS_OBJ_META_LEN
|
|
/**
|
|
* Updates file's metadata
|
|
* @param fs the file system struct
|
|
* @param path path to the file
|
|
* @param meta new metadata. must be SPIFFS_OBJ_META_LEN bytes long.
|
|
*/
|
|
s32_t SPIFFS_update_meta(spiffs *fs, const char *name, const void *meta);
|
|
|
|
/**
|
|
* Updates file's metadata
|
|
* @param fs the file system struct
|
|
* @param fh file handle of the file
|
|
* @param meta new metadata. must be SPIFFS_OBJ_META_LEN bytes long.
|
|
*/
|
|
s32_t SPIFFS_fupdate_meta(spiffs *fs, spiffs_file fh, const void *meta);
|
|
#endif
|
|
|
|
/**
|
|
* Returns last error of last file operation.
|
|
* @param fs the file system struct
|
|
*/
|
|
s32_t SPIFFS_errno(spiffs *fs);
|
|
|
|
/**
|
|
* Clears last error.
|
|
* @param fs the file system struct
|
|
*/
|
|
void SPIFFS_clearerr(spiffs *fs);
|
|
|
|
/**
|
|
* Opens a directory stream corresponding to the given name.
|
|
* The stream is positioned at the first entry in the directory.
|
|
* On hydrogen builds the name argument is ignored as hydrogen builds always correspond
|
|
* to a flat file structure - no directories.
|
|
* @param fs the file system struct
|
|
* @param name the name of the directory
|
|
* @param d pointer the directory stream to be populated
|
|
*/
|
|
spiffs_DIR *SPIFFS_opendir(spiffs *fs, const char *name, spiffs_DIR *d);
|
|
|
|
/**
|
|
* Closes a directory stream
|
|
* @param d the directory stream to close
|
|
*/
|
|
s32_t SPIFFS_closedir(spiffs_DIR *d);
|
|
|
|
/**
|
|
* Reads a directory into given spifs_dirent struct.
|
|
* @param d pointer to the directory stream
|
|
* @param e the dirent struct to be populated
|
|
* @returns null if error or end of stream, else given dirent is returned
|
|
*/
|
|
struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e);
|
|
|
|
/**
|
|
* Runs a consistency check on given filesystem.
|
|
* @param fs the file system struct
|
|
*/
|
|
s32_t SPIFFS_check(spiffs *fs);
|
|
|
|
/**
|
|
* Returns number of total bytes available and number of used bytes.
|
|
* This is an estimation, and depends on if there a many files with little
|
|
* data or few files with much data.
|
|
* NB: If used number of bytes exceeds total bytes, a SPIFFS_check should
|
|
* run. This indicates a power loss in midst of things. In worst case
|
|
* (repeated powerlosses in mending or gc) you might have to delete some files.
|
|
*
|
|
* @param fs the file system struct
|
|
* @param total total number of bytes in filesystem
|
|
* @param used used number of bytes in filesystem
|
|
*/
|
|
s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used);
|
|
|
|
/**
|
|
* Formats the entire file system. All data will be lost.
|
|
* The filesystem must not be mounted when calling this.
|
|
*
|
|
* NB: formatting is awkward. Due to backwards compatibility, SPIFFS_mount
|
|
* MUST be called prior to formatting in order to configure the filesystem.
|
|
* If SPIFFS_mount succeeds, SPIFFS_unmount must be called before calling
|
|
* SPIFFS_format.
|
|
* If SPIFFS_mount fails, SPIFFS_format can be called directly without calling
|
|
* SPIFFS_unmount first.
|
|
*
|
|
* @param fs the file system struct
|
|
*/
|
|
s32_t SPIFFS_format(spiffs *fs);
|
|
|
|
/**
|
|
* Returns nonzero if spiffs is mounted, or zero if unmounted.
|
|
* @param fs the file system struct
|
|
*/
|
|
u8_t SPIFFS_mounted(spiffs *fs);
|
|
|
|
/**
|
|
* Tries to find a block where most or all pages are deleted, and erase that
|
|
* block if found. Does not care for wear levelling. Will not move pages
|
|
* around.
|
|
* If parameter max_free_pages are set to 0, only blocks with only deleted
|
|
* pages will be selected.
|
|
*
|
|
* NB: the garbage collector is automatically called when spiffs needs free
|
|
* pages. The reason for this function is to give possibility to do background
|
|
* tidying when user knows the system is idle.
|
|
*
|
|
* Use with care.
|
|
*
|
|
* Setting max_free_pages to anything larger than zero will eventually wear
|
|
* flash more as a block containing free pages can be erased.
|
|
*
|
|
* Will set err_no to SPIFFS_OK if a block was found and erased,
|
|
* SPIFFS_ERR_NO_DELETED_BLOCK if no matching block was found,
|
|
* or other error.
|
|
*
|
|
* @param fs the file system struct
|
|
* @param max_free_pages maximum number allowed free pages in block
|
|
*/
|
|
s32_t SPIFFS_gc_quick(spiffs *fs, u16_t max_free_pages);
|
|
|
|
/**
|
|
* Will try to make room for given amount of bytes in the filesystem by moving
|
|
* pages and erasing blocks.
|
|
* If it is physically impossible, err_no will be set to SPIFFS_ERR_FULL. If
|
|
* there already is this amount (or more) of free space, SPIFFS_gc will
|
|
* silently return. It is recommended to call SPIFFS_info before invoking
|
|
* this method in order to determine what amount of bytes to give.
|
|
*
|
|
* NB: the garbage collector is automatically called when spiffs needs free
|
|
* pages. The reason for this function is to give possibility to do background
|
|
* tidying when user knows the system is idle.
|
|
*
|
|
* Use with care.
|
|
*
|
|
* @param fs the file system struct
|
|
* @param size amount of bytes that should be freed
|
|
*/
|
|
s32_t SPIFFS_gc(spiffs *fs, u32_t size);
|
|
|
|
/**
|
|
* Check if EOF reached.
|
|
* @param fs the file system struct
|
|
* @param fh the filehandle of the file to check
|
|
*/
|
|
s32_t SPIFFS_eof(spiffs *fs, spiffs_file fh);
|
|
|
|
/**
|
|
* Get position in file.
|
|
* @param fs the file system struct
|
|
* @param fh the filehandle of the file to check
|
|
*/
|
|
s32_t SPIFFS_tell(spiffs *fs, spiffs_file fh);
|
|
|
|
/**
|
|
* Registers a callback function that keeps track on operations on file
|
|
* headers. Do note, that this callback is called from within internal spiffs
|
|
* mechanisms. Any operations on the actual file system being callbacked from
|
|
* in this callback will mess things up for sure - do not do this.
|
|
* This can be used to track where files are and move around during garbage
|
|
* collection, which in turn can be used to build location tables in ram.
|
|
* Used in conjunction with SPIFFS_open_by_page this may improve performance
|
|
* when opening a lot of files.
|
|
* Must be invoked after mount.
|
|
*
|
|
* @param fs the file system struct
|
|
* @param cb_func the callback on file operations
|
|
*/
|
|
s32_t SPIFFS_set_file_callback_func(spiffs *fs, spiffs_file_callback cb_func);
|
|
|
|
#if SPIFFS_IX_MAP
|
|
|
|
/**
|
|
* Maps the first level index lookup to a given memory map.
|
|
* This will make reading big files faster, as the memory map will be used for
|
|
* looking up data pages instead of searching for the indices on the physical
|
|
* medium. When mapping, all affected indicies are found and the information is
|
|
* copied to the array.
|
|
* Whole file or only parts of it may be mapped. The index map will cover file
|
|
* contents from argument offset until and including arguments (offset+len).
|
|
* It is valid to map a longer range than the current file size. The map will
|
|
* then be populated when the file grows.
|
|
* On garbage collections and file data page movements, the map array will be
|
|
* automatically updated. Do not tamper with the map array, as this contains
|
|
* the references to the data pages. Modifying it from outside will corrupt any
|
|
* future readings using this file descriptor.
|
|
* The map will no longer be used when the file descriptor closed or the file
|
|
* is unmapped.
|
|
* This can be useful to get faster and more deterministic timing when reading
|
|
* large files, or when seeking and reading a lot within a file.
|
|
* @param fs the file system struct
|
|
* @param fh the file handle of the file to map
|
|
* @param map a spiffs_ix_map struct, describing the index map
|
|
* @param offset absolute file offset where to start the index map
|
|
* @param len length of the mapping in actual file bytes
|
|
* @param map_buf the array buffer for the look up data - number of required
|
|
* elements in the array can be derived from function
|
|
* SPIFFS_bytes_to_ix_map_entries given the length
|
|
*/
|
|
s32_t SPIFFS_ix_map(spiffs *fs, spiffs_file fh, spiffs_ix_map *map,
|
|
u32_t offset, u32_t len, spiffs_page_ix *map_buf);
|
|
|
|
/**
|
|
* Unmaps the index lookup from this filehandle. All future readings will
|
|
* proceed as normal, requiring reading of the first level indices from
|
|
* physical media.
|
|
* The map and map buffer given in function SPIFFS_ix_map will no longer be
|
|
* referenced by spiffs.
|
|
* It is not strictly necessary to unmap a file before closing it, as closing
|
|
* a file will automatically unmap it.
|
|
* @param fs the file system struct
|
|
* @param fh the file handle of the file to unmap
|
|
*/
|
|
s32_t SPIFFS_ix_unmap(spiffs *fs, spiffs_file fh);
|
|
|
|
/**
|
|
* Moves the offset for the index map given in function SPIFFS_ix_map. Parts or
|
|
* all of the map buffer will repopulated.
|
|
* @param fs the file system struct
|
|
* @param fh the mapped file handle of the file to remap
|
|
* @param offset new absolute file offset where to start the index map
|
|
*/
|
|
s32_t SPIFFS_ix_remap(spiffs *fs, spiffs_file fh, u32_t offset);
|
|
|
|
/**
|
|
* Utility function to get number of spiffs_page_ix entries a map buffer must
|
|
* contain on order to map given amount of file data in bytes.
|
|
* See function SPIFFS_ix_map and SPIFFS_ix_map_entries_to_bytes.
|
|
* @param fs the file system struct
|
|
* @param bytes number of file data bytes to map
|
|
* @return needed number of elements in a spiffs_page_ix array needed to
|
|
* map given amount of bytes in a file
|
|
*/
|
|
s32_t SPIFFS_bytes_to_ix_map_entries(spiffs *fs, u32_t bytes);
|
|
|
|
/**
|
|
* Utility function to amount of file data bytes that can be mapped when
|
|
* mapping a file with buffer having given number of spiffs_page_ix entries.
|
|
* See function SPIFFS_ix_map and SPIFFS_bytes_to_ix_map_entries.
|
|
* @param fs the file system struct
|
|
* @param map_page_ix_entries number of entries in a spiffs_page_ix array
|
|
* @return amount of file data in bytes that can be mapped given a map
|
|
* buffer having given amount of spiffs_page_ix entries
|
|
*/
|
|
s32_t SPIFFS_ix_map_entries_to_bytes(spiffs *fs, u32_t map_page_ix_entries);
|
|
|
|
#endif // SPIFFS_IX_MAP
|
|
|
|
|
|
#if SPIFFS_TEST_VISUALISATION
|
|
/**
|
|
* Prints out a visualization of the filesystem.
|
|
* @param fs the file system struct
|
|
*/
|
|
s32_t SPIFFS_vis(spiffs *fs);
|
|
#endif
|
|
|
|
#if SPIFFS_BUFFER_HELP
|
|
/**
|
|
* Returns number of bytes needed for the filedescriptor buffer given
|
|
* amount of file descriptors.
|
|
*/
|
|
u32_t SPIFFS_buffer_bytes_for_filedescs(spiffs *fs, u32_t num_descs);
|
|
|
|
#if SPIFFS_CACHE
|
|
/**
|
|
* Returns number of bytes needed for the cache buffer given
|
|
* amount of cache pages.
|
|
*/
|
|
u32_t SPIFFS_buffer_bytes_for_cache(spiffs *fs, u32_t num_pages);
|
|
#endif
|
|
#endif
|
|
|
|
#if SPIFFS_CACHE
|
|
#endif
|
|
#if defined(__cplusplus)
|
|
}
|
|
#endif
|
|
|
|
#endif /* SPIFFS_H_ */
|