Add STM32Spiffs

This commit is contained in:
fvanroie 2020-05-10 15:11:44 +02:00
parent 7ad37a04fa
commit 3d313dc978
13 changed files with 943 additions and 47 deletions

View File

@ -46,7 +46,7 @@
#define HASP_HAS_FILESYSTEM (ARDUINO_ARCH_ESP32 > 0 || ARDUINO_ARCH_ESP8266 > 0)
#ifndef HASP_USE_SPIFFS
#define HASP_USE_SPIFFS (HASP_HAS_FILESYSTEM)
#define HASP_USE_SPIFFS 1 //(HASP_HAS_FILESYSTEM)
#endif
#ifndef HASP_USE_EEPROM
@ -87,15 +87,26 @@
/* Includes */
#if HASP_USE_SPIFFS > 0
#if defined(STM32F4xx)
#include "STM32Spiffs.h" // Include the SPIFFS library
#endif
#if defined(ARDUINO_ARCH_ESP32)
#include "SPIFFS.h"
#endif
#include <FS.h> // Include the SPIFFS library
#endif
#if defined(ARDUINO_ARCH_ESP8266)
#include <FS.h> // Include the SPIFFS library
#endif
#include "hasp_spiffs.h"
#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
//#include "lv_zifont.h"
#endif
#endif // SPIFFS
#if HASP_USE_EEPROM > 0

View File

@ -0,0 +1,207 @@
/*
FS.cpp - file system wrapper
Copyright (c) 2015 Ivan Grokhotkov. 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 <Arduino.h>
#include "spiffs.h"
#include "STM32Spiffs.h"
namespace SpiffsLib
{
File::File(spiffs_file f, spiffs *fs)
{
_file = f;
_fs = fs;
}
File::File(void)
{
_file = 0;
_fs = nullptr;
}
int File::read()
{
u8_t ch;
SPIFFS_read(_fs, _file, (u8_t *)&ch, 1);
return ch;
}
int File::peek() { return 0; }
int File::availableForWrite() { return 0; }
int File::available() { return 0; }
int File::read(void *buf, uint16_t nbyte)
{
return SPIFFS_read(_fs, _file, (u8_t *)buf, nbyte);
}
bool File::seek(uint32_t pos)
{
return SPIFFS_lseek(_fs, _file, pos, SPIFFS_SEEK_SET) >= 0;
}
uint32_t File::position()
{
return SPIFFS_tell(_fs, _file);
}
void File::flush()
{
SPIFFS_fflush(_fs, _file);
}
size_t File::write(uint8_t ch)
{
int res = SPIFFS_write(_fs, _file, (u8_t *)&ch, 1);
return res;
}
size_t File::write(const uint8_t *buf, size_t size)
{
int res = SPIFFS_write(_fs, _file, (u8_t *)buf, size);
return res;
}
void File::close()
{
SPIFFS_close(_fs, _file);
}
File::~File(void)
{
Serial.print("File destructor called!");
}
SPIFlash *SpiffsClass::flash;
spiffs SpiffsClass::my_fs;
u8_t SpiffsClass::spiffs_work_buf[LOG_PAGE_SIZE * 2];
u8_t SpiffsClass::spiffs_fds[32 * 4];
u8_t SpiffsClass::spiffs_cache_buf[(LOG_PAGE_SIZE + 32) * 4];
s32_t SpiffsClass::my_spiffs_read(u32_t addr, u32_t size, u8_t *dst)
{
flash->readByteArray(addr, dst, size);
// Serial.print("Reading ");
// Serial.println(*dst);
return SPIFFS_OK;
}
s32_t SpiffsClass::my_spiffs_write(u32_t addr, u32_t size, u8_t *src)
{
flash->writeByteArray(addr, src, size);
Serial.print("Writing ");
Serial.println(size);
return SPIFFS_OK;
}
s32_t SpiffsClass::my_spiffs_erase(u32_t addr, u32_t size)
{
flash->eraseSection(addr, size);
Serial.print("Erasing ");
Serial.print(addr, HEX);
Serial.print(" - ");
Serial.println(size);
return SPIFFS_OK;
}
int SpiffsClass::mount()
{
spiffs_config cfg;
#if SPIFFS_SINGLETON == 0
cfg.phys_size = flash->GetCapacity(); // use all spi flash
cfg.phys_addr = 0; // start spiffs at start of spi flash
cfg.phys_erase_block = 65536; // according to datasheet
cfg.log_block_size = 65536; // let us not complicate things
cfg.log_page_size = LOG_PAGE_SIZE; // as we said
#endif
cfg.hal_read_f = my_spiffs_read;
cfg.hal_write_f = my_spiffs_write;
cfg.hal_erase_f = my_spiffs_erase;
int res = SPIFFS_mount(&my_fs,
&cfg,
spiffs_work_buf,
spiffs_fds,
sizeof(spiffs_fds),
spiffs_cache_buf,
sizeof(spiffs_cache_buf),
0);
Serial.print("mount result: ");
Serial.println(res);
return res;
}
bool SpiffsClass::begin(uint8_t cs)
{
if (!flash)
{
flash = new SPIFlash(cs);
}
flash->begin();
Serial.println(F("Mount Spiffs"));
int res = mount();
Serial.println(res);
if (res == SPIFFS_ERR_NOT_A_FS)
{
Serial.println(F("**************** Spiffs Format ******************"));
res = SPIFFS_format(&my_fs);
Serial.println(res);
Serial.println(F("Mount Spiffs again"));
res = mount();
Serial.println(res);
}
return res == SPIFFS_OK;
}
File SpiffsClass::open(const char *filename, uint8_t mode)
{
spiffs_file fh = SPIFFS_open(&my_fs, filename, mode, 0);
File f(fh, &my_fs);
return f;
};
bool SpiffsClass::exists(const char *filepath)
{
spiffs_DIR d;
struct spiffs_dirent e;
struct spiffs_dirent *pe = &e;
int res;
spiffs_file fd = -1;
SPIFFS_opendir(&my_fs, "/", &d);
while ((pe = SPIFFS_readdir(&d, pe)))
{
if (0 == strncmp(filepath, (char *)pe->name, strlen(filepath)))
{
return true;
}
}
SPIFFS_closedir(&d);
return false;
}
bool SpiffsClass::rename(const char *oldPath, const char *newPath)
{
return SPIFFS_rename(&my_fs, oldPath, newPath) == SPIFFS_OK;
}
} // namespace SpiffsLib

View File

@ -0,0 +1,180 @@
#ifndef STM32SPIFFS_H
#define STM32SPIFFS_H
#define FLASH_CHIP_SELECT_PIN PA15
// these are declared in params_test.h
// typedef signed int32_t s32_t;
// typedef unsigned int u32_t;
// typedef signed short s16_t;
// typedef unsigned short u16_t;
// typedef signed char s8_t;
// typedef unsigned char u8_t;
#include <memory>
#include <Arduino.h>
#include "SPIMemory.h"
#include "spiffs.h"
//#define FILE_READ "r"
//#define FILE_WRITE "w"
//#define FILE_APPEND "a"
#define FILE_READ (SPIFFS_CREAT | SPIFFS_RDONLY )
#define FILE_WRITE (SPIFFS_CREAT | SPIFFS_RDWR | SPIFFS_TRUNC)
#define FILE_APPEND (SPIFFS_CREAT | SPIFFS_RDWR | SPIFFS_APPEND)
namespace SpiffsLib
{
class File : public Stream
{
private:
spiffs_file _file; // file handle
spiffs *_fs; // file system
public:
File(spiffs_file f, spiffs *fs); // wraps an underlying spiffs_file
File(void); // 'empty' constructor
~File();
size_t write(uint8_t);
size_t write(const uint8_t *buf, size_t size);
int availableForWrite();
int available();
int read();
int peek();
void flush();
int read(void *buf, uint16_t nbyte);
bool seek(uint32_t pos);
uint32_t position();
uint32_t size();
void close();
operator bool();
char *name();
// bool isDirectory(void);
// File openNextFile(uint8_t mode = FILE_READ);
// void rewindDirectory(void);
using Print::write;
};
class SpiffsClass
{
private:
// my quick&dirty iterator, should be replaced
spiffs_file getParentDir(const char *filepath, int *indx);
public:
// These are required for initialisation and use of spiffs
static SPIFlash *flash;
static spiffs my_fs;
spiffs_file root;
// This needs to be called to set up the connection to the SD card
// before other methods are used.
bool begin(uint8_t csPin = FLASH_CHIP_SELECT_PIN);
bool begin(uint32_t clock, uint8_t csPin);
//call this when a card is removed. It will allow you to insert and initialise a new card.
void end();
// Open the specified file/directory with the supplied mode (e.g. read or
// write, etc). Returns a File object for interacting with the file.
// Note that currently only one file can be open at a time.
File open(const char *filename, uint8_t mode = FILE_READ);
File open(const String &filename, uint8_t mode = FILE_READ)
{
return open(filename.c_str(), mode);
}
// Methods to determine if the requested file path exists.
bool exists(const char *filepath);
bool exists(const String &filepath)
{
return exists(filepath.c_str());
}
// Create the requested directory heirarchy--if intermediate directories
// do not exist they will be created.
bool mkdir(const char *filepath);
bool mkdir(const String &filepath)
{
return mkdir(filepath.c_str());
}
// Delete the file.
bool remove(const char *filepath);
bool remove(const String &filepath)
{
return remove(filepath.c_str());
}
bool rmdir(const char *filepath);
bool rmdir(const String &filepath)
{
return rmdir(filepath.c_str());
}
bool rename(const char *oldPath, const char *newPath);
private:
// This is used to determine the mode used to open a file
// it's here because it's the easiest place to pass the
// information through the directory walking function. But
// it's probably not the best place for it.
// It shouldn't be set directly--it is set via the parameters to `open`.
int fileOpenMode;
friend class File;
friend bool callback_openPath(spiffs_file &, const char *, bool, void *);
static u8_t spiffs_work_buf[LOG_PAGE_SIZE * 2];
static u8_t spiffs_fds[32 * 4];
static u8_t spiffs_cache_buf[(LOG_PAGE_SIZE + 32) * 4];
int mount();
static s32_t my_spiffs_read(u32_t addr, u32_t size, u8_t *dst);
static s32_t my_spiffs_write(u32_t addr, u32_t size, u8_t *src);
static s32_t my_spiffs_erase(u32_t addr, u32_t size);
};
/*
class SPIFFS
{
public:
static SPIFlash *flash;
static spiffs my_fs;
SPIFFS();
int mount();
bool begin(uint8_t cs);
spiffs_file open(const char *path, const char *mode);
private:
static u8_t spiffs_work_buf[LOG_PAGE_SIZE * 2];
static u8_t spiffs_fds[32 * 4];
static u8_t spiffs_cache_buf[(LOG_PAGE_SIZE + 32) * 4];
static s32_t my_spiffs_read(u32_t addr, u32_t size, u8_t *dst);
static s32_t my_spiffs_write(u32_t addr, u32_t size, u8_t *src);
static s32_t my_spiffs_erase(u32_t addr, u32_t size);
};*/
enum SeekMode
{
SeekSet = 0,
SeekCur = 1,
SeekEnd = 2
};
extern SpiffsClass SPIFFS;
}; // namespace SpiffsLib
typedef SpiffsLib::File File;
typedef SpiffsLib::SpiffsClass SpiffsFS;
static SpiffsFS SPIFFS;
#endif //FS_H

View File

@ -0,0 +1,93 @@
/*
* params_test.h
*
* Created on: May 26, 2013
* Author: petera
*/
#ifndef PARAMS_TEST_H_
#define PARAMS_TEST_H_
#include <stdint.h>
//////////////// TEST PARAMS ////////////////
// default test total emulated spi flash size
#define PHYS_FLASH_SIZE (16 * 1024 * 1024)
// default test spiffs file system size
#define SPIFFS_FLASH_SIZE (2 * 1024 * 1024)
// default test spiffs file system offset in emulated spi flash
#define SPIFFS_PHYS_ADDR (4 * 1024 * 1024)
// default test sector size
#define SECTOR_SIZE 65536
// default test logical block size
#define LOG_BLOCK (SECTOR_SIZE * 2)
// default test logical page size
#define LOG_PAGE (SECTOR_SIZE / 256)
// default test number of filedescs
#define DEFAULT_NUM_FD 16
// default test number of cache pages
#define DEFAULT_NUM_CACHE_PAGES 8
// When testing, test bench create reference files for comparison on
// the actual hard drive. By default, put these on ram drive for speed.
#define TEST_PATH "/dev/shm/spiffs/test-data/"
#define ASSERT(c, m) real_assert((c), (m), __FILE__, __LINE__);
void real_assert(int c, const char * n, const char * file, int l);
/////////// SPIFFS BUILD CONFIG ////////////
// test using filesystem magic
#ifndef SPIFFS_USE_MAGIC
#define SPIFFS_USE_MAGIC 1
#endif
// test using filesystem magic length
#ifndef SPIFFS_USE_MAGIC_LENGTH
#define SPIFFS_USE_MAGIC_LENGTH 1
#endif
// test using extra param in callback
#ifndef SPIFFS_HAL_CALLBACK_EXTRA
#define SPIFFS_HAL_CALLBACK_EXTRA 1
#endif
// test using filehandle offset
#ifndef SPIFFS_FILEHDL_OFFSET
#define SPIFFS_FILEHDL_OFFSET 1
// use this offset
#define TEST_SPIFFS_FILEHDL_OFFSET 0x1000
#endif
#ifdef NO_TEST
#define SPIFFS_LOCK(fs)
#define SPIFFS_UNLOCK(fs)
#else
struct spiffs_t;
extern void test_lock(struct spiffs_t * fs);
extern void test_unlock(struct spiffs_t * fs);
#define SPIFFS_LOCK(fs) test_lock(fs)
#define SPIFFS_UNLOCK(fs) test_unlock(fs)
#endif
// dbg output
#define SPIFFS_DBG(_f, ...) // printf("\x1b[32m" _f "\x1b[0m", ## __VA_ARGS__)
#define SPIFFS_API_DBG(_f, ...) // printf("\n\x1b[1m\x1b[7m" _f "\x1b[0m", ## __VA_ARGS__)
#define SPIFFS_GC_DBG(_f, ...) // printf("\x1b[36m" _f "\x1b[0m", ## __VA_ARGS__)
#define SPIFFS_CACHE_DBG(_f, ...) // printf("\x1b[33m" _f "\x1b[0m", ## __VA_ARGS__)
#define SPIFFS_CHECK_DBG(_f, ...) // printf("\x1b[31m" _f "\x1b[0m", ## __VA_ARGS__)
// needed types
// typedef signed int s32_t;
// typedef unsigned int u32_t;
// typedef signed short s16_t;
// typedef unsigned short u16_t;
// typedef signed char s8_t;
// typedef unsigned char u8_t;
typedef uint8_t u8_t;
typedef int8_t s8_t;
typedef uint16_t u16_t;
typedef int16_t s16_t;
typedef uint32_t u32_t;
typedef int32_t s32_t;
#endif /* PARAMS_TEST_H_ */

View File

@ -0,0 +1,383 @@
/*
* spiffs_config.h
*
* Created on: Jul 3, 2013
* Author: petera
*/
#ifndef SPIFFS_CONFIG_H_
#define SPIFFS_CONFIG_H_
// ----------- 8< ------------
// Following includes are for the linux test build of spiffs
// These may/should/must be removed/altered/replaced in your target
#include "params_test.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <unistd.h>
#ifdef _SPIFFS_TEST
#include "testrunner.h"
#endif
// ----------- >8 ------------
// compile time switches
// Set generic spiffs debug output call.
#ifndef SPIFFS_DBG
#define SPIFFS_DBG(_f, ...) printf(_f, ## __VA_ARGS__)
#endif
// Set spiffs debug output call for garbage collecting.
#ifndef SPIFFS_GC_DBG
#define SPIFFS_GC_DBG(_f, ...) printf(_f, ## __VA_ARGS__)
#endif
// Set spiffs debug output call for caching.
#ifndef SPIFFS_CACHE_DBG
#define SPIFFS_CACHE_DBG(_f, ...) printf(_f, ## __VA_ARGS__)
#endif
// Set spiffs debug output call for system consistency checks.
#ifndef SPIFFS_CHECK_DBG
#define SPIFFS_CHECK_DBG(_f, ...) printf(_f, ## __VA_ARGS__)
#endif
// Set spiffs debug output call for all api invocations.
#ifndef SPIFFS_API_DBG
#define SPIFFS_API_DBG(_f, ...) printf(_f, ## __VA_ARGS__)
#endif
// Defines spiffs debug print formatters
// some general signed number
#ifndef _SPIPRIi
#define _SPIPRIi "%d"
#endif
// address
#ifndef _SPIPRIad
#define _SPIPRIad "%08x"
#endif
// block
#ifndef _SPIPRIbl
#define _SPIPRIbl "%04x"
#endif
// page
#ifndef _SPIPRIpg
#define _SPIPRIpg "%04x"
#endif
// span index
#ifndef _SPIPRIsp
#define _SPIPRIsp "%04x"
#endif
// file descriptor
#ifndef _SPIPRIfd
#define _SPIPRIfd "%d"
#endif
// file object id
#ifndef _SPIPRIid
#define _SPIPRIid "%04x"
#endif
// file flags
#ifndef _SPIPRIfl
#define _SPIPRIfl "%02x"
#endif
// Enable/disable API functions to determine exact number of bytes
// for filedescriptor and cache buffers. Once decided for a configuration,
// this can be disabled to reduce flash.
#ifndef SPIFFS_BUFFER_HELP
#define SPIFFS_BUFFER_HELP 0
#endif
// Enables/disable memory read caching of nucleus file system operations.
// If enabled, memory area must be provided for cache in SPIFFS_mount.
#ifndef SPIFFS_CACHE
#define SPIFFS_CACHE 1
#endif
#if SPIFFS_CACHE
// Enables memory write caching for file descriptors in hydrogen
#ifndef SPIFFS_CACHE_WR
#define SPIFFS_CACHE_WR 1
#endif
// Enable/disable statistics on caching. Debug/test purpose only.
#ifndef SPIFFS_CACHE_STATS
#define SPIFFS_CACHE_STATS 1
#endif
#endif
// Always check header of each accessed page to ensure consistent state.
// If enabled it will increase number of reads, will increase flash.
#ifndef SPIFFS_PAGE_CHECK
#define SPIFFS_PAGE_CHECK 1
#endif
// Define maximum number of gc runs to perform to reach desired free pages.
#ifndef SPIFFS_GC_MAX_RUNS
#define SPIFFS_GC_MAX_RUNS 5
#endif
// Enable/disable statistics on gc. Debug/test purpose only.
#ifndef SPIFFS_GC_STATS
#define SPIFFS_GC_STATS 1
#endif
// Garbage collecting examines all pages in a block which and sums up
// to a block score. Deleted pages normally gives positive score and
// used pages normally gives a negative score (as these must be moved).
// To have a fair wear-leveling, the erase age is also included in score,
// whose factor normally is the most positive.
// The larger the score, the more likely it is that the block will
// picked for garbage collection.
// Garbage collecting heuristics - weight used for deleted pages.
#ifndef SPIFFS_GC_HEUR_W_DELET
#define SPIFFS_GC_HEUR_W_DELET (5)
#endif
// Garbage collecting heuristics - weight used for used pages.
#ifndef SPIFFS_GC_HEUR_W_USED
#define SPIFFS_GC_HEUR_W_USED (-1)
#endif
// Garbage collecting heuristics - weight used for time between
// last erased and erase of this block.
#ifndef SPIFFS_GC_HEUR_W_ERASE_AGE
#define SPIFFS_GC_HEUR_W_ERASE_AGE (50)
#endif
// Object name maximum length. Note that this length include the
// zero-termination character, meaning maximum string of characters
// can at most be SPIFFS_OBJ_NAME_LEN - 1.
#ifndef SPIFFS_OBJ_NAME_LEN
#define SPIFFS_OBJ_NAME_LEN (32)
#endif
// Maximum length of the metadata associated with an object.
// Setting to non-zero value enables metadata-related API but also
// changes the on-disk format, so the change is not backward-compatible.
//
// Do note: the meta length must never exceed
// logical_page_size - (SPIFFS_OBJ_NAME_LEN + 64)
//
// This is derived from following:
// logical_page_size - (SPIFFS_OBJ_NAME_LEN + sizeof(spiffs_page_header) +
// spiffs_object_ix_header fields + at least some LUT entries)
#ifndef SPIFFS_OBJ_META_LEN
#define SPIFFS_OBJ_META_LEN (0)
#endif
// Size of buffer allocated on stack used when copying data.
// Lower value generates more read/writes. No meaning having it bigger
// than logical page size.
#ifndef SPIFFS_COPY_BUFFER_STACK
#define SPIFFS_COPY_BUFFER_STACK (64)
#endif
// Enable this to have an identifiable spiffs filesystem. This will look for
// a magic in all sectors to determine if this is a valid spiffs system or
// not on mount point. If not, SPIFFS_format must be called prior to mounting
// again.
#ifndef SPIFFS_USE_MAGIC
#define SPIFFS_USE_MAGIC (0)
#endif
#if SPIFFS_USE_MAGIC
// Only valid when SPIFFS_USE_MAGIC is enabled. If SPIFFS_USE_MAGIC_LENGTH is
// enabled, the magic will also be dependent on the length of the filesystem.
// For example, a filesystem configured and formatted for 4 megabytes will not
// be accepted for mounting with a configuration defining the filesystem as 2
// megabytes.
#ifndef SPIFFS_USE_MAGIC_LENGTH
#define SPIFFS_USE_MAGIC_LENGTH (0)
#endif
#endif
// SPIFFS_LOCK and SPIFFS_UNLOCK protects spiffs from reentrancy on api level
// These should be defined on a multithreaded system
// define this to enter a mutex if you're running on a multithreaded system
#ifndef SPIFFS_LOCK
#define SPIFFS_LOCK(fs)
#endif
// define this to exit a mutex if you're running on a multithreaded system
#ifndef SPIFFS_UNLOCK
#define SPIFFS_UNLOCK(fs)
#endif
// Enable if only one spiffs instance with constant configuration will exist
// on the target. This will reduce calculations, flash and memory accesses.
// Parts of configuration must be defined below instead of at time of mount.
#ifndef SPIFFS_SINGLETON
#define SPIFFS_SINGLETON 1
#endif
#if SPIFFS_SINGLETON
// Instead of giving parameters in config struct, singleton build must
// give parameters in defines below.
#ifndef SPIFFS_CFG_PHYS_SZ
#define SPIFFS_CFG_PHYS_SZ(ignore) (1024*1024*2)
#endif
#ifndef SPIFFS_CFG_PHYS_ERASE_SZ
#define SPIFFS_CFG_PHYS_ERASE_SZ(ignore) (65536)
#endif
#ifndef SPIFFS_CFG_PHYS_ADDR
#define SPIFFS_CFG_PHYS_ADDR(ignore) (0)
#endif
#ifndef SPIFFS_CFG_LOG_PAGE_SZ
#define SPIFFS_CFG_LOG_PAGE_SZ(ignore) (256)
#endif
#ifndef SPIFFS_CFG_LOG_BLOCK_SZ
#define SPIFFS_CFG_LOG_BLOCK_SZ(ignore) (65536)
#endif
#endif
// Enable this if your target needs aligned data for index tables
#ifndef SPIFFS_ALIGNED_OBJECT_INDEX_TABLES
#define SPIFFS_ALIGNED_OBJECT_INDEX_TABLES 0
#endif
// Enable this if you want the HAL callbacks to be called with the spiffs struct
#ifndef SPIFFS_HAL_CALLBACK_EXTRA
#define SPIFFS_HAL_CALLBACK_EXTRA 0
#endif
// Enable this if you want to add an integer offset to all file handles
// (spiffs_file). This is useful if running multiple instances of spiffs on
// same target, in order to recognise to what spiffs instance a file handle
// belongs.
// NB: This adds config field fh_ix_offset in the configuration struct when
// mounting, which must be defined.
#ifndef SPIFFS_FILEHDL_OFFSET
#define SPIFFS_FILEHDL_OFFSET 0
#endif
// Enable this to compile a read only version of spiffs.
// This will reduce binary size of spiffs. All code comprising modification
// of the file system will not be compiled. Some config will be ignored.
// HAL functions for erasing and writing to spi-flash may be null. Cache
// can be disabled for even further binary size reduction (and ram savings).
// Functions modifying the fs will return SPIFFS_ERR_RO_NOT_IMPL.
// If the file system cannot be mounted due to aborted erase operation and
// SPIFFS_USE_MAGIC is enabled, SPIFFS_ERR_RO_ABORTED_OPERATION will be
// returned.
// Might be useful for e.g. bootloaders and such.
#ifndef SPIFFS_READ_ONLY
#define SPIFFS_READ_ONLY 0
#endif
// Enable this to add a temporal file cache using the fd buffer.
// The effects of the cache is that SPIFFS_open will find the file faster in
// certain cases. It will make it a lot easier for spiffs to find files
// opened frequently, reducing number of readings from the spi flash for
// finding those files.
// This will grow each fd by 6 bytes. If your files are opened in patterns
// with a degree of temporal locality, the system is optimized.
// Examples can be letting spiffs serve web content, where one file is the css.
// The css is accessed for each html file that is opened, meaning it is
// accessed almost every second time a file is opened. Another example could be
// a log file that is often opened, written, and closed.
// The size of the cache is number of given file descriptors, as it piggybacks
// on the fd update mechanism. The cache lives in the closed file descriptors.
// When closed, the fd know the whereabouts of the file. Instead of forgetting
// this, the temporal cache will keep handling updates to that file even if the
// fd is closed. If the file is opened again, the location of the file is found
// directly. If all available descriptors become opened, all cache memory is
// lost.
#ifndef SPIFFS_TEMPORAL_FD_CACHE
#define SPIFFS_TEMPORAL_FD_CACHE 1
#endif
// Temporal file cache hit score. Each time a file is opened, all cached files
// will lose one point. If the opened file is found in cache, that entry will
// gain SPIFFS_TEMPORAL_CACHE_HIT_SCORE points. One can experiment with this
// value for the specific access patterns of the application. However, it must
// be between 1 (no gain for hitting a cached entry often) and 255.
#ifndef SPIFFS_TEMPORAL_CACHE_HIT_SCORE
#define SPIFFS_TEMPORAL_CACHE_HIT_SCORE 4
#endif
// Enable to be able to map object indices to memory.
// This allows for faster and more deterministic reading if cases of reading
// large files and when changing file offset by seeking around a lot.
// When mapping a file's index, the file system will be scanned for index pages
// and the info will be put in memory provided by user. When reading, the
// memory map can be looked up instead of searching for index pages on the
// medium. This way, user can trade memory against performance.
// Whole, parts of, or future parts not being written yet can be mapped. The
// memory array will be owned by spiffs and updated accordingly during garbage
// collecting or when modifying the indices. The latter is invoked by when the
// file is modified in some way. The index buffer is tied to the file
// descriptor.
#ifndef SPIFFS_IX_MAP
#define SPIFFS_IX_MAP 1
#endif
// By default SPIFFS in some cases relies on the property of NOR flash that bits
// cannot be set from 0 to 1 by writing and that controllers will ignore such
// bit changes. This results in fewer reads as SPIFFS can in some cases perform
// blind writes, with all bits set to 1 and only those it needs reset set to 0.
// Most of the chips and controllers allow this behavior, so the default is to
// use this technique. If your controller is one of the rare ones that don't,
// turn this option on and SPIFFS will perform a read-modify-write instead.
#ifndef SPIFFS_NO_BLIND_WRITES
#define SPIFFS_NO_BLIND_WRITES 0
#endif
// Set SPIFFS_TEST_VISUALISATION to non-zero to enable SPIFFS_vis function
// in the api. This function will visualize all filesystem using given printf
// function.
#ifndef SPIFFS_TEST_VISUALISATION
#define SPIFFS_TEST_VISUALISATION 1
#endif
#if SPIFFS_TEST_VISUALISATION
#ifndef spiffs_printf
#define spiffs_printf(...) printf(__VA_ARGS__)
#endif
// spiffs_printf argument for a free page
#ifndef SPIFFS_TEST_VIS_FREE_STR
#define SPIFFS_TEST_VIS_FREE_STR "_"
#endif
// spiffs_printf argument for a deleted page
#ifndef SPIFFS_TEST_VIS_DELE_STR
#define SPIFFS_TEST_VIS_DELE_STR "/"
#endif
// spiffs_printf argument for an index page for given object id
#ifndef SPIFFS_TEST_VIS_INDX_STR
#define SPIFFS_TEST_VIS_INDX_STR(id) "i"
#endif
// spiffs_printf argument for a data page for given object id
#ifndef SPIFFS_TEST_VIS_DATA_STR
#define SPIFFS_TEST_VIS_DATA_STR(id) "d"
#endif
#endif
#ifndef SPIFFS_SECURE_ERASE
#define SPIFFS_SECURE_ERASE 0
#endif
// Types depending on configuration such as the amount of flash bytes
// given to spiffs file system in total (spiffs_file_system_size),
// the logical block size (log_block_size), and the logical page size
// (log_page_size)
//
// Set SPIFFS_TYPES_OVERRIDE if you wish to have your own
// definitions for these types (for example, if you want them
// to be u32_t)
#ifndef SPIFFS_TYPES_OVERRIDE
// Block index type. Make sure the size of this type can hold
// the highest number of all blocks - i.e. spiffs_file_system_size / log_block_size
typedef u16_t spiffs_block_ix;
// Page index type. Make sure the size of this type can hold
// the highest page number of all pages - i.e. spiffs_file_system_size / log_page_size
typedef u16_t spiffs_page_ix;
// Object id type - most significant bit is reserved for index flag. Make sure the
// size of this type can hold the highest object id on a full system,
// i.e. 2 + (spiffs_file_system_size / (2*log_page_size))*2
typedef u16_t spiffs_obj_id;
// Object span index type. Make sure the size of this type can
// hold the largest possible span index on the system -
// i.e. (spiffs_file_system_size / log_page_size) - 1
typedef u16_t spiffs_span_ix;
#endif
#endif /* SPIFFS_CONFIG_H_ */

View File

@ -93,11 +93,21 @@ esp32_flags=
stm32_flags=
${env.build_flags}
-I include/stm32f4
-D IRAM_ATTR= ; No IRAM_ATTR available on STM32
-D STM32
-D STREAMUTILS_USE_EEPROM_UPDATE=1 ; update cell only when changed
-D MQTT_MAX_PACKET_SIZE=2048 ; longer PubSubClient messages
[libs]
stm32_deps=
${env.lib_deps}
SPIMemory@^3.4.0
Ticker@^3.1.5
; STM32duino LwIP@^2.1.2
https://github.com/stm32duino/LwIP.git
https://github.com/khoih-prog/EthernetWebServer_STM32
; -- By default there are no ${override.build_flags} set
; -- to use it, copy platformio_override.ini from the template
[override]

View File

@ -953,7 +953,7 @@ void haspLoadPage(const char * pages)
Log.notice(F("HASP: Loading file %s"), pages);
File file = SPIFFS.open(pages, "r");
File file = SPIFFS.open(pages, FILE_READ);
dispatchJsonl(file);
file.close();

View File

@ -14,15 +14,15 @@
#include "hasp_conf.h"
#if HASP_USE_SPIFFS > 0
#include <FS.h> // Include the SPIFFS library
#if defined(ARDUINO_ARCH_ESP32)
#include "SPIFFS.h"
#endif
#endif
#if HASP_USE_EEPROM > 0
#include "EEPROM.h"
#endif
// #if HASP_USE_SPIFFS > 0
// #include <FS.h> // Include the SPIFFS library
// #if defined(ARDUINO_ARCH_ESP32)
// #include "SPIFFS.h"
// #endif
// #endif
// #if HASP_USE_EEPROM > 0
// #include "EEPROM.h"
// #endif
void confDebugSet(const char * name)
{
@ -94,7 +94,7 @@ void configGetConfig(JsonDocument & settings, bool setupdebug = false)
DeserializationError error;
#if HASP_USE_SPIFFS > 0
File file = SPIFFS.open(configFile, "r");
File file = SPIFFS.open(configFile, FILE_READ);
if(file) {
size_t size = file.size();
@ -268,7 +268,7 @@ void configWriteConfig()
if(writefile) {
#if HASP_USE_SPIFFS > 0
File file = SPIFFS.open(configFile, "w");
File file = SPIFFS.open(configFile, FILE_WRITE);
if(file) {
Log.notice(F("CONF: Writing %s"), configFile.c_str());
size_t size = serializeJson(doc, file);

View File

@ -14,6 +14,7 @@
#include "hasp_gui.h"
#include "hasp_oobe.h"
#include "hasp.h"
#include "hasp_conf.h"
//#include "lv_ex_conf.h"
//#include "tpcal.h"
@ -26,17 +27,19 @@
#define TOUCH_DRIVER 0
#endif
#if HASP_USE_SPIFFS > 0
#if defined(ARDUINO_ARCH_ESP32)
#include "SPIFFS.h"
#endif
#include <FS.h> // Include the SPIFFS library
#endif
// #if HASP_USE_SPIFFS > 0
// #if defined(ARDUINO_ARCH_ESP32)
// #include "SPIFFS.h"
// #include <FS.h> // Include the SPIFFS library
// #elif defined(ARDUINO_ARCH_ESP8266)
// #include <FS.h> // Include the SPIFFS library
// #endif
// #endif
#define BACKLIGHT_CHANNEL 15 // pwm channek 0-15
/* ---------- Screenshot Variables ---------- */
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)|| defined(STM32F4xx)
File pFileOut;
#endif
uint8_t guiSnapshot = 0;
@ -1095,7 +1098,7 @@ static void guiSendBmpHeader()
#if HASP_USE_SPIFFS > 0
void guiTakeScreenshot(const char * pFileName)
{
pFileOut = SPIFFS.open(pFileName, "w");
pFileOut = SPIFFS.open(pFileName, FILE_WRITE);
if(pFileOut == 0) {
Log.warning(F("GUI: %s cannot be opened"), pFileName);

View File

@ -23,11 +23,12 @@
#if defined(ARDUINO_ARCH_ESP32)
#include "SPIFFS.h"
#include <FS.h>
#include <FS.h>
#include <ESP.h>
#elif defined(ARDUINO_ARCH_ESP8266)
#include <FS.h>
#include <ESP.h>
#elif defined(STM32F4xx)
#include "STM32Spiffs.h"
#endif
#if HASP_USE_HTTP > 0
@ -39,6 +40,9 @@ uint16_t httpPort = 80;
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
FS * filesystem = &SPIFFS;
File fsUploadFile;
#elif defined(STM32F4xx)
SpiffsFS * filesystem = &SPIFFS;
File fsUploadFile;
#endif
char httpUser[32] = "";
@ -684,7 +688,7 @@ bool handleFileRead(String path)
if(filesystem->exists(pathWithGz) || filesystem->exists(path)) {
if(filesystem->exists(pathWithGz)) path += F(".gz");
File file = filesystem->open(path, "r");
File file = filesystem->open(path, FILE_READ);
String contentType = getContentType(path);
if(path == F("/edit.htm.gz")) {
contentType = F("text/html");
@ -712,7 +716,7 @@ void handleFileUpload()
filename += upload->filename;
}
if(filename.length() < 32) {
fsUploadFile = filesystem->open(filename, "w");
fsUploadFile = filesystem->open(filename, FILE_WRITE);
Log.notice(F("handleFileUpload Name: %s"), filename.c_str());
} else {
Log.error(F("Filename %s is too long"), filename.c_str());
@ -777,14 +781,14 @@ void handleFileCreate()
if(filesystem->exists(path)) {
return webServer.send(500, PSTR("text/plain"), PSTR("FILE EXISTS"));
}
File file = filesystem->open(path, "w");
File file = filesystem->open(path, FILE_WRITE);
if(file) {
file.close();
} else {
return webServer.send(500, PSTR("text/plain"), PSTR("CREATE FAILED"));
}
webServer.send(200, PSTR("text/plain"), "");
path.clear();
// path.clear();
}
void handleFileList()
@ -796,9 +800,11 @@ void handleFileList()
return;
}
String path = webServer.arg(F("dir"));
Log.verbose(F("handleFileList: %s"), path.c_str());
path.clear();
{
String path = webServer.arg(F("dir"));
Log.verbose(F("handleFileList: %s"), path.c_str());
// path.clear();
}
#if defined(ARDUINO_ARCH_ESP32)
File root = SPIFFS.open("/");

View File

@ -5,12 +5,12 @@
#include "hasp_conf.h"
#include "hasp_spiffs.h"
#if HASP_USE_SPIFFS>0
#if defined(ARDUINO_ARCH_ESP32)
#include "SPIFFS.h"
#endif
#include <FS.h>
#endif
// #if HASP_USE_SPIFFS>0
// #if defined(ARDUINO_ARCH_ESP32)
// #include "SPIFFS.h"
// #endif
// #include <FS.h>
// #endif
void spiffsInfo()
{ // Get all information of your SPIFFS

View File

@ -14,7 +14,6 @@ monitor_port = COM7 ; To change the port, use platform_override.ini
build_flags =
${env.build_flags}
${flags.stm32_flags}
-I include/stm32f4
; -- TFT_eSPI build options ------------------------
${lcd.lolin24}
;-D TFT_MISO=PB4 ;Default
@ -27,16 +26,17 @@ build_flags =
-D TFT_RST=-1 ;D4
-D HASP_OUTPUT_PIN=PE0 ; User LED D2 on DevEBox board
-D HASP_INPUT_PIN=PD15 ; User Button K1 on DevEBox board
-D STM32_SERIAL1 ; Set this option to use Serial1 as default sersial port, leave out if using Serial2
;-D HAL_ETH_MODULE_ENABLED=1 ; enable ethernet support
;-D LAN8742A_PHY_ADDRESS=0x01U ; set LAN8720 PHY address
-D STM32_SERIAL1 ; Set this option to use Serial1 as default serial port, leave out if using Serial2
-D HASP_USE_TASMOTA_SLAVE=1
; -- W5500 Ethernet configuration ------------------
-D HASP_USE_ETHERNET=1
-D W5500_MOSI=PB15 ;SPI2 MOSI
-D W5500_MISO=PB14 ;SPI2 MISO
-D W5500_SCLK=PB13 ;SPI2 SCLK
-D W5500_CS=PB6 ;SPI2 CS
-D W5500_RST=PD1 ;SPI2 CS
;-D HAL_ETH_MODULE_ENABLED=1 ; enable ethernet support
;-D LAN8742A_PHY_ADDRESS=0x01U ; set LAN8720 PHY address
lib_deps =
${env.lib_deps}

View File

@ -16,7 +16,6 @@ monitor_port = COM19 ; To change the port, use platform_override.ini
build_flags =
${env.build_flags}
${flags.stm32_flags}
-I include/stm32f4
; -- TFT_eSPI build options ------------------------
${lcd.lolin24}
;-D TFT_MISO=PB4 ;Default
@ -34,19 +33,23 @@ build_flags =
-D HASP_OUTPUT_PIN=PA1 ; User LED D2 on DevEBox board
-D HASP_INPUT_PIN=PA0 ; User Button K1 on DevEBox board
-D STM32_SERIAL1 ; Set this option to use Serial1 as default sersial port, leave out if using Serial2
; -- LAN8720 Ethernet configuration ------------------
-D HASP_USE_ETHERNET=1
-D USE_BUILTIN_ETHERNET=1
-D HAL_ETH_MODULE_ENABLED=1
; -D LAN8742A_PHY_ADDRESS=0x01U ; moved to include\stm32f4\hal_conf_custom.h
; -D DP83848_PHY_ADDRESS=0x01U
; -- Spiffs Configuration
-D ARCH_STM32=1
-D LOG_PAGE_SIZE=256
-D SPIFFS_HAL_CALLBACK_EXTRA=0
-D NO_TEST=1
lib_deps =
${env.lib_deps}
Ticker@^3.1.5
; STM32duino LwIP@^2.1.2
${libs.stm32_deps}
; STM32duino STM32Ethernet@^1.0.5
https://github.com/stm32duino/LwIP.git
https://github.com/stm32duino/STM32Ethernet.git
https://github.com/khoih-prog/EthernetWebServer_STM32
STM32Spiffs
https://github.com/pellepl/spiffs.git
src_filter = +<*> -<.git/> -<.svn/> -<example/> -<examples/> -<test/> -<tests/> -<lv_lib_zifont/> +<stm32f4/>