MT2503的板子外挂8Mbit的SPI Flash,本打算移植Fatfs,但Fatfs并不支持Wear leveling,后发现LittleFs,一个专门为单片机设计的文件系统,并且支持fail-safe。
详细介绍:https://os.mbed.com/blog/entry/littlefs-high-integrity-embedded-fs/
LittleFs Github https://github.com/ARMmbed/littlefs
LittleFs的移植很简单,只需实现Flash的读、写和擦除基本操作即可,官方例子如下:
#include "lfs.h" // variables used by the filesystem lfs_t lfs; lfs_file_t file; // configuration of the filesystem is provided by this struct const struct lfs_config cfg = { // block device operations .read = user_provided_block_device_read, .prog = user_provided_block_device_prog, .erase = user_provided_block_device_erase, .sync = user_provided_block_device_sync, // block device configuration .read_size = 16, .prog_size = 16, .block_size = 4096, .block_count = 128, .lookahead = 128, }; // entry point int main(void) { // mount the filesystem int err = lfs_mount(&lfs, &cfg); // reformat if we can't mount the filesystem // this should only happen on the first boot if (err) { lfs_format(&lfs, &cfg); lfs_mount(&lfs, &cfg); } // read current count uint32_t boot_count = 0; lfs_file_open(&lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT); lfs_file_read(&lfs, &file, &boot_count, sizeof(boot_count)); // 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 printf("boot_count: %d\n", boot_count); }
已经实现的Flash驱动声明:
void flash_read_block(kal_uint32 addr, kal_uint8 *buff, kal_uint32 len); void flash_write_block(kal_uint32 addr, kal_uint8 *buff, kal_uint32 len); void flash_erase_block(kal_uint32 addr);
操作接口配置:
static int _block_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) { flash_read_block(block * c->block_size + off, (kal_uint8 *)buffer, (kal_uint32)size); return 0; } static int _block_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size) { flash_write_block(block * c->block_size + off, (kal_uint8 *)buffer, (kal_uint32)size); return 0; } static int _block_erase(const struct lfs_config *c, lfs_block_t block) { flash_erase_block(block * c->block_size); return 0; } static int _block_sync(const struct lfs_config *c) { return 0; } const struct lfs_config cfg = { // block device operations .read = _block_read, .prog = _block_prog, .erase = _block_erase, .sync = _block_sync, // block device configuration .read_size = 16, .prog_size = 16, .block_size = 4096, .block_count = 256, .lookahead = 256, };
编译时出现大量Error,经过折腾最终搞定。
总结了一下:
1. armcc默认不支持对结构体指定成员名称进行初始化、不支持可执行代码之后声明变量,CFLAG添加 –gnu 可以解决问题,添加方法请参考《MTK功能机MMI,添加GNU特性》;
2. LittleFs需要提供系统的malloc, free函数接口。
原文地址:http://www.noblock.cn/?p=183