Skip to content

Commit f93bbb1

Browse files
committed
littlefs: Brought integration layer up to v2.0
- Compact for lfs_crc/lfs_fs_size API changes - Updated config options to reflect changes - Modified tests to match new key ordering (FIFO order -> sorted)
1 parent cbaffcf commit f93bbb1

File tree

10 files changed

+164
-191
lines changed

10 files changed

+164
-191
lines changed

LittleFileSystem.cpp

Lines changed: 47 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@
2222

2323
namespace mbed {
2424

25-
extern "C" void lfs_crc(uint32_t *crc, const void *buffer, size_t size)
25+
extern "C" uint32_t lfs_crc(uint32_t crc, const void *buffer, size_t size)
2626
{
27-
uint32_t initial_xor = *crc;
27+
uint32_t initial_xor = crc;
2828
MbedCRC<POLY_32BIT_REV_ANSI, 32> ct(initial_xor, 0x0, true, false);
29-
ct.compute((void *)buffer, size, (uint32_t *) crc);
29+
ct.compute((void *)buffer, size, &crc);
30+
return crc;
3031
}
3132

3233
////// Conversion functions //////
@@ -142,14 +143,15 @@ static int lfs_bd_sync(const struct lfs_config *c)
142143

143144
// Filesystem implementation (See LittleFileSystem.h)
144145
LittleFileSystem::LittleFileSystem(const char *name, BlockDevice *bd,
145-
lfs_size_t read_size, lfs_size_t prog_size,
146-
lfs_size_t block_size, lfs_size_t lookahead)
146+
lfs_size_t block_size, uint32_t block_cycles,
147+
lfs_size_t cache_size, lfs_size_t lookahead_size)
147148
: FileSystem(name)
148-
, _read_size(read_size)
149-
, _prog_size(prog_size)
150-
, _block_size(block_size)
151-
, _lookahead(lookahead)
152149
{
150+
memset(&_config, 0, sizeof(_config));
151+
_config.block_size = block_size;
152+
_config.block_cycles = block_cycles;
153+
_config.cache_size = cache_size;
154+
_config.lookahead_size = lookahead_size;
153155
if (bd) {
154156
mount(bd);
155157
}
@@ -174,29 +176,18 @@ int LittleFileSystem::mount(BlockDevice *bd)
174176
return err;
175177
}
176178

177-
memset(&_config, 0, sizeof(_config));
178-
_config.context = bd;
179-
_config.read = lfs_bd_read;
180-
_config.prog = lfs_bd_prog;
181-
_config.erase = lfs_bd_erase;
182-
_config.sync = lfs_bd_sync;
183-
_config.read_size = bd->get_read_size();
184-
if (_config.read_size < _read_size) {
185-
_config.read_size = _read_size;
186-
}
187-
_config.prog_size = bd->get_program_size();
188-
if (_config.prog_size < _prog_size) {
189-
_config.prog_size = _prog_size;
190-
}
191-
_config.block_size = bd->get_erase_size();
192-
if (_config.block_size < _block_size) {
193-
_config.block_size = _block_size;
194-
}
195-
_config.block_count = bd->size() / _config.block_size;
196-
_config.lookahead = 32 * ((_config.block_count + 31) / 32);
197-
if (_config.lookahead > _lookahead) {
198-
_config.lookahead = _lookahead;
199-
}
179+
_config.context = bd;
180+
_config.read = lfs_bd_read;
181+
_config.prog = lfs_bd_prog;
182+
_config.erase = lfs_bd_erase;
183+
_config.sync = lfs_bd_sync;
184+
_config.read_size = bd->get_read_size();
185+
_config.prog_size = bd->get_program_size();
186+
_config.block_size = lfs_max(_config.block_size, (lfs_size_t)bd->get_erase_size());
187+
_config.block_count = bd->size() / _config.block_size;
188+
_config.block_cycles = _config.block_cycles;
189+
_config.cache_size = lfs_max(_config.cache_size, _config.prog_size);
190+
_config.lookahead_size = lfs_min(_config.lookahead_size, 8 * ((_config.block_count + 63) / 64));
200191

201192
err = lfs_mount(&_lfs, &_config);
202193
if (err) {
@@ -236,11 +227,11 @@ int LittleFileSystem::unmount()
236227
}
237228

238229
int LittleFileSystem::format(BlockDevice *bd,
239-
lfs_size_t read_size, lfs_size_t prog_size,
240-
lfs_size_t block_size, lfs_size_t lookahead)
230+
lfs_size_t block_size, uint32_t block_cycles,
231+
lfs_size_t cache_size, lfs_size_t lookahead_size)
241232
{
242233
LFS_INFO("format(%p, %ld, %ld, %ld, %ld)",
243-
bd, read_size, prog_size, block_size, lookahead);
234+
bd, block_size, block_cycles, cache_size, lookahead_size);
244235
int err = bd->init();
245236
if (err) {
246237
LFS_INFO("format -> %d", err);
@@ -251,28 +242,18 @@ int LittleFileSystem::format(BlockDevice *bd,
251242
struct lfs_config _config;
252243

253244
memset(&_config, 0, sizeof(_config));
254-
_config.context = bd;
255-
_config.read = lfs_bd_read;
256-
_config.prog = lfs_bd_prog;
257-
_config.erase = lfs_bd_erase;
258-
_config.sync = lfs_bd_sync;
259-
_config.read_size = bd->get_read_size();
260-
if (_config.read_size < read_size) {
261-
_config.read_size = read_size;
262-
}
263-
_config.prog_size = bd->get_program_size();
264-
if (_config.prog_size < prog_size) {
265-
_config.prog_size = prog_size;
266-
}
267-
_config.block_size = bd->get_erase_size();
268-
if (_config.block_size < block_size) {
269-
_config.block_size = block_size;
270-
}
271-
_config.block_count = bd->size() / _config.block_size;
272-
_config.lookahead = 32 * ((_config.block_count + 31) / 32);
273-
if (_config.lookahead > lookahead) {
274-
_config.lookahead = lookahead;
275-
}
245+
_config.context = bd;
246+
_config.read = lfs_bd_read;
247+
_config.prog = lfs_bd_prog;
248+
_config.erase = lfs_bd_erase;
249+
_config.sync = lfs_bd_sync;
250+
_config.read_size = bd->get_read_size();
251+
_config.prog_size = bd->get_program_size();
252+
_config.block_size = lfs_max(block_size, (lfs_size_t)bd->get_erase_size());
253+
_config.block_count = bd->size() / _config.block_size;
254+
_config.block_cycles = block_cycles;
255+
_config.cache_size = lfs_max(cache_size, _config.prog_size);
256+
_config.lookahead_size = lfs_min(lookahead_size, 8 * ((_config.block_count + 63) / 64));
276257

277258
err = lfs_format(&_lfs, &_config);
278259
if (err) {
@@ -314,7 +295,10 @@ int LittleFileSystem::reformat(BlockDevice *bd)
314295
}
315296

316297
int err = LittleFileSystem::format(bd,
317-
_read_size, _prog_size, _block_size, _lookahead);
298+
_config.block_size,
299+
_config.block_cycles,
300+
_config.cache_size,
301+
_config.lookahead_size);
318302
if (err) {
319303
LFS_INFO("reformat -> %d", err);
320304
_mutex.unlock();
@@ -376,24 +360,18 @@ int LittleFileSystem::stat(const char *name, struct stat *st)
376360
return lfs_toerror(err);
377361
}
378362

379-
static int lfs_statvfs_count(void *p, lfs_block_t b)
380-
{
381-
*(lfs_size_t *)p += 1;
382-
return 0;
383-
}
384-
385363
int LittleFileSystem::statvfs(const char *name, struct statvfs *st)
386364
{
387365
memset(st, 0, sizeof(struct statvfs));
388366

389-
lfs_size_t in_use = 0;
367+
lfs_ssize_t in_use = 0;
390368
_mutex.lock();
391369
LFS_INFO("statvfs(\"%s\", %p)", name, st);
392-
int err = lfs_traverse(&_lfs, lfs_statvfs_count, &in_use);
393-
LFS_INFO("statvfs -> %d", lfs_toerror(err));
370+
in_use = lfs_fs_size(&_lfs);
371+
LFS_INFO("statvfs -> %d", lfs_toerror(in_use));
394372
_mutex.unlock();
395-
if (err) {
396-
return err;
373+
if (in_use < 0) {
374+
return in_use;
397375
}
398376

399377
st->f_bsize = _config.block_size;

LittleFileSystem.h

Lines changed: 40 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -38,29 +38,30 @@ class LittleFileSystem : public mbed::FileSystem {
3838
*
3939
* @param name Name of the file system in the tree.
4040
* @param bd Block device to mount. Mounted immediately if not NULL.
41-
* @param read_size
42-
* Minimum size of a block read. This determines the size of read buffers.
43-
* This may be larger than the physical read size to improve performance
44-
* by caching more of the block device.
45-
* @param prog_size
46-
* Minimum size of a block program. This determines the size of program
47-
* buffers. This may be larger than the physical program size to improve
48-
* performance by caching more of the block device.
4941
* @param block_size
50-
* Size of an erasable block. This does not impact ram consumption and
51-
* may be larger than the physical erase size. However, this should be
52-
* kept small as each file currently takes up an entire block.
53-
* @param lookahead
54-
* Number of blocks to lookahead during block allocation. A larger
55-
* lookahead reduces the number of passes required to allocate a block.
56-
* The lookahead buffer requires only 1 bit per block so it can be quite
57-
* large with little ram impact. Should be a multiple of 32.
42+
* Size of a logical block. This does not impact ram consumption and
43+
* may be larger than the physical erase block. If the physical erase
44+
* block is larger, littlefs will use that instead. Larger values will
45+
* be faster but waste more storage when files are not aligned to a
46+
* block size.
47+
* @param block_cycles
48+
* Number of erase cycles before a block is forcefully evicted. Larger
49+
* values are more efficient but cause less even wear distribution. 0
50+
* disables dynamic wear-leveling.
51+
* @param cache_size
52+
* Size of read/program caches. Each file uses 1 cache, and littlefs
53+
* allocates 2 caches for internal operations. Larger values should be
54+
* faster but uses more RAM.
55+
* @param lookahead_size
56+
* Size of the lookahead buffer. A larger lookahead reduces the
57+
* allocation scans and results in a faster filesystem but uses
58+
* more RAM.
5859
*/
5960
LittleFileSystem(const char *name = NULL, mbed::BlockDevice *bd = NULL,
60-
lfs_size_t read_size = MBED_LFS_READ_SIZE,
61-
lfs_size_t prog_size = MBED_LFS_PROG_SIZE,
6261
lfs_size_t block_size = MBED_LFS_BLOCK_SIZE,
63-
lfs_size_t lookahead = MBED_LFS_LOOKAHEAD);
62+
uint32_t block_cycles = MBED_LFS_BLOCK_CYCLES,
63+
lfs_size_t cache_size = MBED_LFS_CACHE_SIZE,
64+
lfs_size_t lookahead = MBED_LFS_LOOKAHEAD_SIZE);
6465

6566
virtual ~LittleFileSystem();
6667

@@ -69,29 +70,30 @@ class LittleFileSystem : public mbed::FileSystem {
6970
* The block device to format should be mounted when this function is called.
7071
*
7172
* @param bd This is the block device that will be formatted.
72-
* @param read_size
73-
* Minimum size of a block read. This determines the size of read buffers.
74-
* This may be larger than the physical read size to improve performance
75-
* by caching more of the block device.
76-
* @param prog_size
77-
* Minimum size of a block program. This determines the size of program
78-
* buffers. This may be larger than the physical program size to improve
79-
* performance by caching more of the block device.
8073
* @param block_size
81-
* Size of an erasable block. This does not impact ram consumption and
82-
* may be larger than the physical erase size. However, this should be
83-
* kept small as each file currently takes up an entire block.
84-
* @param lookahead
85-
* Number of blocks to lookahead during block allocation. A larger
86-
* lookahead reduces the number of passes required to allocate a block.
87-
* The lookahead buffer requires only 1 bit per block so it can be quite
88-
* large with little ram impact. Should be a multiple of 32.
74+
* Size of a logical block. This does not impact ram consumption and
75+
* may be larger than the physical erase block. If the physical erase
76+
* block is larger, littlefs will use that instead. Larger values will
77+
* be faster but waste more storage when files are not aligned to a
78+
* block size.
79+
* @param block_cycles
80+
* Number of erase cycles before a block is forcefully evicted. Larger
81+
* values are more efficient but cause less even wear distribution. 0
82+
* disables dynamic wear-leveling.
83+
* @param cache_size
84+
* Size of read/program caches. Each file uses 1 cache, and littlefs
85+
* allocates 2 caches for internal operations. Larger values should be
86+
* faster but uses more RAM.
87+
* @param lookahead_size
88+
* Size of the lookahead buffer. A larger lookahead reduces the
89+
* allocation scans and results in a faster filesystem but uses
90+
* more RAM.
8991
*/
9092
static int format(mbed::BlockDevice *bd,
91-
lfs_size_t read_size = MBED_LFS_READ_SIZE,
92-
lfs_size_t prog_size = MBED_LFS_PROG_SIZE,
9393
lfs_size_t block_size = MBED_LFS_BLOCK_SIZE,
94-
lfs_size_t lookahead = MBED_LFS_LOOKAHEAD);
94+
uint32_t block_cycles = MBED_LFS_BLOCK_CYCLES,
95+
lfs_size_t cache_size = MBED_LFS_CACHE_SIZE,
96+
lfs_size_t lookahead_size = MBED_LFS_LOOKAHEAD_SIZE);
9597

9698
/** Mount a file system to a block device.
9799
*
@@ -290,12 +292,6 @@ class LittleFileSystem : public mbed::FileSystem {
290292
struct lfs_config _config;
291293
mbed::BlockDevice *_bd; // The block device
292294

293-
// default parameters
294-
const lfs_size_t _read_size;
295-
const lfs_size_t _prog_size;
296-
const lfs_size_t _block_size;
297-
const lfs_size_t _lookahead;
298-
299295
// thread-safe locking
300296
PlatformMutex _mutex;
301297
};

TESTS/filesystem/dirs/main.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -176,16 +176,16 @@ void test_directory_iteration()
176176
TEST_ASSERT_EQUAL(DT_DIR, res);
177177
res = dir[0].read(&ent);
178178
TEST_ASSERT_EQUAL(1, res);
179-
res = strcmp(ent.d_name, "potato");
179+
res = strcmp(ent.d_name, "burito");
180180
TEST_ASSERT_EQUAL(0, res);
181181
res = ent.d_type;
182-
TEST_ASSERT_EQUAL(DT_DIR, res);
182+
TEST_ASSERT_EQUAL(DT_REG, res);
183183
res = dir[0].read(&ent);
184184
TEST_ASSERT_EQUAL(1, res);
185-
res = strcmp(ent.d_name, "burito");
185+
res = strcmp(ent.d_name, "potato");
186186
TEST_ASSERT_EQUAL(0, res);
187187
res = ent.d_type;
188-
TEST_ASSERT_EQUAL(DT_REG, res);
188+
TEST_ASSERT_EQUAL(DT_DIR, res);
189189
res = dir[0].read(&ent);
190190
TEST_ASSERT_EQUAL(0, res);
191191
res = dir[0].close();
@@ -267,13 +267,13 @@ void test_nested_directories()
267267
TEST_ASSERT_EQUAL(DT_DIR, res);
268268
res = dir[0].read(&ent);
269269
TEST_ASSERT_EQUAL(1, res);
270-
res = strcmp(ent.d_name, "sweet");
270+
res = strcmp(ent.d_name, "fried");
271271
TEST_ASSERT_EQUAL(0, res);
272272
res = ent.d_type;
273273
TEST_ASSERT_EQUAL(DT_DIR, res);
274274
res = dir[0].read(&ent);
275275
TEST_ASSERT_EQUAL(1, res);
276-
res = strcmp(ent.d_name, "fried");
276+
res = strcmp(ent.d_name, "sweet");
277277
TEST_ASSERT_EQUAL(0, res);
278278
res = ent.d_type;
279279
TEST_ASSERT_EQUAL(DT_DIR, res);
@@ -300,7 +300,7 @@ void test_multi_block_directory()
300300
res = fs.mkdir("cactus", 0777);
301301
TEST_ASSERT_EQUAL(0, res);
302302
for (int i = 0; i < 128; i++) {
303-
sprintf((char *)buffer, "cactus/test%d", i);
303+
sprintf((char *)buffer, "cactus/test%03d", i);
304304
res = fs.mkdir((char *)buffer, 0777);
305305
TEST_ASSERT_EQUAL(0, res);
306306
}
@@ -326,7 +326,7 @@ void test_multi_block_directory()
326326
res = ent.d_type;
327327
TEST_ASSERT_EQUAL(DT_DIR, res);
328328
for (int i = 0; i < 128; i++) {
329-
sprintf((char *)buffer, "test%d", i);
329+
sprintf((char *)buffer, "test%03d", i);
330330
res = dir[0].read(&ent);
331331
TEST_ASSERT_EQUAL(1, res);
332332
res = strcmp(ent.d_name, (char *)buffer);
@@ -509,13 +509,13 @@ void test_directory_rename()
509509
TEST_ASSERT_EQUAL(DT_DIR, res);
510510
res = dir[0].read(&ent);
511511
TEST_ASSERT_EQUAL(1, res);
512-
res = strcmp(ent.d_name, "sweet");
512+
res = strcmp(ent.d_name, "fried");
513513
TEST_ASSERT_EQUAL(0, res);
514514
res = ent.d_type;
515515
TEST_ASSERT_EQUAL(DT_DIR, res);
516516
res = dir[0].read(&ent);
517517
TEST_ASSERT_EQUAL(1, res);
518-
res = strcmp(ent.d_name, "fried");
518+
res = strcmp(ent.d_name, "sweet");
519519
TEST_ASSERT_EQUAL(0, res);
520520
res = ent.d_type;
521521
TEST_ASSERT_EQUAL(DT_DIR, res);
@@ -569,13 +569,13 @@ void test_directory_rename()
569569
TEST_ASSERT_EQUAL(DT_DIR, res);
570570
res = dir[0].read(&ent);
571571
TEST_ASSERT_EQUAL(1, res);
572-
res = strcmp(ent.d_name, "sweet");
572+
res = strcmp(ent.d_name, "fried");
573573
TEST_ASSERT_EQUAL(0, res);
574574
res = ent.d_type;
575575
TEST_ASSERT_EQUAL(DT_DIR, res);
576576
res = dir[0].read(&ent);
577577
TEST_ASSERT_EQUAL(1, res);
578-
res = strcmp(ent.d_name, "fried");
578+
res = strcmp(ent.d_name, "sweet");
579579
TEST_ASSERT_EQUAL(0, res);
580580
res = ent.d_type;
581581
TEST_ASSERT_EQUAL(DT_DIR, res);
@@ -631,13 +631,13 @@ void test_directory_rename()
631631
TEST_ASSERT_EQUAL(DT_DIR, res);
632632
res = dir[0].read(&ent);
633633
TEST_ASSERT_EQUAL(1, res);
634-
res = strcmp(ent.d_name, "sweet");
634+
res = strcmp(ent.d_name, "fried");
635635
TEST_ASSERT_EQUAL(0, res);
636636
res = ent.d_type;
637637
TEST_ASSERT_EQUAL(DT_DIR, res);
638638
res = dir[0].read(&ent);
639639
TEST_ASSERT_EQUAL(1, res);
640-
res = strcmp(ent.d_name, "fried");
640+
res = strcmp(ent.d_name, "sweet");
641641
TEST_ASSERT_EQUAL(0, res);
642642
res = ent.d_type;
643643
TEST_ASSERT_EQUAL(DT_DIR, res);

0 commit comments

Comments
 (0)