mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-19 23:22:16 +03:00
Support for multiple FileSystem instances
This commit is contained in:
parent
c32518974b
commit
1db2c8aa89
@ -38,7 +38,6 @@ extern "C" {
|
|||||||
#include "pgmspace.h"
|
#include "pgmspace.h"
|
||||||
#include "esp8266_peri.h"
|
#include "esp8266_peri.h"
|
||||||
#include "twi.h"
|
#include "twi.h"
|
||||||
//#include "spiffs/spiffs.h"
|
|
||||||
|
|
||||||
void yield(void);
|
void yield(void);
|
||||||
|
|
||||||
|
@ -20,60 +20,126 @@
|
|||||||
*/
|
*/
|
||||||
#include "FileSystem.h"
|
#include "FileSystem.h"
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
|
#include "spiffs/spiffs_esp8266.h"
|
||||||
|
|
||||||
bool FSClass::mount() {
|
#define LOGICAL_PAGE_SIZE 256
|
||||||
if(SPIFFS_mounted(&_filesystemStorageHandle)) return true;
|
#define LOGICAL_BLOCK_SIZE 512
|
||||||
int res = spiffs_mount();
|
|
||||||
if(res != 0){
|
|
||||||
int formated = SPIFFS_format(&_filesystemStorageHandle);
|
// These addresses are defined in the linker script.
|
||||||
if(formated != 0) return false;
|
// For each flash memory size there is a linker script variant
|
||||||
res = spiffs_mount();
|
// which sets spiffs location and size.
|
||||||
}
|
extern "C" uint32_t _SPIFFS_start;
|
||||||
return (res == 0);
|
extern "C" uint32_t _SPIFFS_end;
|
||||||
|
|
||||||
|
static s32_t api_spiffs_read(u32_t addr, u32_t size, u8_t *dst);
|
||||||
|
static s32_t api_spiffs_write(u32_t addr, u32_t size, u8_t *src);
|
||||||
|
static s32_t api_spiffs_erase(u32_t addr, u32_t size);
|
||||||
|
|
||||||
|
FSClass FS((uint32_t) &_SPIFFS_start, (uint32_t) &_SPIFFS_end, 4);
|
||||||
|
|
||||||
|
FSClass::FSClass(uint32_t beginAddress, uint32_t endAddress, uint32_t maxOpenFiles)
|
||||||
|
: _beginAddress(beginAddress)
|
||||||
|
, _endAddress(endAddress)
|
||||||
|
, _maxOpenFiles(maxOpenFiles)
|
||||||
|
, _fs({0})
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int FSClass::_mountInternal(){
|
||||||
|
if (_beginAddress == 0 || _beginAddress >= _endAddress){
|
||||||
|
SPIFFS_API_DBG_E("Can't start file system, wrong address\r\n");
|
||||||
|
return SPIFFS_ERR_NOT_CONFIGURED;
|
||||||
|
}
|
||||||
|
|
||||||
|
spiffs_config cfg = {0};
|
||||||
|
cfg.phys_addr = _beginAddress;
|
||||||
|
cfg.phys_size = _endAddress - _beginAddress;
|
||||||
|
cfg.phys_erase_block = INTERNAL_FLASH_SECTOR_SIZE;
|
||||||
|
cfg.log_block_size = LOGICAL_BLOCK_SIZE;
|
||||||
|
cfg.log_page_size = LOGICAL_PAGE_SIZE;
|
||||||
|
cfg.hal_read_f = api_spiffs_read;
|
||||||
|
cfg.hal_write_f = api_spiffs_write;
|
||||||
|
cfg.hal_erase_f = api_spiffs_erase;
|
||||||
|
|
||||||
|
SPIFFS_API_DBG_V("FSClass::_mountInternal: start:%x, size:%d Kb\n", cfg.phys_addr, cfg.phys_size / 1024);
|
||||||
|
|
||||||
|
_work.reset(new uint8_t[LOGICAL_BLOCK_SIZE]);
|
||||||
|
_fdsSize = 32 * _maxOpenFiles;
|
||||||
|
_fds.reset(new uint8_t[_fdsSize]);
|
||||||
|
_cacheSize = (32 + LOGICAL_PAGE_SIZE) * _maxOpenFiles;
|
||||||
|
_cache.reset(new uint8_t[_cacheSize]);
|
||||||
|
|
||||||
|
s32_t res = SPIFFS_mount(&_fs,
|
||||||
|
&cfg,
|
||||||
|
_work.get(),
|
||||||
|
_fds.get(),
|
||||||
|
_fdsSize,
|
||||||
|
_cache.get(),
|
||||||
|
_cacheSize,
|
||||||
|
NULL);
|
||||||
|
SPIFFS_API_DBG_V("FSClass::_mountInternal: %d\n", res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FSClass::mount() {
|
||||||
|
if(SPIFFS_mounted(&_fs))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
int res = _mountInternal();
|
||||||
|
if(res != SPIFFS_OK){
|
||||||
|
int formated = SPIFFS_format(&_fs);
|
||||||
|
if(formated != SPIFFS_OK)
|
||||||
|
return false;
|
||||||
|
res = _mountInternal();
|
||||||
|
}
|
||||||
|
return (res == SPIFFS_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: need to invalidate open file objects
|
||||||
void FSClass::unmount() {
|
void FSClass::unmount() {
|
||||||
if(SPIFFS_mounted(&_filesystemStorageHandle))
|
if(SPIFFS_mounted(&_fs))
|
||||||
SPIFFS_unmount(&_filesystemStorageHandle);
|
SPIFFS_unmount(&_fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FSClass::format() {
|
bool FSClass::format() {
|
||||||
if(!SPIFFS_mounted(&_filesystemStorageHandle)){
|
if(!SPIFFS_mounted(&_fs)){
|
||||||
spiffs_mount();
|
_mountInternal();
|
||||||
}
|
}
|
||||||
SPIFFS_unmount(&_filesystemStorageHandle);
|
SPIFFS_unmount(&_fs);
|
||||||
int formated = SPIFFS_format(&_filesystemStorageHandle);
|
int formated = SPIFFS_format(&_fs);
|
||||||
if(formated != 0) return false;
|
if(formated != SPIFFS_OK)
|
||||||
return (spiffs_mount() == 0);
|
return false;
|
||||||
|
return (_mountInternal() == SPIFFS_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FSClass::check() {
|
bool FSClass::check() {
|
||||||
return SPIFFS_check(&_filesystemStorageHandle) == 0;
|
return SPIFFS_check(&_fs) == SPIFFS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FSClass::exists(char *filename) {
|
bool FSClass::exists(char *filename) {
|
||||||
spiffs_stat stat = {0};
|
spiffs_stat stat = {0};
|
||||||
if (SPIFFS_stat(&_filesystemStorageHandle, filename, &stat) < 0)
|
if (SPIFFS_stat(&_fs, filename, &stat) < 0)
|
||||||
return false;
|
return false;
|
||||||
return stat.name[0] != '\0';
|
return stat.name[0] != '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FSClass::create(char *filepath){
|
bool FSClass::create(char *filepath){
|
||||||
return SPIFFS_creat(&_filesystemStorageHandle, filepath, 0) == 0;
|
return SPIFFS_creat(&_fs, filepath, 0) == SPIFFS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FSClass::remove(char *filepath){
|
bool FSClass::remove(char *filepath){
|
||||||
return SPIFFS_remove(&_filesystemStorageHandle, filepath) == 0;
|
return SPIFFS_remove(&_fs, filepath) == SPIFFS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FSClass::rename(char *filename, char *newname) {
|
bool FSClass::rename(char *filename, char *newname) {
|
||||||
return SPIFFS_rename(&_filesystemStorageHandle, filename, newname) == 0;
|
return SPIFFS_rename(&_fs, filename, newname) == SPIFFS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t FSClass::totalBytes(){
|
size_t FSClass::totalBytes(){
|
||||||
u32_t totalBytes;
|
u32_t totalBytes;
|
||||||
u32_t usedBytes;
|
u32_t usedBytes;
|
||||||
if(SPIFFS_info(&_filesystemStorageHandle, &totalBytes, &usedBytes) == 0)
|
if(SPIFFS_info(&_fs, &totalBytes, &usedBytes) == SPIFFS_OK)
|
||||||
return totalBytes;
|
return totalBytes;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -81,13 +147,16 @@ size_t FSClass::totalBytes(){
|
|||||||
size_t FSClass::usedBytes(){
|
size_t FSClass::usedBytes(){
|
||||||
u32_t totalBytes;
|
u32_t totalBytes;
|
||||||
u32_t usedBytes;
|
u32_t usedBytes;
|
||||||
if(SPIFFS_info(&_filesystemStorageHandle, &totalBytes, &usedBytes) == 0)
|
if(SPIFFS_info(&_fs, &totalBytes, &usedBytes) == SPIFFS_OK)
|
||||||
return usedBytes;
|
return usedBytes;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FSFile FSClass::open(char *filename, uint8_t mode) {
|
FSFile FSClass::open(char *filename, uint8_t mode) {
|
||||||
if(String(filename) == "" || String(filename) == "/") return FSFile("/");
|
if(strcmp(filename, "") == 0 ||
|
||||||
|
strcmp(filename, "/") == 0)
|
||||||
|
return FSFile(&_fs, "/");
|
||||||
|
|
||||||
int repeats = 0;
|
int repeats = 0;
|
||||||
bool notExist;
|
bool notExist;
|
||||||
bool canRecreate = (mode & SPIFFS_CREAT) == SPIFFS_CREAT;
|
bool canRecreate = (mode & SPIFFS_CREAT) == SPIFFS_CREAT;
|
||||||
@ -95,8 +164,8 @@ FSFile FSClass::open(char *filename, uint8_t mode) {
|
|||||||
|
|
||||||
do{
|
do{
|
||||||
notExist = false;
|
notExist = false;
|
||||||
res = SPIFFS_open(&_filesystemStorageHandle, filename, (spiffs_flags)mode, 0);
|
res = SPIFFS_open(&_fs, filename, (spiffs_flags)mode, 0);
|
||||||
int code = SPIFFS_errno(&_filesystemStorageHandle);
|
int code = SPIFFS_errno(&_fs);
|
||||||
if (res < 0){
|
if (res < 0){
|
||||||
SPIFFS_API_DBG_E("open errno %d\n", code);
|
SPIFFS_API_DBG_E("open errno %d\n", code);
|
||||||
notExist = (code == SPIFFS_ERR_NOT_FOUND || code == SPIFFS_ERR_DELETED || code == SPIFFS_ERR_FILE_DELETED || code == SPIFFS_ERR_IS_FREE);
|
notExist = (code == SPIFFS_ERR_NOT_FOUND || code == SPIFFS_ERR_DELETED || code == SPIFFS_ERR_FILE_DELETED || code == SPIFFS_ERR_IS_FREE);
|
||||||
@ -106,63 +175,68 @@ FSFile FSClass::open(char *filename, uint8_t mode) {
|
|||||||
} while (notExist && canRecreate && repeats++ < 3);
|
} while (notExist && canRecreate && repeats++ < 3);
|
||||||
|
|
||||||
if(res){
|
if(res){
|
||||||
return FSFile(res);
|
return FSFile(&_fs, res);
|
||||||
}
|
}
|
||||||
return FSFile();
|
return FSFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
FSFile FSClass::open(spiffs_dirent* entry, uint8_t mode){
|
FSFile FSClass::open(spiffs_dirent* entry, uint8_t mode){
|
||||||
int res = SPIFFS_open_by_dirent(&_filesystemStorageHandle, entry, (spiffs_flags)mode, 0);
|
int res = SPIFFS_open_by_dirent(&_fs, entry, (spiffs_flags)mode, 0);
|
||||||
if(res){
|
if (res){
|
||||||
return FSFile(res);
|
return FSFile(&_fs, res);
|
||||||
}
|
}
|
||||||
return FSFile();
|
return FSFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
FSClass FS;
|
FSFile::FSFile()
|
||||||
|
: _file(0)
|
||||||
FSFile::FSFile() {
|
, _stats({0})
|
||||||
_file = 0;
|
, _fs(0)
|
||||||
_stats = {0};
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
FSFile::FSFile(String path) {
|
FSFile::FSFile(spiffs* fs, String path)
|
||||||
|
: _fs(fs)
|
||||||
|
{
|
||||||
if(path == "/"){
|
if(path == "/"){
|
||||||
_file = 0x1;
|
_file = 0x1;
|
||||||
os_sprintf((char*)_stats.name, "%s", (char*)path.c_str());
|
os_sprintf((char*)_stats.name, "%s", (char*)path.c_str());
|
||||||
_stats.size = 0;
|
_stats.size = 0;
|
||||||
_stats.type = SPIFFS_TYPE_DIR;
|
_stats.type = SPIFFS_TYPE_DIR;
|
||||||
SPIFFS_opendir(&_filesystemStorageHandle, (char*)_stats.name, &_dir);
|
SPIFFS_opendir(_fs, (char*)_stats.name, &_dir);
|
||||||
} else {
|
} else {
|
||||||
_file = SPIFFS_open(&_filesystemStorageHandle, (char *)path.c_str(), (spiffs_flags)FSFILE_READ, 0);
|
_file = SPIFFS_open(_fs, (char *)path.c_str(), (spiffs_flags)FSFILE_READ, 0);
|
||||||
if(SPIFFS_fstat(&_filesystemStorageHandle, _file, &_stats) != 0){
|
if(SPIFFS_fstat(_fs, _file, &_stats) != 0){
|
||||||
SPIFFS_API_DBG_E("fstat errno %d\n", SPIFFS_errno(&_filesystemStorageHandle));
|
SPIFFS_API_DBG_E("fstat errno %d\n", SPIFFS_errno(_fs));
|
||||||
}
|
}
|
||||||
//debugf("FSFile name: %s, size: %d, type: %d\n", _stats.name, _stats.size, _stats.type);
|
//debugf("FSFile name: %s, size: %d, type: %d\n", _stats.name, _stats.size, _stats.type);
|
||||||
if(_stats.type == SPIFFS_TYPE_DIR){
|
if(_stats.type == SPIFFS_TYPE_DIR){
|
||||||
SPIFFS_opendir(&_filesystemStorageHandle, (char*)_stats.name, &_dir);
|
SPIFFS_opendir(_fs, (char*)_stats.name, &_dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FSFile::FSFile(file_t f) {
|
FSFile::FSFile(spiffs* fs, file_t f)
|
||||||
_file = f;
|
: _file(f)
|
||||||
if(SPIFFS_fstat(&_filesystemStorageHandle, _file, &_stats) != 0){
|
, _fs(fs)
|
||||||
SPIFFS_API_DBG_E("fstat errno %d\n", SPIFFS_errno(&_filesystemStorageHandle));
|
{
|
||||||
|
if(SPIFFS_fstat(_fs, _file, &_stats) != 0){
|
||||||
|
SPIFFS_API_DBG_E("fstat errno %d\n", SPIFFS_errno(_fs));
|
||||||
}
|
}
|
||||||
//debugf("FSFile name: %s, size: %d, type: %d\n", _stats.name, _stats.size, _stats.type);
|
//debugf("FSFile name: %s, size: %d, type: %d\n", _stats.name, _stats.size, _stats.type);
|
||||||
if(_stats.type == SPIFFS_TYPE_DIR){
|
if(_stats.type == SPIFFS_TYPE_DIR){
|
||||||
SPIFFS_opendir(&_filesystemStorageHandle, (char*)_stats.name, &_dir);
|
SPIFFS_opendir(_fs, (char*)_stats.name, &_dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FSFile::close() {
|
void FSFile::close() {
|
||||||
if (! _file) return;
|
if (!_file)
|
||||||
|
return;
|
||||||
if(_stats.type == SPIFFS_TYPE_DIR){
|
if(_stats.type == SPIFFS_TYPE_DIR){
|
||||||
SPIFFS_closedir(&_dir);
|
SPIFFS_closedir(&_dir);
|
||||||
}
|
}
|
||||||
if(os_strlen((char*)_stats.name) > 1)
|
if(os_strlen((char*)_stats.name) > 1)
|
||||||
SPIFFS_close(&_filesystemStorageHandle, _file);
|
SPIFFS_close(_fs, _file);
|
||||||
_file = 0;
|
_file = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,97 +249,138 @@ bool FSFile::isDirectory(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FSFile::rewindDirectory() {
|
void FSFile::rewindDirectory() {
|
||||||
if (!_file || !isDirectory()) return;
|
if (!_file || !isDirectory())
|
||||||
|
return;
|
||||||
SPIFFS_closedir(&_dir);
|
SPIFFS_closedir(&_dir);
|
||||||
SPIFFS_opendir(&_filesystemStorageHandle, (char*)_stats.name, &_dir);
|
SPIFFS_opendir(_fs, (char*)_stats.name, &_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
FSFile FSFile::openNextFile(){
|
FSFile FSFile::openNextFile(){
|
||||||
if (!_file || !isDirectory()) return FSFile();
|
if (!_file || !isDirectory())
|
||||||
|
return FSFile();
|
||||||
struct spiffs_dirent e;
|
struct spiffs_dirent e;
|
||||||
struct spiffs_dirent *pe = &e;
|
struct spiffs_dirent *pe = &e;
|
||||||
if ((pe = SPIFFS_readdir(&_dir, pe))){
|
if ((pe = SPIFFS_readdir(&_dir, pe))){
|
||||||
|
// TODO: store actual FS pointer
|
||||||
return FS.open((char *)pe->name);
|
return FS.open((char *)pe->name);
|
||||||
}
|
}
|
||||||
return FSFile();
|
return FSFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t FSFile::size() {
|
uint32_t FSFile::size() {
|
||||||
if(!_file) return 0;
|
if(!_file)
|
||||||
if(_stats.size) return _stats.size;
|
return 0;
|
||||||
uint32_t pos = SPIFFS_tell(&_filesystemStorageHandle, _file);
|
if(_stats.size)
|
||||||
SPIFFS_lseek(&_filesystemStorageHandle, _file, 0, SPIFFS_SEEK_END);
|
return _stats.size;
|
||||||
_stats.size = SPIFFS_tell(&_filesystemStorageHandle, _file);
|
uint32_t pos = SPIFFS_tell(_fs, _file);
|
||||||
SPIFFS_lseek(&_filesystemStorageHandle, _file, pos, SPIFFS_SEEK_SET);
|
SPIFFS_lseek(_fs, _file, 0, SPIFFS_SEEK_END);
|
||||||
|
_stats.size = SPIFFS_tell(_fs, _file);
|
||||||
|
SPIFFS_lseek(_fs, _file, pos, SPIFFS_SEEK_SET);
|
||||||
return _stats.size;
|
return _stats.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FSFile::available() {
|
int FSFile::available() {
|
||||||
if (!_file) return 0;
|
if (!_file)
|
||||||
uint32_t pos = SPIFFS_tell(&_filesystemStorageHandle, _file);
|
return 0;
|
||||||
|
uint32_t pos = SPIFFS_tell(_fs, _file);
|
||||||
return size() - pos;
|
return size() - pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t FSFile::seek(uint32_t pos) {
|
uint32_t FSFile::seek(uint32_t pos) {
|
||||||
if (!_file) return 0;
|
if (!_file)
|
||||||
return SPIFFS_lseek(&_filesystemStorageHandle, _file, pos, SPIFFS_SEEK_SET);
|
return 0;
|
||||||
|
return SPIFFS_lseek(_fs, _file, pos, SPIFFS_SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t FSFile::position() {
|
uint32_t FSFile::position() {
|
||||||
if (!_file) return 0;
|
if (!_file)
|
||||||
return SPIFFS_tell(&_filesystemStorageHandle, _file);
|
return 0;
|
||||||
|
return SPIFFS_tell(_fs, _file);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FSFile::eof() {
|
bool FSFile::eof() {
|
||||||
if (!_file) return 0;
|
if (!_file)
|
||||||
return SPIFFS_eof(&_filesystemStorageHandle, _file);
|
return 0;
|
||||||
|
return SPIFFS_eof(_fs, _file);
|
||||||
}
|
}
|
||||||
|
|
||||||
int FSFile::read(void *buf, uint16_t nbyte) {
|
int FSFile::read(void *buf, uint16_t nbyte) {
|
||||||
if (! _file || isDirectory()) return -1;
|
if (!_file || isDirectory())
|
||||||
return SPIFFS_read(&_filesystemStorageHandle, _file, buf, nbyte);
|
return -1;
|
||||||
|
return SPIFFS_read(_fs, _file, buf, nbyte);
|
||||||
}
|
}
|
||||||
|
|
||||||
int FSFile::read() {
|
int FSFile::read() {
|
||||||
if (! _file || isDirectory()) return -1;
|
if (! _file || isDirectory())
|
||||||
|
return -1;
|
||||||
int val;
|
int val;
|
||||||
if(SPIFFS_read(&_filesystemStorageHandle, _file, &val, 1) != 1) return -1;
|
if(SPIFFS_read(_fs, _file, &val, 1) != 1) return -1;
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FSFile::peek() {
|
int FSFile::peek() {
|
||||||
if (! _file || isDirectory()) return 0;
|
if (!_file || isDirectory())
|
||||||
|
return 0;
|
||||||
int c = read();
|
int c = read();
|
||||||
SPIFFS_lseek(&_filesystemStorageHandle, _file, -1, SPIFFS_SEEK_CUR);
|
SPIFFS_lseek(_fs, _file, -1, SPIFFS_SEEK_CUR);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t FSFile::write(const uint8_t *buf, size_t size){
|
size_t FSFile::write(const uint8_t *buf, size_t size){
|
||||||
if (! _file || isDirectory()) return 0;
|
if (!_file || isDirectory())
|
||||||
int res = SPIFFS_write(&_filesystemStorageHandle, _file, (uint8_t *)buf, size);
|
return 0;
|
||||||
|
int res = SPIFFS_write(_fs, _file, (uint8_t *)buf, size);
|
||||||
return (res > 0)?(size_t)res:0;
|
return (res > 0)?(size_t)res:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t FSFile::write(uint8_t val) {
|
size_t FSFile::write(uint8_t val) {
|
||||||
if (! _file || isDirectory()) return 0;
|
if (!_file || isDirectory())
|
||||||
|
return 0;
|
||||||
return write(&val, 1);
|
return write(&val, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FSFile::flush(){
|
void FSFile::flush(){
|
||||||
if (! _file || isDirectory()) return;
|
if (!_file || isDirectory())
|
||||||
SPIFFS_fflush(&_filesystemStorageHandle, _file);
|
return;
|
||||||
|
SPIFFS_fflush(_fs, _file);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FSFile::remove(){
|
bool FSFile::remove(){
|
||||||
if (! _file) return 0;
|
if (!_file)
|
||||||
|
return 0;
|
||||||
close();
|
close();
|
||||||
return SPIFFS_remove(&_filesystemStorageHandle, (char *)_stats.name) == 0;
|
return SPIFFS_remove(_fs, (char *)_stats.name) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FSFile::lastError(){
|
int FSFile::lastError(){
|
||||||
return SPIFFS_errno(&_filesystemStorageHandle);
|
return SPIFFS_errno(_fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FSFile::clearError(){
|
void FSFile::clearError(){
|
||||||
_filesystemStorageHandle.err_code = SPIFFS_OK;
|
_fs->err_code = SPIFFS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static s32_t api_spiffs_read(u32_t addr, u32_t size, u8_t *dst){
|
||||||
|
SPIFFS_API_DBG_V("api_spiffs_read: 0x%08x len: %u\n", addr, size);
|
||||||
|
flashmem_read(dst, addr, size);
|
||||||
|
return SPIFFS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static s32_t api_spiffs_write(u32_t addr, u32_t size, u8_t *src){
|
||||||
|
SPIFFS_API_DBG_V("api_spiffs_write: 0x%08x len: %u\n", addr, size);
|
||||||
|
flashmem_write(src, addr, size);
|
||||||
|
return SPIFFS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static s32_t api_spiffs_erase(u32_t addr, u32_t size){
|
||||||
|
SPIFFS_API_DBG_V("api_spiffs_erase: 0x%08x len: %u\n", addr, size);
|
||||||
|
u32_t sect_first = flashmem_get_sector_of_address(addr);
|
||||||
|
u32_t sect_last = flashmem_get_sector_of_address(addr+size);
|
||||||
|
while( sect_first <= sect_last )
|
||||||
|
if( !flashmem_erase_sector( sect_first ++ ) )
|
||||||
|
return SPIFFS_ERR_INTERNAL;
|
||||||
|
return SPIFFS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
#ifndef _SPIFFS_CORE_FILESYSTEM_H_
|
#ifndef _SPIFFS_CORE_FILESYSTEM_H_
|
||||||
#define _SPIFFS_CORE_FILESYSTEM_H_
|
#define _SPIFFS_CORE_FILESYSTEM_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include "spiffs/spiffs.h"
|
#include "spiffs/spiffs.h"
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
class String;
|
|
||||||
|
|
||||||
#define FSFILE_READ SPIFFS_RDONLY
|
#define FSFILE_READ SPIFFS_RDONLY
|
||||||
#define FSFILE_WRITE (SPIFFS_RDONLY | SPIFFS_WRONLY | SPIFFS_CREAT | SPIFFS_APPEND )
|
#define FSFILE_WRITE (SPIFFS_RDONLY | SPIFFS_WRONLY | SPIFFS_CREAT | SPIFFS_APPEND )
|
||||||
@ -34,10 +34,11 @@ private:
|
|||||||
spiffs_stat _stats;
|
spiffs_stat _stats;
|
||||||
file_t _file;
|
file_t _file;
|
||||||
spiffs_DIR _dir;
|
spiffs_DIR _dir;
|
||||||
|
spiffs * _fs;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FSFile(String path);
|
FSFile(spiffs* fs, String path);
|
||||||
FSFile(file_t f);
|
FSFile(spiffs* fs, file_t f);
|
||||||
FSFile(void);
|
FSFile(void);
|
||||||
virtual size_t write(uint8_t);
|
virtual size_t write(uint8_t);
|
||||||
virtual size_t write(const uint8_t *buf, size_t size);
|
virtual size_t write(const uint8_t *buf, size_t size);
|
||||||
@ -83,10 +84,9 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
class FSClass {
|
class FSClass {
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
FSClass(uint32_t beginAddress, uint32_t endAddress, uint32_t maxOpenFiles);
|
||||||
|
|
||||||
bool mount();
|
bool mount();
|
||||||
void unmount();
|
void unmount();
|
||||||
bool format();
|
bool format();
|
||||||
@ -97,17 +97,30 @@ public:
|
|||||||
bool rename(char *filename, char *newname);
|
bool rename(char *filename, char *newname);
|
||||||
size_t totalBytes();
|
size_t totalBytes();
|
||||||
size_t usedBytes();
|
size_t usedBytes();
|
||||||
size_t size(){ return _filesystemStorageHandle.cfg.phys_size; }
|
size_t size(){ return _fs.cfg.phys_size; }
|
||||||
size_t blockSize(){ return _filesystemStorageHandle.cfg.log_block_size; }
|
size_t blockSize(){ return _fs.cfg.log_block_size; }
|
||||||
size_t totalBlocks(){ return _filesystemStorageHandle.block_count; }
|
size_t totalBlocks(){ return _fs.block_count; }
|
||||||
size_t freeBlocks(){ return _filesystemStorageHandle.free_blocks; }
|
size_t freeBlocks(){ return _fs.free_blocks; }
|
||||||
size_t pageSize(){ return _filesystemStorageHandle.cfg.log_page_size; }
|
size_t pageSize(){ return _fs.cfg.log_page_size; }
|
||||||
size_t allocatedPages(){ return _filesystemStorageHandle.stats_p_allocated; }
|
size_t allocatedPages(){ return _fs.stats_p_allocated; }
|
||||||
size_t deletedPages(){ return _filesystemStorageHandle.stats_p_deleted; }
|
size_t deletedPages(){ return _fs.stats_p_deleted; }
|
||||||
|
|
||||||
FSFile open(char *filename, uint8_t mode = FSFILE_READ);
|
FSFile open(char *filename, uint8_t mode = FSFILE_READ);
|
||||||
FSFile open(spiffs_dirent* entry, uint8_t mode = FSFILE_READ);
|
FSFile open(spiffs_dirent* entry, uint8_t mode = FSFILE_READ);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int _mountInternal();
|
||||||
|
std::unique_ptr<uint8_t[]> _work;
|
||||||
|
std::unique_ptr<uint8_t[]> _fds;
|
||||||
|
size_t _fdsSize;
|
||||||
|
std::unique_ptr<uint8_t[]> _cache;
|
||||||
|
size_t _cacheSize;
|
||||||
|
uint32_t _beginAddress;
|
||||||
|
uint32_t _endAddress;
|
||||||
|
uint32_t _maxOpenFiles;
|
||||||
|
spiffs _fs;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class FSFile;
|
friend class FSFile;
|
||||||
};
|
};
|
||||||
|
@ -78,5 +78,4 @@ void init() {
|
|||||||
timer1_isr_init();
|
timer1_isr_init();
|
||||||
os_timer_setfn(µs_overflow_timer, (os_timer_func_t*) µs_overflow_tick, 0);
|
os_timer_setfn(µs_overflow_timer, (os_timer_func_t*) µs_overflow_tick, 0);
|
||||||
os_timer_arm(µs_overflow_timer, 60000, REPEAT);
|
os_timer_arm(µs_overflow_timer, 60000, REPEAT);
|
||||||
spiffs_mount();
|
|
||||||
}
|
}
|
||||||
|
@ -146,79 +146,3 @@ uint32_t flashmem_get_sector_of_address( uint32_t addr ){
|
|||||||
return (addr - INTERNAL_FLASH_START_ADDRESS) / INTERNAL_FLASH_SECTOR_SIZE;;
|
return (addr - INTERNAL_FLASH_START_ADDRESS) / INTERNAL_FLASH_SECTOR_SIZE;;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
SPIFFS BOOTSTRAP
|
|
||||||
*/
|
|
||||||
|
|
||||||
//SPIFFS Address Range (defined in eagle ld)
|
|
||||||
extern uint32_t _SPIFFS_start;
|
|
||||||
extern uint32_t _SPIFFS_end;
|
|
||||||
|
|
||||||
//SPIFFS Storage Handle
|
|
||||||
spiffs _filesystemStorageHandle;
|
|
||||||
|
|
||||||
//SPIFFS Buffers (INTERNAL_FLASH_PAGE_SIZE = 256) Total 1792 bytes
|
|
||||||
static u8_t spiffs_work_buf[INTERNAL_FLASH_PAGE_SIZE*2]; //512 bytes
|
|
||||||
static u8_t spiffs_fds[32*4]; //128 bytes
|
|
||||||
static u8_t spiffs_cache[(INTERNAL_FLASH_PAGE_SIZE+32)*4]; //1152 bytes
|
|
||||||
|
|
||||||
//SPIFFS API Read CallBack
|
|
||||||
static s32_t api_spiffs_read(u32_t addr, u32_t size, u8_t *dst){
|
|
||||||
SPIFFS_API_DBG_V("api_spiffs_read: 0x%08x len: %u\n", addr, size);
|
|
||||||
flashmem_read(dst, addr, size);
|
|
||||||
return SPIFFS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
//SPIFFS API Write CallBack
|
|
||||||
static s32_t api_spiffs_write(u32_t addr, u32_t size, u8_t *src){
|
|
||||||
SPIFFS_API_DBG_V("api_spiffs_write: 0x%08x len: %u\n", addr, size);
|
|
||||||
flashmem_write(src, addr, size);
|
|
||||||
return SPIFFS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
//SPIFFS API Erase CallBack
|
|
||||||
static s32_t api_spiffs_erase(u32_t addr, u32_t size){
|
|
||||||
SPIFFS_API_DBG_V("api_spiffs_erase: 0x%08x len: %u\n", addr, size);
|
|
||||||
u32_t sect_first = flashmem_get_sector_of_address(addr);
|
|
||||||
u32_t sect_last = flashmem_get_sector_of_address(addr+size);
|
|
||||||
while( sect_first <= sect_last )
|
|
||||||
if( !flashmem_erase_sector( sect_first ++ ) )
|
|
||||||
return SPIFFS_ERR_INTERNAL;
|
|
||||||
return SPIFFS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Our own SPIFFS Setup Method
|
|
||||||
// All of the above gets put in the configuration
|
|
||||||
// and a mount attempt is made, initializing the storage handle
|
|
||||||
// that is used in all further api calls
|
|
||||||
s32_t spiffs_mount(){
|
|
||||||
u32_t start_address = (u32_t)&_SPIFFS_start;
|
|
||||||
u32_t end_address = (u32_t)&_SPIFFS_end;
|
|
||||||
if (start_address == 0 || start_address >= end_address){
|
|
||||||
SPIFFS_API_DBG_E("Can't start file system, wrong address");
|
|
||||||
return SPIFFS_ERR_NOT_CONFIGURED;
|
|
||||||
}
|
|
||||||
|
|
||||||
spiffs_config cfg = {0};
|
|
||||||
cfg.phys_addr = start_address;
|
|
||||||
cfg.phys_size = end_address - start_address;
|
|
||||||
cfg.phys_erase_block = INTERNAL_FLASH_SECTOR_SIZE; // according to datasheet
|
|
||||||
cfg.log_block_size = INTERNAL_FLASH_SECTOR_SIZE * 2; // Important to make large
|
|
||||||
cfg.log_page_size = INTERNAL_FLASH_PAGE_SIZE; // according to datasheet
|
|
||||||
cfg.hal_read_f = api_spiffs_read;
|
|
||||||
cfg.hal_write_f = api_spiffs_write;
|
|
||||||
cfg.hal_erase_f = api_spiffs_erase;
|
|
||||||
|
|
||||||
SPIFFS_API_DBG_V("spiffs_mount: start:%x, size:%d Kb\n", cfg.phys_addr, cfg.phys_size / 1024);
|
|
||||||
|
|
||||||
s32_t res = SPIFFS_mount(&_filesystemStorageHandle,
|
|
||||||
&cfg,
|
|
||||||
spiffs_work_buf,
|
|
||||||
spiffs_fds,
|
|
||||||
sizeof(spiffs_fds),
|
|
||||||
spiffs_cache,
|
|
||||||
sizeof(spiffs_cache),
|
|
||||||
NULL);
|
|
||||||
SPIFFS_API_DBG_V("spiffs_mount: %d\n", res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
@ -24,14 +24,11 @@ The small 4KB sectors allow for greater flexibility in applications that require
|
|||||||
#define INTERNAL_FLASH_WRITE_UNIT_SIZE 4
|
#define INTERNAL_FLASH_WRITE_UNIT_SIZE 4
|
||||||
#define INTERNAL_FLASH_READ_UNIT_SIZE 4
|
#define INTERNAL_FLASH_READ_UNIT_SIZE 4
|
||||||
|
|
||||||
extern spiffs _filesystemStorageHandle;
|
|
||||||
|
|
||||||
extern uint32_t flashmem_write( const void *from, uint32_t toaddr, uint32_t size );
|
extern uint32_t flashmem_write( const void *from, uint32_t toaddr, uint32_t size );
|
||||||
extern uint32_t flashmem_read( void *to, uint32_t fromaddr, uint32_t size );
|
extern uint32_t flashmem_read( void *to, uint32_t fromaddr, uint32_t size );
|
||||||
extern bool flashmem_erase_sector( uint32_t sector_id );
|
extern bool flashmem_erase_sector( uint32_t sector_id );
|
||||||
uint32_t flashmem_find_sector( uint32_t address, uint32_t *pstart, uint32_t *pend );
|
uint32_t flashmem_find_sector( uint32_t address, uint32_t *pstart, uint32_t *pend );
|
||||||
uint32_t flashmem_get_sector_of_address( uint32_t addr );
|
uint32_t flashmem_get_sector_of_address( uint32_t addr );
|
||||||
s32_t spiffs_mount();
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user