Skip to content

Commit 799f680

Browse files
committed
Update SPIFFS to 0.2-64-g15e5618
fix some exceptions due to unaligned memory access remove leftover changes from NodeMCU (SPIFFS_eof and SPIFFS_ftell)
1 parent d075d8b commit 799f680

File tree

9 files changed

+355
-216
lines changed

9 files changed

+355
-216
lines changed

hardware/esp8266com/esp8266/cores/esp8266/spiffs/README

+25-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
SPIFFS (SPI Flash File System)
2-
V0.3.0
2+
V0.3.2
33

44
Copyright (c) 2013-2015 Peter Andersson (pelleplutt1976<at>gmail.com)
55

@@ -58,6 +58,30 @@ For testing and contributions, see the docs/IMPLEMENTING file.
5858

5959
* HISTORY
6060

61+
0.3.2
62+
Limit cache size if too much cache is given (thanks pgeiem)
63+
New feature - Controlled erase. #23
64+
SPIFFS_rename leaks file descriptors #28 (thanks benpicco)
65+
moved dbg print defines in test framework to params_test.h
66+
lseek should return the resulting offset (thanks hefloryd)
67+
fixed type on dbg ifdefs
68+
silence warning about signed/unsigned comparison when spiffs_obj_id is 32 bit (thanks benpicco)
69+
Possible error in test_spiffs.c #21 (thanks yihcdaso-yeskela)
70+
Cache might writethrough too often #16
71+
even moar testrunner updates
72+
Test framework update and some added tests
73+
Some thoughts for next gen
74+
Test sigsevs when having too many sectors #13 (thanks alonewolfx2)
75+
GC might be suboptimal #11
76+
Fix eternal readdir when objheader at last block, last entry
77+
78+
New API functions:
79+
SPIFFS_gc_quick - call a nonintrusive gc
80+
SPIFFS_gc - call a full-scale intrusive gc
81+
82+
0.3.1
83+
Removed two return warnings, was too triggerhappy on release
84+
6185
0.3.0
6286
Added existing namecheck when creating files
6387
Lots of static analysis bugs #6

hardware/esp8266com/esp8266/cores/esp8266/spiffs/spiffs.h

+74-16
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
#ifndef SPIFFS_H_
1111
#define SPIFFS_H_
12-
#ifdef __cplusplus
12+
#if defined(__cplusplus)
1313
extern "C" {
1414
#endif
1515

@@ -47,6 +47,9 @@ extern "C" {
4747
#define SPIFFS_ERR_ERASE_FAIL -10027
4848
#define SPIFFS_ERR_MAGIC_NOT_POSSIBLE -10028
4949

50+
#define SPIFFS_ERR_NO_DELETED_BLOCKS -10029
51+
52+
#define SPIFFS_ERR_FILE_EXISTS -10030
5053

5154
#define SPIFFS_ERR_INTERNAL -10050
5255

@@ -62,12 +65,25 @@ typedef u16_t spiffs_mode;
6265
// object type
6366
typedef u8_t spiffs_obj_type;
6467

68+
#if SPIFFS_HAL_CALLBACK_EXTRA
69+
struct spiffs_t;
70+
71+
/* spi read call function type */
72+
typedef s32_t (*spiffs_read)(struct spiffs_t *fs, u32_t addr, u32_t size, u8_t *dst);
73+
/* spi write call function type */
74+
typedef s32_t (*spiffs_write)(struct spiffs_t *fs, u32_t addr, u32_t size, u8_t *src);
75+
/* spi erase call function type */
76+
typedef s32_t (*spiffs_erase)(struct spiffs_t *fs, u32_t addr, u32_t size);
77+
78+
#else // SPIFFS_HAL_CALLBACK_EXTRA
79+
6580
/* spi read call function type */
6681
typedef s32_t (*spiffs_read)(u32_t addr, u32_t size, u8_t *dst);
6782
/* spi write call function type */
6883
typedef s32_t (*spiffs_write)(u32_t addr, u32_t size, u8_t *src);
6984
/* spi erase call function type */
7085
typedef s32_t (*spiffs_erase)(u32_t addr, u32_t size);
86+
#endif // SPIFFS_HAL_CALLBACK_EXTRA
7187

7288
/* file system check callback report operation */
7389
typedef enum {
@@ -88,21 +104,26 @@ typedef enum {
88104
} spiffs_check_report;
89105

90106
/* file system check callback function */
107+
#if SPIFFS_HAL_CALLBACK_EXTRA
108+
typedef void (*spiffs_check_callback)(struct spiffs_t *fs, spiffs_check_type type, spiffs_check_report report,
109+
u32_t arg1, u32_t arg2);
110+
#else // SPIFFS_HAL_CALLBACK_EXTRA
91111
typedef void (*spiffs_check_callback)(spiffs_check_type type, spiffs_check_report report,
92112
u32_t arg1, u32_t arg2);
113+
#endif // SPIFFS_HAL_CALLBACK_EXTRA
93114

94115
#ifndef SPIFFS_DBG
95116
#define SPIFFS_DBG(...) \
96117
print(__VA_ARGS__)
97118
#endif
98119
#ifndef SPIFFS_GC_DBG
99-
#define SPIFFS_GC_DBG(...) c_printf(__VA_ARGS__)
120+
#define SPIFFS_GC_DBG(...) printf(__VA_ARGS__)
100121
#endif
101122
#ifndef SPIFFS_CACHE_DBG
102-
#define SPIFFS_CACHE_DBG(...) c_printf(__VA_ARGS__)
123+
#define SPIFFS_CACHE_DBG(...) printf(__VA_ARGS__)
103124
#endif
104125
#ifndef SPIFFS_CHECK_DBG
105-
#define SPIFFS_CHECK_DBG(...) c_printf(__VA_ARGS__)
126+
#define SPIFFS_CHECK_DBG(...) printf(__VA_ARGS__)
106127
#endif
107128

108129
/* Any write to the filehandle is appended to end of the file */
@@ -119,6 +140,8 @@ typedef void (*spiffs_check_callback)(spiffs_check_type type, spiffs_check_repor
119140
#define SPIFFS_RDWR (SPIFFS_RDONLY | SPIFFS_WRONLY)
120141
/* Any writes to the filehandle will never be cached */
121142
#define SPIFFS_DIRECT (1<<5)
143+
/* If SPIFFS_CREAT and SPIFFS_EXCL are set, SPIFFS_open() shall fail if the file exists */
144+
#define SPIFFS_EXCL (1<<6)
122145

123146
#define SPIFFS_SEEK_SET (0)
124147
#define SPIFFS_SEEK_CUR (1)
@@ -166,7 +189,7 @@ typedef struct {
166189
#endif
167190
} spiffs_config;
168191

169-
typedef struct {
192+
typedef struct spiffs_t {
170193
// file system configuration
171194
spiffs_config cfg;
172195
// number of logical blocks
@@ -224,6 +247,8 @@ typedef struct {
224247

225248
// mounted flag
226249
u8_t mounted;
250+
// user data
251+
void *user_data;
227252
// config magic
228253
u32_t config_magic;
229254
} spiffs;
@@ -387,7 +412,7 @@ s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh);
387412
* @param fs the file system struct
388413
* @param fh the filehandle of the file to close
389414
*/
390-
void SPIFFS_close(spiffs *fs, spiffs_file fh);
415+
s32_t SPIFFS_close(spiffs *fs, spiffs_file fh);
391416

392417
/**
393418
* Renames a file
@@ -440,7 +465,6 @@ struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e);
440465
*/
441466
s32_t SPIFFS_check(spiffs *fs);
442467

443-
444468
/**
445469
* Returns number of total bytes available and number of used bytes.
446470
* This is an estimation, and depends on if there a many files with little
@@ -465,27 +489,60 @@ s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used);
465489
* SPIFFS_format.
466490
* If SPIFFS_mount fails, SPIFFS_format can be called directly without calling
467491
* SPIFFS_unmount first.
492+
*
493+
* @param fs the file system struct
468494
*/
469495
s32_t SPIFFS_format(spiffs *fs);
470496

471497
/**
472498
* Returns nonzero if spiffs is mounted, or zero if unmounted.
499+
* @param fs the file system struct
473500
*/
474501
u8_t SPIFFS_mounted(spiffs *fs);
475502

476503
/**
477-
* Check if EOF reached.
478-
* @param fs the file system struct
479-
* @param fh the filehandle of the file to check
504+
* Tries to find a block where most or all pages are deleted, and erase that
505+
* block if found. Does not care for wear levelling. Will not move pages
506+
* around.
507+
* If parameter max_free_pages are set to 0, only blocks with only deleted
508+
* pages will be selected.
509+
*
510+
* NB: the garbage collector is automatically called when spiffs needs free
511+
* pages. The reason for this function is to give possibility to do background
512+
* tidying when user knows the system is idle.
513+
*
514+
* Use with care.
515+
*
516+
* Setting max_free_pages to anything larger than zero will eventually wear
517+
* flash more as a block containing free pages can be erased.
518+
*
519+
* Will set err_no to SPIFFS_OK if a block was found and erased,
520+
* SPIFFS_ERR_NO_DELETED_BLOCK if no matching block was found,
521+
* or other error.
522+
*
523+
* @param fs the file system struct
524+
* @param max_free_pages maximum number allowed free pages in block
480525
*/
481-
s32_t SPIFFS_eof(spiffs *fs, spiffs_file fh);
526+
s32_t SPIFFS_gc_quick(spiffs *fs, u16_t max_free_pages);
482527

483528
/**
484-
* Get the current position of the data pointer.
529+
* Will try to make room for given amount of bytes in the filesystem by moving
530+
* pages and erasing blocks.
531+
* If it is physically impossible, err_no will be set to SPIFFS_ERR_FULL. If
532+
* there already is this amount (or more) of free space, SPIFFS_gc will
533+
* silently return. It is recommended to call SPIFFS_info before invoking
534+
* this method in order to determine what amount of bytes to give.
535+
*
536+
* NB: the garbage collector is automatically called when spiffs needs free
537+
* pages. The reason for this function is to give possibility to do background
538+
* tidying when user knows the system is idle.
539+
*
540+
* Use with care.
541+
*
485542
* @param fs the file system struct
486-
* @param fh the filehandle of the open file
543+
* @param size amount of bytes that should be freed
487544
*/
488-
s32_t SPIFFS_tell(spiffs *fs, spiffs_file fh);
545+
s32_t SPIFFS_gc(spiffs *fs, u32_t size);
489546

490547
#if SPIFFS_TEST_VISUALISATION
491548
/**
@@ -511,8 +568,9 @@ u32_t SPIFFS_buffer_bytes_for_cache(spiffs *fs, u32_t num_pages);
511568
#endif
512569
#endif
513570

514-
515-
#ifdef __cplusplus
571+
#if SPIFFS_CACHE
572+
#endif
573+
#if defined(__cplusplus)
516574
}
517575
#endif
518576

hardware/esp8266com/esp8266/cores/esp8266/spiffs/spiffs_cache.c

+16-20
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ static spiffs_cache_page *spiffs_cache_page_get(spiffs *fs, spiffs_page_ix pix)
2020
if ((cache->cpage_use_map & (1<<i)) &&
2121
(cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 &&
2222
cp->pix == pix ) {
23-
SPIFFS_CACHE_DBG("CACHE_GET: have cache page %d for %04x\n", i, pix);
23+
SPIFFS_CACHE_DBG("CACHE_GET: have cache page %i for %04x\n", i, pix);
2424
cp->last_access = cache->last_access;
2525
return cp;
2626
}
@@ -39,16 +39,16 @@ static s32_t spiffs_cache_page_free(spiffs *fs, int ix, u8_t write_back) {
3939
(cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 &&
4040
(cp->flags & SPIFFS_CACHE_FLAG_DIRTY)) {
4141
u8_t *mem = spiffs_get_cache_page(fs, cache, ix);
42-
res = fs->cfg.hal_write_f(SPIFFS_PAGE_TO_PADDR(fs, cp->pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), mem);
42+
res = SPIFFS_HAL_WRITE(fs, SPIFFS_PAGE_TO_PADDR(fs, cp->pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), mem);
4343
}
4444

4545
cp->flags = 0;
4646
cache->cpage_use_map &= ~(1 << ix);
4747

4848
if (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) {
49-
SPIFFS_CACHE_DBG("CACHE_FREE: free cache page %d objid %04x\n", ix, cp->obj_id);
49+
SPIFFS_CACHE_DBG("CACHE_FREE: free cache page %i objid %04x\n", ix, cp->obj_id);
5050
} else {
51-
SPIFFS_CACHE_DBG("CACHE_FREE: free cache page %d pix %04x\n", ix, cp->pix);
51+
SPIFFS_CACHE_DBG("CACHE_FREE: free cache page %i pix %04x\n", ix, cp->pix);
5252
}
5353
}
5454

@@ -98,7 +98,7 @@ static spiffs_cache_page *spiffs_cache_page_allocate(spiffs *fs) {
9898
spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i);
9999
cache->cpage_use_map |= (1<<i);
100100
cp->last_access = cache->last_access;
101-
SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page %d\n", i);
101+
SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page %i\n", i);
102102
return cp;
103103
}
104104
}
@@ -137,10 +137,7 @@ s32_t spiffs_phys_rd(
137137
} else {
138138
if ((op & SPIFFS_OP_TYPE_MASK) == SPIFFS_OP_T_OBJ_LU2) {
139139
// for second layer lookup functions, we do not cache in order to prevent shredding
140-
return fs->cfg.hal_read_f(
141-
addr ,
142-
len,
143-
dst);
140+
return SPIFFS_HAL_READ(fs, addr, len, dst);
144141
}
145142
#if SPIFFS_CACHE_STATS
146143
fs->cache_misses++;
@@ -151,8 +148,7 @@ s32_t spiffs_phys_rd(
151148
cp->flags = SPIFFS_CACHE_FLAG_WRTHRU;
152149
cp->pix = SPIFFS_PADDR_TO_PAGE(fs, addr);
153150
}
154-
155-
s32_t res2 = fs->cfg.hal_read_f(
151+
s32_t res2 = SPIFFS_HAL_READ(fs,
156152
addr - SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr),
157153
SPIFFS_CFG_LOG_PAGE_SZ(fs),
158154
spiffs_get_cache_page(fs, cache, cp->ix));
@@ -161,7 +157,7 @@ s32_t spiffs_phys_rd(
161157
}
162158
}
163159
u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix);
164-
c_memcpy(dst, &mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], len);
160+
memcpy(dst, &mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], len);
165161
return res;
166162
}
167163

@@ -186,24 +182,24 @@ s32_t spiffs_phys_wr(
186182
(op & SPIFFS_OP_TYPE_MASK) != SPIFFS_OP_T_OBJ_LU) {
187183
// page is being deleted, wipe from cache - unless it is a lookup page
188184
spiffs_cache_page_free(fs, cp->ix, 0);
189-
return fs->cfg.hal_write_f(addr, len, src);
185+
return SPIFFS_HAL_WRITE(fs, addr, len, src);
190186
}
191187

192188
u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix);
193-
c_memcpy(&mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], src, len);
189+
memcpy(&mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], src, len);
194190

195191
cache->last_access++;
196192
cp->last_access = cache->last_access;
197193

198-
if (cp->flags && SPIFFS_CACHE_FLAG_WRTHRU) {
194+
if (cp->flags & SPIFFS_CACHE_FLAG_WRTHRU) {
199195
// page is being updated, no write-cache, just pass thru
200-
return fs->cfg.hal_write_f(addr, len, src);
196+
return SPIFFS_HAL_WRITE(fs, addr, len, src);
201197
} else {
202198
return SPIFFS_OK;
203199
}
204200
} else {
205201
// no cache page, no write cache - just write thru
206-
return fs->cfg.hal_write_f(addr, len, src);
202+
return SPIFFS_HAL_WRITE(fs, addr, len, src);
207203
}
208204
}
209205

@@ -282,17 +278,17 @@ void spiffs_cache_init(spiffs *fs) {
282278
}
283279

284280
spiffs_cache cache;
285-
c_memset(&cache, 0, sizeof(spiffs_cache));
281+
memset(&cache, 0, sizeof(spiffs_cache));
286282
cache.cpage_count = cache_entries;
287283
cache.cpages = (u8_t *)((u8_t *)fs->cache + sizeof(spiffs_cache));
288284

289285
cache.cpage_use_map = 0xffffffff;
290286
cache.cpage_use_mask = cache_mask;
291-
c_memcpy(fs->cache, &cache, sizeof(spiffs_cache));
287+
memcpy(fs->cache, &cache, sizeof(spiffs_cache));
292288

293289
spiffs_cache *c = spiffs_get_cache(fs);
294290

295-
c_memset(c->cpages, 0, c->cpage_count * SPIFFS_CACHE_PAGE_SIZE(fs));
291+
memset(c->cpages, 0, c->cpage_count * SPIFFS_CACHE_PAGE_SIZE(fs));
296292

297293
c->cpage_use_map &= ~(c->cpage_use_mask);
298294
for (i = 0; i < cache.cpage_count; i++) {

0 commit comments

Comments
 (0)