Browse Source

Merge pull request #173 from cesanta/flags

Be careful resetting flag bits
pull/184/merge
Peter Andersson 7 years ago
committed by GitHub
parent
commit
1350deb54c
  1. 5
      .travis.yml
  2. 11
      src/default/spiffs_config.h
  3. 23
      src/spiffs_check.c
  4. 13
      src/spiffs_nucleus.c
  5. 7
      src/test/test_spiffs.c

5
.travis.yml

@ -5,4 +5,7 @@ compiler:
before_script: before_script:
script: make all && make clean && make test && make build-all && make clean test FLAGS=-DSPIFFS_OBJ_META_LEN=8 script: >
make all && make clean && make test && make build-all &&
make clean test FLAGS=-DSPIFFS_OBJ_META_LEN=8 &&
make clean test FLAGS=-DSPIFFS_NO_BLIND_WRITES=1

11
src/default/spiffs_config.h

@ -311,6 +311,17 @@
#define SPIFFS_IX_MAP 1 #define SPIFFS_IX_MAP 1
#endif #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 // Set SPIFFS_TEST_VISUALISATION to non-zero to enable SPIFFS_vis function
// in the api. This function will visualize all filesystem using given printf // in the api. This function will visualize all filesystem using given printf
// function. // function.

23
src/spiffs_check.c

@ -161,11 +161,17 @@ static s32_t spiffs_delete_obj_lazy(spiffs *fs, spiffs_obj_id obj_id) {
return SPIFFS_OK; return SPIFFS_OK;
} }
SPIFFS_CHECK_RES(res); SPIFFS_CHECK_RES(res);
u8_t flags = 0xff & ~SPIFFS_PH_FLAG_IXDELE; u8_t flags = 0xff;
#if SPIFFS_NO_BLIND_WRITES
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ,
0, SPIFFS_PAGE_TO_PADDR(fs, objix_hdr_pix) + offsetof(spiffs_page_header, flags),
sizeof(flags), &flags);
SPIFFS_CHECK_RES(res);
#endif
flags &= ~SPIFFS_PH_FLAG_IXDELE;
res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT,
0, SPIFFS_PAGE_TO_PADDR(fs, objix_hdr_pix) + offsetof(spiffs_page_header, flags), 0, SPIFFS_PAGE_TO_PADDR(fs, objix_hdr_pix) + offsetof(spiffs_page_header, flags),
sizeof(u8_t), sizeof(flags), &flags);
(u8_t *)&flags);
return res; return res;
} }
@ -423,10 +429,17 @@ static s32_t spiffs_lookup_check_validate(spiffs *fs, spiffs_obj_id lu_obj_id, s
// just finalize // just finalize
SPIFFS_CHECK_DBG("LU: FIXUP: unfinalized page is referred, finalizing\n"); SPIFFS_CHECK_DBG("LU: FIXUP: unfinalized page is referred, finalizing\n");
CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix);
u8_t flags = 0xff & ~SPIFFS_PH_FLAG_FINAL; u8_t flags = 0xff;
#if SPIFFS_NO_BLIND_WRITES
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_READ,
0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + offsetof(spiffs_page_header, flags),
sizeof(flags), &flags);
SPIFFS_CHECK_RES(res);
#endif
flags &= ~SPIFFS_PH_FLAG_FINAL;
res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT,
0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + offsetof(spiffs_page_header, flags), 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + offsetof(spiffs_page_header, flags),
sizeof(u8_t), (u8_t*)&flags); sizeof(flags), &flags);
} }
} }
} }

13
src/spiffs_nucleus.c

@ -877,8 +877,6 @@ s32_t spiffs_page_delete(
spiffs *fs, spiffs *fs,
spiffs_page_ix pix) { spiffs_page_ix pix) {
s32_t res; s32_t res;
spiffs_page_header hdr;
hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_USED);
// mark deleted entry in source object lookup // mark deleted entry in source object lookup
spiffs_obj_id d_obj_id = SPIFFS_OBJ_ID_DELETED; spiffs_obj_id d_obj_id = SPIFFS_OBJ_ID_DELETED;
res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_DELE, res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_DELE,
@ -892,11 +890,18 @@ s32_t spiffs_page_delete(
fs->stats_p_allocated--; fs->stats_p_allocated--;
// mark deleted in source page // mark deleted in source page
u8_t flags = 0xff;
#if SPIFFS_NO_BLIND_WRITES
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_READ,
0, SPIFFS_PAGE_TO_PADDR(fs, pix) + offsetof(spiffs_page_header, flags),
sizeof(flags), &flags);
SPIFFS_CHECK_RES(res);
#endif
flags &= ~(SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_USED);
res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_DELE, res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_DELE,
0, 0,
SPIFFS_PAGE_TO_PADDR(fs, pix) + offsetof(spiffs_page_header, flags), SPIFFS_PAGE_TO_PADDR(fs, pix) + offsetof(spiffs_page_header, flags),
sizeof(u8_t), sizeof(flags), &flags);
(u8_t *)&hdr.flags);
return res; return res;
} }

7
src/test/test_spiffs.c

@ -200,7 +200,11 @@ static s32_t _write(
} }
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
if (((addr + i) & (SPIFFS_CFG_LOG_PAGE_SZ(&__fs)-1)) != offsetof(spiffs_page_header, flags)) { #if !SPIFFS_NO_BLIND_WRITES
if (((addr + i) & (SPIFFS_CFG_LOG_PAGE_SZ(&__fs)-1)) == offsetof(spiffs_page_header, flags)) {
/* Blind flag writes are allowed. */
} else
#endif
if (check_valid_flash && ((AREA(addr + i) ^ src[i]) & src[i])) { if (check_valid_flash && ((AREA(addr + i) ^ src[i]) & src[i])) {
printf("trying to write %02x to %02x at addr %08x (as part of writing %d bytes to addr %08x)\n", src[i], AREA(addr + i), addr+i, size, addr); printf("trying to write %02x to %02x at addr %08x (as part of writing %d bytes to addr %08x)\n", src[i], AREA(addr + i), addr+i, size, addr);
spiffs_page_ix pix = (addr + i) / SPIFFS_CFG_LOG_PAGE_SZ(&__fs); spiffs_page_ix pix = (addr + i) / SPIFFS_CFG_LOG_PAGE_SZ(&__fs);
@ -208,7 +212,6 @@ static s32_t _write(
ERREXIT(); ERREXIT();
return -1; return -1;
} }
}
AREA(addr + i) &= src[i]; AREA(addr + i) &= src[i];
} }
return 0; return 0;

Loading…
Cancel
Save