mirror of
https://github.com/pellepl/spiffs.git
synced 2026-09-27 03:17:35 +00:00
restructured build system, broken out generic parts
This commit is contained in:
@@ -45,6 +45,9 @@ This way of "write by nand" is used considerably in spiffs.
|
|||||||
|
|
||||||
Common characteristics of NOR flashes are quick reads, but slow writes.
|
Common characteristics of NOR flashes are quick reads, but slow writes.
|
||||||
|
|
||||||
|
And finally, unlike NAND flashes, NOR flashes seem to not need any error
|
||||||
|
correction. They always write correctly I gather.
|
||||||
|
|
||||||
|
|
||||||
** Spiffs logical structure
|
** Spiffs logical structure
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
FILES += spiffs_nucleus.c \
|
spiffs = ../generic/spiffs/src
|
||||||
spiffs_gc.c \
|
FLAGS += -DCONFIG_BUILD_SPIFFS
|
||||||
spiffs_hydrogen.c \
|
INC += -I${spiffs}
|
||||||
spiffs_cache.c \
|
CPATH += ${spiffs}
|
||||||
spiffs_check.c
|
CFILES += spiffs_nucleus.c
|
||||||
|
CFILES += spiffs_gc.c
|
||||||
|
CFILES += spiffs_hydrogen.c
|
||||||
|
CFILES += spiffs_cache.c
|
||||||
|
CFILES += spiffs_check.c
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ MKDIR = mkdir -p
|
|||||||
#
|
#
|
||||||
###############
|
###############
|
||||||
|
|
||||||
FILES = main.c \
|
CFILES = main.c \
|
||||||
test_spiffs.c \
|
test_spiffs.c \
|
||||||
test_dev.c \
|
test_dev.c \
|
||||||
test_check.c \
|
test_check.c \
|
||||||
@@ -48,9 +48,9 @@ COMPILEROPTIONS = $(INCLUDE_DIRECTIVES)
|
|||||||
|
|
||||||
vpath %.c ${sourcedir} ${sourcedir}/default ${sourcedir}/test
|
vpath %.c ${sourcedir} ${sourcedir}/default ${sourcedir}/test
|
||||||
|
|
||||||
OBJFILES = $(FILES:%.c=${builddir}/%.o)
|
OBJFILES = $(CFILES:%.c=${builddir}/%.o)
|
||||||
|
|
||||||
DEPFILES = $(FILES:%.c=${builddir}/%.d)
|
DEPFILES = $(CFILES:%.c=${builddir}/%.d)
|
||||||
|
|
||||||
ALLOBJFILES += $(OBJFILES)
|
ALLOBJFILES += $(OBJFILES)
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,8 @@
|
|||||||
|
|
||||||
#define SPIFFS_ERR_INTERNAL -10050
|
#define SPIFFS_ERR_INTERNAL -10050
|
||||||
|
|
||||||
|
#define SPIFFS_ERR_TEST -10100
|
||||||
|
|
||||||
|
|
||||||
// spiffs file descriptor index type. must be signed
|
// spiffs file descriptor index type. must be signed
|
||||||
typedef s16_t spiffs_file;
|
typedef s16_t spiffs_file;
|
||||||
|
|||||||
@@ -541,6 +541,9 @@ static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh) {
|
|||||||
res = spiffs_hydro_write(fs, fd,
|
res = spiffs_hydro_write(fs, fd,
|
||||||
spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix),
|
spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix),
|
||||||
fd->cache_page->offset, fd->cache_page->size);
|
fd->cache_page->offset, fd->cache_page->size);
|
||||||
|
if (res < SPIFFS_OK) {
|
||||||
|
fs->errno = res;
|
||||||
|
}
|
||||||
spiffs_cache_fd_release(fs, fd->cache_page);
|
spiffs_cache_fd_release(fs, fd->cache_page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,10 @@
|
|||||||
#ifndef PARAMS_TEST_H_
|
#ifndef PARAMS_TEST_H_
|
||||||
#define PARAMS_TEST_H_
|
#define PARAMS_TEST_H_
|
||||||
|
|
||||||
#define FLASH_SIZE 2*1024*1024
|
#define FLASH_SIZE (2*1024*1024)
|
||||||
#define SECTOR_SIZE 65536
|
#define SECTOR_SIZE 65536
|
||||||
#define LOG_BLOCK SECTOR_SIZE*2
|
#define LOG_BLOCK (SECTOR_SIZE*2)
|
||||||
#define LOG_PAGE SECTOR_SIZE/256
|
#define LOG_PAGE (SECTOR_SIZE/256)
|
||||||
|
|
||||||
#define FD_BUF_SIZE 64*6
|
#define FD_BUF_SIZE 64*6
|
||||||
#define CACHE_BUF_SIZE (LOG_PAGE + 32)*8
|
#define CACHE_BUF_SIZE (LOG_PAGE + 32)*8
|
||||||
|
|||||||
@@ -25,4 +25,96 @@ void teardown() {
|
|||||||
_teardown();
|
_teardown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(interrupted_write) {
|
||||||
|
const char *name = "interrupt";
|
||||||
|
const char *name2 = "interrupt2";
|
||||||
|
int res;
|
||||||
|
spiffs_file fd;
|
||||||
|
|
||||||
|
const u32_t sz = SPIFFS_CFG_LOG_PAGE_SZ(FS)*8;
|
||||||
|
u8_t *buf = malloc(sz);
|
||||||
|
memrand(buf, sz);
|
||||||
|
|
||||||
|
printf(" create reference file\n");
|
||||||
|
fd = SPIFFS_open(FS, name, SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0);
|
||||||
|
TEST_CHECK(fd > 0);
|
||||||
|
clear_flash_ops_log();
|
||||||
|
res = SPIFFS_write(FS, fd, buf, sz);
|
||||||
|
TEST_CHECK(res >= 0);
|
||||||
|
SPIFFS_close(FS, fd);
|
||||||
|
|
||||||
|
u32_t written = get_flash_ops_log_write_bytes();
|
||||||
|
printf(" written bytes: %i\n", written);
|
||||||
|
|
||||||
|
|
||||||
|
printf(" create error file\n");
|
||||||
|
fd = SPIFFS_open(FS, name2, SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0);
|
||||||
|
TEST_CHECK(fd > 0);
|
||||||
|
clear_flash_ops_log();
|
||||||
|
invoke_error_after_write_bytes(written/2, 0);
|
||||||
|
res = SPIFFS_write(FS, fd, buf, sz);
|
||||||
|
SPIFFS_close(FS, fd);
|
||||||
|
TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_TEST);
|
||||||
|
|
||||||
|
clear_flash_ops_log();
|
||||||
|
|
||||||
|
#if SPIFFS_CACHE
|
||||||
|
// delete all cache
|
||||||
|
spiffs_cache *cache = spiffs_get_cache(FS);
|
||||||
|
cache->cpage_use_map = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
printf(" read error file\n");
|
||||||
|
fd = SPIFFS_open(FS, name2, SPIFFS_RDONLY, 0);
|
||||||
|
TEST_CHECK(fd > 0);
|
||||||
|
|
||||||
|
spiffs_stat s;
|
||||||
|
res = SPIFFS_fstat(FS, fd, &s);
|
||||||
|
TEST_CHECK(res >= 0);
|
||||||
|
printf(" file size: %i\n", s.size);
|
||||||
|
|
||||||
|
if (s.size > 0) {
|
||||||
|
u8_t *buf2 = malloc(s.size);
|
||||||
|
res = SPIFFS_read(FS, fd, buf2, s.size);
|
||||||
|
TEST_CHECK(res >= 0);
|
||||||
|
|
||||||
|
u32_t ix = 0;
|
||||||
|
for (ix = 0; ix < s.size; ix += 16) {
|
||||||
|
int i;
|
||||||
|
printf(" ");
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
printf("%02x", buf[ix+i]);
|
||||||
|
}
|
||||||
|
printf(" ");
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
printf("%02x", buf2[ix+i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
free(buf2);
|
||||||
|
}
|
||||||
|
SPIFFS_close(FS, fd);
|
||||||
|
|
||||||
|
|
||||||
|
printf(" FS check\n");
|
||||||
|
SPIFFS_check(FS);
|
||||||
|
|
||||||
|
printf(" read error file again\n");
|
||||||
|
fd = SPIFFS_open(FS, name2, SPIFFS_APPEND | SPIFFS_RDWR, 0);
|
||||||
|
TEST_CHECK(fd > 0);
|
||||||
|
res = SPIFFS_fstat(FS, fd, &s);
|
||||||
|
TEST_CHECK(res >= 0);
|
||||||
|
printf(" file size: %i\n", s.size);
|
||||||
|
printf(" write file\n");
|
||||||
|
res = SPIFFS_write(FS, fd, buf, sz);
|
||||||
|
TEST_CHECK(res >= 0);
|
||||||
|
SPIFFS_close(FS, fd);
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
|
||||||
|
return TEST_RES_OK;
|
||||||
|
|
||||||
|
} TEST_END(interrupted_write)
|
||||||
|
|
||||||
SUITE_END(dev_tests)
|
SUITE_END(dev_tests)
|
||||||
|
|||||||
+46
-6
@@ -32,6 +32,10 @@ static u32_t bytes_rd = 0;
|
|||||||
static u32_t bytes_wr = 0;
|
static u32_t bytes_wr = 0;
|
||||||
static u32_t reads = 0;
|
static u32_t reads = 0;
|
||||||
static u32_t writes = 0;
|
static u32_t writes = 0;
|
||||||
|
static u32_t error_after_bytes_written = 0;
|
||||||
|
static u32_t error_after_bytes_read = 0;
|
||||||
|
static char error_after_bytes_written_once_only = 0;
|
||||||
|
static char error_after_bytes_read_once_only = 0;
|
||||||
static char log_flash_ops = 1;
|
static char log_flash_ops = 1;
|
||||||
static u32_t fs_check_fixes = 0;
|
static u32_t fs_check_fixes = 0;
|
||||||
|
|
||||||
@@ -69,6 +73,12 @@ static s32_t _read(u32_t addr, u32_t size, u8_t *dst) {
|
|||||||
if (log_flash_ops) {
|
if (log_flash_ops) {
|
||||||
bytes_rd += size;
|
bytes_rd += size;
|
||||||
reads++;
|
reads++;
|
||||||
|
if (error_after_bytes_read > 0 && bytes_rd >= error_after_bytes_read) {
|
||||||
|
if (error_after_bytes_read_once_only) {
|
||||||
|
error_after_bytes_read = 0;
|
||||||
|
}
|
||||||
|
return SPIFFS_ERR_TEST;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
memcpy(dst, &area[addr], size);
|
memcpy(dst, &area[addr], size);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -80,6 +90,12 @@ static s32_t _write(u32_t addr, u32_t size, u8_t *src) {
|
|||||||
if (log_flash_ops) {
|
if (log_flash_ops) {
|
||||||
bytes_wr += size;
|
bytes_wr += size;
|
||||||
writes++;
|
writes++;
|
||||||
|
if (error_after_bytes_written > 0 && bytes_wr >= error_after_bytes_written) {
|
||||||
|
if (error_after_bytes_written_once_only) {
|
||||||
|
error_after_bytes_written = 0;
|
||||||
|
}
|
||||||
|
return SPIFFS_ERR_TEST;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
if (((addr + i) & (LOG_PAGE-1)) != offsetof(spiffs_page_header, flags)) {
|
if (((addr + i) & (LOG_PAGE-1)) != offsetof(spiffs_page_header, flags)) {
|
||||||
@@ -293,12 +309,39 @@ void fs_reset() {
|
|||||||
|
|
||||||
SPIFFS_mount(&__fs, &c, _work, _fds, sizeof(_fds), _cache, sizeof(_cache), spiffs_check_cb_f);
|
SPIFFS_mount(&__fs, &c, _work, _fds, sizeof(_fds), _cache, sizeof(_cache), spiffs_check_cb_f);
|
||||||
|
|
||||||
|
clear_flash_ops_log();
|
||||||
|
log_flash_ops = 1;
|
||||||
|
fs_check_fixes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_flash_ops_log(int enable) {
|
||||||
|
log_flash_ops = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_flash_ops_log() {
|
||||||
bytes_rd = 0;
|
bytes_rd = 0;
|
||||||
bytes_wr = 0;
|
bytes_wr = 0;
|
||||||
reads = 0;
|
reads = 0;
|
||||||
writes = 0;
|
writes = 0;
|
||||||
log_flash_ops = 1;
|
error_after_bytes_read = 0;
|
||||||
fs_check_fixes = 0;
|
error_after_bytes_written = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32_t get_flash_ops_log_read_bytes() {
|
||||||
|
return bytes_rd;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32_t get_flash_ops_log_write_bytes() {
|
||||||
|
return bytes_wr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void invoke_error_after_read_bytes(u32_t b, char once_only) {
|
||||||
|
error_after_bytes_read = b;
|
||||||
|
error_after_bytes_read_once_only = once_only;
|
||||||
|
}
|
||||||
|
void invoke_error_after_write_bytes(u32_t b, char once_only) {
|
||||||
|
error_after_bytes_written = b;
|
||||||
|
error_after_bytes_written_once_only = once_only;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fs_set_validate_flashing(int i) {
|
void fs_set_validate_flashing(int i) {
|
||||||
@@ -406,9 +449,7 @@ int test_create_file(char *name) {
|
|||||||
CHECK_RES(res);
|
CHECK_RES(res);
|
||||||
fd = SPIFFS_open(FS, name, SPIFFS_RDONLY, 0);
|
fd = SPIFFS_open(FS, name, SPIFFS_RDONLY, 0);
|
||||||
CHECK(fd >= 0);
|
CHECK(fd >= 0);
|
||||||
log_flash_ops = 0;
|
|
||||||
res = SPIFFS_fstat(FS, fd, &s);
|
res = SPIFFS_fstat(FS, fd, &s);
|
||||||
log_flash_ops = 1;
|
|
||||||
CHECK_RES(res);
|
CHECK_RES(res);
|
||||||
CHECK(strcmp((char*)s.name, name) == 0);
|
CHECK(strcmp((char*)s.name, name) == 0);
|
||||||
CHECK(s.size == 0);
|
CHECK(s.size == 0);
|
||||||
@@ -455,9 +496,7 @@ int test_create_and_write_file(char *name, int size, int chunk_size) {
|
|||||||
close(pfd);
|
close(pfd);
|
||||||
|
|
||||||
spiffs_stat stat;
|
spiffs_stat stat;
|
||||||
log_flash_ops = 0;
|
|
||||||
res = SPIFFS_fstat(FS, fd, &stat);
|
res = SPIFFS_fstat(FS, fd, &stat);
|
||||||
log_flash_ops = 1;
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
printf(" failed fstat, %i\n",res);
|
printf(" failed fstat, %i\n",res);
|
||||||
}
|
}
|
||||||
@@ -501,6 +540,7 @@ void _teardown() {
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
dump_flash_access_stats();
|
dump_flash_access_stats();
|
||||||
|
clear_flash_ops_log();
|
||||||
#if SPIFFS_GC_STATS
|
#if SPIFFS_GC_STATS
|
||||||
if ((FS)->stats_gc_runs > 0)
|
if ((FS)->stats_gc_runs > 0)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -66,6 +66,12 @@ void area_write(u32_t addr, u8_t *buf, u32_t size);
|
|||||||
void area_read(u32_t addr, u8_t *buf, u32_t size);
|
void area_read(u32_t addr, u8_t *buf, u32_t size);
|
||||||
void dump_erase_counts(spiffs *fs);
|
void dump_erase_counts(spiffs *fs);
|
||||||
void dump_flash_access_stats();
|
void dump_flash_access_stats();
|
||||||
|
void set_flash_ops_log(int enable);
|
||||||
|
void clear_flash_ops_log();
|
||||||
|
u32_t get_flash_ops_log_read_bytes();
|
||||||
|
u32_t get_flash_ops_log_write_bytes();
|
||||||
|
void invoke_error_after_read_bytes(u32_t b, char once_only);
|
||||||
|
void invoke_error_after_write_bytes(u32_t b, char once_only);
|
||||||
|
|
||||||
void memrand(u8_t *b, int len);
|
void memrand(u8_t *b, int len);
|
||||||
int test_create_file(char *name);
|
int test_create_file(char *name);
|
||||||
|
|||||||
@@ -9,6 +9,6 @@
|
|||||||
|
|
||||||
void add_suites() {
|
void add_suites() {
|
||||||
ADD_SUITE(dev_tests);
|
ADD_SUITE(dev_tests);
|
||||||
ADD_SUITE(check_tests);
|
//ADD_SUITE(check_tests);
|
||||||
ADD_SUITE(hydrogen_tests)
|
//ADD_SUITE(hydrogen_tests)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user