littlefs-project / littlefs

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

Test LittleFS on SPI NAND Flash in mbed OS #547

Open rogeryou opened 3 years ago

rogeryou commented 3 years ago

Hi all,

My issue is related about #421 #11 #536 #422

I am testing littlefs on Macronix SPI NAND in mbed OS. I test with read_size, .prog_size and .cache_size = 2048 bytes. I try writing and reading some different size of files. The result is OK if the size is smaller than 2048, but if the size of the file is bigger than 2048, the test result is failed. I write a file with 4096 byte, the driver will execute Page program command twice. I have printed some information. The first address is 0xa0000, the second address is 0xa0800. The second address should be 0xa1000, because the page offset of SPI NAND Flash is 0x1000 instead of page size(2048). I have analyzed the source code, as below

static int lfs2_bd_prog(lfs2_t *lfs2,
        lfs2_cache_t *pcache, lfs2_cache_t *rcache, bool validate,
        lfs2_block_t block, lfs2_off_t off,
        const void *buffer, lfs2_size_t size) {
    const uint8_t *data = buffer;
    LFS2_ASSERT(block == LFS2_BLOCK_INLINE || block < lfs2->cfg->block_count);
    LFS2_ASSERT(off + size <= lfs2->cfg->block_size);

    while (size > 0) {
        if (block == pcache->block &&
                off >= pcache->off &&
                off < pcache->off + lfs2->cfg->cache_size) {
            // already fits in pcache?
            lfs2_size_t diff = lfs2_min(size,
                    lfs2->cfg->cache_size - (off-pcache->off));
            memcpy(&pcache->buffer[off-pcache->off], data, diff);

            data += diff;
            off += diff;
            size -= diff;

            pcache->size = lfs2_max(pcache->size, off - pcache->off);
            if (pcache->size == lfs2->cfg->cache_size) {
                // eagerly flush out pcache if we fill up
                int err = lfs2_bd_flush(lfs2, pcache, rcache, validate);
                if (err) {
                    return err;
                }
            }

            continue;
        }

        // pcache must have been flushed, either by programming and
        // entire block or manually flushing the pcache
        LFS2_ASSERT(pcache->block == LFS2_BLOCK_NULL);

        // prepare pcache, first condition can no longer fail
        pcache->block = block;
        pcache->off = lfs2_aligndown(off, lfs2->cfg->prog_size);
        pcache->size = 0;
    }

    return 0;
}

Does anyone could tell me how I can handle with this situation? Need modify the source code about off? @geky @kazola @visakh-png

Have a nice day!

JonJust commented 3 years ago

Did you ever get this working? I've heard reports that using buffers sizes larger than 256 bytes can cause issues