From 57da16ea6d4a2aaf4c83c183dbe0efd4330bbbf8 Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Mon, 9 Sep 2013 15:56:53 +0200 Subject: [PATCH] restructured build system, broken out generic parts --- docs/IMPLEMENTING | 0 docs/TECH_SPEC | 3 ++ files.mk | 15 ++++--- makefile | 6 +-- src/spiffs.h | 2 + src/spiffs_hydrogen.c | 3 ++ src/test/params_test.h | 6 +-- src/test/test_dev.c | 92 ++++++++++++++++++++++++++++++++++++++++++ src/test/test_spiffs.c | 52 +++++++++++++++++++++--- src/test/test_spiffs.h | 6 +++ src/test/testsuites.c | 4 +- 11 files changed, 169 insertions(+), 20 deletions(-) create mode 100644 docs/IMPLEMENTING diff --git a/docs/IMPLEMENTING b/docs/IMPLEMENTING new file mode 100644 index 0000000..e69de29 diff --git a/docs/TECH_SPEC b/docs/TECH_SPEC index ae3950e..b4755a6 100644 --- a/docs/TECH_SPEC +++ b/docs/TECH_SPEC @@ -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. +And finally, unlike NAND flashes, NOR flashes seem to not need any error +correction. They always write correctly I gather. + ** Spiffs logical structure diff --git a/files.mk b/files.mk index 47dce8b..5202ba0 100644 --- a/files.mk +++ b/files.mk @@ -1,6 +1,9 @@ -FILES += spiffs_nucleus.c \ - spiffs_gc.c \ - spiffs_hydrogen.c \ - spiffs_cache.c \ - spiffs_check.c - +spiffs = ../generic/spiffs/src +FLAGS += -DCONFIG_BUILD_SPIFFS +INC += -I${spiffs} +CPATH += ${spiffs} +CFILES += spiffs_nucleus.c +CFILES += spiffs_gc.c +CFILES += spiffs_hydrogen.c +CFILES += spiffs_cache.c +CFILES += spiffs_check.c diff --git a/makefile b/makefile index e9bc195..485d90c 100644 --- a/makefile +++ b/makefile @@ -29,7 +29,7 @@ MKDIR = mkdir -p # ############### -FILES = main.c \ +CFILES = main.c \ test_spiffs.c \ test_dev.c \ test_check.c \ @@ -48,9 +48,9 @@ COMPILEROPTIONS = $(INCLUDE_DIRECTIVES) 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) diff --git a/src/spiffs.h b/src/spiffs.h index 7f3fc90..339a748 100644 --- a/src/spiffs.h +++ b/src/spiffs.h @@ -39,6 +39,8 @@ #define SPIFFS_ERR_INTERNAL -10050 +#define SPIFFS_ERR_TEST -10100 + // spiffs file descriptor index type. must be signed typedef s16_t spiffs_file; diff --git a/src/spiffs_hydrogen.c b/src/spiffs_hydrogen.c index 249581c..539e679 100644 --- a/src/spiffs_hydrogen.c +++ b/src/spiffs_hydrogen.c @@ -541,6 +541,9 @@ static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh) { res = spiffs_hydro_write(fs, fd, spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), fd->cache_page->offset, fd->cache_page->size); + if (res < SPIFFS_OK) { + fs->errno = res; + } spiffs_cache_fd_release(fs, fd->cache_page); } } diff --git a/src/test/params_test.h b/src/test/params_test.h index ee9fcb0..3c7c6bc 100644 --- a/src/test/params_test.h +++ b/src/test/params_test.h @@ -8,10 +8,10 @@ #ifndef PARAMS_TEST_H_ #define PARAMS_TEST_H_ -#define FLASH_SIZE 2*1024*1024 +#define FLASH_SIZE (2*1024*1024) #define SECTOR_SIZE 65536 -#define LOG_BLOCK SECTOR_SIZE*2 -#define LOG_PAGE SECTOR_SIZE/256 +#define LOG_BLOCK (SECTOR_SIZE*2) +#define LOG_PAGE (SECTOR_SIZE/256) #define FD_BUF_SIZE 64*6 #define CACHE_BUF_SIZE (LOG_PAGE + 32)*8 diff --git a/src/test/test_dev.c b/src/test/test_dev.c index 0357d39..b3f3cc3 100644 --- a/src/test/test_dev.c +++ b/src/test/test_dev.c @@ -25,4 +25,96 @@ void 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) diff --git a/src/test/test_spiffs.c b/src/test/test_spiffs.c index de83d82..6fd0242 100644 --- a/src/test/test_spiffs.c +++ b/src/test/test_spiffs.c @@ -32,6 +32,10 @@ static u32_t bytes_rd = 0; static u32_t bytes_wr = 0; static u32_t reads = 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 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) { bytes_rd += size; 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); return 0; @@ -80,6 +90,12 @@ static s32_t _write(u32_t addr, u32_t size, u8_t *src) { if (log_flash_ops) { bytes_wr += size; 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++) { 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); + 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_wr = 0; reads = 0; writes = 0; - log_flash_ops = 1; - fs_check_fixes = 0; + error_after_bytes_read = 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) { @@ -406,9 +449,7 @@ int test_create_file(char *name) { CHECK_RES(res); fd = SPIFFS_open(FS, name, SPIFFS_RDONLY, 0); CHECK(fd >= 0); - log_flash_ops = 0; res = SPIFFS_fstat(FS, fd, &s); - log_flash_ops = 1; CHECK_RES(res); CHECK(strcmp((char*)s.name, name) == 0); CHECK(s.size == 0); @@ -455,9 +496,7 @@ int test_create_and_write_file(char *name, int size, int chunk_size) { close(pfd); spiffs_stat stat; - log_flash_ops = 0; res = SPIFFS_fstat(FS, fd, &stat); - log_flash_ops = 1; if (res < 0) { printf(" failed fstat, %i\n",res); } @@ -501,6 +540,7 @@ void _teardown() { #endif #endif dump_flash_access_stats(); + clear_flash_ops_log(); #if SPIFFS_GC_STATS if ((FS)->stats_gc_runs > 0) #endif diff --git a/src/test/test_spiffs.h b/src/test/test_spiffs.h index 2013c10..4949926 100644 --- a/src/test/test_spiffs.h +++ b/src/test/test_spiffs.h @@ -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 dump_erase_counts(spiffs *fs); 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); int test_create_file(char *name); diff --git a/src/test/testsuites.c b/src/test/testsuites.c index 6752f99..198b7c6 100644 --- a/src/test/testsuites.c +++ b/src/test/testsuites.c @@ -9,6 +9,6 @@ void add_suites() { ADD_SUITE(dev_tests); - ADD_SUITE(check_tests); - ADD_SUITE(hydrogen_tests) + //ADD_SUITE(check_tests); + //ADD_SUITE(hydrogen_tests) }