littlefs-project / littlefs

A little fail-safe filesystem designed for microcontrollers
BSD 3-Clause "New" or "Revised" License
5.16k stars 793 forks source link

Start file system at fixed position in Flash #204

Open safirxps opened 5 years ago

safirxps commented 5 years ago

Hi,

I am using flashless MCU with QSPI external flash, program is running in XIP mode, the flash I am using is 512 MBytes from Gigadevice GD25S512MD, main software is located at the beginning of the flash, How to tell LittleFS to start file system at fixed address in Flash ? My software is located @ address 0 mapped to 0x60000000 I would like LittleFs starting @address 0x20000 for exemple. Thanks

geky commented 5 years ago

Hi @safirxps, littlefs takes a block device and uses the full range of addresses. But you control this block device, so if you wanted to you can map the addresses littlefs is using to any address on the underlying storage.

Here's a quick example of how you could map the addresses to omit 0-0x20000:

#define READ_SIZE 1
#define PROG_SIZE 1
#define ERASE_SIZE 4096
#define APP_SIZE 20*ERASE_SIZE
#define FLASH_SIZE 512*ERASE_SIZE

int bd_read(const struct lfs_config *c, lfs_block_t block,
        lfs_off_t off, void *buffer, lfs_size_t size) {
    // calculate new block address
    return real_bd_read(c, block + (APP_SIZE/ERASE_SIZE), off, size);
}

struct lfs_config cfg = {
    .read_size = READ_SIZE,
    .prog_size = PROG_SIZE,
    .block_size = ERASE_SIZE,
    .block_count = (FLASH_SIZE - APP_SIZE) / ERASE_SIZE, // omit first 20 blocks from size
    .read = bd_read,
    .prog = bd_prog,
    .erase = bd_erase,
};

Note you need to make sure the offset is aligned to the block size (erase size) or else bad things will happen!

EDIT: Fixed math (block + (APP_SIZE/ERASE_SIZE))

safirxps commented 5 years ago

Hi Geky,

Thanks for your answer, I will try. By the way I am little confused with this flash http://www.elm-tech.com/en/products/spi-flash-memory/gd25s512m/gd25s512m.pdf page 9 could you help me to configure in LittleFS the config block for read_size, prog_size and block_size; ?

Rgds David

geky commented 5 years ago

Yeah, the names storage devices use for different block sizes is a mess.

Looking at that datasheet, the GD25S512M can do byte-level read and writes, and can erase 4KiB sectors. So something like this should work:

read_size = 1
prog_size = 1
cache_size = anything from 1 to 4096, larger values use more RAM but may be faster
block_size = 4096

As for the other sizes in the datasheet:

The page size is how many bytes can be programmed at once. You should take special care to send multiple program operations for any programs > page size (littlefs guarantees alignment, but may send larger buffers).

The difference in sector size vs block size is the amount of bytes erased in a single command. Block erases can get you faster erase throughput, but littlefs doesn't take advantage of this so it's probably not worth implementing.

geky commented 5 years ago

There's an open source implementation of a SPI driver in Mbed OS, it may be useful as a reference: https://github.com/ARMmbed/mbed-os/blob/master/components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp#L285

safirxps commented 5 years ago

Hi geky

I am experiencing one problem using LittleFs is there any forum somewhere or it is possible to ask in this issues board ?

Thanks

geky commented 5 years ago

Creating an issue is the best place right now.

I'm considering creating a gitter for littlefs, but it doesn't exist yet.

safirxps commented 5 years ago

Hi Geky, On the first question of this post your answered : return real_bd_read(c, block - (APP_SIZE/ERASE_SIZE), off, size); Are you sure it is block minus (APP_SIZE/ERASE_SIZE) ? thanks

geky commented 5 years ago

Oh! My bad. You are right, I believe that should be block + (APP_SIZE/ERASE_SIZE).