39#include "spiffs_nucleus.h"
42#define _FDIRECT 0x80000
46#define O_DIRECT _FDIRECT
81 struct spiffs_t *fs,
unsigned addr,
unsigned size, uint8_t *dst)
88 struct spiffs_t *fs,
unsigned addr,
unsigned size, uint8_t *src)
103 size_t erase_block_size,
size_t logical_block_size,
104 size_t logical_page_size,
size_t max_num_open_descriptors,
106 std::function<
void()> post_format_hook)
108 , postFormatHook_(std::move(post_format_hook))
110 , workBuffer_(new uint8_t[logical_page_size * 2])
111 , fdSpaceSize_(max_num_open_descriptors * sizeof(spiffs_fd))
112 , fdSpace_(new uint8_t[fdSpaceSize_])
113 , cacheSize_(sizeof(spiffs_cache) +
114 cache_pages * (sizeof(spiffs_cache_page) + logical_page_size))
115 , cache_(new uint8_t[cacheSize_])
120 memset(
fs_, 0,
sizeof(spiffs));
121 fs_->user_data =
this;
126 .phys_size = size_on_disk,
127 .phys_addr = physical_address,
128 .phys_erase_block = erase_block_size,
129 .log_block_size = logical_block_size,
130 .log_page_size = logical_page_size};
131 memcpy(&
fs_->cfg, &tmp,
sizeof(
fs_->cfg));
192 memcpy(&tmp, &
fs_->cfg,
sizeof(tmp));
202 spiffs_flags ffs_flags = 0;
203 if (flags & O_APPEND)
205 ffs_flags |= SPIFFS_O_APPEND;
209 ffs_flags |= SPIFFS_O_TRUNC;
213 ffs_flags |= SPIFFS_O_CREAT;
215 if ((flags & O_ACCMODE) == O_RDONLY)
217 ffs_flags |= SPIFFS_O_RDONLY;
219 if ((flags & O_ACCMODE) == O_WRONLY)
221 ffs_flags |= SPIFFS_O_WRONLY;
223 if ((flags & O_ACCMODE) == O_RDWR)
225 ffs_flags |= SPIFFS_O_RDWR;
227 if (flags & O_DIRECT)
229 ffs_flags |= SPIFFS_O_DIRECT;
233 ffs_flags |= SPIFFS_O_EXCL;
236 spiffs_file fd = ::SPIFFS_open(
fs_, path, ffs_flags, 0);
255 spiffs_file fd = file->
privInt;
258 int result = SPIFFS_close(
fs_, fd);
260 if (result != SPIFFS_OK)
273 int result = SPIFFS_remove(
fs_, path);
288 spiffs_file fd = file->
privInt;
290 ssize_t result = SPIFFS_read(
fs_, fd, buf, count);
305 spiffs_file fd = file->
privInt;
307 ssize_t result = SPIFFS_write(
fs_, fd, (
void *)buf, count);
328 spiffs_file fd = file->
privInt;
334 return (off_t)-EINVAL;
336 spiffs_whence = SPIFFS_SEEK_SET;
339 spiffs_whence = SPIFFS_SEEK_CUR;
342 spiffs_whence = SPIFFS_SEEK_END;
346 off_t result = SPIFFS_lseek(
fs_, fd, offset, spiffs_whence);
361 memset(stat, 0,
sizeof(*stat));
362 stat->st_ino = ffs_stat->obj_id;
363 stat->st_size = ffs_stat->size;
364 switch (ffs_stat->type)
368 case SPIFFS_TYPE_FILE:
369 stat->st_mode = S_IFREG;
371 case SPIFFS_TYPE_DIR:
372 stat->st_mode = S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
374 case SPIFFS_TYPE_HARD_LINK:
375 stat->st_mode = S_IFLNK | S_IXUSR | S_IXGRP | S_IXOTH;
377 case SPIFFS_TYPE_SOFT_LINK:
378 stat->st_mode = S_IFLNK | S_IXUSR | S_IXGRP | S_IXOTH;
382 stat->st_mode |= S_IRUSR | S_IRGRP | S_IROTH |
383 S_IWUSR | S_IWGRP | S_IWOTH;
392 spiffs_file fd = file->
privInt;
393 spiffs_stat ffs_stat;
395 ssize_t result = SPIFFS_fstat(
fs_, fd, &ffs_stat);
412 spiffs_stat ffs_stat;
414 if (!strcmp(path,
"") || !strcmp(path,
"/"))
417 ffs_stat.type = SPIFFS_TYPE_DIR;
423 ssize_t result = SPIFFS_stat(
fs_, path, &ffs_stat);
441 spiffs_file fd = file->
privInt;
443 int result = SPIFFS_fflush(
fs_, fd);
458 int result = SPIFFS_closedir(&dir->
dir_);
478 SPIFFS_OBJ_NAME_LEN +
479 strlen(this->name) + 1));
482 spiffs_DIR *result = SPIFFS_opendir(
fs_,
name, &dir->
dir_);
507 spiffs_dirent *result = SPIFFS_readdir(&dir->
dir_, &
dirent);
530 switch (spiffs_error)
538 case SPIFFS_ERR_NOT_MOUNTED:
542 case SPIFFS_ERR_FULL:
544 case SPIFFS_ERR_NOT_FOUND:
546 case SPIFFS_ERR_END_OF_OBJECT:
548 case SPIFFS_ERR_DELETED:
550 case SPIFFS_ERR_NOT_FINALIZED:
552 case SPIFFS_ERR_NOT_INDEX:
554 case SPIFFS_ERR_OUT_OF_FILE_DESCS:
556 case SPIFFS_ERR_FILE_CLOSED:
558 case SPIFFS_ERR_FILE_DELETED:
560 case SPIFFS_ERR_BAD_DESCRIPTOR:
562 case SPIFFS_ERR_IS_INDEX:
564 case SPIFFS_ERR_IS_FREE:
566 case SPIFFS_ERR_INDEX_SPAN_MISMATCH:
568 case SPIFFS_ERR_DATA_SPAN_MISMATCH:
570 case SPIFFS_ERR_INDEX_REF_FREE:
572 case SPIFFS_ERR_INDEX_REF_LU:
574 case SPIFFS_ERR_INDEX_REF_INVALID:
576 case SPIFFS_ERR_INDEX_FREE:
578 case SPIFFS_ERR_INDEX_LU:
580 case SPIFFS_ERR_INDEX_INVALID:
582 case SPIFFS_ERR_NOT_WRITABLE:
584 case SPIFFS_ERR_NOT_READABLE:
586 case SPIFFS_ERR_CONFLICTING_NAME:
588 case SPIFFS_ERR_NOT_CONFIGURED:
591 case SPIFFS_ERR_NOT_A_FS:
593 case SPIFFS_ERR_MOUNTED:
595 case SPIFFS_ERR_ERASE_FAIL:
597 case SPIFFS_ERR_MAGIC_NOT_POSSIBLE:
600 case SPIFFS_ERR_NO_DELETED_BLOCKS:
603 case SPIFFS_ERR_FILE_EXISTS:
606 case SPIFFS_ERR_NOT_A_FILE:
608 case SPIFFS_ERR_RO_NOT_IMPL:
610 case SPIFFS_ERR_RO_ABORTED_OPERATION:
612 case SPIFFS_ERR_PROBE_TOO_FEW_BLOCKS:
614 case SPIFFS_ERR_PROBE_NOT_A_FS:
616 case SPIFFS_ERR_NAME_TOO_LONG:
619 case SPIFFS_ERR_IX_MAP_UNMAPPED:
621 case SPIFFS_ERR_IX_MAP_MAPPED:
623 case SPIFFS_ERR_IX_MAP_BAD_RANGE:
625 case SPIFFS_ERR_SEEK_BOUNDS:
628 case SPIFFS_ERR_INTERNAL:
631 case SPIFFS_ERR_TEST:
void extern_spiffs_unlock(struct spiffs_t *fs)
Provide mutex unlock.
void extern_spiffs_lock(struct spiffs_t *fs)
Provide mutex lock.
int globalLastSPIFFSError
global error number for the last SPIFFS error
static void stat_post_process(struct stat *stat, spiffs_stat *ffs_stat)
Common post processing for SPIFFS::stat() and SPIFFS::fstat().
See OSMutexLock in os/OS.hxx.
const char * name
device name
Base class for all File systems.
void unlock()
Unlock a mutex.
Generic SPIFFS base class.
OSMutex lock_
whole file system lock
static void extern_unlock(struct spiffs_t *fs)
Provide mutex unlock.
ssize_t read(File *file, void *buf, size_t count) override
Read from a file or device.
int errno_translate(int spiffs_error)
Translate a SPIFFS specific error number to a standard POSIX errno.
ssize_t write(File *file, const void *buf, size_t count) override
Write to a file or device.
File * opendir(File *file, const char *name) override
Open a directory.
int fsync(File *file) override
Synchronize (flush) a file to disk.
int open(File *file, const char *path, int flags, int mode) override
Open a file or device.
off_t lseek(File *f, off_t offset, int whence) override
Seek method.
int fstat(File *file, struct stat *stat) override
Get the status information of a file or device.
int close(File *file) override
Close a file or device.
static int flash_read(struct spiffs_t *fs, unsigned addr, unsigned size, uint8_t *dst)
SPIFFS callback to read flash.
int closedir(File *file) override
Close a directory.
void unmount()
Flushes caches and unmounts the filesystem.
spiffs * fs_
file system instance metadata
int stat(const char *path, struct stat *stat) override
Get the status information of a file or device.
int unlink(const char *path) override
Remove a file.
static int flash_write(struct spiffs_t *fs, unsigned addr, unsigned size, uint8_t *src)
SPIFFS callback to write flash.
uint32_t fdSpaceSize_
size in bytes of the fdSpace_
static void extern_lock(struct spiffs_t *fs)
Provide mutex lock.
uint8_t * fdSpace_
file descriptor metadata
void * cache_
memory for cache
static int flash_erase(struct spiffs_t *fs, unsigned addr, unsigned size)
SPIFFS callback to erase flash.
struct dirent * readdir(File *file) override
Read the next entry in a directory.
void format() override
Format the file system, all data will be lost.
uint32_t cacheSize_
size in bytes of cache_
SPIFFS(size_t physical_address, size_t size_on_disk, size_t erase_block_size, size_t logical_block_size, size_t logical_page_size, size_t max_num_open_descriptors=16, size_t cache_pages=8, std::function< void()> post_format_hook=nullptr)
Constructor.
uint8_t * workBuffer_
work buffer for the file system
bool formatted_
has the file system been formatted since last reboot?
bool anyDirty_
Bit that is set to 1 when any write operation happens to this FS.
int do_mount()
Helper to mount the file system.
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
uint8_t dirty
true if this file is dirty and needs flush
uint8_t dir
true if this is a directory, else false
int privInt
file reference specific data "int"
void * priv
file reference specific data "pointer"
Open directory metadata structure.
struct dirent dirent_
directory entry
spiffs_DIR dir_
directory object
Directory entry structure.
char d_name[]
filename string of entry
ino_t d_ino
file serial number