mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-07 16:23:38 +03:00
Rework SPIFFS API to be more Arduino like
SD Style commands and Stream API
This commit is contained in:
parent
cfac2cacb1
commit
53e8bd8f4d
@ -1,178 +1,208 @@
|
|||||||
/****
|
/*
|
||||||
* Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
|
FileSystem.cpp - SPIFS implementation for esp8266
|
||||||
* Created 2015 by Skurydin Alexey
|
|
||||||
* http://github.com/anakod/Sming
|
|
||||||
* All files of the Sming Core are provided under the LGPL v3 license.
|
|
||||||
****/
|
|
||||||
|
|
||||||
|
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
|
||||||
|
This file is part of the esp8266 core for Arduino environment.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
#include "FileSystem.h"
|
#include "FileSystem.h"
|
||||||
#include "WString.h"
|
#include "Arduino.h"
|
||||||
|
|
||||||
file_t fileOpen(const String name, FileOpenFlags flags)
|
boolean FSClass::mount(){
|
||||||
{
|
if(_mounted) return true;
|
||||||
int repeats = 0;
|
_mounted = spiffs_mount();
|
||||||
bool notExist;
|
return _mounted;
|
||||||
bool canRecreate = (flags & eFO_CreateIfNotExist) == eFO_CreateIfNotExist;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
notExist = false;
|
|
||||||
res = SPIFFS_open(&_filesystemStorageHandle, name.c_str(), (spiffs_flags)flags, 0);
|
|
||||||
int code = SPIFFS_errno(&_filesystemStorageHandle);
|
|
||||||
if (res < 0)
|
|
||||||
{
|
|
||||||
debugf("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);
|
|
||||||
//debugf("recreate? %d %d %d", notExist, canRecreate, (repeats < 3));
|
|
||||||
if (notExist && canRecreate)
|
|
||||||
fileDelete(name); // fix for deleted files
|
|
||||||
}
|
|
||||||
} while (notExist && canRecreate && repeats++ < 3);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fileClose(file_t file)
|
void FSClass::unmount(){
|
||||||
{
|
if(!_mounted) return;
|
||||||
SPIFFS_close(&_filesystemStorageHandle, file);
|
spiffs_unmount();
|
||||||
|
_mounted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t fileWrite(file_t file, const void* data, size_t size)
|
boolean FSClass::format(){
|
||||||
{
|
return spiffs_format();
|
||||||
int res = SPIFFS_write(&_filesystemStorageHandle, file, (void *)data, size);
|
|
||||||
if (res < 0)
|
|
||||||
{
|
|
||||||
debugf("write errno %d\n", SPIFFS_errno(&_filesystemStorageHandle));
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t fileRead(file_t file, void* data, size_t size)
|
boolean FSClass::exists(const char *filename){
|
||||||
{
|
|
||||||
int res = SPIFFS_read(&_filesystemStorageHandle, file, data, size);
|
|
||||||
if (res < 0)
|
|
||||||
{
|
|
||||||
debugf("read errno %d\n", SPIFFS_errno(&_filesystemStorageHandle));
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fileSeek(file_t file, int offset, SeekOriginFlags origin)
|
|
||||||
{
|
|
||||||
return SPIFFS_lseek(&_filesystemStorageHandle, file, offset, origin);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool fileIsEOF(file_t file)
|
|
||||||
{
|
|
||||||
return SPIFFS_eof(&_filesystemStorageHandle, file);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t fileTell(file_t file)
|
|
||||||
{
|
|
||||||
return SPIFFS_tell(&_filesystemStorageHandle, file);
|
|
||||||
}
|
|
||||||
|
|
||||||
int fileFlush(file_t file)
|
|
||||||
{
|
|
||||||
return SPIFFS_fflush(&_filesystemStorageHandle, file);
|
|
||||||
}
|
|
||||||
|
|
||||||
int fileStats(const String name, spiffs_stat *stat)
|
|
||||||
{
|
|
||||||
return SPIFFS_stat(&_filesystemStorageHandle, name.c_str(), stat);
|
|
||||||
}
|
|
||||||
|
|
||||||
int fileStats(file_t file, spiffs_stat *stat)
|
|
||||||
{
|
|
||||||
return SPIFFS_fstat(&_filesystemStorageHandle, file, stat);
|
|
||||||
}
|
|
||||||
|
|
||||||
void fileDelete(const String name)
|
|
||||||
{
|
|
||||||
SPIFFS_remove(&_filesystemStorageHandle, name.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void fileDelete(file_t file)
|
|
||||||
{
|
|
||||||
SPIFFS_fremove(&_filesystemStorageHandle, file);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool fileExist(const String name)
|
|
||||||
{
|
|
||||||
spiffs_stat stat = {0};
|
spiffs_stat stat = {0};
|
||||||
if (fileStats(name.c_str(), &stat) < 0) return false;
|
if (SPIFFS_stat(&_filesystemStorageHandle, filename, &stat) < 0) return false;
|
||||||
return stat.name[0] != '\0';
|
return stat.name[0] != '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean FSClass::create(const char *filepath){
|
||||||
|
return SPIFFS_creat(&_filesystemStorageHandle, filepath, 0) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
int fileLastError(file_t fd)
|
boolean FSClass::remove(const char *filepath){
|
||||||
{
|
return SPIFFS_remove(&_filesystemStorageHandle, filepath) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean FSClass::rename(const char *filename, const char *newname){
|
||||||
|
return SPIFFS_rename(&_filesystemStorageHandle, filename, newname) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FSFile FSClass::open(const char *filename, uint8_t mode){
|
||||||
|
int repeats = 0;
|
||||||
|
bool notExist;
|
||||||
|
bool canRecreate = (mode & SPIFFS_CREAT) == SPIFFS_CREAT;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
do{
|
||||||
|
notExist = false;
|
||||||
|
res = SPIFFS_open(&_filesystemStorageHandle, filename, (spiffs_flags)mode, 0);
|
||||||
|
int code = SPIFFS_errno(&_filesystemStorageHandle);
|
||||||
|
if (res < 0){
|
||||||
|
debugf("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);
|
||||||
|
if (notExist && canRecreate)
|
||||||
|
remove(filename); // fix for deleted files
|
||||||
|
}
|
||||||
|
} while (notExist && canRecreate && repeats++ < 3);
|
||||||
|
|
||||||
|
if(res){
|
||||||
|
return FSFile(res);
|
||||||
|
}
|
||||||
|
return FSFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
FSClass FS;
|
||||||
|
|
||||||
|
FSFile::FSFile(){
|
||||||
|
_file = 0;
|
||||||
|
_stats = {0};
|
||||||
|
}
|
||||||
|
|
||||||
|
FSFile::FSFile(file_t f){
|
||||||
|
_file = f;
|
||||||
|
if(SPIFFS_fstat(&_filesystemStorageHandle, _file, &_stats) != 0){
|
||||||
|
debugf("mount errno %d\n", SPIFFS_errno(&_filesystemStorageHandle));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSFile::close(){
|
||||||
|
if (! _file) return;
|
||||||
|
SPIFFS_close(&_filesystemStorageHandle, _file);
|
||||||
|
_file = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FSFile::size(){
|
||||||
|
if(! _file) return 0;
|
||||||
|
uint32_t pos = SPIFFS_tell(&_filesystemStorageHandle, _file);
|
||||||
|
SPIFFS_lseek(&_filesystemStorageHandle, _file, 0, SPIFFS_SEEK_END);
|
||||||
|
uint32_t size = SPIFFS_tell(&_filesystemStorageHandle, _file);
|
||||||
|
SPIFFS_lseek(&_filesystemStorageHandle, _file, pos, SPIFFS_SEEK_SET);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FSFile::seek(uint32_t pos){
|
||||||
|
if (! _file) return 0;
|
||||||
|
return SPIFFS_lseek(&_filesystemStorageHandle, _file, pos, SPIFFS_SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FSFile::position(){
|
||||||
|
if (! _file) return 0;
|
||||||
|
return SPIFFS_tell(&_filesystemStorageHandle, _file);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean FSFile::eof(){
|
||||||
|
if (! _file) return 0;
|
||||||
|
return SPIFFS_eof(&_filesystemStorageHandle, _file);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean FSFile::isDirectory(void){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FSFile::read(void *buf, uint16_t nbyte){
|
||||||
|
if (! _file) return -1;
|
||||||
|
return SPIFFS_read(&_filesystemStorageHandle, _file, buf, nbyte);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FSFile::read(){
|
||||||
|
if (! _file) return -1;
|
||||||
|
int val;
|
||||||
|
if(SPIFFS_read(&_filesystemStorageHandle, _file, &val, 1) != 1) return -1;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FSFile::peek() {
|
||||||
|
if (! _file) return 0;
|
||||||
|
int c = read();
|
||||||
|
SPIFFS_lseek(&_filesystemStorageHandle, _file, -1, SPIFFS_SEEK_CUR);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FSFile::available() {
|
||||||
|
if (! _file) return 0;
|
||||||
|
uint32_t pos = SPIFFS_tell(&_filesystemStorageHandle, _file);
|
||||||
|
SPIFFS_lseek(&_filesystemStorageHandle, _file, 0, SPIFFS_SEEK_END);
|
||||||
|
uint32_t size = SPIFFS_tell(&_filesystemStorageHandle, _file);
|
||||||
|
SPIFFS_lseek(&_filesystemStorageHandle, _file, pos, SPIFFS_SEEK_SET);
|
||||||
|
return size - pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FSFile::write(const uint8_t *buf, size_t size){
|
||||||
|
if (! _file) return 0;
|
||||||
|
return SPIFFS_write(&_filesystemStorageHandle, _file, (uint8_t *)buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FSFile::write(uint8_t val) {
|
||||||
|
if (! _file) return 0;
|
||||||
|
return write(&val, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSFile::flush(){
|
||||||
|
if (! _file) return;
|
||||||
|
SPIFFS_fflush(&_filesystemStorageHandle, _file);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FSFile::remove(){
|
||||||
|
if (! _file) return 0;
|
||||||
|
return SPIFFS_fremove(&_filesystemStorageHandle, _file);
|
||||||
|
_file = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FSFile::lastError(){
|
||||||
return SPIFFS_errno(&_filesystemStorageHandle);
|
return SPIFFS_errno(&_filesystemStorageHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fileClearLastError(file_t fd)
|
void FSFile::clearError(){
|
||||||
{
|
|
||||||
_filesystemStorageHandle.errno = SPIFFS_OK;
|
_filesystemStorageHandle.errno = SPIFFS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fileSetContent(const String fileName, const char *content)
|
char * FSFile::name(){
|
||||||
{
|
return 0;
|
||||||
file_t file = fileOpen(fileName.c_str(), eFO_CreateNewAlways | eFO_WriteOnly);
|
|
||||||
fileWrite(file, content, os_strlen(content));
|
|
||||||
fileClose(file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t fileGetSize(const String fileName)
|
|
||||||
{
|
|
||||||
file_t file = fileOpen(fileName.c_str(), eFO_ReadOnly);
|
|
||||||
// Get size
|
|
||||||
fileSeek(file, 0, eSO_FileEnd);
|
|
||||||
int size = fileTell(file);
|
/*
|
||||||
fileClose(file);
|
spiffs_DIR *dirOpen(spiffs_DIR *d){
|
||||||
return size;
|
return SPIFFS_opendir(&_filesystemStorageHandle, 0, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
String fileGetContent(const String fileName)
|
int dirClose(spiffs_DIR *d){
|
||||||
{
|
return SPIFFS_closedir(d);
|
||||||
file_t file = fileOpen(fileName.c_str(), eFO_ReadOnly);
|
|
||||||
// Get size
|
|
||||||
fileSeek(file, 0, eSO_FileEnd);
|
|
||||||
int size = fileTell(file);
|
|
||||||
if (size <= 0)
|
|
||||||
{
|
|
||||||
fileClose(file);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
fileSeek(file, 0, eSO_FileStart);
|
|
||||||
char* buffer = new char[size + 1];
|
|
||||||
buffer[size] = 0;
|
|
||||||
fileRead(file, buffer, size);
|
|
||||||
fileClose(file);
|
|
||||||
String res = buffer;
|
|
||||||
delete[] buffer;
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int fileGetContent(const String fileName, char* buffer, int bufSize)
|
file_t dirOpenFile(spiffs_dirent* entry, uint8_t flags){
|
||||||
{
|
return SPIFFS_open_by_dirent(&_filesystemStorageHandle, entry, (spiffs_flags)flags, 0);
|
||||||
if (buffer == NULL || bufSize == 0) return 0;
|
|
||||||
*buffer = 0;
|
|
||||||
|
|
||||||
file_t file = fileOpen(fileName.c_str(), eFO_ReadOnly);
|
|
||||||
// Get size
|
|
||||||
fileSeek(file, 0, eSO_FileEnd);
|
|
||||||
int size = fileTell(file);
|
|
||||||
if (size <= 0 || bufSize <= size)
|
|
||||||
{
|
|
||||||
fileClose(file);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
buffer[size] = 0;
|
|
||||||
fileSeek(file, 0, eSO_FileStart);
|
|
||||||
fileRead(file, buffer, size);
|
|
||||||
fileClose(file);
|
|
||||||
return size;
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
@ -1,59 +1,83 @@
|
|||||||
/****
|
/*
|
||||||
* Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
|
FileSystem.h - SPIFS implementation for esp8266
|
||||||
* Created 2015 by Skurydin Alexey
|
|
||||||
* http://github.com/anakod/Sming
|
|
||||||
* All files of the Sming Core are provided under the LGPL v3 license.
|
|
||||||
****/
|
|
||||||
|
|
||||||
#ifndef _SMING_CORE_FILESYSTEM_H_
|
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
|
||||||
#define _SMING_CORE_FILESYSTEM_H_
|
This file is part of the esp8266 core for Arduino environment.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
#ifndef _SPIFFS_CORE_FILESYSTEM_H_
|
||||||
|
#define _SPIFFS_CORE_FILESYSTEM_H_
|
||||||
|
|
||||||
#include "spiffs/spiffs.h"
|
#include "spiffs/spiffs.h"
|
||||||
|
#include "Arduino.h"
|
||||||
class String;
|
class String;
|
||||||
|
|
||||||
enum FileOpenFlags
|
#define FSFILE_READ SPIFFS_RDONLY
|
||||||
{
|
#define FSFILE_WRITE (SPIFFS_RDONLY | SPIFFS_WRONLY | SPIFFS_CREAT | SPIFFS_APPEND | SPIFFS_TRUNC)
|
||||||
eFO_ReadOnly = SPIFFS_RDONLY,
|
|
||||||
eFO_WriteOnly = SPIFFS_WRONLY,
|
class FSFile : public Stream {
|
||||||
eFO_ReadWrite = eFO_ReadOnly | eFO_WriteOnly,
|
private:
|
||||||
eFO_CreateIfNotExist = SPIFFS_CREAT,
|
spiffs_stat _stats;
|
||||||
eFO_Append = SPIFFS_APPEND,
|
file_t _file;
|
||||||
eFO_Truncate = SPIFFS_TRUNC,
|
|
||||||
eFO_CreateNewAlways = eFO_CreateIfNotExist | eFO_Truncate
|
public:
|
||||||
|
FSFile(file_t f);
|
||||||
|
FSFile(void);
|
||||||
|
virtual size_t write(uint8_t);
|
||||||
|
virtual size_t write(const uint8_t *buf, size_t size);
|
||||||
|
virtual int read();
|
||||||
|
virtual int peek();
|
||||||
|
virtual int available();
|
||||||
|
virtual void flush();
|
||||||
|
int read(void *buf, uint16_t nbyte);
|
||||||
|
uint32_t seek(uint32_t pos);
|
||||||
|
uint32_t remove();
|
||||||
|
uint32_t position();
|
||||||
|
uint32_t size();
|
||||||
|
boolean eof();
|
||||||
|
void close();
|
||||||
|
int lastError();
|
||||||
|
void clearError();
|
||||||
|
operator bool(){ return _file > 0; }
|
||||||
|
char * name();
|
||||||
|
boolean isDirectory(void);
|
||||||
|
|
||||||
|
using Print::write;
|
||||||
};
|
};
|
||||||
|
|
||||||
static FileOpenFlags operator|(FileOpenFlags lhs, FileOpenFlags rhs)
|
class FSClass {
|
||||||
{
|
|
||||||
return (FileOpenFlags) ((int)lhs| (int)rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef enum
|
private:
|
||||||
{
|
boolean _mounted;
|
||||||
eSO_FileStart = SPIFFS_SEEK_SET,
|
|
||||||
eSO_CurrentPos = SPIFFS_SEEK_CUR,
|
|
||||||
eSO_FileEnd = SPIFFS_SEEK_END
|
|
||||||
} SeekOriginFlags;
|
|
||||||
|
|
||||||
file_t fileOpen(const String name, FileOpenFlags flags);
|
public:
|
||||||
void fileClose(file_t file);
|
boolean mount();
|
||||||
size_t fileWrite(file_t file, const void* data, size_t size);
|
void unmount();
|
||||||
size_t fileRead(file_t file, void* data, size_t size);
|
boolean format();
|
||||||
int fileSeek(file_t file, int offset, SeekOriginFlags origin);
|
boolean exists(const char *filename);
|
||||||
bool fileIsEOF(file_t file);
|
boolean create(const char *filepath);
|
||||||
int32_t fileTell(file_t file);
|
boolean remove(const char *filepath);
|
||||||
int fileFlush(file_t file);
|
boolean rename(const char *filename, const char *newname);
|
||||||
int fileLastError(file_t fd);
|
|
||||||
void fileClearLastError(file_t fd);
|
|
||||||
void fileSetContent(const String fileName, const char *content);
|
|
||||||
uint32_t fileGetSize(const String fileName);
|
|
||||||
String fileGetContent(const String fileName);
|
|
||||||
int fileGetContent(const String fileName, char* buffer, int bufSize);
|
|
||||||
|
|
||||||
|
FSFile open(const char *filename, uint8_t mode = FSFILE_READ);
|
||||||
|
|
||||||
int fileStats(const String name, spiffs_stat *stat);
|
private:
|
||||||
int fileStats(file_t file, spiffs_stat *stat);
|
friend class FSFile;
|
||||||
void fileDelete(const String name);
|
};
|
||||||
void fileDelete(file_t file);
|
|
||||||
bool fileExist(const String name);
|
|
||||||
|
|
||||||
#endif /* _SMING_CORE_FILESYSTEM_H_ */
|
extern FSClass FS;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -8,21 +8,17 @@ static u8_t spiffs_work_buf[LOG_PAGE_SIZE*2];
|
|||||||
static u8_t spiffs_fds[32*4];
|
static u8_t spiffs_fds[32*4];
|
||||||
static u8_t spiffs_cache[(LOG_PAGE_SIZE+32)*4];
|
static u8_t spiffs_cache[(LOG_PAGE_SIZE+32)*4];
|
||||||
|
|
||||||
static s32_t api_spiffs_read(u32_t addr, u32_t size, u8_t *dst)
|
static s32_t api_spiffs_read(u32_t addr, u32_t size, u8_t *dst){
|
||||||
{
|
|
||||||
flashmem_read(dst, addr, size);
|
flashmem_read(dst, addr, size);
|
||||||
return SPIFFS_OK;
|
return SPIFFS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static s32_t api_spiffs_write(u32_t addr, u32_t size, u8_t *src)
|
static s32_t api_spiffs_write(u32_t addr, u32_t size, u8_t *src){
|
||||||
{
|
|
||||||
//debugf("api_spiffs_write");
|
|
||||||
flashmem_write(src, addr, size);
|
flashmem_write(src, addr, size);
|
||||||
return SPIFFS_OK;
|
return SPIFFS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static s32_t api_spiffs_erase(u32_t addr, u32_t size)
|
static s32_t api_spiffs_erase(u32_t addr, u32_t size){
|
||||||
{
|
|
||||||
debugf("api_spiffs_erase");
|
debugf("api_spiffs_erase");
|
||||||
u32_t sect_first = flashmem_get_sector_of_address(addr);
|
u32_t sect_first = flashmem_get_sector_of_address(addr);
|
||||||
u32_t sect_last = sect_first;
|
u32_t sect_last = sect_first;
|
||||||
@ -45,48 +41,40 @@ extern uint32_t _SPIFFS_end;
|
|||||||
spiffs_config spiffs_get_storage_config()
|
spiffs_config spiffs_get_storage_config()
|
||||||
{
|
{
|
||||||
spiffs_config cfg = {0};
|
spiffs_config cfg = {0};
|
||||||
|
if ((u32_t)&_SPIFFS_start == 0) return cfg;
|
||||||
cfg.phys_addr = (u32_t)&_SPIFFS_start;
|
cfg.phys_addr = (u32_t)&_SPIFFS_start;
|
||||||
if (cfg.phys_addr == 0)
|
|
||||||
return cfg;
|
|
||||||
cfg.phys_addr += 0x3000;
|
cfg.phys_addr += 0x3000;
|
||||||
cfg.phys_addr &= 0xFFFFC000; // align to 4 sector.
|
cfg.phys_addr &= 0xFFFFC000; // align to 4 sector.
|
||||||
cfg.phys_size = (u32_t)((u32_t)&_SPIFFS_end - (u32_t)&_SPIFFS_start);
|
cfg.phys_size = (u32_t)((u32_t)&_SPIFFS_end - (u32_t)&_SPIFFS_start);
|
||||||
/*cfg.phys_addr = INTERNAL_FLASH_SIZE - SPIFFS_WORK_SIZE + INTERNAL_FLASH_START_ADDRESS;
|
|
||||||
cfg.phys_addr += 0x3000;
|
|
||||||
cfg.phys_addr &= 0xFFFFC000; // align to 4 sector.
|
|
||||||
cfg.phys_size = SPIFFS_WORK_SIZE;*/
|
|
||||||
cfg.phys_erase_block = INTERNAL_FLASH_SECTOR_SIZE; // according to datasheet
|
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_block_size = INTERNAL_FLASH_SECTOR_SIZE * 2; // Important to make large
|
||||||
cfg.log_page_size = LOG_PAGE_SIZE; // as we said
|
cfg.log_page_size = LOG_PAGE_SIZE; // as we said
|
||||||
return cfg;
|
return cfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool spiffs_format_internal()
|
bool spiffs_format_internal(){
|
||||||
{
|
|
||||||
spiffs_config cfg = spiffs_get_storage_config();
|
spiffs_config cfg = spiffs_get_storage_config();
|
||||||
if (cfg.phys_addr == 0)
|
if (cfg.phys_addr == 0){
|
||||||
{
|
SYSTEM_ERROR("Can't format file system, wrong address");
|
||||||
SYSTEM_ERROR("Can't format file system, wrong address");
|
return false;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u32_t sect_first, sect_last;
|
u32_t sect_first, sect_last;
|
||||||
sect_first = cfg.phys_addr;
|
sect_first = flashmem_get_first_free_block_address();
|
||||||
sect_first = flashmem_get_sector_of_address((u32_t)&_SPIFFS_start);
|
|
||||||
sect_last = flashmem_get_sector_of_address((u32_t)&_SPIFFS_end);
|
sect_last = flashmem_get_sector_of_address((u32_t)&_SPIFFS_end);
|
||||||
debugf("sect_first: %x, sect_last: %x\n", sect_first, sect_last);
|
debugf("sect_first: %x, sect_last: %x\n", sect_first, sect_last);
|
||||||
while( sect_first <= sect_last )
|
while( sect_first <= sect_last ){
|
||||||
if(!flashmem_erase_sector( sect_first ++ ))
|
if(!flashmem_erase_sector( sect_first ++ ))
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void spiffs_mount()
|
bool spiffs_mount(){
|
||||||
{
|
|
||||||
spiffs_config cfg = spiffs_get_storage_config();
|
spiffs_config cfg = spiffs_get_storage_config();
|
||||||
if (cfg.phys_addr == 0)
|
if (cfg.phys_addr == 0){
|
||||||
{
|
SYSTEM_ERROR("Can't start file system, wrong address");
|
||||||
SYSTEM_ERROR("Can't start file system, wrong address");
|
return false;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
debugf("fs.start:%x, size:%d Kb\n", cfg.phys_addr, cfg.phys_size / 1024);
|
debugf("fs.start:%x, size:%d Kb\n", cfg.phys_addr, cfg.phys_size / 1024);
|
||||||
@ -98,13 +86,14 @@ void spiffs_mount()
|
|||||||
uint32_t dat;
|
uint32_t dat;
|
||||||
bool writeFirst = false;
|
bool writeFirst = false;
|
||||||
flashmem_read(&dat, cfg.phys_addr, 4);
|
flashmem_read(&dat, cfg.phys_addr, 4);
|
||||||
//debugf("%X", dat);
|
|
||||||
|
|
||||||
if (dat == UINT32_MAX)
|
if (dat == UINT32_MAX){
|
||||||
{
|
debugf("First init file system");
|
||||||
debugf("First init file system");
|
if(!spiffs_format_internal()){
|
||||||
spiffs_format_internal();
|
SYSTEM_ERROR("Can't format file system");
|
||||||
writeFirst = true;
|
return false;
|
||||||
|
}
|
||||||
|
writeFirst = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int res = SPIFFS_mount(&_filesystemStorageHandle,
|
int res = SPIFFS_mount(&_filesystemStorageHandle,
|
||||||
@ -117,65 +106,43 @@ void spiffs_mount()
|
|||||||
NULL);
|
NULL);
|
||||||
debugf("mount res: %d\n", res);
|
debugf("mount res: %d\n", res);
|
||||||
|
|
||||||
if (writeFirst)
|
if(res != 0) return false;
|
||||||
{
|
|
||||||
file_t fd = SPIFFS_open(&_filesystemStorageHandle, "initialize_fs_header.dat", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0);
|
|
||||||
SPIFFS_write(&_filesystemStorageHandle, fd, (u8_t *)"1", 1);
|
|
||||||
SPIFFS_fremove(&_filesystemStorageHandle, fd);
|
|
||||||
SPIFFS_close(&_filesystemStorageHandle, fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
//dat=0;
|
if (writeFirst){
|
||||||
//flashmem_read(&dat, cfg.phys_addr, 4);
|
file_t fd = SPIFFS_open(&_filesystemStorageHandle, "initialize_fs_header.dat", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0);
|
||||||
//debugf("%X", dat);
|
SPIFFS_write(&_filesystemStorageHandle, fd, (u8_t *)"1", 1);
|
||||||
|
SPIFFS_fremove(&_filesystemStorageHandle, fd);
|
||||||
|
SPIFFS_close(&_filesystemStorageHandle, fd);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void spiffs_unmount()
|
void spiffs_unmount(){
|
||||||
{
|
|
||||||
SPIFFS_unmount(&_filesystemStorageHandle);
|
SPIFFS_unmount(&_filesystemStorageHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FS formatting function
|
bool spiffs_format(){
|
||||||
bool spiffs_format()
|
|
||||||
{
|
|
||||||
spiffs_unmount();
|
spiffs_unmount();
|
||||||
spiffs_format_internal();
|
if(!spiffs_format_internal()) return false;
|
||||||
spiffs_mount();
|
spiffs_mount();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//int spiffs_check( void )
|
void test_spiffs(){
|
||||||
//{
|
|
||||||
// ets_wdt_disable();
|
|
||||||
// int res = (int)SPIFFS_check(&_filesystemStorageHandle);
|
|
||||||
// ets_wdt_enable();
|
|
||||||
// return res;
|
|
||||||
//}
|
|
||||||
|
|
||||||
void test_spiffs()
|
|
||||||
{
|
|
||||||
char buf[12] = {0};
|
char buf[12] = {0};
|
||||||
|
|
||||||
// Surely, I've mounted spiffs before entering here
|
|
||||||
|
|
||||||
spiffs_file fd;
|
spiffs_file fd;
|
||||||
spiffs_stat st = {0};
|
spiffs_stat st = {0};
|
||||||
SPIFFS_stat(&_filesystemStorageHandle, "my_file.txt", &st);
|
SPIFFS_stat(&_filesystemStorageHandle, "my_file.txt", &st);
|
||||||
if (st.size <= 0)
|
if (st.size <= 0){
|
||||||
{
|
fd = SPIFFS_open(&_filesystemStorageHandle, "my_file.txt", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0);
|
||||||
fd = SPIFFS_open(&_filesystemStorageHandle, "my_file.txt", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0);
|
if (SPIFFS_write(&_filesystemStorageHandle, fd, (u8_t *)"Hello world", 11) < 0)
|
||||||
if (SPIFFS_write(&_filesystemStorageHandle, fd, (u8_t *)"Hello world", 11) < 0)
|
debugf("errno %d\n", SPIFFS_errno(&_filesystemStorageHandle));
|
||||||
debugf("errno %d\n", SPIFFS_errno(&_filesystemStorageHandle));
|
SPIFFS_close(&_filesystemStorageHandle, fd);
|
||||||
SPIFFS_close(&_filesystemStorageHandle, fd);
|
debugf("file created");
|
||||||
debugf("file created");
|
} else debugf("file %s exist :)", st.name);
|
||||||
}
|
|
||||||
else
|
|
||||||
debugf("file %s exist :)", st.name);
|
|
||||||
|
|
||||||
|
|
||||||
fd = SPIFFS_open(&_filesystemStorageHandle, "my_file.txt", SPIFFS_RDWR, 0);
|
fd = SPIFFS_open(&_filesystemStorageHandle, "my_file.txt", SPIFFS_RDWR, 0);
|
||||||
if (SPIFFS_read(&_filesystemStorageHandle, fd, (u8_t *)buf, 11) < 0) debugf("errno %d\n", SPIFFS_errno(&_filesystemStorageHandle));
|
if (SPIFFS_read(&_filesystemStorageHandle, fd, (u8_t *)buf, 11) < 0) debugf("errno %d\n", SPIFFS_errno(&_filesystemStorageHandle));
|
||||||
SPIFFS_close(&_filesystemStorageHandle, fd);
|
SPIFFS_close(&_filesystemStorageHandle, fd);
|
||||||
|
|
||||||
debugf("--> %s <--\n", buf);
|
debugf("--> %s <--\n", buf);
|
||||||
}
|
}
|
||||||
|
@ -83,12 +83,10 @@ typedef enum {
|
|||||||
} spiffs_check_report;
|
} spiffs_check_report;
|
||||||
|
|
||||||
/* file system check callback function */
|
/* file system check callback function */
|
||||||
typedef void (*spiffs_check_callback)(spiffs_check_type type, spiffs_check_report report,
|
typedef void (*spiffs_check_callback)(spiffs_check_type type, spiffs_check_report report, u32_t arg1, u32_t arg2);
|
||||||
u32_t arg1, u32_t arg2);
|
|
||||||
|
|
||||||
#ifndef SPIFFS_DBG
|
#ifndef SPIFFS_DBG
|
||||||
#define SPIFFS_DBG(...) \
|
#define SPIFFS_DBG(...) printf(__VA_ARGS__)
|
||||||
print(__VA_ARGS__)
|
|
||||||
#endif
|
#endif
|
||||||
#ifndef SPIFFS_GC_DBG
|
#ifndef SPIFFS_GC_DBG
|
||||||
#define SPIFFS_GC_DBG(...) printf(__VA_ARGS__)
|
#define SPIFFS_GC_DBG(...) printf(__VA_ARGS__)
|
||||||
@ -456,7 +454,7 @@ u32_t SPIFFS_buffer_bytes_for_cache(spiffs *fs, u32_t num_pages);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void spiffs_mount();
|
bool spiffs_mount();
|
||||||
void spiffs_unmount();
|
void spiffs_unmount();
|
||||||
bool spiffs_format();
|
bool spiffs_format();
|
||||||
spiffs_config spiffs_get_storage_config();
|
spiffs_config spiffs_get_storage_config();
|
||||||
|
@ -20,7 +20,7 @@ static spiffs_cache_page *spiffs_cache_page_get(spiffs *fs, spiffs_page_ix pix)
|
|||||||
if ((cache->cpage_use_map & (1<<i)) &&
|
if ((cache->cpage_use_map & (1<<i)) &&
|
||||||
(cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 &&
|
(cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 &&
|
||||||
cp->pix == pix ) {
|
cp->pix == pix ) {
|
||||||
SPIFFS_CACHE_DBG("CACHE_GET: have cache page %u for %04x\n", i, pix);
|
SPIFFS_CACHE_DBG("CACHE_GET: have cache page %d for %04x\n", i, pix);
|
||||||
cp->last_access = cache->last_access;
|
cp->last_access = cache->last_access;
|
||||||
return cp;
|
return cp;
|
||||||
}
|
}
|
||||||
@ -46,9 +46,9 @@ static s32_t spiffs_cache_page_free(spiffs *fs, int ix, u8_t write_back) {
|
|||||||
cache->cpage_use_map &= ~(1 << ix);
|
cache->cpage_use_map &= ~(1 << ix);
|
||||||
|
|
||||||
if (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) {
|
if (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) {
|
||||||
SPIFFS_CACHE_DBG("CACHE_FREE: free cache page %u objid %04x\n", ix, cp->obj_id);
|
SPIFFS_CACHE_DBG("CACHE_FREE: free cache page %d objid %04x\n", ix, cp->obj_id);
|
||||||
} else {
|
} else {
|
||||||
SPIFFS_CACHE_DBG("CACHE_FREE: free cache page %u pix %04x\n", ix, cp->pix);
|
SPIFFS_CACHE_DBG("CACHE_FREE: free cache page %d pix %04x\n", ix, cp->pix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ static spiffs_cache_page *spiffs_cache_page_allocate(spiffs *fs) {
|
|||||||
spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i);
|
spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i);
|
||||||
cache->cpage_use_map |= (1<<i);
|
cache->cpage_use_map |= (1<<i);
|
||||||
cp->last_access = cache->last_access;
|
cp->last_access = cache->last_access;
|
||||||
SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page %u\n", i);
|
SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page %d\n", i);
|
||||||
return cp;
|
return cp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user