Hi. First of all, great work! I really enjoy the web simulator.
To implement the user needs to supply these functions:
.read = user_provided_block_device_read,
.prog = user_provided_block_device_prog,
.erase = user_provided_block_device_erase,
.sync = user_provided_block_device_sync,
Do you have an example of how these should look?
E.g. like the examples here: https://github.com/pellepl/spiffs/wiki/Integrate-spiffs
I'm asking because it seems the function arguments required are at a layer of abstraction higher than a driver, which usually just has: (SPI handle, address, size, *buffer).
Best regards
Frederik
Ok, i found your example in the mbed wrapper. Now I just need to know what data type buffer needs to be? I'm assuming uint8_t due to SPI being 8-bit hardware, but the void type confuses me
Ah, thanks!
The easiest route to using littlefs is to use mbed OS if you can. There the SPI drivers are already taken care of you, so in most cases you just have to choose the right pins (example).
For porting littlefs directly, here's the declaration of the block device functions:
https://github.com/geky/littlefs/blob/5ee20e8d774adf0bb538269870b3552fdfc0e046/lfs.h#L95-L114
For example, read gives you these arguments:
const struct lfs_config *cfg - This is a pointer to the config struct itself. This lets you access properties used by littlefs, such as cfg->block_size or cfg->block_count.
You can also use cfg to get access to a SPI object by storing the object in cfg->context. The context variable is only used to pass context to the block device driver.
lfs_block_t block - This is a 32 bit block number. The size of a block is determined by cfg->block_size.
lfs_off_t off - This is a 32 bit byte offset into the current block. The address can be determined by this formula block*cfg->block_size + off.
const void *buffer - This is the buffer for either storing the data or it contains the data to program. It is a void* to match functions like memcpy, though you can just treat it like a uint8_t*.
lfs_size_t size - This is a 32 bit size that indicates how many bytes to read/program.
Here's a quick example that gets the types you mentioned:
int lfs_bd_read(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, void *buffer, lfs_size_t size) {
SPI *spi = cfg->context; // must have been assigned before lfs_mount was called
uint32_t spi_address = block*cfg->block_size + off;
uint32_t spi_size = size;
uint8_t *spi_data = buffer;
blahblahblah
return 0;
}
You can also look into the existing ports as examples in case it helps:
Hopefully that helps
Thanks for the help!
I have littlefs running and I am doing some testing, however I would like to be able to determine how much space littlefs is using, and how full the flash is. It seems this function:
int lfs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data);
is made for the purpose, however I can't get my head around how to extract that data, with those arguments.
Best regards
Frederik
Glad to hear you were able to get littlefs working!
lfs_traverse is the most raw api in littlefs. It can give you a lot of information but isn't the easiest to use.
To use lfs_traverse you pass it a callback along with a pointer to state you can use. The callback is then
called with every block address the filesystem is using.
If you want to count the number of blocks in use you can ignore the address and do something like this:
// global
static int lfs_count(void *p, lfs_block_t b) {
*(lfs_size_t *)p += 1;
return 0;
}
// in main
lfs_size_t in_use = 0;
lfs_traverse(&lfs, lfs_count, &in_use);
printf("blocks in use %u (%u%%)\n", in_use, (100*in_use)/config.block_count);
The implementation of statfs in littlefs-fuse might be useful:
https://github.com/geky/littlefs-fuse/blob/8bbedd2e0687792bc8dd3a6d3029f636fd4587d4/lfs_fuse.c#L93-L115
Note: Since littlefs files are copy-on-write, traverse may report the same block multiple times for files that are in the middle of being modified. littlefs isn't smart enough to do anything about this. If all of the files are closed during traverse the block count should be pretty accurate.
Most helpful comment
Glad to hear you were able to get littlefs working!
lfs_traverseis the most raw api in littlefs. It can give you a lot of information but isn't the easiest to use.To use
lfs_traverseyou pass it a callback along with a pointer to state you can use. The callback is thencalled with every block address the filesystem is using.
If you want to count the number of blocks in use you can ignore the address and do something like this:
The implementation of statfs in littlefs-fuse might be useful:
https://github.com/geky/littlefs-fuse/blob/8bbedd2e0687792bc8dd3a6d3029f636fd4587d4/lfs_fuse.c#L93-L115
Note: Since littlefs files are copy-on-write, traverse may report the same block multiple times for files that are in the middle of being modified. littlefs isn't smart enough to do anything about this. If all of the files are closed during traverse the block count should be pretty accurate.