Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
Nodemcu Firmware
Commits
8d68ad7e
Commit
8d68ad7e
authored
Jul 16, 2015
by
Johny Mattsson
Browse files
Updated SPIFFS to 0.3.2, plus alignment fix.
parent
239008d5
Changes
8
Hide whitespace changes
Inline
Side-by-side
app/modules/file.c
View file @
8d68ad7e
...
...
@@ -110,7 +110,7 @@ static int file_seek (lua_State *L)
int
op
=
luaL_checkoption
(
L
,
1
,
"cur"
,
modenames
);
long
offset
=
luaL_optlong
(
L
,
2
,
0
);
op
=
fs_seek
(
file_fd
,
offset
,
mode
[
op
]);
if
(
op
)
if
(
op
<
0
)
lua_pushnil
(
L
);
/* error */
else
lua_pushinteger
(
L
,
fs_tell
(
file_fd
));
...
...
app/spiffs/spiffs.h
View file @
8d68ad7e
...
...
@@ -13,7 +13,6 @@
extern
"C"
{
#endif
#include "c_stdio.h"
#include "spiffs_config.h"
#define SPIFFS_OK 0
...
...
@@ -41,6 +40,14 @@ extern "C" {
#define SPIFFS_ERR_NOT_WRITABLE -10021
#define SPIFFS_ERR_NOT_READABLE -10022
#define SPIFFS_ERR_CONFLICTING_NAME -10023
#define SPIFFS_ERR_NOT_CONFIGURED -10024
#define SPIFFS_ERR_NOT_A_FS -10025
#define SPIFFS_ERR_MOUNTED -10026
#define SPIFFS_ERR_ERASE_FAIL -10027
#define SPIFFS_ERR_MAGIC_NOT_POSSIBLE -10028
#define SPIFFS_ERR_NO_DELETED_BLOCKS -10029
#define SPIFFS_ERR_INTERNAL -10050
...
...
@@ -215,6 +222,11 @@ typedef struct {
// check callback function
spiffs_check_callback
check_cb_f
;
// mounted flag
u8_t
mounted
;
// config magic
u32_t
config_magic
;
}
spiffs
;
/* spiffs file status struct */
...
...
@@ -242,7 +254,10 @@ typedef struct {
// functions
/**
* Initializes the file system dynamic parameters and mounts the filesystem
* Initializes the file system dynamic parameters and mounts the filesystem.
* If SPIFFS_USE_MAGIC is enabled the mounting may fail with SPIFFS_ERR_NOT_A_FS
* if the flash does not contain a recognizable file system.
* In this case, SPIFFS_format must be called prior to remounting.
* @param fs the file system struct
* @param config the physical and logical configuration of the file system
* @param work a memory work buffer comprising 2*config->log_page_size
...
...
@@ -308,7 +323,7 @@ spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_fl
* @param len how much to read
* @returns number of bytes read, or -1 if error
*/
s32_t
SPIFFS_read
(
spiffs
*
fs
,
spiffs_file
fh
,
void
*
buf
,
u
32_t
len
);
s32_t
SPIFFS_read
(
spiffs
*
fs
,
spiffs_file
fh
,
void
*
buf
,
s
32_t
len
);
/**
* Writes to given filehandle.
...
...
@@ -318,7 +333,7 @@ s32_t SPIFFS_read(spiffs *fs, spiffs_file fh, void *buf, u32_t len);
* @param len how much to write
* @returns number of bytes written, or -1 if error
*/
s32_t
SPIFFS_write
(
spiffs
*
fs
,
spiffs_file
fh
,
void
*
buf
,
u
32_t
len
);
s32_t
SPIFFS_write
(
spiffs
*
fs
,
spiffs_file
fh
,
void
*
buf
,
s
32_t
len
);
/**
* Moves the read/write file offset
...
...
@@ -426,6 +441,12 @@ struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e);
*/
s32_t
SPIFFS_check
(
spiffs
*
fs
);
/**
* Searches for a block with only deleted entries. If found, it is erased.
* @param fs the file system struct
*/
s32_t
SPIFFS_erase_deleted_block
(
spiffs
*
fs
);
/**
* Returns number of total bytes available and number of used bytes.
...
...
@@ -442,13 +463,69 @@ s32_t SPIFFS_check(spiffs *fs);
s32_t
SPIFFS_info
(
spiffs
*
fs
,
u32_t
*
total
,
u32_t
*
used
);
/**
* Check if EOF reached.
* Formats the entire file system. All data will be lost.
* The filesystem must not be mounted when calling this.
*
* NB: formatting is awkward. Due to backwards compatibility, SPIFFS_mount
* MUST be called prior to formatting in order to configure the filesystem.
* If SPIFFS_mount succeeds, SPIFFS_unmount must be called before calling
* SPIFFS_format.
* If SPIFFS_mount fails, SPIFFS_format can be called directly without calling
* SPIFFS_unmount first.
*
* @param fs the file system struct
*/
s32_t
SPIFFS_format
(
spiffs
*
fs
);
/**
* Returns nonzero if spiffs is mounted, or zero if unmounted.
* @param fs the file system struct
* @param fh the filehandle of the file to check
*/
s32_t
SPIFFS_eof
(
spiffs
*
fs
,
spiffs_file
fh
);
s32_t
SPIFFS_tell
(
spiffs
*
fs
,
spiffs_file
fh
);
s32_t
SPIFFS_size
(
spiffs
*
fs
,
spiffs_file
fh
);
u8_t
SPIFFS_mounted
(
spiffs
*
fs
);
/**
* Tries to find a block where most or all pages are deleted, and erase that
* block if found. Does not care for wear levelling. Will not move pages
* around.
* If parameter max_free_pages are set to 0, only blocks with only deleted
* pages will be selected.
*
* NB: the garbage collector is automatically called when spiffs needs free
* pages. The reason for this function is to give possibility to do background
* tidying when user knows the system is idle.
*
* Use with care.
*
* Setting max_free_pages to anything larger than zero will eventually wear
* flash more as a block containing free pages can be erased.
*
* Will set err_no to SPIFFS_OK if a block was found and erased,
* SPIFFS_ERR_NO_DELETED_BLOCK if no matching block was found,
* or other error.
*
* @param fs the file system struct
* @param max_free_pages maximum number allowed free pages in block
*/
s32_t
SPIFFS_gc_quick
(
spiffs
*
fs
,
u16_t
max_free_pages
);
/**
* Will try to make room for given amount of bytes in the filesystem by moving
* pages and erasing blocks.
* If it is physically impossible, err_no will be set to SPIFFS_ERR_FULL. If
* there already is this amount (or more) of free space, SPIFFS_gc will
* silently return. It is recommended to call SPIFFS_info before invoking
* this method in order to determine what amount of bytes to give.
*
* NB: the garbage collector is automatically called when spiffs needs free
* pages. The reason for this function is to give possibility to do background
* tidying when user knows the system is idle.
*
* Use with care.
*
* @param fs the file system struct
* @param size amount of bytes that should be freed
*/
s32_t
SPIFFS_gc
(
spiffs
*
fs
,
u32_t
size
);
#if SPIFFS_TEST_VISUALISATION
/**
...
...
@@ -495,6 +572,10 @@ int myspiffs_check( void );
int
myspiffs_rename
(
const
char
*
old
,
const
char
*
newname
);
size_t
myspiffs_size
(
int
fd
);
s32_t
SPIFFS_eof
(
spiffs
*
fs
,
spiffs_file
fh
);
s32_t
SPIFFS_tell
(
spiffs
*
fs
,
spiffs_file
fh
);
s32_t
SPIFFS_size
(
spiffs
*
fs
,
spiffs_file
fh
);
#if defined(__cplusplus)
}
#endif
...
...
app/spiffs/spiffs_cache.c
View file @
8d68ad7e
...
...
@@ -195,7 +195,7 @@ s32_t spiffs_phys_wr(
cache
->
last_access
++
;
cp
->
last_access
=
cache
->
last_access
;
if
(
cp
->
flags
&
&
SPIFFS_CACHE_FLAG_WRTHRU
)
{
if
(
cp
->
flags
&
SPIFFS_CACHE_FLAG_WRTHRU
)
{
// page is being updated, no write-cache, just pass thru
return
fs
->
cfg
.
hal_write_f
(
addr
,
len
,
src
);
}
else
{
...
...
app/spiffs/spiffs_config.h
View file @
8d68ad7e
...
...
@@ -119,6 +119,14 @@ typedef uint8_t u8_t;
#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
// SPIFFS_LOCK and SPIFFS_UNLOCK protects spiffs from reentrancy on api level
// These should be defined on a multithreaded system
...
...
app/spiffs/spiffs_gc.c
View file @
8d68ad7e
...
...
@@ -8,31 +8,11 @@ static s32_t spiffs_gc_erase_block(
spiffs
*
fs
,
spiffs_block_ix
bix
)
{
s32_t
res
;
u32_t
addr
=
SPIFFS_BLOCK_TO_PADDR
(
fs
,
bix
);
s32_t
size
=
SPIFFS_CFG_LOG_BLOCK_SZ
(
fs
);
SPIFFS_GC_DBG
(
"gc: erase block %i
\n
"
,
bix
);
// here we ignore res, just try erasing the block
while
(
size
>
0
)
{
SPIFFS_GC_DBG
(
"gc: erase %08x:%08x
\n
"
,
addr
,
SPIFFS_CFG_PHYS_ERASE_SZ
(
fs
));
(
void
)
fs
->
cfg
.
hal_erase_f
(
addr
,
SPIFFS_CFG_PHYS_ERASE_SZ
(
fs
));
addr
+=
SPIFFS_CFG_PHYS_ERASE_SZ
(
fs
);
size
-=
SPIFFS_CFG_PHYS_ERASE_SZ
(
fs
);
}
fs
->
free_blocks
++
;
// register erase count for this block
res
=
_spiffs_wr
(
fs
,
SPIFFS_OP_C_WRTHRU
|
SPIFFS_OP_T_OBJ_LU2
,
0
,
SPIFFS_ERASE_COUNT_PADDR
(
fs
,
bix
),
sizeof
(
spiffs_obj_id
),
(
u8_t
*
)
&
fs
->
max_erase_count
);
res
=
spiffs_erase_block
(
fs
,
bix
);
SPIFFS_CHECK_RES
(
res
);
fs
->
max_erase_count
++
;
if
(
fs
->
max_erase_count
==
SPIFFS_OBJ_ID_IX_FLAG
)
{
fs
->
max_erase_count
=
0
;
}
#if SPIFFS_CACHE
{
u32_t
i
;
...
...
@@ -48,7 +28,7 @@ static s32_t spiffs_gc_erase_block(
// the block is erased. Compared to the non-quick gc, the quick one ensures
// that no updates are needed on existing objects on pages that are erased.
s32_t
spiffs_gc_quick
(
spiffs
*
fs
)
{
spiffs
*
fs
,
u16_t
max_free_pages
)
{
s32_t
res
=
SPIFFS_OK
;
u32_t
blocks
=
fs
->
block_count
;
spiffs_block_ix
cur_block
=
0
;
...
...
@@ -67,6 +47,7 @@ s32_t spiffs_gc_quick(
// check each block
while
(
res
==
SPIFFS_OK
&&
blocks
--
)
{
u16_t
deleted_pages_in_block
=
0
;
u16_t
free_pages_in_block
=
0
;
int
obj_lookup_page
=
0
;
// check each object lookup page
...
...
@@ -83,9 +64,12 @@ s32_t spiffs_gc_quick(
deleted_pages_in_block
++
;
}
else
if
(
obj_id
==
SPIFFS_OBJ_ID_FREE
)
{
// kill scan, go for next block
obj_lookup_page
=
SPIFFS_OBJ_LOOKUP_PAGES
(
fs
);
res
=
1
;
// kill object lu loop
break
;
free_pages_in_block
++
;
if
(
free_pages_in_block
>
max_free_pages
)
{
obj_lookup_page
=
SPIFFS_OBJ_LOOKUP_PAGES
(
fs
);
res
=
1
;
// kill object lu loop
break
;
}
}
else
{
// kill scan, go for next block
obj_lookup_page
=
SPIFFS_OBJ_LOOKUP_PAGES
(
fs
);
...
...
@@ -98,7 +82,9 @@ s32_t spiffs_gc_quick(
}
// per object lookup page
if
(
res
==
1
)
res
=
SPIFFS_OK
;
if
(
res
==
SPIFFS_OK
&&
deleted_pages_in_block
==
SPIFFS_PAGES_PER_BLOCK
(
fs
)
-
SPIFFS_OBJ_LOOKUP_PAGES
(
fs
))
{
if
(
res
==
SPIFFS_OK
&&
deleted_pages_in_block
+
free_pages_in_block
==
SPIFFS_PAGES_PER_BLOCK
(
fs
)
-
SPIFFS_OBJ_LOOKUP_PAGES
(
fs
)
&&
free_pages_in_block
<=
max_free_pages
)
{
// found a fully deleted block
fs
->
stats_p_deleted
-=
deleted_pages_in_block
;
res
=
spiffs_gc_erase_block
(
fs
,
cur_block
);
...
...
@@ -110,10 +96,13 @@ s32_t spiffs_gc_quick(
cur_block_addr
+=
SPIFFS_CFG_LOG_BLOCK_SZ
(
fs
);
}
// per block
if
(
res
==
SPIFFS_OK
)
{
res
=
SPIFFS_ERR_NO_DELETED_BLOCKS
;
}
return
res
;
}
// Checks if garbag
a
collecting is necessary. If so a candidate block is found,
// Checks if garbag
e
collecting is necessary. If so a candidate block is found,
// cleansed and erased
s32_t
spiffs_gc_check
(
spiffs
*
fs
,
...
...
@@ -130,12 +119,15 @@ s32_t spiffs_gc_check(
}
u32_t
needed_pages
=
(
len
+
SPIFFS_DATA_PAGE_SIZE
(
fs
)
-
1
)
/
SPIFFS_DATA_PAGE_SIZE
(
fs
);
if
(
fs
->
free_blocks
<=
2
&&
(
s32_t
)
needed_pages
>
free_pages
)
{
// if (fs->free_blocks <= 2 && (s32_t)needed_pages > free_pages) {
// SPIFFS_GC_DBG("gc: full freeblk:%i needed:%i free:%i dele:%i\n", fs->free_blocks, needed_pages, free_pages, fs->stats_p_deleted);
// return SPIFFS_ERR_FULL;
// }
if
((
s32_t
)
needed_pages
>
(
s32_t
)(
free_pages
+
fs
->
stats_p_deleted
))
{
SPIFFS_GC_DBG
(
"gc_check: full freeblk:%i needed:%i free:%i dele:%i
\n
"
,
fs
->
free_blocks
,
needed_pages
,
free_pages
,
fs
->
stats_p_deleted
);
return
SPIFFS_ERR_FULL
;
}
//printf("gcing started %i dirty, blocks %i free, want %i bytes\n", fs->stats_p_allocated + fs->stats_p_deleted, fs->free_blocks, len);
do
{
SPIFFS_GC_DBG
(
"
\n
gc_check #%i: run gc free_blocks:%i pfree:%i pallo:%i pdele:%i [%i] len:%i of %i
\n
"
,
tries
,
...
...
@@ -145,11 +137,13 @@ s32_t spiffs_gc_check(
spiffs_block_ix
*
cands
;
int
count
;
spiffs_block_ix
cand
;
res
=
spiffs_gc_find_candidate
(
fs
,
&
cands
,
&
count
);
s32_t
prev_free_pages
=
free_pages
;
// if the fs is crammed, ignore block age when selecting candidate - kind of a bad state
res
=
spiffs_gc_find_candidate
(
fs
,
&
cands
,
&
count
,
free_pages
<=
0
);
SPIFFS_CHECK_RES
(
res
);
if
(
count
==
0
)
{
SPIFFS_GC_DBG
(
"gc_check: no candidates, return
\n
"
);
return
res
;
return
(
s32_t
)
needed_pages
<
free_pages
?
SPIFFS_OK
:
SPIFFS_ERR_FULL
;
}
#if SPIFFS_GC_STATS
fs
->
stats_gc_runs
++
;
...
...
@@ -176,6 +170,12 @@ s32_t spiffs_gc_check(
(
SPIFFS_PAGES_PER_BLOCK
(
fs
)
-
SPIFFS_OBJ_LOOKUP_PAGES
(
fs
))
*
(
fs
->
block_count
-
2
)
-
fs
->
stats_p_allocated
-
fs
->
stats_p_deleted
;
if
(
prev_free_pages
<=
0
&&
prev_free_pages
==
free_pages
)
{
// abort early to reduce wear, at least tried once
SPIFFS_GC_DBG
(
"gc_check: early abort, no result on gc when fs crammed
\n
"
);
break
;
}
}
while
(
++
tries
<
SPIFFS_GC_MAX_RUNS
&&
(
fs
->
free_blocks
<=
2
||
(
s32_t
)
len
>
free_pages
*
(
s32_t
)
SPIFFS_DATA_PAGE_SIZE
(
fs
)));
...
...
@@ -234,7 +234,8 @@ s32_t spiffs_gc_erase_page_stats(
s32_t
spiffs_gc_find_candidate
(
spiffs
*
fs
,
spiffs_block_ix
**
block_candidates
,
int
*
candidate_count
)
{
int
*
candidate_count
,
char
fs_crammed
)
{
s32_t
res
=
SPIFFS_OK
;
u32_t
blocks
=
fs
->
block_count
;
spiffs_block_ix
cur_block
=
0
;
...
...
@@ -307,7 +308,7 @@ s32_t spiffs_gc_find_candidate(
s32_t
score
=
deleted_pages_in_block
*
SPIFFS_GC_HEUR_W_DELET
+
used_pages_in_block
*
SPIFFS_GC_HEUR_W_USED
+
erase_age
*
SPIFFS_GC_HEUR_W_ERASE_AGE
;
erase_age
*
(
fs_crammed
?
0
:
SPIFFS_GC_HEUR_W_ERASE_AGE
)
;
int
cand_ix
=
0
;
SPIFFS_GC_DBG
(
"gc_check: bix:%i del:%i use:%i score:%i
\n
"
,
cur_block
,
deleted_pages_in_block
,
used_pages_in_block
,
score
);
while
(
cand_ix
<
max_candidates
)
{
...
...
app/spiffs/spiffs_hydrogen.c
View file @
8d68ad7e
...
...
@@ -21,6 +21,36 @@ u32_t SPIFFS_buffer_bytes_for_cache(spiffs *fs, u32_t num_pages) {
#endif
#endif
u8_t
SPIFFS_mounted
(
spiffs
*
fs
)
{
return
SPIFFS_CHECK_MOUNT
(
fs
);
}
s32_t
SPIFFS_format
(
spiffs
*
fs
)
{
SPIFFS_API_CHECK_CFG
(
fs
);
if
(
SPIFFS_CHECK_MOUNT
(
fs
))
{
fs
->
err_code
=
SPIFFS_ERR_MOUNTED
;
return
-
1
;
}
s32_t
res
;
SPIFFS_LOCK
(
fs
);
spiffs_block_ix
bix
=
0
;
while
(
bix
<
fs
->
block_count
)
{
fs
->
max_erase_count
=
0
;
res
=
spiffs_erase_block
(
fs
,
bix
);
if
(
res
!=
SPIFFS_OK
)
{
res
=
SPIFFS_ERR_ERASE_FAIL
;
}
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
bix
++
;
}
SPIFFS_UNLOCK
(
fs
);
return
0
;
}
s32_t
SPIFFS_mount
(
spiffs
*
fs
,
spiffs_config
*
config
,
u8_t
*
work
,
u8_t
*
fd_space
,
u32_t
fd_space_size
,
void
*
cache
,
u32_t
cache_size
,
...
...
@@ -34,10 +64,10 @@ s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work,
c_memset
(
fd_space
,
0
,
fd_space_size
);
// align fd_space pointer to pointer size byte boundary, below is safe
u8_t
ptr_size
=
sizeof
(
void
*
);
//
#pragma GCC diagnostic push
//
#pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
u8_t
addr_lsb
=
(
u8
_t
)(((
u32
_t
)
fd_space
)
&
(
ptr_size
-
1
)
)
;
//
#pragma GCC diagnostic pop
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
u8_t
addr_lsb
=
(
(
u8_t
)
fd_space
)
&
(
ptr_size
-
1
);
#pragma GCC diagnostic pop
if
(
addr_lsb
)
{
fd_space
+=
(
ptr_size
-
addr_lsb
);
fd_space_size
-=
(
ptr_size
-
addr_lsb
);
...
...
@@ -46,10 +76,10 @@ s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work,
fs
->
fd_count
=
(
fd_space_size
/
sizeof
(
spiffs_fd
));
// align cache pointer to 4 byte boundary, below is safe
//
#pragma GCC diagnostic push
//
#pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
addr_lsb
=
(
u8
_t
)(((
u32
_t
)
cache
)
&
(
ptr_size
-
1
)
)
;
//
#pragma GCC diagnostic pop
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
addr_lsb
=
(
(
u8_t
)
cache
)
&
(
ptr_size
-
1
);
#pragma GCC diagnostic pop
if
(
addr_lsb
)
{
u8_t
*
cache_8
=
(
u8_t
*
)
cache
;
cache_8
+=
(
ptr_size
-
addr_lsb
);
...
...
@@ -61,11 +91,20 @@ s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work,
}
#if SPIFFS_CACHE
fs
->
cache
=
cache
;
fs
->
cache_size
=
cache_size
;
fs
->
cache_size
=
(
cache_size
>
(
config
->
log_page_size
*
32
))
?
config
->
log_page_size
*
32
:
cache_size
;
spiffs_cache_init
(
fs
);
#endif
s32_t
res
=
spiffs_obj_lu_scan
(
fs
);
s32_t
res
;
#if SPIFFS_USE_MAGIC
res
=
SPIFFS_CHECK_MAGIC_POSSIBLE
(
fs
)
?
SPIFFS_OK
:
SPIFFS_ERR_MAGIC_NOT_POSSIBLE
;
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
#endif
fs
->
config_magic
=
SPIFFS_CONFIG_MAGIC
;
res
=
spiffs_obj_lu_scan
(
fs
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
SPIFFS_DBG
(
"page index byte len: %i
\n
"
,
SPIFFS_CFG_LOG_PAGE_SZ
(
fs
));
...
...
@@ -79,13 +118,15 @@ s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work,
fs
->
check_cb_f
=
check_cb_f
;
fs
->
mounted
=
1
;
SPIFFS_UNLOCK
(
fs
);
return
0
;
}
void
SPIFFS_unmount
(
spiffs
*
fs
)
{
if
(
!
SPIFFS_CHECK_MOUNT
(
fs
))
return
;
if
(
!
SPIFFS_CHECK_CFG
(
fs
)
||
!
SPIFFS_CHECK_MOUNT
(
fs
))
return
;
SPIFFS_LOCK
(
fs
);
u32_t
i
;
spiffs_fd
*
fds
=
(
spiffs_fd
*
)
fs
->
fd_space
;
...
...
@@ -98,7 +139,8 @@ void SPIFFS_unmount(spiffs *fs) {
spiffs_fd_return
(
fs
,
cur_fd
->
file_nbr
);
}
}
fs
->
block_count
=
0
;
fs
->
mounted
=
0
;
SPIFFS_UNLOCK
(
fs
);
}
...
...
@@ -112,6 +154,7 @@ void SPIFFS_clearerr(spiffs *fs) {
s32_t
SPIFFS_creat
(
spiffs
*
fs
,
char
*
path
,
spiffs_mode
mode
)
{
(
void
)
mode
;
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
spiffs_obj_id
obj_id
;
...
...
@@ -127,6 +170,7 @@ s32_t SPIFFS_creat(spiffs *fs, char *path, spiffs_mode mode) {
spiffs_file
SPIFFS_open
(
spiffs
*
fs
,
char
*
path
,
spiffs_flags
flags
,
spiffs_mode
mode
)
{
(
void
)
mode
;
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
...
...
@@ -185,6 +229,7 @@ spiffs_file SPIFFS_open(spiffs *fs, char *path, spiffs_flags flags, spiffs_mode
}
spiffs_file
SPIFFS_open_by_dirent
(
spiffs
*
fs
,
struct
spiffs_dirent
*
e
,
spiffs_flags
flags
,
spiffs_mode
mode
)
{
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
...
...
@@ -213,7 +258,8 @@ spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_fl
return
fd
->
file_nbr
;
}
s32_t
SPIFFS_read
(
spiffs
*
fs
,
spiffs_file
fh
,
void
*
buf
,
u32_t
len
)
{
s32_t
SPIFFS_read
(
spiffs
*
fs
,
spiffs_file
fh
,
void
*
buf
,
s32_t
len
)
{
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
...
...
@@ -281,7 +327,8 @@ static s32_t spiffs_hydro_write(spiffs *fs, spiffs_fd *fd, void *buf, u32_t offs
}
s32_t
SPIFFS_write
(
spiffs
*
fs
,
spiffs_file
fh
,
void
*
buf
,
u32_t
len
)
{
s32_t
SPIFFS_write
(
spiffs
*
fs
,
spiffs_file
fh
,
void
*
buf
,
s32_t
len
)
{
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
...
...
@@ -400,6 +447,7 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, u32_t len) {
}
s32_t
SPIFFS_lseek
(
spiffs
*
fs
,
spiffs_file
fh
,
s32_t
offs
,
int
whence
)
{
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
...
...
@@ -440,10 +488,11 @@ s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) {
SPIFFS_UNLOCK
(
fs
);
return
0
;
return
offs
;
}
s32_t
SPIFFS_remove
(
spiffs
*
fs
,
char
*
path
)
{
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
...
...
@@ -477,6 +526,7 @@ s32_t SPIFFS_remove(spiffs *fs, char *path) {
}
s32_t
SPIFFS_fremove
(
spiffs
*
fs
,
spiffs_file
fh
)
{
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
...
...
@@ -525,6 +575,7 @@ static s32_t spiffs_stat_pix(spiffs *fs, spiffs_page_ix pix, spiffs_file fh, spi
}
s32_t
SPIFFS_stat
(
spiffs
*
fs
,
char
*
path
,
spiffs_stat
*
s
)
{
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
...
...
@@ -542,6 +593,7 @@ s32_t SPIFFS_stat(spiffs *fs, char *path, spiffs_stat *s) {
}
s32_t
SPIFFS_fstat
(
spiffs
*
fs
,
spiffs_file
fh
,
spiffs_stat
*
s
)
{
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
...
...
@@ -595,6 +647,7 @@ static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh) {
}
s32_t
SPIFFS_fflush
(
spiffs
*
fs
,
spiffs_file
fh
)
{
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
s32_t
res
=
SPIFFS_OK
;
#if SPIFFS_CACHE_WR
...
...
@@ -608,6 +661,11 @@ s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh) {
}
void
SPIFFS_close
(
spiffs
*
fs
,
spiffs_file
fh
)
{
if
(
!
SPIFFS_CHECK_CFG
((
fs
)))
{
(
fs
)
->
err_code
=
SPIFFS_ERR_NOT_CONFIGURED
;
return
;
}
if
(
!
SPIFFS_CHECK_MOUNT
(
fs
))
{
fs
->
err_code
=
SPIFFS_ERR_NOT_MOUNTED
;
return
;
...
...
@@ -623,6 +681,7 @@ void SPIFFS_close(spiffs *fs, spiffs_file fh) {
}
s32_t
SPIFFS_rename
(
spiffs
*
fs
,
char
*
old
,
char
*
new
)
{
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
...
...
@@ -652,9 +711,8 @@ s32_t SPIFFS_rename(spiffs *fs, char *old, char *new) {
res
=
spiffs_object_update_index_hdr
(
fs
,
fd
,
fd
->
obj_id
,
fd
->
objix_hdr_pix
,
0
,
(
u8_t
*
)
new
,
0
,
&
pix_dummy
);
if
(
res
!=
SPIFFS_OK
)
{
spiffs_fd_return
(
fs
,
fd
->
file_nbr
);
}
spiffs_fd_return
(
fs
,
fd
->
file_nbr
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
SPIFFS_UNLOCK
(
fs
);
...
...
@@ -664,10 +722,17 @@ s32_t SPIFFS_rename(spiffs *fs, char *old, char *new) {
spiffs_DIR
*
SPIFFS_opendir
(
spiffs
*
fs
,
char
*
name
,
spiffs_DIR
*
d
)
{
(
void
)
name
;
if
(
!
SPIFFS_CHECK_CFG
((
fs
)))
{
(
fs
)
->
err_code
=
SPIFFS_ERR_NOT_CONFIGURED
;
return
0
;
}
if
(
!
SPIFFS_CHECK_MOUNT
(
fs
))
{
fs
->
err_code
=
SPIFFS_ERR_NOT_MOUNTED
;
return
0
;
}
d
->
fs
=
fs
;
d
->
block
=
0
;
d
->
entry
=
0
;
...
...
@@ -743,12 +808,14 @@ struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e) {
}
s32_t
SPIFFS_closedir
(
spiffs_DIR
*
d
)
{
SPIFFS_API_CHECK_CFG
(
d
->
fs
);
SPIFFS_API_CHECK_MOUNT
(
d
->
fs
);
return
0
;
}
s32_t
SPIFFS_check
(
spiffs
*
fs
)
{
s32_t
res
;
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
...
...
@@ -766,6 +833,7 @@ s32_t SPIFFS_check(spiffs *fs) {
s32_t
SPIFFS_info
(
spiffs
*
fs
,
u32_t
*
total
,
u32_t
*
used
)
{
s32_t
res
=
SPIFFS_OK
;
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
...
...
@@ -787,7 +855,7 @@ s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used) {
return
res
;
}
s32_t
SPIFFS_
eof
(
spiffs
*
fs
,
spiffs_file
fh
)
{
s32_t
SPIFFS_
tell
(
spiffs
*
fs
,
spiffs_file
fh
)
{
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
...
...
@@ -800,13 +868,13 @@ s32_t SPIFFS_eof(spiffs *fs, spiffs_file fh) {
spiffs_fflush_cache
(
fs
,
fh
);
#endif
res
=
(
fd
->
fdoffset
==
fd
->
size
)
;
res
=
fd
->
fdoffset
;
SPIFFS_UNLOCK
(
fs
);
return
res
;
}
s32_t
SPIFFS_
tell
(
spiffs
*
fs
,
spiffs_file
fh
)
{
s32_t
SPIFFS_
eof
(
spiffs
*
fs
,
spiffs_file
fh
)
{
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
...
...
@@ -819,7 +887,7 @@ s32_t SPIFFS_tell(spiffs *fs, spiffs_file fh) {
spiffs_fflush_cache
(
fs
,
fh
);
#endif
res
=
fd
->
fdoffset
;
res
=
(
fd
->
fdoffset
==
fd
->
size
)
;
SPIFFS_UNLOCK
(
fs
);
return
res
;
...
...
@@ -844,9 +912,38 @@ s32_t SPIFFS_size(spiffs *fs, spiffs_file fh) {
return
res
;
}
s32_t
SPIFFS_gc_quick
(
spiffs
*
fs
,
u16_t
max_free_pages
)
{
s32_t
res
;
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
res
=
spiffs_gc_quick
(
fs
,
max_free_pages
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
SPIFFS_UNLOCK
(
fs
);
return
0
;
}
s32_t
SPIFFS_gc
(
spiffs
*
fs
,
u32_t
size
)
{
s32_t
res
;
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
res
=
spiffs_gc_check
(
fs
,
size
);
SPIFFS_API_CHECK_RES_UNLOCK
(
fs
,
res
);
SPIFFS_UNLOCK
(
fs
);
return
0
;
}
#if SPIFFS_TEST_VISUALISATION
s32_t
SPIFFS_vis
(
spiffs
*
fs
)
{
s32_t
res
=
SPIFFS_OK
;
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
...
...
app/spiffs/spiffs_nucleus.c
View file @
8d68ad7e
...
...
@@ -142,9 +142,13 @@ s32_t spiffs_obj_lu_find_entry_visitor(
cur_block
++
;
cur_block_addr
=
cur_block
*
SPIFFS_CFG_LOG_BLOCK_SZ
(
fs
);
if
(
cur_block
>=
fs
->
block_count
)
{
// block wrap
cur_block
=
0
;
cur_block_addr
=
0
;
if
(
flags
&
SPIFFS_VIS_NO_WRAP
)
{
return
SPIFFS_VIS_END
;
}
else
{
// block wrap
cur_block
=
0
;
cur_block_addr
=
0
;
}
}
}
...
...
@@ -213,6 +217,45 @@ s32_t spiffs_obj_lu_find_entry_visitor(
return
SPIFFS_VIS_END
;
}
s32_t
spiffs_erase_block
(
spiffs
*
fs
,
spiffs_block_ix
bix
)
{
s32_t
res
;
u32_t
addr
=
SPIFFS_BLOCK_TO_PADDR
(
fs
,
bix
);
s32_t
size
=
SPIFFS_CFG_LOG_BLOCK_SZ
(
fs
);
// here we ignore res, just try erasing the block
while
(
size
>
0
)
{
SPIFFS_DBG
(
"erase %08x:%08x
\n
"
,
addr
,
SPIFFS_CFG_PHYS_ERASE_SZ
(
fs
));
(
void
)
fs
->
cfg
.
hal_erase_f
(
addr
,
SPIFFS_CFG_PHYS_ERASE_SZ
(
fs
));
addr
+=
SPIFFS_CFG_PHYS_ERASE_SZ
(
fs
);
size
-=
SPIFFS_CFG_PHYS_ERASE_SZ
(
fs
);
}
fs
->
free_blocks
++
;
// register erase count for this block
res
=
_spiffs_wr
(
fs
,
SPIFFS_OP_C_WRTHRU
|
SPIFFS_OP_T_OBJ_LU2
,
0
,
SPIFFS_ERASE_COUNT_PADDR
(
fs
,
bix
),
sizeof
(
spiffs_obj_id
),
(
u8_t
*
)
&
fs
->
max_erase_count
);
SPIFFS_CHECK_RES
(
res
);
#if SPIFFS_USE_MAGIC
// finally, write magic
spiffs_obj_id
magic
=
SPIFFS_MAGIC
(
fs
);
res
=
_spiffs_wr
(
fs
,
SPIFFS_OP_C_WRTHRU
|
SPIFFS_OP_T_OBJ_LU2
,
0
,
SPIFFS_MAGIC_PADDR
(
fs
,
bix
),
sizeof
(
spiffs_obj_id
),
(
u8_t
*
)
&
magic
);
SPIFFS_CHECK_RES
(
res
);
#endif
fs
->
max_erase_count
++
;
if
(
fs
->
max_erase_count
==
SPIFFS_OBJ_ID_IX_FLAG
)
{
fs
->
max_erase_count
=
0
;
}
return
res
;
}
static
s32_t
spiffs_obj_lu_scan_v
(
spiffs
*
fs
,
...
...
@@ -238,40 +281,44 @@ static s32_t spiffs_obj_lu_scan_v(
return
SPIFFS_VIS_COUNTINUE
;
}
// Scans thru all obj lu and counts free, deleted and used pages
// Find the maximum block erase count
// Checks magic if enabled
s32_t
spiffs_obj_lu_scan
(
spiffs
*
fs
)
{
s32_t
res
;
spiffs_block_ix
bix
;
int
entry
;
#if SPIFFS_USE_MAGIC
spiffs_block_ix
unerased_bix
=
(
spiffs_block_ix
)
-
1
;
#endif
fs
->
free_blocks
=
0
;
fs
->
stats_p_allocated
=
0
;
fs
->
stats_p_deleted
=
0
;
res
=
spiffs_obj_lu_find_entry_visitor
(
fs
,
0
,
0
,
0
,
0
,
spiffs_obj_lu_scan_v
,
0
,
0
,
&
bix
,
&
entry
);
if
(
res
==
SPIFFS_VIS_END
)
{
res
=
SPIFFS_OK
;
}
SPIFFS_CHECK_RES
(
res
);
// find out erase count
// if enabled, check magic
bix
=
0
;
spiffs_obj_id
erase_count_final
;
spiffs_obj_id
erase_count_min
=
SPIFFS_OBJ_ID_FREE
;
spiffs_obj_id
erase_count_max
=
0
;
while
(
bix
<
fs
->
block_count
)
{
#if SPIFFS_USE_MAGIC
spiffs_obj_id
magic
;
res
=
_spiffs_rd
(
fs
,
SPIFFS_OP_T_OBJ_LU2
|
SPIFFS_OP_C_READ
,
0
,
SPIFFS_MAGIC_PADDR
(
fs
,
bix
)
,
sizeof
(
spiffs_obj_id
),
(
u8_t
*
)
&
magic
);
SPIFFS_CHECK_RES
(
res
);
if
(
magic
!=
SPIFFS_MAGIC
(
fs
))
{
if
(
unerased_bix
==
(
spiffs_block_ix
)
-
1
)
{
// allow one unerased block as it might be powered down during an erase
unerased_bix
=
bix
;
}
else
{
// more than one unerased block, bail out
SPIFFS_CHECK_RES
(
SPIFFS_ERR_NOT_A_FS
);
}
}
#endif
spiffs_obj_id
erase_count
;
res
=
_spiffs_rd
(
fs
,
SPIFFS_OP_T_OBJ_LU2
|
SPIFFS_OP_C_READ
,
...
...
@@ -297,6 +344,38 @@ s32_t spiffs_obj_lu_scan(
fs
->
max_erase_count
=
erase_count_final
;
#if SPIFFS_USE_MAGIC
if
(
unerased_bix
!=
(
spiffs_block_ix
)
-
1
)
{
// found one unerased block, remedy
SPIFFS_DBG
(
"mount: erase block %i
\n
"
,
bix
);
res
=
spiffs_erase_block
(
fs
,
unerased_bix
);
SPIFFS_CHECK_RES
(
res
);
}
#endif
// count blocks
fs
->
free_blocks
=
0
;
fs
->
stats_p_allocated
=
0
;
fs
->
stats_p_deleted
=
0
;
res
=
spiffs_obj_lu_find_entry_visitor
(
fs
,
0
,
0
,
0
,
0
,
spiffs_obj_lu_scan_v
,
0
,
0
,
&
bix
,
&
entry
);
if
(
res
==
SPIFFS_VIS_END
)
{
res
=
SPIFFS_OK
;
}
SPIFFS_CHECK_RES
(
res
);
return
res
;
}
...
...
@@ -310,7 +389,10 @@ s32_t spiffs_obj_lu_find_free(
int
*
lu_entry
)
{
s32_t
res
;
if
(
!
fs
->
cleaning
&&
fs
->
free_blocks
<
2
)
{
res
=
spiffs_gc_quick
(
fs
);
res
=
spiffs_gc_quick
(
fs
,
0
);
if
(
res
==
SPIFFS_ERR_NO_DELETED_BLOCKS
)
{
res
=
SPIFFS_OK
;
}
SPIFFS_CHECK_RES
(
res
);
if
(
fs
->
free_blocks
<
2
)
{
return
SPIFFS_ERR_FULL
;
...
...
app/spiffs/spiffs_nucleus.h
View file @
8d68ad7e
...
...
@@ -124,13 +124,17 @@
#define SPIFFS_EV_IX_NEW 1
#define SPIFFS_EV_IX_DEL 2
#define SPIFFS_OBJ_ID_IX_FLAG (1<<(8*sizeof(spiffs_obj_id)-1))
#define SPIFFS_OBJ_ID_IX_FLAG
((spiffs_obj_id)
(1<<(8*sizeof(spiffs_obj_id)-1))
)
#define SPIFFS_UNDEFINED_LEN (u32_t)(-1)
#define SPIFFS_OBJ_ID_DELETED ((spiffs_obj_id)0)
#define SPIFFS_OBJ_ID_FREE ((spiffs_obj_id)-1)
#define SPIFFS_MAGIC(fs) ((spiffs_obj_id)(0x20140529 ^ SPIFFS_CFG_LOG_PAGE_SZ(fs)))
#define SPIFFS_CONFIG_MAGIC (0x20090315)
#if SPIFFS_SINGLETON == 0
#define SPIFFS_CFG_LOG_PAGE_SZ(fs) \
((fs)->cfg.log_page_size)
...
...
@@ -189,9 +193,18 @@
// returns data size in a data page
#define SPIFFS_DATA_PAGE_SIZE(fs) \
( SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header) )
// returns physical address for block's erase count
// returns physical address for block's erase count,
// always in the physical last entry of the last object lookup page
#define SPIFFS_ERASE_COUNT_PADDR(fs, bix) \
( SPIFFS_BLOCK_TO_PADDR(fs, bix) + SPIFFS_OBJ_LOOKUP_PAGES(fs) * SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_obj_id) )
// returns physical address for block's magic,
// always in the physical second last entry of the last object lookup page
#define SPIFFS_MAGIC_PADDR(fs, bix) \
( SPIFFS_BLOCK_TO_PADDR(fs, bix) + SPIFFS_OBJ_LOOKUP_PAGES(fs) * SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_obj_id)*2 )
// checks if there is any room for magic in the object luts
#define SPIFFS_CHECK_MAGIC_POSSIBLE(fs) \
( (SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) % (SPIFFS_CFG_LOG_PAGE_SZ(fs)/sizeof(spiffs_obj_id))) * sizeof(spiffs_obj_id) \
<= (SPIFFS_CFG_LOG_PAGE_SZ(fs)-sizeof(spiffs_obj_id)*2) )
// define helpers object
...
...
@@ -238,7 +251,10 @@
#define SPIFFS_CHECK_MOUNT(fs) \
((fs)->block_count > 0)
((fs)->mounted != 0)
#define SPIFFS_CHECK_CFG(fs) \
((fs)->config_magic == SPIFFS_CONFIG_MAGIC)
#define SPIFFS_CHECK_RES(res) \
do { \
...
...
@@ -251,6 +267,12 @@
return -1; \
}
#define SPIFFS_API_CHECK_CFG(fs) \
if (!SPIFFS_CHECK_CFG((fs))) { \
(fs)->err_code = SPIFFS_ERR_NOT_CONFIGURED; \
return -1; \
}
#define SPIFFS_API_CHECK_RES(fs, res) \
if ((res) < SPIFFS_OK) { \
(fs)->err_code = (res); \
...
...
@@ -381,6 +403,8 @@ typedef struct {
// object structs
// page header, part of each page except object lookup pages
// NB: this is always aligned when the data page is an object index,
// as in this case struct spiffs_page_object_ix is used
typedef
struct
__attribute
((
packed
))
{
// object id
spiffs_obj_id
obj_id
;
...
...
@@ -391,11 +415,10 @@ typedef struct __attribute(( packed )) {
}
spiffs_page_header
;
// object index header page header
typedef
struct
__attribute
((
packed
))
{
typedef
struct
__attribute
((
packed
,
aligned
(
4
)
))
{
// common page header
spiffs_page_header
p_hdr
;
// alignment
u8_t
_align
[
4
-
((
sizeof
(
spiffs_page_header
)
+
sizeof
(
spiffs_obj_type
)
+
SPIFFS_OBJ_NAME_LEN
)
&
3
)
==
0
?
4
:
((
sizeof
(
spiffs_page_header
)
+
sizeof
(
spiffs_obj_type
)
+
SPIFFS_OBJ_NAME_LEN
)
&
3
)];
// size of object
u32_t
size
;
// type of object
...
...
@@ -405,9 +428,8 @@ typedef struct __attribute(( packed )) {
}
spiffs_page_object_ix_header
;
// object index page header
typedef
struct
__attribute
((
packed
))
{
typedef
struct
__attribute
((
packed
,
aligned
(
4
)
))
{
spiffs_page_header
p_hdr
;
u8_t
_align
[
4
-
(
sizeof
(
spiffs_page_header
)
&
3
)
==
0
?
4
:
(
sizeof
(
spiffs_page_header
)
&
3
)];
}
spiffs_page_object_ix
;
// callback func for object lookup visitor
...
...
@@ -478,6 +500,10 @@ s32_t spiffs_obj_lu_find_entry_visitor(
spiffs_block_ix
*
block_ix
,
int
*
lu_entry
);
s32_t
spiffs_erase_block
(
spiffs
*
fs
,
spiffs_block_ix
bix
);
// ---------------
s32_t
spiffs_obj_lu_scan
(
...
...
@@ -625,14 +651,15 @@ s32_t spiffs_gc_erase_page_stats(
s32_t
spiffs_gc_find_candidate
(
spiffs
*
fs
,
spiffs_block_ix
**
block_candidate
,
int
*
candidate_count
);
int
*
candidate_count
,
char
fs_crammed
);
s32_t
spiffs_gc_clean
(
spiffs
*
fs
,
spiffs_block_ix
bix
);
s32_t
spiffs_gc_quick
(
spiffs
*
fs
);
spiffs
*
fs
,
u16_t
max_free_pages
);
// ---------------
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment