LittleFs的移植和使用
由于前段时间换了一个开发平台,而之前使用的平台的文件系统是Fats,但是明显感觉文件的写入速度比较慢,应该是内部默认是64Kflash擦除,在网上偶然看到关于littlefs的文章,所以此次将整个移植过程贴出来供大家参考。
1.移植过程参考
https://blog.csdn.net/skyfreedoms/article/details/5837067
https://blog.csdn.net/qq_18204721/article/details/82490954
2.首先在GitHub上下载littlefs的源码
移植过程参考上述文章,需要注意的点为,如果你的平台没有微库,则需要自己实现自己的内存管理函数
// Allocate memory, only used if buffers are not provided to littlefs
static inline void *lfs_malloc(size_t size) {
#ifndef LFS_NO_MALLOC
return LocalAlloc(1,size);
#else
(void)size;
return NULL;
#endif
}
// Deallocate memory, only used if buffers are not provided to littlefs
static inline void lfs_free(void *p) {
#ifndef LFS_NO_MALLOC
LocalFree§;
#else
(void)p;
#endif
}
因为如果按照上面一篇博文使用全局数组的话,会导致无法打开多个文件,只能一次打开一个文件,显然不满足我们的需求,所以需要使用动态内存申请。
3.附上移植后的测试代码,方便大家理解
//lfs
#define LFS_TEST_DEMO
#ifdef LFS_TEST_DEMO
lfs_t g_lfs;
lfs_file_t g_lfs_file[3];
struct lfs_config g_lfs_cfg;
lfs_free_t g_lfs_free;
lfs_dir_t g_dir[2];
uint8_t lfs_read_buf[256] = {0};
uint8_t lfs_prog_buf[256] = {0};
uint8_t lfs_lookahead_buf[256] = {0};
uint8_t lfs_file_buf[256] = {0};
static int lfs_fuse_statfs_count(void* p,lfs_block_t block)
{
(lfs_size_t)p += 1;
return 0;
}
void lfs_free_spcae(u32* free_space)
{
lfs_size_t use_space = 0;
int err = lfs_traverse(&g_lfs,lfs_fuse_statfs_count,&use_space);
if(err)
{
return ;
}
*free_space = g_lfs_cfg.block_count - use_space;
}
void lfs_set_config(void)
{
// configuration of the filesystem is provided by this struct
g_lfs_cfg.read = block_device_read,
g_lfs_cfg.prog = block_device_prog,
g_lfs_cfg.erase = block_device_erase,
g_lfs_cfg.sync = block_device_sync,
g_lfs_cfg.read_size = 256,
g_lfs_cfg.prog_size = 256,
g_lfs_cfg.block_size = 4096,
g_lfs_cfg.block_count = 512,
g_lfs_cfg.lookahead = 256,
#if 0
g_lfs_cfg.read_buffer = lfs_read_buf;
g_lfs_cfg.prog_buffer = lfs_prog_buf;
g_lfs_cfg.lookahead_buffer = lfs_lookahead_buf;
g_lfs_cfg.file_buffer = lfs_file_buf;
#else //动态申请内存则可以处理多个文件 使用数组则不行
g_lfs_cfg.read_buffer = NULL;
g_lfs_cfg.prog_buffer = NULL;
g_lfs_cfg.lookahead_buffer = NULL;
g_lfs_cfg.file_buffer = NULL;
#endif
}
void lfs_test_demo(void)
{
#if 0
u8 lfs_write_buf1[1024] = {“123456789”};
u8 lfs_write_buf2[1024] = {“abcdefghi”};
u8 lfs_read_buf1[1024] = {0};
u8 lfs_read_buf2[1024] = {0};
u32 lfs_free_spcae_size = 0;
int lfs_dir_pos = 0;
struct lfs_info lfs_file_info = {0};
lfs_set_config();
// mount the filesystem
lfs_format(&g_lfs, &g_lfs_cfg);
int err = lfs_mount(&g_lfs, &g_lfs_cfg);
// reformat if we can't mount the filesystem
// this should only happen on the first boot
if (err) {
LFS_DEBUG("lfs need formart flash to mount filesystem: %d\n", __LINE__);
lfs_format(&g_lfs, &g_lfs_cfg);
lfs_mount(&g_lfs, &g_lfs_cfg);
}
err = lfs_dir_open(&g_lfs, &g_dir[0], "E:");
LFS_DEBUG("lfs dir open error:%d LINE %d\n",err, __LINE__);
if(err == LFS_ERR_NOENT)
{
lfs_mkdir(&g_lfs ,"E:");
LFS_DEBUG("lfs makedir LINE %d\n", __LINE__);
}
err = lfs_dir_open(&g_lfs, &g_dir[0], "E:/data");
LFS_DEBUG("lfs dir error:%d LINE %d\n",err, __LINE__);
if(err == LFS_ERR_NOENT)
{
lfs_mkdir(&g_lfs ,"E:/data");
LFS_DEBUG("lfs makedir LINE %d\n", __LINE__);
}
lfs_free_spcae(&lfs_free_spcae_size);
LFS_DEBUG("lfs free spce = %d LINE %d\n",lfs_free_spcae_size, __LINE__);
// read current count
err = lfs_file_open(&g_lfs, &g_lfs_file[0], "E:/boot1", LFS_O_RDWR | LFS_O_CREAT);
if (err) {
LFS_DEBUG("lfs open1 error:%d LINE %d\n",err, __LINE__);
}
err = lfs_file_open(&g_lfs, &g_lfs_file[1], "E:/boot2", LFS_O_RDWR | LFS_O_CREAT);
if (err) {
LFS_DEBUG("lfs open2 error:%d LINE %d\n",err, __LINE__);
}
err = lfs_file_open(&g_lfs, &g_lfs_file[2], "E:/data/boot3", LFS_O_RDWR | LFS_O_CREAT);
if (err) {
LFS_DEBUG("lfs open3 error:%d LINE %d\n",err, __LINE__);
}
err = lfs_file_write(&g_lfs, &g_lfs_file[0], lfs_write_buf1, sizeof(lfs_write_buf1));
if (err) {
LFS_DEBUG("lfs write1 len:%d LINE %d\n",err, __LINE__);
}
err = lfs_file_write(&g_lfs, &g_lfs_file[1], lfs_write_buf2, sizeof(lfs_write_buf2));
if (err) {
LFS_DEBUG("lfs write2 len:%d LINE %d\n",err, __LINE__);
}
//if not set cursor will read data error
lfs_file_seek(&g_lfs, &g_lfs_file[0],0,LFS_SEEK_SET);
lfs_file_seek(&g_lfs, &g_lfs_file[1],0,LFS_SEEK_SET);
err = lfs_file_read(&g_lfs, &g_lfs_file[0], lfs_read_buf1, sizeof(lfs_read_buf1));
if (err) {
LFS_DEBUG("lfs read len:%d LINE %d\n", err,__LINE__);
}
err = lfs_file_read(&g_lfs, &g_lfs_file[1], lfs_read_buf2, sizeof(lfs_read_buf2));
if (err) {
LFS_DEBUG("lfs read2 len:%d LINE %d\n", err,__LINE__);
}
// remember the storage is not updated until the file is closed successfully
err = lfs_file_close(&g_lfs, &g_lfs_file[0]);
if (err) {
LFS_DEBUG("lfs close1 error:%d LINE %d\n", err,__LINE__);
}
err = lfs_file_close(&g_lfs, &g_lfs_file[1]);
if (err) {
LFS_DEBUG("lfs close2 error:%d LINE %d\n", err,__LINE__);
}
err = lfs_file_close(&g_lfs, &g_lfs_file[2]);
if (err) {
LFS_DEBUG("lfs close3 error:%d LINE %d\n", err,__LINE__);
}
LFS_DEBUG("lfs read1 data: %s %d\n",lfs_read_buf1, __LINE__);
LFS_DEBUG("lfs read2 data: %s %d\n",lfs_read_buf2, __LINE__);
lfs_free_spcae(&lfs_free_spcae_size);
LFS_DEBUG("lfs free spce = %d LINE %d\n",lfs_free_spcae_size, __LINE__);
lfs_stat(&g_lfs,"E:/boot1", &lfs_file_info);
LFS_DEBUG("lfs get E:/boot1 file info type = %d size = %d filename = %s LINE %d\n",lfs_file_info.type,lfs_file_info.size,lfs_file_info.name, __LINE__);
memset(&lfs_file_info,0x00,sizeof(lfs_file_info));
lfs_stat(&g_lfs,"E:", &lfs_file_info);
LFS_DEBUG("lfs get E: file info type = %d size = %d filename = %s LINE %d\n",lfs_file_info.type,lfs_file_info.size,lfs_file_info.name, __LINE__);
lfs_dir_open(&g_lfs, &g_dir[0], "E:");
lfs_dir_pos = lfs_dir_tell(&g_lfs, &g_dir[0]);
LFS_DEBUG("lfs dir tell = %d LINE %d\n",lfs_dir_pos, __LINE__);
lfs_dir_read(&g_lfs, &g_dir[0], &lfs_file_info);
LFS_DEBUG("lfs get E:/ file info type = %d size = %d filename = %s LINE %d\n",lfs_file_info.type,lfs_file_info.size,lfs_file_info.name, __LINE__);
lfs_dir_read(&g_lfs, &g_dir[0], &lfs_file_info);
LFS_DEBUG("lfs get E:/ file info type = %d size = %d filename = %s LINE %d\n",lfs_file_info.type,lfs_file_info.size,lfs_file_info.name, __LINE__);
lfs_dir_read(&g_lfs, &g_dir[0], &lfs_file_info);
LFS_DEBUG("lfs get E:/ file info type = %d size = %d filename = %s LINE %d\n",lfs_file_info.type,lfs_file_info.size,lfs_file_info.name, __LINE__);
lfs_dir_read(&g_lfs, &g_dir[0], &lfs_file_info);
LFS_DEBUG("lfs get E:/ file info type = %d size = %d filename = %s LINE %d\n",lfs_file_info.type,lfs_file_info.size,lfs_file_info.name, __LINE__);
lfs_dir_open(&g_lfs, &g_dir[1], "E:/data");
lfs_dir_pos = lfs_dir_tell(&g_lfs, &g_dir[1]);
LFS_DEBUG("lfs dir tell = %d LINE %d\n",lfs_dir_pos, __LINE__);
lfs_dir_read(&g_lfs, &g_dir[1], &lfs_file_info);
LFS_DEBUG("lfs get E:/data file info type = %d size = %d filename = %s LINE %d\n",lfs_file_info.type,lfs_file_info.size,lfs_file_info.name, __LINE__);
lfs_dir_read(&g_lfs, &g_dir[1], &lfs_file_info);
LFS_DEBUG("lfs get E:/data file info type = %d size = %d filename = %s LINE %d\n",lfs_file_info.type,lfs_file_info.size,lfs_file_info.name, __LINE__);
lfs_dir_read(&g_lfs, &g_dir[1], &lfs_file_info);
LFS_DEBUG("lfs get E:/data file info type = %d size = %d filename = %s LINE %d\n",lfs_file_info.type,lfs_file_info.size,lfs_file_info.name, __LINE__);
lfs_dir_read(&g_lfs, &g_dir[1], &lfs_file_info);
LFS_DEBUG("lfs get E:/data file info type = %d size = %d filename = %s LINE %d\n",lfs_file_info.type,lfs_file_info.size,lfs_file_info.name, __LINE__);
lfs_dir_open(&g_lfs, &g_dir[1], ".");
lfs_dir_pos = lfs_dir_tell(&g_lfs, &g_dir[1]);
LFS_DEBUG("lfs dir tell = %d LINE %d\n",lfs_dir_pos, __LINE__);
lfs_dir_read(&g_lfs, &g_dir[1], &lfs_file_info);
LFS_DEBUG("lfs get ./ file info type = %d size = %d filename = %s LINE %d\n",lfs_file_info.type,lfs_file_info.size,lfs_file_info.name, __LINE__);
lfs_dir_read(&g_lfs, &g_dir[1], &lfs_file_info);
LFS_DEBUG("lfs get ./ file info type = %d size = %d filename = %s LINE %d\n",lfs_file_info.type,lfs_file_info.size,lfs_file_info.name, __LINE__);
lfs_dir_read(&g_lfs, &g_dir[1], &lfs_file_info);
LFS_DEBUG("lfs get ./ file info type = %d size = %d filename = %s LINE %d\n",lfs_file_info.type,lfs_file_info.size,lfs_file_info.name, __LINE__);
lfs_dir_read(&g_lfs, &g_dir[1], &lfs_file_info);
LFS_DEBUG("lfs get ./ file info type = %d size = %d filename = %s LINE %d\n",lfs_file_info.type,lfs_file_info.size,lfs_file_info.name, __LINE__);
// release any resources we were using
err = lfs_unmount(&g_lfs);
if (err) {
LFS_DEBUG("lfs ummount error: %d\n", __LINE__);
}
// print the boot count
LFS_DEBUG("boot_count: %s\n", lfs_read_buf1);
LFS_DEBUG("boot_count: %s\n", lfs_read_buf2);
#else //无目录写法
u8 lfs_write_buf1[1024] = {“123456789”};
u8 lfs_write_buf2[1024] = {“abcdefghi”};
u8 lfs_read_buf1[1024] = {0};
u8 lfs_read_buf2[1024] = {0};
u32 lfs_free_spcae_size = 0;
int lfs_dir_pos = 0;
struct lfs_info lfs_file_info = {0};
lfs_set_config();
// mount the filesystem
lfs_format(&g_lfs, &g_lfs_cfg);
int err = lfs_mount(&g_lfs, &g_lfs_cfg);
// reformat if we can't mount the filesystem
// this should only happen on the first boot
if (err) {
LFS_DEBUG("lfs need formart flash to mount filesystem: %d\n", __LINE__);
lfs_format(&g_lfs, &g_lfs_cfg);
lfs_mount(&g_lfs, &g_lfs_cfg);
}
lfs_free_spcae(&lfs_free_spcae_size);
LFS_DEBUG("lfs free spce = %d LINE %d\n",lfs_free_spcae_size, __LINE__);
// read current count
err = lfs_file_open(&g_lfs, &g_lfs_file[0], "E:\\boot1", LFS_O_RDWR | LFS_O_CREAT);
if (err) {
LFS_DEBUG("lfs open1 error:%d LINE %d\n",err, __LINE__);
}
err = lfs_file_open(&g_lfs, &g_lfs_file[1], "E:\\boot2", LFS_O_RDWR | LFS_O_CREAT);
if (err) {
LFS_DEBUG("lfs open2 error:%d LINE %d\n",err, __LINE__);
}
err = lfs_file_open(&g_lfs, &g_lfs_file[2], "E:\\boot3", LFS_O_RDWR | LFS_O_CREAT);
if (err) {
LFS_DEBUG("lfs open3 error:%d LINE %d\n",err, __LINE__);
}
err = lfs_file_write(&g_lfs, &g_lfs_file[0], lfs_write_buf1, sizeof(lfs_write_buf1));
if (err) {
LFS_DEBUG("lfs write1 len:%d LINE %d\n",err, __LINE__);
}
err = lfs_file_write(&g_lfs, &g_lfs_file[1], lfs_write_buf2, sizeof(lfs_write_buf2));
if (err) {
LFS_DEBUG("lfs write2 len:%d LINE %d\n",err, __LINE__);
}
//if not set cursor will read data error
lfs_file_seek(&g_lfs, &g_lfs_file[0],0,LFS_SEEK_SET);
lfs_file_seek(&g_lfs, &g_lfs_file[1],0,LFS_SEEK_SET);
err = lfs_file_read(&g_lfs, &g_lfs_file[0], lfs_read_buf1, sizeof(lfs_read_buf1));
if (err) {
LFS_DEBUG("lfs read len:%d LINE %d\n", err,__LINE__);
}
err = lfs_file_read(&g_lfs, &g_lfs_file[1], lfs_read_buf2, sizeof(lfs_read_buf2));
if (err) {
LFS_DEBUG("lfs read2 len:%d LINE %d\n", err,__LINE__);
}
// remember the storage is not updated until the file is closed successfully
err = lfs_file_close(&g_lfs, &g_lfs_file[0]);
if (err) {
LFS_DEBUG("lfs close1 error:%d LINE %d\n", err,__LINE__);
}
err = lfs_file_close(&g_lfs, &g_lfs_file[1]);
if (err) {
LFS_DEBUG("lfs close2 error:%d LINE %d\n", err,__LINE__);
}
err = lfs_file_close(&g_lfs, &g_lfs_file[2]);
if (err) {
LFS_DEBUG("lfs close3 error:%d LINE %d\n", err,__LINE__);
}
LFS_DEBUG("lfs read1 data: %s %d\n",lfs_read_buf1, __LINE__);
LFS_DEBUG("lfs read2 data: %s %d\n",lfs_read_buf2, __LINE__);
lfs_free_spcae(&lfs_free_spcae_size);
LFS_DEBUG("lfs free spce = %d LINE %d\n",lfs_free_spcae_size, __LINE__);
lfs_dir_open(&g_lfs, &g_dir[0], ".");
lfs_dir_pos = lfs_dir_tell(&g_lfs, &g_dir[0]);
LFS_DEBUG("lfs dir tell = %d LINE %d\n",lfs_dir_pos, __LINE__);
lfs_dir_read(&g_lfs, &g_dir[0], &lfs_file_info);
LFS_DEBUG("lfs get ./ file info type = %d size = %d filename = %s LINE %d\n",lfs_file_info.type,lfs_file_info.size,lfs_file_info.name, __LINE__);
lfs_dir_read(&g_lfs, &g_dir[0], &lfs_file_info);
LFS_DEBUG("lfs get ./ file info type = %d size = %d filename = %s LINE %d\n",lfs_file_info.type,lfs_file_info.size,lfs_file_info.name, __LINE__);
lfs_dir_read(&g_lfs, &g_dir[0], &lfs_file_info);
LFS_DEBUG("lfs get ./ file info type = %d size = %d filename = %s LINE %d\n",lfs_file_info.type,lfs_file_info.size,lfs_file_info.name, __LINE__);
lfs_dir_read(&g_lfs, &g_dir[0], &lfs_file_info);
LFS_DEBUG("lfs get ./ file info type = %d size = %d filename = %s LINE %d\n",lfs_file_info.type,lfs_file_info.size,lfs_file_info.name, __LINE__);
lfs_dir_read(&g_lfs, &g_dir[0], &lfs_file_info);
LFS_DEBUG("lfs get ./ file info type = %d size = %d filename = %s LINE %d\n",lfs_file_info.type,lfs_file_info.size,lfs_file_info.name, __LINE__);
// release any resources we were using
err = lfs_unmount(&g_lfs);
if (err) {
LFS_DEBUG("lfs ummount error: %d\n", __LINE__);
}
// print the boot count
LFS_DEBUG("boot_count: %s\n", lfs_read_buf1);
LFS_DEBUG("boot_count: %s\n", lfs_read_buf2);
#endif
}
#endif
其他的深入就交给大家自己去发掘吧。^ - ^
上一篇: C# 页面调用控制台应用程序
下一篇: FreeModbus的移植