最近在调试littlefs文件系统中遇到了很多问题,经过几天的调试都一一解决了,目前在nor flash 和nand flash 上都测试通过,下面做一个记录。
#include "lfs_port.h"
#ifdef NANDFLASH
#define PAGE_SIZE 2048 //page size in bytes
#define OFFSETBLOCK 40 //前5M不能用
#define READ_SIZE 512 //512
#define PROG_SIZE 512
#define BLOCK_SIZE 64*2048 //Size of an erasable block in bytes
#define BLOCK_COUNT (10-5)*1024/128 //(64-5)*1024/128, //Number of erasable blocks on the device.
#define CACHE_SIZE 512 //512
#define LOOKAHEAD_SIZE 512 //512
#define BLOCK_CYCLES 500
#else //nor flash
#define OFFSETBLOCK 534 //front 534 sector
#define SECTOR_SIZE 4096
#define READ_SIZE 256
#define PROG_SIZE 256
#define BLOCK_SIZE 4096 //Size of an erasable sector in bytes
#define BLOCK_COUNT 1024 //(8*1024-OFFSETBLOCK*4)/4
#define CACHE_SIZE 256 //256
#define LOOKAHEAD_SIZE 128 //128
#define BLOCK_CYCLES 500
#endif
static lfs_config_t mlfs={
#ifdef NANDFLASH
.flash_init=spi_nand_init,
.flash_read=spi_nand_read,
.flash_write=spi_nand_write,
.flash_erase=spi_nand_erase_block,
#else //nor flash
.flash_init=spi_nor_init,
.flash_read=spi_nor_read,
.flash_write=spi_nor_flash_write,
.flash_erase=spi_nor_erase_sector,
#endif
};
u32_t page_size=PAGE_SIZE; //note:宏不能做除数
u32_t block_size=BLOCK_SIZE;
/**
* lfs与底层flash读数据接口
* @param c
* @param block 块编号
* @param off 块内偏移地址
* @param buffer 用于存储读取到的数据
* @param size 要读取的字节数
* @return
*/
static int lfs_deskio_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size)
{
#ifdef NANDFLASH
if(0==mlfs.flash_read(OFFSETBLOCK+block, off/page_size,off%page_size,buffer, size))
#else
if(0==mlfs.flash_read((OFFSETBLOCK+block)*c->block_size+off,buffer, size))
#endif
return LFS_ERR_OK;
else return LFS_ERR_IO;
}
/**
* lfs与底层flash写数据接口
* @param c
* @param block 块编号
* @param off 块内偏移地址
* @param buffer 待写入的数据
* @param size 待写入数据的大小
* @return
*/
static int lfs_deskio_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size)
{
#ifdef NANDFLASH
if(0==mlfs.flash_write(OFFSETBLOCK+block, off/page_size,off%page_size,(void*)buffer, size))
#else
if(0==mlfs.flash_write((OFFSETBLOCK+block)*c->block_size+off,(void*)buffer, size))
#endif
return LFS_ERR_OK;
else return LFS_ERR_IO;
}
/**
* lfs与底层flash擦除接口
* @param c
* @param block 块编号
* @return
*/
static int lfs_deskio_erase(const struct lfs_config *c, lfs_block_t block)
{
#ifdef NANDFLASH
if(0==mlfs.flash_erase(OFFSETBLOCK+block))
#else
if(0==mlfs.flash_erase((OFFSETBLOCK+block)*c->block_size))
#endif
return LFS_ERR_OK;
else return LFS_ERR_IO;
}
static int lfs_deskio_sync(const struct lfs_config *c)
{
return LFS_ERR_OK;
}
s32_t lfs_init(void)
{
return mlfs.flash_init();
}
const struct lfs_config lfs_cfg =
{
// block device operations
.read = lfs_deskio_read,
.prog = lfs_deskio_prog,
.erase = lfs_deskio_erase,
.sync = lfs_deskio_sync,
// block device configuration
.read_size = READ_SIZE,
.prog_size = PROG_SIZE,
.block_size = BLOCK_SIZE, //Size of an erasable block in bytes
.block_count =BLOCK_COUNT, //(64-5)*1024/128, //Number of erasable blocks on the device.
.cache_size = CACHE_SIZE, //2048
.lookahead_size =LOOKAHEAD_SIZE, //1024
.block_cycles = BLOCK_CYCLES,
};
// entry point
void lfs_test(const struct lfs_config *cfg,lfs_t *lfs, lfs_file_t *file)
{
// mount the filesystem
int err = lfs_mount(lfs, cfg);
if(err<0)printfk("lfs_mount:err\r\n");
// reformat if we can't mount the filesystem
// this should only happen on the first boot
if (err)
{
err=lfs_format(lfs, cfg);
if(err<0)printfk("lfs_format:err \r\n");
err=lfs_mount(lfs, cfg);
if(err<0)printfk("lfs_mount:err \r\n");
}
// read current count
uint32_t boot_count = 0;
if(err==0)
{
err=lfs_file_open(lfs, file, "boot_count", LFS_O_RDWR | LFS_O_CREAT);
if(err<0)printfk("lfs_file_open:err \r\n");
err=lfs_file_read(lfs, file, &boot_count, sizeof(boot_count));
if(err<0)printfk("lfs_file_read:err \r\n");
// update boot count
boot_count += 1;
lfs_file_rewind(lfs, file);
lfs_file_write(lfs, file, &boot_count, sizeof(boot_count));
// remember the storage is not updated until the file is closed successfully
lfs_file_close(lfs, file);
// release any resources we were using
lfs_unmount(lfs);
}
// print the boot count
printfk("boot_count: %d\n", boot_count);
}
..\third\littlefs\lfs.c:5336:trace: lfs_mount(801113FC, 80110E30 {.context=00000000, .read=801066BC, .prog=8010663C, .erase=80106604, .sync=8010673C, .read_size=2048, .prog_size=2048, .block_size=131072, .block_count=40, .block_cycles=500, .cache_size=2048, .lookahead_size=2048, .read_buffer=00000000, .prog_buffer=00000000, .lookahead_buffer=00000000, .name_max=0, .file_max=0, .attr_max=0})
..\third\littlefs\lfs.c:5355:trace: lfs_mount -> -12
lfs_mount:err
..\third\littlefs\lfs.c:5306:trace: lfs_format(801113FC, 80110E30 {.context=00000000, .read=801066BC, .prog=8010663C, .erase=80106604, .sync=8010673C, .read_size=2048, .prog_size=2048, .block_size=131072, .block_count=40, .block_cycles=500, .cache_size=2048, .lookahead_size=2048, .read_buffer=00000000, .prog_buffer=00000000, .lookahead_buffer=00000000, .name_max=0, .file_max=0, .attr_max=0})
..\third\littlefs\lfs.c:5325:trace: lfs_format -> -12
lfs_format:err
..\third\littlefs\lfs.c:5336:trace: lfs_mount(801113FC, 80110E30 {.context=00000000, .read=801066BC, .prog=8010663C, .erase=80106604, .sync=8010673C, .read_size=2048, .prog_size=2048, .block_size=131072, .block_count=40, .block_cycles=500, .cache_size=2048, .lookahead_size=2048, .read_buffer=00000000, .prog_buffer=00000000, .lookahead_buffer=00000000, .name_max=0, .file_max=0, .attr_max=0})
..\third\littlefs\lfs.c:5355:trace: lfs_mount -> -12
lfs_mount:err