023月 2019

1

985

0

移植LittleFs

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函数接口。

Comments (0)