mirror of
https://github.com/pellepl/spiffs.git
synced 2026-09-29 20:37:36 +00:00
This will also add possibility to probe the filesystems length beforehand to fully mounting it. Thanks @hreintke. Added API funcs: SPIFFS_probe_nbr_of_blocks Added config: SPIFFS_USE_MAGIC_LENGTH
This commit is contained in:
@@ -119,6 +119,17 @@
|
||||
#define SPIFFS_USE_MAGIC (0)
|
||||
#endif
|
||||
|
||||
#if SPIFFS_USE_MAGIC
|
||||
// Only valid when SPIFFS_USE_MAGIC is enabled. If SPIFFS_USE_MAGIC_LENGTH is
|
||||
// enabled, the magic will also be dependent on the length of the filesystem.
|
||||
// For example, a filesystem configured and formatted for 4 megabytes will not
|
||||
// be accepted for mounting with a configuration defining the filesystem as 2
|
||||
// megabytes.
|
||||
#ifndef SPIFFS_USE_MAGIC_LENGTH
|
||||
#define SPIFFS_USE_MAGIC_LENGTH (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// SPIFFS_LOCK and SPIFFS_UNLOCK protects spiffs from reentrancy on api level
|
||||
// These should be defined on a multithreaded system
|
||||
|
||||
@@ -131,7 +142,6 @@
|
||||
#define SPIFFS_UNLOCK(fs)
|
||||
#endif
|
||||
|
||||
|
||||
// Enable if only one spiffs instance with constant configuration will exist
|
||||
// on the target. This will reduce calculations, flash and memory accesses.
|
||||
// Parts of configuration must be defined below instead of at time of mount.
|
||||
|
||||
@@ -282,6 +282,33 @@ typedef struct {
|
||||
|
||||
// functions
|
||||
|
||||
#if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH
|
||||
/**
|
||||
* Special function. This takes a spiffs config struct and returns
|
||||
* the number of blocks this file system was formatted with.
|
||||
* This function relies on following in the passed config struct:
|
||||
* hal_read_f, phys_addr, and log_page_size.
|
||||
*
|
||||
* Do note, that caution should be taken with the value returned here.
|
||||
*
|
||||
* There is no check whatsoever that the flash actually contains a file
|
||||
* system - meaning that just any number could be returned.
|
||||
*
|
||||
* There is neither any check that the configuration is set correctly.
|
||||
* The block size may for instance differ.
|
||||
*
|
||||
* One must be sure of the page size and the physical address when
|
||||
* calling this function.
|
||||
*
|
||||
* The resulting value can then be used to set the config structs
|
||||
* phys_size by multiplying it with the known block size.
|
||||
*
|
||||
* @param config essential parts of the physical and logical
|
||||
* configuration of the file system
|
||||
*/
|
||||
s32_t SPIFFS_probe_nbr_of_blocks(spiffs_config *config);
|
||||
#endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
||||
@@ -61,6 +61,17 @@ s32_t SPIFFS_format(spiffs *fs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH
|
||||
|
||||
s32_t SPIFFS_probe_nbr_of_blocks(spiffs_config *config) {
|
||||
SPIFFS_LOCK(fs);
|
||||
s32_t block_count = spiffs_probe(config);
|
||||
SPIFFS_UNLOCK(fs);
|
||||
return block_count;
|
||||
}
|
||||
|
||||
#endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH
|
||||
|
||||
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,
|
||||
|
||||
+26
-2
@@ -243,7 +243,7 @@ s32_t spiffs_erase_block(
|
||||
|
||||
#if SPIFFS_USE_MAGIC
|
||||
// finally, write magic
|
||||
spiffs_obj_id magic = SPIFFS_MAGIC(fs);
|
||||
spiffs_obj_id magic = SPIFFS_MAGIC(fs, bix);
|
||||
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);
|
||||
@@ -259,6 +259,30 @@ s32_t spiffs_erase_block(
|
||||
}
|
||||
|
||||
|
||||
#if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH
|
||||
s32_t spiffs_probe(
|
||||
spiffs_config *cfg) {
|
||||
s32_t res;
|
||||
spiffs dummy_fs; // create a dummy fs struct just to be able to use macros
|
||||
memcpy(&dummy_fs.cfg, cfg, sizeof(spiffs_config));
|
||||
spiffs_obj_id magic;
|
||||
u32_t paddr = SPIFFS_MAGIC_PADDR(&dummy_fs, (spiffs_block_ix)0);
|
||||
#if SPIFFS_HAL_CALLBACK_EXTRA
|
||||
// not any proper fs to report here, so callback with null
|
||||
// (cross fingers that no-one gets angry)
|
||||
res = cfg->hal_read_f((void *)0, paddr, sizeof(spiffs_obj_id), (u8_t *)&magic);
|
||||
#else
|
||||
res = cfg->hal_read_f(paddr, sizeof(spiffs_obj_id), (u8_t *)&magic);
|
||||
#endif
|
||||
SPIFFS_CHECK_RES(res);
|
||||
|
||||
// unwind the magic crap to get nbr of blocks
|
||||
dummy_fs.block_count = 0;
|
||||
return SPIFFS_MAGIC(&dummy_fs, 0) ^ magic;
|
||||
}
|
||||
#endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH
|
||||
|
||||
|
||||
static s32_t spiffs_obj_lu_scan_v(
|
||||
spiffs *fs,
|
||||
spiffs_obj_id obj_id,
|
||||
@@ -311,7 +335,7 @@ s32_t spiffs_obj_lu_scan(
|
||||
sizeof(spiffs_obj_id), (u8_t *)&magic);
|
||||
|
||||
SPIFFS_CHECK_RES(res);
|
||||
if (magic != SPIFFS_MAGIC(fs)) {
|
||||
if (magic != SPIFFS_MAGIC(fs, bix)) {
|
||||
if (unerased_bix == (spiffs_block_ix)-1) {
|
||||
// allow one unerased block as it might be powered down during an erase
|
||||
unerased_bix = bix;
|
||||
|
||||
+14
-1
@@ -131,7 +131,15 @@
|
||||
#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)))
|
||||
#if SPIFFS_USE_MAGIC
|
||||
#if !SPIFFS_USE_MAGIC_LENGTH
|
||||
#define SPIFFS_MAGIC(fs, bix) \
|
||||
((spiffs_obj_id)(0x20140529 ^ SPIFFS_CFG_LOG_PAGE_SZ(fs)))
|
||||
#else // SPIFFS_USE_MAGIC_LENGTH
|
||||
#define SPIFFS_MAGIC(fs, bix) \
|
||||
((spiffs_obj_id)(0x20140529 ^ SPIFFS_CFG_LOG_PAGE_SZ(fs) ^ ((fs)->block_count - (bix))))
|
||||
#endif // SPIFFS_USE_MAGIC_LENGTH
|
||||
#endif // SPIFFS_USE_MAGIC
|
||||
|
||||
#define SPIFFS_CONFIG_MAGIC (0x20090315)
|
||||
|
||||
@@ -530,6 +538,11 @@ s32_t spiffs_erase_block(
|
||||
spiffs *fs,
|
||||
spiffs_block_ix bix);
|
||||
|
||||
#if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH
|
||||
s32_t spiffs_probe(
|
||||
spiffs_config *cfg);
|
||||
#endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH
|
||||
|
||||
// ---------------
|
||||
|
||||
s32_t spiffs_obj_lu_scan(
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
#define SPIFFS_PHYS_ADDR (4*1024*1024)
|
||||
|
||||
// test using filesystem magic
|
||||
//#define SPIFFS_USE_MAGIC 1
|
||||
#define SPIFFS_USE_MAGIC 1
|
||||
// test using filesystem magic length
|
||||
#define SPIFFS_USE_MAGIC_LENGTH 1
|
||||
|
||||
#define SECTOR_SIZE 65536
|
||||
#define LOG_BLOCK (SECTOR_SIZE*2)
|
||||
|
||||
@@ -35,6 +35,76 @@ TEST(info)
|
||||
}
|
||||
TEST_END(info)
|
||||
|
||||
#if SPIFFS_USE_MAGIC
|
||||
TEST(magic)
|
||||
{
|
||||
fs_reset_specific(0, 0, 65536*16, 65536, 65536, 256);
|
||||
SPIFFS_unmount(FS);
|
||||
|
||||
TEST_CHECK_EQ(fs_mount_specific(0, 65536*16, 65536, 65536, 256), SPIFFS_OK);
|
||||
SPIFFS_unmount(FS);
|
||||
|
||||
TEST_CHECK_NEQ(fs_mount_specific(0, 65536*16, 65536, 65536, 128), SPIFFS_OK);
|
||||
TEST_CHECK_EQ(SPIFFS_errno(FS), SPIFFS_ERR_NOT_A_FS);
|
||||
|
||||
TEST_CHECK_NEQ(fs_mount_specific(4, 65536*16, 65536, 65536, 256), SPIFFS_OK);
|
||||
TEST_CHECK_EQ(SPIFFS_errno(FS), SPIFFS_ERR_NOT_A_FS);
|
||||
|
||||
return TEST_RES_OK;
|
||||
}
|
||||
TEST_END(magic)
|
||||
|
||||
|
||||
#if SPIFFS_USE_MAGIC_LENGTH
|
||||
TEST(magic_length)
|
||||
{
|
||||
fs_reset_specific(0, 0, 65536*16, 65536, 65536, 256);
|
||||
SPIFFS_unmount(FS);
|
||||
|
||||
TEST_CHECK_EQ(fs_mount_specific(0, 65536*16, 65536, 65536, 256), SPIFFS_OK);
|
||||
SPIFFS_unmount(FS);
|
||||
|
||||
TEST_CHECK_NEQ(fs_mount_specific(0, 65536*8, 65536, 65536, 256), SPIFFS_OK);
|
||||
TEST_CHECK_EQ(SPIFFS_errno(FS), SPIFFS_ERR_NOT_A_FS);
|
||||
|
||||
TEST_CHECK_NEQ(fs_mount_specific(0, 65536*15, 65536, 65536, 256), SPIFFS_OK);
|
||||
TEST_CHECK_EQ(SPIFFS_errno(FS), SPIFFS_ERR_NOT_A_FS);
|
||||
|
||||
TEST_CHECK_NEQ(fs_mount_specific(0, 65536*17, 65536, 65536, 256), SPIFFS_OK);
|
||||
TEST_CHECK_EQ(SPIFFS_errno(FS), SPIFFS_ERR_NOT_A_FS);
|
||||
|
||||
TEST_CHECK_NEQ(fs_mount_specific(0, 65536*256, 65536, 65536, 256), SPIFFS_OK);
|
||||
TEST_CHECK_EQ(SPIFFS_errno(FS), SPIFFS_ERR_NOT_A_FS);
|
||||
|
||||
return TEST_RES_OK;
|
||||
}
|
||||
TEST_END(magic_length)
|
||||
|
||||
|
||||
TEST(magic_length_probe)
|
||||
{
|
||||
fs_reset_specific(0, 0, 65536*16, 65536, 65536, 256);
|
||||
TEST_CHECK_EQ(SPIFFS_probe_nbr_of_blocks(&__fs.cfg), 16);
|
||||
|
||||
fs_reset_specific(0, 0, 65536*24, 65536, 65536, 256);
|
||||
TEST_CHECK_EQ(SPIFFS_probe_nbr_of_blocks(&__fs.cfg), 24);
|
||||
|
||||
fs_reset_specific(0, 0, 32768*16, 32768, 32768, 128);
|
||||
TEST_CHECK_EQ(SPIFFS_probe_nbr_of_blocks(&__fs.cfg), 16);
|
||||
|
||||
fs_reset_specific(0, 0, 16384*37, 16384, 16384, 128);
|
||||
TEST_CHECK_EQ(SPIFFS_probe_nbr_of_blocks(&__fs.cfg), 37);
|
||||
|
||||
fs_reset_specific(0, 0, 4096*11, 4096, 4096, 256);
|
||||
TEST_CHECK_EQ(SPIFFS_probe_nbr_of_blocks(&__fs.cfg), 11);
|
||||
|
||||
return TEST_RES_OK;
|
||||
}
|
||||
TEST_END(magic_length_probe)
|
||||
|
||||
#endif // SPIFFS_USE_MAGIC_LENGTH
|
||||
|
||||
#endif // SPIFFS_USE_MAGIC
|
||||
|
||||
TEST(missing_file)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user