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