小型文件系统(littlefs)

简介

LittleFs设计之初的重点特性是:
(1)低资源消耗;
(2)掉电保护;
(3)擦写均衡,
本章节重点讨论第(2)和(3)这两个特性,第(1)个特性则贯穿在整个设计过程中。后文把LittleFs简称为lfs。

1 具体功能介绍

1.1 掉电保护

最经典的掉电保护方法有两种,一种是使用日志,一种是通过COW方式。lfs结合了两种方法,并优化了两种方案的缺点,提供了一套掉电保护策略。

1.1.1 日志方式


具体步骤为:
(1) 写入数据之前,先在日志区存储开始标志,记录要写入的数据位置和大小;
(2) 待写入的数据写入日志区;
(3) 待写入的数据写入数据区;
(4) 写入完成之后,在日志区记录结束标志。
模拟掉电场景:
(1) 步骤1完成,步骤2没有完成;重启之后,保持原来的数据,日志无效;
(2) 步骤1,2完成了,步骤3没有完成,尝试把步骤2的数据写入到数据区;
(3) 步骤1,2,3完成了,步骤4没有完成,同样尝试把步骤2的数据写入到数据区;

1.1.2 Cow机制


具体步骤为:
(1) 想更新节点F的数据,先申请一个新的节点,把F的旧数据拷贝过去,然后更新新的数据;
(2) 把父节点的指针指向新的节点,去掉旧节点的指针。
模拟掉电场景:
(1)步骤(1)完成了,步骤(2)没有完成,则使用旧的数据,新的节点变成孤儿节点。

1.1.3 lfs掉电保护

lfs结合了日志方式和COW机制两种方式进行掉电保护,并且优化了两种方案。
前面谈过文件系统三要素,超级块,inode,以及数据。对应lfs来说,他把超级块以及inode通过日志的方式存储,两种采用统一的存储结构,后文称两者为元数据;普通数据则采用cow的方式存储,采用czt逆序链表的方式。

1.1.3.1 元数据的存储


元数据(对应root,dir)采用双block的方式存储,互为备份,每个block都有一个revision序号,值越大,表示block的数据越新,每个block默认可以存储最多0xff个文件的数据,如果超过这个值,则需要compact(压缩)。
Compact是干什么呢? 即当数据的大小大于某个值的时候,把数据整合,剔除同一个id的旧的数据,然后写入到备份block里面。
在compact的过程中,如果发现整合的数据还是大于某个值,怎么办呢?需要split(分片)。

1.1.3.2 普通数据的存储(CTZ)

Lfs的数据采用ctz链表的方式逆向管理,这与传统的文件系统有比较大的差别。具体对比见下图所示。

传统的方式添加数据,需要建立旧的数据到新的数据的索引。这样做有两个弊端:
(1) 当数据特别多的时候,这样一个个的索引过去查找,比较费时间。
(2) 当使用cow机制的时候,在文件后面每增加一次数据,需要把所有的索引都重新建立一个,这样带来的性能损耗特别大。
为了解决这两个问题,lfs采用了下面的管理方式。

(1) 采用逆向的指针,这样常规的追加数据,不需要额外的开销来重新建立所有的索引;
(2) 每个偶数block有多个指针,指向更远的数据,这样可以在检索的时候加快速度。
指针的建立采用了CTZ(二进制中最后一个不为0的位,其右边0的个数)的方式。大概原理就是,block N 如果是一个能被 2^X整除的数,那么他就存在指向N – 2^X的指针,指针的数目为ctz(N)+1。

从上表可以看出,block 2多一个指向0的指针,block 4多一个指向0,2的指针。
咱们已经知道了实际数据(对应file)采用czt list的方式存储,最新的数据block指向次新的数据block(这个是为了提高COW的效率)。
一次常规更新数据的过程大概为(实际比这个复杂很多,需要考虑cache、孤儿、crc等问题):
(1) 往file文件中写入数据;
(2) 申请一个新的block,并且把file文件最后一个block的数据复制到新的block,并追加要写入的数据;
(3) 更新新block的czt list(在block的头部会占用一定的4字节倍数的字节来记录索引,这个czt list只是用来fseek的加快速度);
(4) 文件fclose的时候,更新对应的元数据信息到父节点中。
掉电保护的具体场景:
步骤(1),(2),(3)完成了,但是(4)没有完成。因为索引还没有建立起来,数据虽然写入了,但是没有人知道,文件系统会丢失最新的数据,保留修改之前的数据。
步骤(4)过程中掉电了。步骤(4)是更新元数据,元数据采用了主备的方式,并且采取了如下的格式:

正常的提交流程为:
(1)提交tag;
(2)提交data;
(3)提交crc。
当tag和data提交了,但是CRC没有提交的时候,crc就会校验失败,这个时候前面crc校验通过的部分,就会被relocate到一个新的块,这样由于断电导致的数据异常,则回退成功。注意:crc校验的时机,在提交一个新的commit到对应的元数据的时候。

1.2 擦写均衡

了解擦写均衡之前,先需要知道littlefs是怎么管理物理block的,怎么才能申请到一个空闲的block。

1.2.1 Block管理

为了节省内容,Littlefs对空闲block的管理采用了滑窗方式,滑窗的大小是可以配置,默认是32bit,对应32个block的使用情况。

当文件系统需要申请一个空闲的block的时候,从lookahead中寻找没有置位的block,申请成功,则给对应的block位置1。当当前的窗口中的所有block都被占用的时候,就需要滑动窗口了,一次性滑动窗口大小的距离,即默认一次滑动32个block。

当窗口滑动了之后,lookahead中又有了新的空闲的block可以申请。
问题来了,怎么定义一个block是不是空闲的呢?
一片flash的总的block是有限的,假设其序号从0->N,lookahead对应的block范围是I->J,Littlefs会通过lfs_fs_traverse遍历所有使用到的block,如果这个block在I->J之间,则说明block被使用了,否则就是空闲的。

1.2.2 擦写均衡的实现

通过前面的滑窗机制,可以一定程度上的避免每次操作到的都是同一个片区的block。但是这还不够,因为每次启动的时候,滑窗都是从block0开始滑动的,这个会导致前面的block使用频率高于后面的block。所以,我们需要找到办法,让每次启动的时候,滑窗的位置都是随机的,极致的随机,就是平均了。
为此,littlefs使用了crc作为随机数,再通过简单的运算,得到了滑窗启动的时候的起始位置。
问题又来了,crc哪儿来的,干什么的?
Crc就是元数据提交的终结符号,用来校验提交是不是正确的,littlefs借用了crc之间相互异或带来的不确定性来作为滑窗的启动地址,一定程度上复用了现有的机制达到了随机的目的。

1.3 文件读写

写入流程:

读取流程:

LittleFs文件系统相关推荐

  1. littlefs文件系统适配norflash和nandflash

    littlefs文件系统适配norflash和nandflash 文章目录 littlefs文件系统适配norflash和nandflash 测试对象 题记: 程序如下(nand flash+nor ...

  2. 使用littlefs-fuse在PC端调试littlefs文件系统

    背景 littlefs是arm面向嵌入式设备推出的一款掉电安全的小型文件系统,具有抗掉电,动态磨损均衡,RAM/ROM需求少等特点,具体介绍可见 https://github.com/ARMmbed/ ...

  3. stm32 fatfs fopen err_disk__小型文件系统FatFS和LittleFS对比和区别

    关注.星标公众号,不错过精彩内容 素材来源:网络编辑整理:strongerHuang 对于许多物联网设备而言,拥有一个小型且具有弹性的文件系统至关重要. 在MCU上运行的文件系统不多,绝大部分人应该知 ...

  4. 鸿蒙轻内核源码分析:文件系统LittleFS

    摘要:本文先介绍下LFS文件系统结构体的结构体和全局变量,然后分析下LFS文件操作接口. 本文分享自华为云社区<# 鸿蒙轻内核M核源码分析系列二一 02 文件系统LittleFS>,作者: ...

  5. 嵌入式文件系统FatFS和LittleFS对比

    关注+星标公众号,不错过精彩内容 作者 | strongerHuang 微信公众号 | strongerHuang 对于许多嵌入式电子设备而言,拥有一个小型且具有"弹性"的文件系统 ...

  6. 小型文件系统FatFS和LittleFS对比和区别

    关注.星标公众号,不错过精彩内容 素材来源:网络 编辑整理:strongerHuang 对于许多物联网设备而言,拥有一个小型且具有弹性的文件系统至关重要. 在MCU上运行的文件系统不多,绝大部分人应该 ...

  7. ESP8266 NodeMCU Web 服务器:在仪表盘中显示传感器读数

    了解如何使用 ESP8266 NodeMCU 构建网络服务器以在仪表盘中显示传感器读数.例如,我们将以两种不同的仪表显示 BME280 传感器的温度和湿度:线性和径向.您可以轻松修改项目以绘制任何其他 ...

  8. RT-Thread学习

    一.入门 RT-Thread官网 官网文档 Rt-thread学习文档 RT-Thread官方bilibili视频号 GD32官网 教你动手移植RT-Thread到国产MCU 如何移植RT-Threa ...

  9. 基于STM32的RTOS教程——RT-Thread学习教程

    下面所有资料都是转载整理于:https://www.rt-thread.org/document/site/#/ 文章目录 新手指导 版本简介 学习路线 入门学习 无RTOS经验 模拟运行 快速上手 ...

最新文章

  1. python多线程扫描_python实现多线程扫描网站目录
  2. 文本编辑器创建菜单栏
  3. 从零开始入门 K8s | 可观测性:你的应用健康吗?
  4. Java虚拟机9:Java类加载机制
  5. OpenGL高斯模糊
  6. 《Angular从零到一》导读
  7. C#LeetCode刷题之#283-移动零(Move Zeroes)
  8. paip.手机ROOT过程总结
  9. C语言从入门到精通保姆级教程(2021版上)
  10. Ansible 运维自动化 ( 配置管理工具 )
  11. java 总线_用于 Java 的服务总线库
  12. TypeScript瞎看看
  13. 关于swiftUI和UIKit混用
  14. Gmail邮件客户端pop3和smtp服务器配置
  15. 全国增值税发票查验平台验证码识别
  16. 华硕服务器不分区重装系统,华硕笔记本重装系统不能进入系统怎么办
  17. Excel学习日记:L8-工作表的设定与多个工作表合并计算
  18. 如何将pdf转换成ppt文件
  19. uniapp 选择元素,操作元素属性
  20. Oracle闪回恢复区(fast recovery area,FRA)

热门文章

  1. 基于SpringBoot+Thymeleaf兼职招聘网站
  2. 在更改计算机的设置路由器,怎么改路由器wifi密码 怎么修改路由器wifi密码
  3. Nginx启动报错: could not open error log file: open() q unable to find local peer: 192.168.10.102:8848,
  4. 2019年终总结,忙碌而充实的一年
  5. MyBatis中设置事务自动提交
  6. BlueTooth: 蓝牙基带数据传输机理分析
  7. 微服务系统架构设计系列 - RateLimiter - 1. 限流器简介与一般算法
  8. 深度搜索算法C语言实现--以走迷宫为例
  9. 王道计算机组成原理课代表 - 考研计算机 第四章 指令系统 究极精华总结笔记
  10. Snipaste常用快捷键(详细总结)