This is a style change to make littlefs's callbacks consistent with most
callback declarations found in C. That is, taking in a user-provided
`void*`.
Previously, these callbacks took a pointer to the config struct itself,
which indirectly contained a user provided context, and this gets the
job done, but taking in a callback with a `void*` is arguably more
expected, has a better chance of integrating with C++/OS-specific code,
and is more likely to be optimized out by a clever compiler.
---
As a part of these changes, the geometry for the test bds needed to be
moved into bd specific configuration objects. This is a good change as
it also allows for testing situations where littlefs's geometry does not
match the underlying bd.
As an embedded library, littlefs's configuration straddles two worlds.
In most cases the configuration is usually constant at build time, but
when integrated into OSs, the configuration needs to be dynamically
configurable.
To help with this, littlefs has a separate lfs_config struct that can be
placed into ROM when possible.
But you know what's better than ROM configuration? Truely inlinable
static configuration known at compile-time. In addition to avoiding the
RAM cost, compile-time configuration allows for additional compiler
optimizations, such as constexpr-elimination and removal of unused
code-paths.
So how to enable static configuration?
1. define LFS_STATICCFG
2. implement callbacks as global functions:
- lfs_read
- lfs_prog
- lfs_erase
- lfs_sync
2. define the now-required constants that configure littlefs:
- LFS_READ_SIZE
- LFS_PROG_SIZE
- LFS_BLOCK_SIZE
- LFS_BLOCK_COUNT
- LFS_BLOCK_CYCLES
- LFS_CACHE_SIZE
- LFS_LOOKAHEAD_SIZE
- LFS_READ_BUFFER (optional)
- LFS_PROG_BUFFER (optional)
- LFS_LOOKAHEAD_BUFFER (optional)
- LFS_NAME_MAX (optional)
- LFS_FILE_MAX (optional)
- LFS_ATTR_MAX (optional)
Note, there is a separate configuration for the file configuration, this
can be enabled/disabled independently of LFS_STATICCFG. You will likely
want to define this as well if you are looking for the smallest code
size.
In order to avoid a mess of #ifdefs, the internals of littlefs use a
simple macro that redirects to either the dynamic or static config at
compile time:
#ifdef LFS_STATICCFG
#define LFS_CFG_READ_SIZE(lfs) ((void)lfs, LFS_READ_SIZE)
#else
#define LFS_CFG_READ_SIZE(lfs) lfs->cfg->read_size
#endif
Unfortunately it does look like there still may be a lot of issues
related to warnings of comparisons against constants... If only C had
a way to ignore warnings on individual statements...
Original idea by apmorton
Moved .travis.yml over to use the new test framework. A part of this
involved testing all of the configurations ran on the old framework
and deciding which to carry over. The new framework duplicates some of
the cases tested by the configurations so some configurations could be
dropped.
The .travis.yml includes some extreme ones, such as no inline files,
relocations every cycle, no intrinsics, power-loss every byte, unaligned
block_count and lookahead, and odd read_sizes.
There were several configurations were some tests failed because of
limitations in the tests themselves, so many conditions were added
to make sure the configurations can run on as many tests as possible.
- Removed old tests and test scripts
- Reorganize the block devices to live under one directory
- Plugged new test framework into Makefile
renamed:
- scripts/test_.py -> scripts/test.py
- tests_ -> tests
- {file,ram,test}bd/* -> bd/*
It took a surprising amount of effort to make the Makefile behave since
it turns out the "test_%" rule could override "tests/test_%.toml.test"
which is generated as part of test.py.