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
849407b2
Commit
849407b2
authored
Jul 18, 2015
by
Vowstar
Browse files
Merge pull request #558 from DiUS/spiffs-0.3.2
Updated SPIFFS to 0.3.2.
parents
239008d5
8d68ad7e
Changes
8
Hide whitespace changes
Inline
Side-by-side
app/modules/file.c
View file @
849407b2
...
@@ -110,7 +110,7 @@ static int file_seek (lua_State *L)
...
@@ -110,7 +110,7 @@ static int file_seek (lua_State *L)
int
op
=
luaL_checkoption
(
L
,
1
,
"cur"
,
modenames
);
int
op
=
luaL_checkoption
(
L
,
1
,
"cur"
,
modenames
);
long
offset
=
luaL_optlong
(
L
,
2
,
0
);
long
offset
=
luaL_optlong
(
L
,
2
,
0
);
op
=
fs_seek
(
file_fd
,
offset
,
mode
[
op
]);
op
=
fs_seek
(
file_fd
,
offset
,
mode
[
op
]);
if
(
op
)
if
(
op
<
0
)
lua_pushnil
(
L
);
/* error */
lua_pushnil
(
L
);
/* error */
else
else
lua_pushinteger
(
L
,
fs_tell
(
file_fd
));
lua_pushinteger
(
L
,
fs_tell
(
file_fd
));
...
...
app/spiffs/spiffs.h
View file @
849407b2
...
@@ -13,7 +13,6 @@
...
@@ -13,7 +13,6 @@
extern
"C"
{
extern
"C"
{
#endif
#endif
#include "c_stdio.h"
#include "spiffs_config.h"
#include "spiffs_config.h"
#define SPIFFS_OK 0
#define SPIFFS_OK 0
...
@@ -41,6 +40,14 @@ extern "C" {
...
@@ -41,6 +40,14 @@ extern "C" {
#define SPIFFS_ERR_NOT_WRITABLE -10021
#define SPIFFS_ERR_NOT_WRITABLE -10021
#define SPIFFS_ERR_NOT_READABLE -10022
#define SPIFFS_ERR_NOT_READABLE -10022
#define SPIFFS_ERR_CONFLICTING_NAME -10023
#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
#define SPIFFS_ERR_INTERNAL -10050
...
@@ -215,6 +222,11 @@ typedef struct {
...
@@ -215,6 +222,11 @@ typedef struct {
// check callback function
// check callback function
spiffs_check_callback
check_cb_f
;
spiffs_check_callback
check_cb_f
;
// mounted flag
u8_t
mounted
;
// config magic
u32_t
config_magic
;
}
spiffs
;
}
spiffs
;
/* spiffs file status struct */
/* spiffs file status struct */
...
@@ -242,7 +254,10 @@ typedef struct {
...
@@ -242,7 +254,10 @@ typedef struct {
// functions
// 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 fs the file system struct
* @param config the physical and logical configuration of the file system
* @param config the physical and logical configuration of the file system
* @param work a memory work buffer comprising 2*config->log_page_size
* @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
...
@@ -308,7 +323,7 @@ spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_fl
* @param len how much to read
* @param len how much to read
* @returns number of bytes read, or -1 if error
* @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.
* Writes to given filehandle.
...
@@ -318,7 +333,7 @@ s32_t SPIFFS_read(spiffs *fs, spiffs_file fh, void *buf, u32_t len);
...
@@ -318,7 +333,7 @@ s32_t SPIFFS_read(spiffs *fs, spiffs_file fh, void *buf, u32_t len);
* @param len how much to write
* @param len how much to write
* @returns number of bytes written, or -1 if error
* @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
* Moves the read/write file offset
...
@@ -426,6 +441,12 @@ struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e);
...
@@ -426,6 +441,12 @@ struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e);
*/
*/
s32_t
SPIFFS_check
(
spiffs
*
fs
);
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.
* Returns number of total bytes available and number of used bytes.
...
@@ -442,13 +463,69 @@ s32_t SPIFFS_check(spiffs *fs);
...
@@ -442,13 +463,69 @@ s32_t SPIFFS_check(spiffs *fs);
s32_t
SPIFFS_info
(
spiffs
*
fs
,
u32_t
*
total
,
u32_t
*
used
);
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 fs the file system struct
* @param fh the filehandle of the file to check
*/
*/
s32_t
SPIFFS_eof
(
spiffs
*
fs
,
spiffs_file
fh
);
u8_t
SPIFFS_mounted
(
spiffs
*
fs
);
s32_t
SPIFFS_tell
(
spiffs
*
fs
,
spiffs_file
fh
);
s32_t
SPIFFS_size
(
spiffs
*
fs
,
spiffs_file
fh
);
/**
* 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
#if SPIFFS_TEST_VISUALISATION
/**
/**
...
@@ -495,6 +572,10 @@ int myspiffs_check( void );
...
@@ -495,6 +572,10 @@ int myspiffs_check( void );
int
myspiffs_rename
(
const
char
*
old
,
const
char
*
newname
);
int
myspiffs_rename
(
const
char
*
old
,
const
char
*
newname
);
size_t
myspiffs_size
(
int
fd
);
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)
#if defined(__cplusplus)
}
}
#endif
#endif
...
...
app/spiffs/spiffs_cache.c
View file @
849407b2
...
@@ -195,7 +195,7 @@ s32_t spiffs_phys_wr(
...
@@ -195,7 +195,7 @@ s32_t spiffs_phys_wr(
cache
->
last_access
++
;
cache
->
last_access
++
;
cp
->
last_access
=
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
// page is being updated, no write-cache, just pass thru
return
fs
->
cfg
.
hal_write_f
(
addr
,
len
,
src
);
return
fs
->
cfg
.
hal_write_f
(
addr
,
len
,
src
);
}
else
{
}
else
{
...
...
app/spiffs/spiffs_config.h
View file @
849407b2
...
@@ -119,6 +119,14 @@ typedef uint8_t u8_t;
...
@@ -119,6 +119,14 @@ typedef uint8_t u8_t;
#define SPIFFS_COPY_BUFFER_STACK (64)
#define SPIFFS_COPY_BUFFER_STACK (64)
#endif
#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
// SPIFFS_LOCK and SPIFFS_UNLOCK protects spiffs from reentrancy on api level
// These should be defined on a multithreaded system
// These should be defined on a multithreaded system
...
...
app/spiffs/spiffs_gc.c
View file @
849407b2
...
@@ -8,31 +8,11 @@ static s32_t spiffs_gc_erase_block(
...
@@ -8,31 +8,11 @@ static s32_t spiffs_gc_erase_block(
spiffs
*
fs
,
spiffs
*
fs
,
spiffs_block_ix
bix
)
{
spiffs_block_ix
bix
)
{
s32_t
res
;
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
);
SPIFFS_GC_DBG
(
"gc: erase block %i
\n
"
,
bix
);
res
=
spiffs_erase_block
(
fs
,
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
);
SPIFFS_CHECK_RES
(
res
);
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
#if SPIFFS_CACHE
{
{
u32_t
i
;
u32_t
i
;
...
@@ -48,7 +28,7 @@ static s32_t spiffs_gc_erase_block(
...
@@ -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
// 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.
// that no updates are needed on existing objects on pages that are erased.
s32_t
spiffs_gc_quick
(
s32_t
spiffs_gc_quick
(
spiffs
*
fs
)
{
spiffs
*
fs
,
u16_t
max_free_pages
)
{
s32_t
res
=
SPIFFS_OK
;
s32_t
res
=
SPIFFS_OK
;
u32_t
blocks
=
fs
->
block_count
;
u32_t
blocks
=
fs
->
block_count
;
spiffs_block_ix
cur_block
=
0
;
spiffs_block_ix
cur_block
=
0
;
...
@@ -67,6 +47,7 @@ s32_t spiffs_gc_quick(
...
@@ -67,6 +47,7 @@ s32_t spiffs_gc_quick(
// check each block
// check each block
while
(
res
==
SPIFFS_OK
&&
blocks
--
)
{
while
(
res
==
SPIFFS_OK
&&
blocks
--
)
{
u16_t
deleted_pages_in_block
=
0
;
u16_t
deleted_pages_in_block
=
0
;
u16_t
free_pages_in_block
=
0
;
int
obj_lookup_page
=
0
;
int
obj_lookup_page
=
0
;
// check each object lookup page
// check each object lookup page
...
@@ -83,9 +64,12 @@ s32_t spiffs_gc_quick(
...
@@ -83,9 +64,12 @@ s32_t spiffs_gc_quick(
deleted_pages_in_block
++
;
deleted_pages_in_block
++
;
}
else
if
(
obj_id
==
SPIFFS_OBJ_ID_FREE
)
{
}
else
if
(
obj_id
==
SPIFFS_OBJ_ID_FREE
)
{
// kill scan, go for next block
// kill scan, go for next block
obj_lookup_page
=
SPIFFS_OBJ_LOOKUP_PAGES
(
fs
);
free_pages_in_block
++
;
res
=
1
;
// kill object lu loop
if
(
free_pages_in_block
>
max_free_pages
)
{
break
;
obj_lookup_page
=
SPIFFS_OBJ_LOOKUP_PAGES
(
fs
);
res
=
1
;
// kill object lu loop
break
;
}
}
else
{
}
else
{
// kill scan, go for next block
// kill scan, go for next block
obj_lookup_page
=
SPIFFS_OBJ_LOOKUP_PAGES
(
fs
);
obj_lookup_page
=
SPIFFS_OBJ_LOOKUP_PAGES
(
fs
);
...
@@ -98,7 +82,9 @@ s32_t spiffs_gc_quick(
...
@@ -98,7 +82,9 @@ s32_t spiffs_gc_quick(
}
// per object lookup page
}
// per object lookup page
if
(
res
==
1
)
res
=
SPIFFS_OK
;
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
// found a fully deleted block
fs
->
stats_p_deleted
-=
deleted_pages_in_block
;
fs
->
stats_p_deleted
-=
deleted_pages_in_block
;
res
=
spiffs_gc_erase_block
(
fs
,
cur_block
);
res
=
spiffs_gc_erase_block
(
fs
,
cur_block
);
...
@@ -110,10 +96,13 @@ s32_t spiffs_gc_quick(
...
@@ -110,10 +96,13 @@ s32_t spiffs_gc_quick(
cur_block_addr
+=
SPIFFS_CFG_LOG_BLOCK_SZ
(
fs
);
cur_block_addr
+=
SPIFFS_CFG_LOG_BLOCK_SZ
(
fs
);
}
// per block
}
// per block
if
(
res
==
SPIFFS_OK
)
{
res
=
SPIFFS_ERR_NO_DELETED_BLOCKS
;
}
return
res
;
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
// cleansed and erased
s32_t
spiffs_gc_check
(
s32_t
spiffs_gc_check
(
spiffs
*
fs
,
spiffs
*
fs
,
...
@@ -130,12 +119,15 @@ s32_t spiffs_gc_check(
...
@@ -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
);
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
;
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
{
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
"
,
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
,
tries
,
...
@@ -145,11 +137,13 @@ s32_t spiffs_gc_check(
...
@@ -145,11 +137,13 @@ s32_t spiffs_gc_check(
spiffs_block_ix
*
cands
;
spiffs_block_ix
*
cands
;
int
count
;
int
count
;
spiffs_block_ix
cand
;
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
);
SPIFFS_CHECK_RES
(
res
);
if
(
count
==
0
)
{
if
(
count
==
0
)
{
SPIFFS_GC_DBG
(
"gc_check: no candidates, return
\n
"
);
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
#if SPIFFS_GC_STATS
fs
->
stats_gc_runs
++
;
fs
->
stats_gc_runs
++
;
...
@@ -176,6 +170,12 @@ s32_t spiffs_gc_check(
...
@@ -176,6 +170,12 @@ s32_t spiffs_gc_check(
(
SPIFFS_PAGES_PER_BLOCK
(
fs
)
-
SPIFFS_OBJ_LOOKUP_PAGES
(
fs
))
*
(
fs
->
block_count
-
2
)
(
SPIFFS_PAGES_PER_BLOCK
(
fs
)
-
SPIFFS_OBJ_LOOKUP_PAGES
(
fs
))
*
(
fs
->
block_count
-
2
)
-
fs
->
stats_p_allocated
-
fs
->
stats_p_deleted
;
-
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
||
}
while
(
++
tries
<
SPIFFS_GC_MAX_RUNS
&&
(
fs
->
free_blocks
<=
2
||
(
s32_t
)
len
>
free_pages
*
(
s32_t
)
SPIFFS_DATA_PAGE_SIZE
(
fs
)));
(
s32_t
)
len
>
free_pages
*
(
s32_t
)
SPIFFS_DATA_PAGE_SIZE
(
fs
)));
...
@@ -234,7 +234,8 @@ s32_t spiffs_gc_erase_page_stats(
...
@@ -234,7 +234,8 @@ s32_t spiffs_gc_erase_page_stats(
s32_t
spiffs_gc_find_candidate
(
s32_t
spiffs_gc_find_candidate
(
spiffs
*
fs
,
spiffs
*
fs
,
spiffs_block_ix
**
block_candidates
,
spiffs_block_ix
**
block_candidates
,
int
*
candidate_count
)
{
int
*
candidate_count
,
char
fs_crammed
)
{
s32_t
res
=
SPIFFS_OK
;
s32_t
res
=
SPIFFS_OK
;
u32_t
blocks
=
fs
->
block_count
;
u32_t
blocks
=
fs
->
block_count
;
spiffs_block_ix
cur_block
=
0
;
spiffs_block_ix
cur_block
=
0
;
...
@@ -307,7 +308,7 @@ s32_t spiffs_gc_find_candidate(
...
@@ -307,7 +308,7 @@ s32_t spiffs_gc_find_candidate(
s32_t
score
=
s32_t
score
=
deleted_pages_in_block
*
SPIFFS_GC_HEUR_W_DELET
+
deleted_pages_in_block
*
SPIFFS_GC_HEUR_W_DELET
+
used_pages_in_block
*
SPIFFS_GC_HEUR_W_USED
+
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
;
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
);
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
)
{
while
(
cand_ix
<
max_candidates
)
{
...
...
app/spiffs/spiffs_hydrogen.c
View file @
849407b2
...
@@ -21,6 +21,36 @@ u32_t SPIFFS_buffer_bytes_for_cache(spiffs *fs, u32_t num_pages) {
...
@@ -21,6 +21,36 @@ u32_t SPIFFS_buffer_bytes_for_cache(spiffs *fs, u32_t num_pages) {
#endif
#endif
#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
,
s32_t
SPIFFS_mount
(
spiffs
*
fs
,
spiffs_config
*
config
,
u8_t
*
work
,
u8_t
*
fd_space
,
u32_t
fd_space_size
,
u8_t
*
fd_space
,
u32_t
fd_space_size
,
void
*
cache
,
u32_t
cache_size
,
void
*
cache
,
u32_t
cache_size
,
...
@@ -34,10 +64,10 @@ s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work,
...
@@ -34,10 +64,10 @@ s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work,
c_memset
(
fd_space
,
0
,
fd_space_size
);
c_memset
(
fd_space
,
0
,
fd_space_size
);
// align fd_space pointer to pointer size byte boundary, below is safe
// align fd_space pointer to pointer size byte boundary, below is safe
u8_t
ptr_size
=
sizeof
(
void
*
);
u8_t
ptr_size
=
sizeof
(
void
*
);
//
#pragma GCC diagnostic push
#pragma GCC diagnostic push
//
#pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
#pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
u8_t
addr_lsb
=
(
u8
_t
)(((
u32
_t
)
fd_space
)
&
(
ptr_size
-
1
)
)
;
u8_t
addr_lsb
=
(
(
u8_t
)
fd_space
)
&
(
ptr_size
-
1
);
//
#pragma GCC diagnostic pop
#pragma GCC diagnostic pop
if
(
addr_lsb
)
{
if
(
addr_lsb
)
{
fd_space
+=
(
ptr_size
-
addr_lsb
);
fd_space
+=
(
ptr_size
-
addr_lsb
);
fd_space_size
-=
(
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,
...
@@ -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
));
fs
->
fd_count
=
(
fd_space_size
/
sizeof
(
spiffs_fd
));
// align cache pointer to 4 byte boundary, below is safe
// align cache pointer to 4 byte boundary, below is safe
//
#pragma GCC diagnostic push
#pragma GCC diagnostic push
//
#pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
#pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
addr_lsb
=
(
u8
_t
)(((
u32
_t
)
cache
)
&
(
ptr_size
-
1
)
)
;
addr_lsb
=
(
(
u8_t
)
cache
)
&
(
ptr_size
-
1
);
//
#pragma GCC diagnostic pop
#pragma GCC diagnostic pop
if
(
addr_lsb
)
{
if
(
addr_lsb
)
{
u8_t
*
cache_8
=
(
u8_t
*
)
cache
;
u8_t
*
cache_8
=
(
u8_t
*
)
cache
;
cache_8
+=
(
ptr_size
-
addr_lsb
);
cache_8
+=
(
ptr_size
-
addr_lsb
);
...
@@ -61,11 +91,20 @@ s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work,
...
@@ -61,11 +91,20 @@ s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work,
}
}
#if SPIFFS_CACHE
#if SPIFFS_CACHE
fs
->
cache
=
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
);
spiffs_cache_init
(
fs
);
#endif
#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_API_CHECK_RES_UNLOCK
(
fs
,
res
);
SPIFFS_DBG
(
"page index byte len: %i
\n
"
,
SPIFFS_CFG_LOG_PAGE_SZ
(
fs
));
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,
...
@@ -79,13 +118,15 @@ s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work,
fs
->
check_cb_f
=
check_cb_f
;
fs
->
check_cb_f
=
check_cb_f
;
fs
->
mounted
=
1
;
SPIFFS_UNLOCK
(
fs
);
SPIFFS_UNLOCK
(
fs
);
return
0
;
return
0
;
}
}
void
SPIFFS_unmount
(
spiffs
*
fs
)
{
void
SPIFFS_unmount
(
spiffs
*
fs
)
{
if
(
!
SPIFFS_CHECK_MOUNT
(
fs
))
return
;
if
(
!
SPIFFS_CHECK_CFG
(
fs
)
||
!
SPIFFS_CHECK_MOUNT
(
fs
))
return
;
SPIFFS_LOCK
(
fs
);
SPIFFS_LOCK
(
fs
);
u32_t
i
;
u32_t
i
;
spiffs_fd
*
fds
=
(
spiffs_fd
*
)
fs
->
fd_space
;
spiffs_fd
*
fds
=
(
spiffs_fd
*
)
fs
->
fd_space
;
...
@@ -98,7 +139,8 @@ void SPIFFS_unmount(spiffs *fs) {
...
@@ -98,7 +139,8 @@ void SPIFFS_unmount(spiffs *fs) {
spiffs_fd_return
(
fs
,
cur_fd
->
file_nbr
);
spiffs_fd_return
(
fs
,
cur_fd
->
file_nbr
);
}
}
}
}
fs
->
block_count
=
0
;
fs
->
mounted
=
0
;
SPIFFS_UNLOCK
(
fs
);
SPIFFS_UNLOCK
(
fs
);
}
}
...
@@ -112,6 +154,7 @@ void SPIFFS_clearerr(spiffs *fs) {
...
@@ -112,6 +154,7 @@ void SPIFFS_clearerr(spiffs *fs) {
s32_t
SPIFFS_creat
(
spiffs
*
fs
,
char
*
path
,
spiffs_mode
mode
)
{
s32_t
SPIFFS_creat
(
spiffs
*
fs
,
char
*
path
,
spiffs_mode
mode
)
{
(
void
)
mode
;
(
void
)
mode
;
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
SPIFFS_LOCK
(
fs
);
spiffs_obj_id
obj_id
;
spiffs_obj_id
obj_id
;
...
@@ -127,6 +170,7 @@ s32_t SPIFFS_creat(spiffs *fs, char *path, spiffs_mode mode) {
...
@@ -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
)
{
spiffs_file
SPIFFS_open
(
spiffs
*
fs
,
char
*
path
,
spiffs_flags
flags
,
spiffs_mode
mode
)
{
(
void
)
mode
;
(
void
)
mode
;
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
SPIFFS_LOCK
(
fs
);
...
@@ -185,6 +229,7 @@ spiffs_file SPIFFS_open(spiffs *fs, char *path, spiffs_flags flags, spiffs_mode
...
@@ -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_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_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
SPIFFS_LOCK
(
fs
);
...
@@ -213,7 +258,8 @@ spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_fl
...
@@ -213,7 +258,8 @@ spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_fl
return
fd
->
file_nbr
;
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_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
SPIFFS_LOCK
(
fs
);
...
@@ -281,7 +327,8 @@ static s32_t spiffs_hydro_write(spiffs *fs, spiffs_fd *fd, void *buf, u32_t offs
...
@@ -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_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
SPIFFS_LOCK
(
fs
);
...
@@ -400,6 +447,7 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, u32_t len) {
...
@@ -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
)
{
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_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
SPIFFS_LOCK
(
fs
);
...
@@ -440,10 +488,11 @@ s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) {
...
@@ -440,10 +488,11 @@ s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) {
SPIFFS_UNLOCK
(
fs
);
SPIFFS_UNLOCK
(
fs
);
return
0
;
return
offs
;
}
}
s32_t
SPIFFS_remove
(
spiffs
*
fs
,
char
*
path
)
{
s32_t
SPIFFS_remove
(
spiffs
*
fs
,
char
*
path
)
{
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
SPIFFS_LOCK
(
fs
);
...
@@ -477,6 +526,7 @@ s32_t SPIFFS_remove(spiffs *fs, char *path) {
...
@@ -477,6 +526,7 @@ s32_t SPIFFS_remove(spiffs *fs, char *path) {
}
}
s32_t
SPIFFS_fremove
(
spiffs
*
fs
,
spiffs_file
fh
)
{
s32_t
SPIFFS_fremove
(
spiffs
*
fs
,
spiffs_file
fh
)
{
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
SPIFFS_LOCK
(
fs
);
...
@@ -525,6 +575,7 @@ static s32_t spiffs_stat_pix(spiffs *fs, spiffs_page_ix pix, spiffs_file fh, spi
...
@@ -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
)
{
s32_t
SPIFFS_stat
(
spiffs
*
fs
,
char
*
path
,
spiffs_stat
*
s
)
{
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
SPIFFS_LOCK
(
fs
);
...
@@ -542,6 +593,7 @@ s32_t SPIFFS_stat(spiffs *fs, char *path, spiffs_stat *s) {
...
@@ -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
)
{
s32_t
SPIFFS_fstat
(
spiffs
*
fs
,
spiffs_file
fh
,
spiffs_stat
*
s
)
{
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
SPIFFS_LOCK
(
fs
);
...
@@ -595,6 +647,7 @@ static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh) {
...
@@ -595,6 +647,7 @@ static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh) {
}
}
s32_t
SPIFFS_fflush
(
spiffs
*
fs
,
spiffs_file
fh
)
{
s32_t
SPIFFS_fflush
(
spiffs
*
fs
,
spiffs_file
fh
)
{
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
s32_t
res
=
SPIFFS_OK
;
s32_t
res
=
SPIFFS_OK
;
#if SPIFFS_CACHE_WR
#if SPIFFS_CACHE_WR
...
@@ -608,6 +661,11 @@ s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh) {
...
@@ -608,6 +661,11 @@ s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh) {
}
}
void
SPIFFS_close
(
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
))
{
if
(
!
SPIFFS_CHECK_MOUNT
(
fs
))
{
fs
->
err_code
=
SPIFFS_ERR_NOT_MOUNTED
;
fs
->
err_code
=
SPIFFS_ERR_NOT_MOUNTED
;
return
;
return
;
...
@@ -623,6 +681,7 @@ void SPIFFS_close(spiffs *fs, spiffs_file fh) {
...
@@ -623,6 +681,7 @@ void SPIFFS_close(spiffs *fs, spiffs_file fh) {
}
}
s32_t
SPIFFS_rename
(
spiffs
*
fs
,
char
*
old
,
char
*
new
)
{
s32_t
SPIFFS_rename
(
spiffs
*
fs
,
char
*
old
,
char
*
new
)
{
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
SPIFFS_LOCK
(
fs
);
...
@@ -652,9 +711,8 @@ s32_t SPIFFS_rename(spiffs *fs, char *old, char *new) {
...
@@ -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
,
res
=
spiffs_object_update_index_hdr
(
fs
,
fd
,
fd
->
obj_id
,
fd
->
objix_hdr_pix
,
0
,
(
u8_t
*
)
new
,
0
,
&
pix_dummy
);
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_API_CHECK_RES_UNLOCK
(
fs
,
res
);
SPIFFS_UNLOCK
(
fs
);
SPIFFS_UNLOCK
(
fs
);
...
@@ -664,10 +722,17 @@ s32_t SPIFFS_rename(spiffs *fs, char *old, char *new) {
...
@@ -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
)
{
spiffs_DIR
*
SPIFFS_opendir
(
spiffs
*
fs
,
char
*
name
,
spiffs_DIR
*
d
)
{
(
void
)
name
;
(
void
)
name
;
if
(
!
SPIFFS_CHECK_CFG
((
fs
)))
{
(
fs
)
->
err_code
=
SPIFFS_ERR_NOT_CONFIGURED
;
return
0
;
}
if
(
!
SPIFFS_CHECK_MOUNT
(
fs
))
{
if
(
!
SPIFFS_CHECK_MOUNT
(
fs
))
{
fs
->
err_code
=
SPIFFS_ERR_NOT_MOUNTED
;
fs
->
err_code
=
SPIFFS_ERR_NOT_MOUNTED
;
return
0
;
return
0
;
}
}
d
->
fs
=
fs
;
d
->
fs
=
fs
;
d
->
block
=
0
;
d
->
block
=
0
;
d
->
entry
=
0
;
d
->
entry
=
0
;
...
@@ -743,12 +808,14 @@ struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e) {
...
@@ -743,12 +808,14 @@ struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e) {
}
}
s32_t
SPIFFS_closedir
(
spiffs_DIR
*
d
)
{
s32_t
SPIFFS_closedir
(
spiffs_DIR
*
d
)
{
SPIFFS_API_CHECK_CFG
(
d
->
fs
);
SPIFFS_API_CHECK_MOUNT
(
d
->
fs
);
SPIFFS_API_CHECK_MOUNT
(
d
->
fs
);
return
0
;
return
0
;
}
}
s32_t
SPIFFS_check
(
spiffs
*
fs
)
{
s32_t
SPIFFS_check
(
spiffs
*
fs
)
{
s32_t
res
;
s32_t
res
;
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
SPIFFS_LOCK
(
fs
);
...
@@ -766,6 +833,7 @@ s32_t SPIFFS_check(spiffs *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
SPIFFS_info
(
spiffs
*
fs
,
u32_t
*
total
,
u32_t
*
used
)
{
s32_t
res
=
SPIFFS_OK
;
s32_t
res
=
SPIFFS_OK
;
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
SPIFFS_LOCK
(
fs
);
...
@@ -787,7 +855,7 @@ s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used) {
...
@@ -787,7 +855,7 @@ s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used) {
return
res
;
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_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
SPIFFS_LOCK
(
fs
);
...
@@ -800,13 +868,13 @@ s32_t SPIFFS_eof(spiffs *fs, spiffs_file fh) {
...
@@ -800,13 +868,13 @@ s32_t SPIFFS_eof(spiffs *fs, spiffs_file fh) {
spiffs_fflush_cache
(
fs
,
fh
);
spiffs_fflush_cache
(
fs
,
fh
);
#endif
#endif
res
=
(
fd
->
fdoffset
==
fd
->
size
)
;
res
=
fd
->
fdoffset
;
SPIFFS_UNLOCK
(
fs
);
SPIFFS_UNLOCK
(
fs
);
return
res
;
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_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
SPIFFS_LOCK
(
fs
);
...
@@ -819,7 +887,7 @@ s32_t SPIFFS_tell(spiffs *fs, spiffs_file fh) {
...
@@ -819,7 +887,7 @@ s32_t SPIFFS_tell(spiffs *fs, spiffs_file fh) {
spiffs_fflush_cache
(
fs
,
fh
);
spiffs_fflush_cache
(
fs
,
fh
);
#endif
#endif
res
=
fd
->
fdoffset
;
res
=
(
fd
->
fdoffset
==
fd
->
size
)
;
SPIFFS_UNLOCK
(
fs
);
SPIFFS_UNLOCK
(
fs
);
return
res
;
return
res
;
...
@@ -844,9 +912,38 @@ s32_t SPIFFS_size(spiffs *fs, spiffs_file fh) {
...
@@ -844,9 +912,38 @@ s32_t SPIFFS_size(spiffs *fs, spiffs_file fh) {
return
res
;
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
#if SPIFFS_TEST_VISUALISATION
s32_t
SPIFFS_vis
(
spiffs
*
fs
)
{
s32_t
SPIFFS_vis
(
spiffs
*
fs
)
{
s32_t
res
=
SPIFFS_OK
;
s32_t
res
=
SPIFFS_OK
;
SPIFFS_API_CHECK_CFG
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_API_CHECK_MOUNT
(
fs
);
SPIFFS_LOCK
(
fs
);
SPIFFS_LOCK
(
fs
);
...
...
app/spiffs/spiffs_nucleus.c
View file @
849407b2
...
@@ -142,9 +142,13 @@ s32_t spiffs_obj_lu_find_entry_visitor(
...
@@ -142,9 +142,13 @@ s32_t spiffs_obj_lu_find_entry_visitor(
cur_block
++
;
cur_block
++
;
cur_block_addr
=
cur_block
*
SPIFFS_CFG_LOG_BLOCK_SZ
(
fs
);
cur_block_addr
=
cur_block
*
SPIFFS_CFG_LOG_BLOCK_SZ
(
fs
);
if
(
cur_block
>=
fs
->
block_count
)
{
if
(
cur_block
>=
fs
->
block_count
)
{
// block wrap
if
(
flags
&
SPIFFS_VIS_NO_WRAP
)
{
cur_block
=
0
;
return
SPIFFS_VIS_END
;
cur_block_addr
=
0
;
}
else
{
// block wrap
cur_block
=
0
;
cur_block_addr
=
0
;
}
}
}
}
}
...
@@ -213,6 +217,45 @@ s32_t spiffs_obj_lu_find_entry_visitor(
...
@@ -213,6 +217,45 @@ s32_t spiffs_obj_lu_find_entry_visitor(
return
SPIFFS_VIS_END
;
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
(
static
s32_t
spiffs_obj_lu_scan_v
(
spiffs
*
fs
,
spiffs
*
fs
,
...
@@ -238,40 +281,44 @@ static s32_t spiffs_obj_lu_scan_v(
...
@@ -238,40 +281,44 @@ static s32_t spiffs_obj_lu_scan_v(
return
SPIFFS_VIS_COUNTINUE
;
return
SPIFFS_VIS_COUNTINUE
;
}
}
// Scans thru all obj lu and counts free, deleted and used pages
// Scans thru all obj lu and counts free, deleted and used pages
// Find the maximum block erase count
// Find the maximum block erase count
// Checks magic if enabled
s32_t
spiffs_obj_lu_scan
(
s32_t
spiffs_obj_lu_scan
(
spiffs
*
fs
)
{
spiffs
*
fs
)
{
s32_t
res
;
s32_t
res
;
spiffs_block_ix
bix
;
spiffs_block_ix
bix
;
int
entry
;
int
entry
;
#if SPIFFS_USE_MAGIC
spiffs_block_ix
unerased_bix
=
(
spiffs_block_ix
)
-
1
;
#endif
fs
->
free_blocks
=
0
;
// find out erase count
fs
->
stats_p_allocated
=
0
;
// if enabled, check magic
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
);
bix
=
0
;
bix
=
0
;
spiffs_obj_id
erase_count_final
;
spiffs_obj_id
erase_count_final
;
spiffs_obj_id
erase_count_min
=
SPIFFS_OBJ_ID_FREE
;
spiffs_obj_id
erase_count_min
=
SPIFFS_OBJ_ID_FREE
;
spiffs_obj_id
erase_count_max
=
0
;
spiffs_obj_id
erase_count_max
=
0
;
while
(
bix
<
fs
->
block_count
)
{
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
;
spiffs_obj_id
erase_count
;
res
=
_spiffs_rd
(
fs
,
res
=
_spiffs_rd
(
fs
,
SPIFFS_OP_T_OBJ_LU2
|
SPIFFS_OP_C_READ
,
SPIFFS_OP_T_OBJ_LU2
|
SPIFFS_OP_C_READ
,
...
@@ -297,6 +344,38 @@ s32_t spiffs_obj_lu_scan(
...
@@ -297,6 +344,38 @@ s32_t spiffs_obj_lu_scan(
fs
->
max_erase_count
=
erase_count_final
;
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
;
return
res
;
}
}
...
@@ -310,7 +389,10 @@ s32_t spiffs_obj_lu_find_free(
...
@@ -310,7 +389,10 @@ s32_t spiffs_obj_lu_find_free(
int
*
lu_entry
)
{
int
*
lu_entry
)
{
s32_t
res
;
s32_t
res
;
if
(
!
fs
->
cleaning
&&
fs
->
free_blocks
<
2
)
{
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
);
SPIFFS_CHECK_RES
(
res
);
if
(
fs
->
free_blocks
<
2
)
{
if
(
fs
->
free_blocks
<
2
)
{
return
SPIFFS_ERR_FULL
;
return
SPIFFS_ERR_FULL
;
...
...
app/spiffs/spiffs_nucleus.h
View file @
849407b2
...
@@ -124,13 +124,17 @@
...
@@ -124,13 +124,17 @@
#define SPIFFS_EV_IX_NEW 1
#define SPIFFS_EV_IX_NEW 1
#define SPIFFS_EV_IX_DEL 2
#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_UNDEFINED_LEN (u32_t)(-1)
#define SPIFFS_OBJ_ID_DELETED ((spiffs_obj_id)0)
#define SPIFFS_OBJ_ID_DELETED ((spiffs_obj_id)0)
#define SPIFFS_OBJ_ID_FREE ((spiffs_obj_id)-1)
#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
#if SPIFFS_SINGLETON == 0
#define SPIFFS_CFG_LOG_PAGE_SZ(fs) \
#define SPIFFS_CFG_LOG_PAGE_SZ(fs) \
((fs)->cfg.log_page_size)
((fs)->cfg.log_page_size)
...
@@ -189,9 +193,18 @@
...
@@ -189,9 +193,18 @@
// returns data size in a data page
// returns data size in a data page
#define SPIFFS_DATA_PAGE_SIZE(fs) \
#define SPIFFS_DATA_PAGE_SIZE(fs) \
( SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header) )
( 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) \
#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) )
( 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
// define helpers object
...
@@ -238,7 +251,10 @@
...
@@ -238,7 +251,10 @@
#define SPIFFS_CHECK_MOUNT(fs) \
#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) \
#define SPIFFS_CHECK_RES(res) \
do { \
do { \
...
@@ -251,6 +267,12 @@
...
@@ -251,6 +267,12 @@
return -1; \
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) \
#define SPIFFS_API_CHECK_RES(fs, res) \
if ((res) < SPIFFS_OK) { \
if ((res) < SPIFFS_OK) { \
(fs)->err_code = (res); \
(fs)->err_code = (res); \
...
@@ -381,6 +403,8 @@ typedef struct {
...
@@ -381,6 +403,8 @@ typedef struct {
// object structs
// object structs
// page header, part of each page except object lookup pages
// 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
))
{
typedef
struct
__attribute
((
packed
))
{
// object id
// object id
spiffs_obj_id
obj_id
;
spiffs_obj_id
obj_id
;
...
@@ -391,11 +415,10 @@ typedef struct __attribute(( packed )) {
...
@@ -391,11 +415,10 @@ typedef struct __attribute(( packed )) {
}
spiffs_page_header
;
}
spiffs_page_header
;
// object index header page header
// object index header page header
typedef
struct
__attribute
((
packed
))
{
typedef
struct
__attribute
((
packed
,
aligned
(
4
)
))
{
// common page header
// common page header
spiffs_page_header
p_hdr
;
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
// size of object
u32_t
size
;
u32_t
size
;
// type of object
// type of object
...
@@ -405,9 +428,8 @@ typedef struct __attribute(( packed )) {
...
@@ -405,9 +428,8 @@ typedef struct __attribute(( packed )) {
}
spiffs_page_object_ix_header
;
}
spiffs_page_object_ix_header
;
// object index page header
// object index page header
typedef
struct
__attribute
((
packed
))
{
typedef
struct
__attribute
((
packed
,
aligned
(
4
)
))
{
spiffs_page_header
p_hdr
;
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
;
}
spiffs_page_object_ix
;
// callback func for object lookup visitor
// callback func for object lookup visitor
...
@@ -478,6 +500,10 @@ s32_t spiffs_obj_lu_find_entry_visitor(
...
@@ -478,6 +500,10 @@ s32_t spiffs_obj_lu_find_entry_visitor(
spiffs_block_ix
*
block_ix
,
spiffs_block_ix
*
block_ix
,
int
*
lu_entry
);
int
*
lu_entry
);
s32_t
spiffs_erase_block
(
spiffs
*
fs
,
spiffs_block_ix
bix
);
// ---------------
// ---------------
s32_t
spiffs_obj_lu_scan
(
s32_t
spiffs_obj_lu_scan
(
...
@@ -625,14 +651,15 @@ s32_t spiffs_gc_erase_page_stats(
...
@@ -625,14 +651,15 @@ s32_t spiffs_gc_erase_page_stats(
s32_t
spiffs_gc_find_candidate
(
s32_t
spiffs_gc_find_candidate
(
spiffs
*
fs
,
spiffs
*
fs
,
spiffs_block_ix
**
block_candidate
,
spiffs_block_ix
**
block_candidate
,
int
*
candidate_count
);
int
*
candidate_count
,
char
fs_crammed
);
s32_t
spiffs_gc_clean
(
s32_t
spiffs_gc_clean
(
spiffs
*
fs
,
spiffs
*
fs
,
spiffs_block_ix
bix
);
spiffs_block_ix
bix
);
s32_t
spiffs_gc_quick
(
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