31

RTOS文件系统对比:LittleFS Vs. SPIFFS

 4 years ago
source link: http://www.cnblogs.com/gmpy/p/12498999.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

概述

在RTOS上免费的文件系统本身就不多,广泛使用且掉电安全的就更少了。本文选取当前RTOS上比较受欢迎的两个文件系统 SPIFFS 和 LittleFS 做全方位的对比,以便项目上评估在RTOS上使用什么FS。

对嵌入式设备来说,掉电时有发生。如果文件系统无法保证掉电安全,那么非常有可能在某一次掉电时,设备就变砖了。

不管是 SPIFFS 还是 LittleFS 的小型文件系统,都号称做到掉电安全。而常见的FAT32由于无法做到掉电安全,或者某些特供版要付费使用,更多时候是在需要Windows兼容性时才会考虑。

开源协议

不管是 SPIFFS 还是 LittleFS 都开源在 GitHub 中。前者是 MIT开源协议,后者是 BSD开源协议。

在文章 《了解常见的开源协议(BSD, GPL, LGPL,MIT)》 上这么评论 BSD开源协议

BSD代码鼓励代码共享,但需要尊重代码作者的著作权。BSD由于允许使用者修改和重新发布代码,也允许使用或在BSD代码上开发商业软件发布和销售,因此是对商业集成很友好的协议。

对MIT开源协议有如下总结:

MIT是和BSD一样宽范的许可协议,作者只想保留版权,而无任何其他了限制。也就是说,你必须在你的发行版里包含原许可协议的声明,无论你是以二进制发布的还是以源代码发布的。

虽然从使用者的权限来说,MIT开源协议要比BSD开源协议更少限制,但 对企业商用来说,两者都可放心使用

社区维护情况

以GibHub上第一个提交作为项目开始时间,那么SPIFFS项目作者是 Peter Andersson ,始于2013年7月4日。而LittleFS的作者是 Christopher Haster ,始于2017年2月20日。值得一提的是,LittleFS是ARM工程师折腾出来的文件系统,最先应该是运用在ARMmbed上的。

从时间上来说,LittleFS项目要晚于SPIFFS项目。我们再看看社区当前维护情况。

SPIFFS项目在2018年没有任何提交,在2019年只有2个提交。分析提交补丁的内容,我们发现对FS的运行流程有实质修改的最后一个提交是在2017年10月15日。换句话说,SPIFFS项目要不是已经足够稳定到没有任何bug,要不渐渐被遗弃。

相比与SPIFFS项目的落日余晖,LittleFS更像冉冉升起的太阳。从2017年到文本撰稿时的2020年3月初,社区一直非常活跃,以2019年为例,共计合并了124个提交,释放了10个版本。目前最新的版本是2.1.4,而据我与作者的沟通,其正在为2.2版本做Bug修复。

到目前为止,在GitHub的统计上,SPIFFS项目共计934个星,而LittleFS项目达到1.7K个星。

因此,SPIFFS在社区上已经不怎么维护,而LittleFS依然活跃。持续迭代的软件会更强大和更稳定。

静态系统资源

对比静态系统资源,我们主要比较编译后的bin文件的text/data/bss段的大小。

text段:存放代码执行语句
data段:存放已初始化的全局变量和局部静态变量
bss段:未初始化的全局变量和局部静态变量

这3个段的数据都是在编译时就已经确定下来的。如果某一个软件代码量非常庞大,其对应的text段也会庞大,也就意味着在运行时,需要用更多的内存存放代码语句。

我设计了下面的Shell命令统计静态信息:

find -name "*.o" -exec size {} \; | awk '
    BEGIN{
        datasum = 0;
        textsum = 0;
        bsssum = 0;
    };
    /data/{
        getline;
        textsum += $1;
        datasum += $2;
        bsssum += $3;
    };
    END{
        printf "text %d\ndata %d\nbss %d\n", textsum, datasum, bsssum
    }
'

统计结果如下:

FS text data bss littlefs 24000 0 0 spiffs 36940 0 0

可以发现,SPIFFS的代码量比LittleFS多53%,也就意味着SPIFFS需要更多的内存存放代码。

实测-环境

并不是所有的对比都可以直接从代码上看出来,我们需要上机实测。实测是为了获取最真实的对比数据。

不讲环境和配置,直接对比SPIFFS和LittleFS,简直是在耍流氓。因此,我们先看看实测的环境。

测试时使用 0.3.7 版本的SPIFFS,其配置如下:

phys_size = 5013504B
phys_addr = 0
phys_erase_block = 32K
log_block_szie = 64K
log_page_size = 256B

测试时使用 2.1.3 版本的LittleFS,其配置如下:

read_size = 256B
prog_size = 256B
block_szie = 32K or 4K
cache_size = 256B
lookahead_size = 16

在旺宏16M的SPI Nor上测试,SPI Nor运行在4线读写命令和100MHz的SPI时钟频率上。用于做测试的分区有4896KB。

确保RTOS上并无任何无关进程在抢CPU、IO资源。

换句话说,测试在使用相同的硬件环境,无其他进程干扰的情况下进行。

空间利用率

文件系统需要额外空间存放一些元数据,因此用户可用的空间实际大小并不直接等于分区大小。在 4896KB 的分区上分别挂载SPIFFS和Littlefs两个文件系统,他们的可用空间是多少呢?

空的文件系统体现不出来,我们试着往不同文件系统中存放一些资源文件,再观察使用情况。

这些资源文件在ubuntu的ext4 (块大小为4K)中统计有2794KB的大小。以此为标准,我们看看SPIFFS和LittleFS的空间使用情况

FS used(KB) total(KB) note SPIFFS 2722 4607 LittleFS 3680 4896 block size = 32K LittleFS 2800 4896 block size = 4K

由于LittleFS的块大小决定了文件存储的最小单位,因此分别统计块大小为4K和32K的空间使用情况。当块越大,则越有可能会出现空间浪费的情况。例如32K的块大小,即使文件内容只有1KB,LittleFS也会为其分配32K的空间,造成了31K的空间浪费。

从空间利用率来看,SPIFFS略优于LittleFS。

掉电安全和修复

文件系统的掉电安全指在任意一时刻掉电,文件系统依然能保证其一致性,文件系统允许丢失掉电时没写完整的数据,但不能奔溃。

我们通过读写掉电的方式验证掉电安全,即在读写压测时随机时间掉电,再次上电后需要保证文件系统正常运行且已写入的文件数据不丢失。

SPIFFS掉电后需要调用 SPIFFS_check() 进行修复,否则无法保证文件系统一致性。这就类似于ext4与e2fsck的关系。

在实测中,4896KB的空间,SPIFFS的修复竟然要5~10s,相对于一次RTOS启动总耗时2~3s而言,简直无法忍受。在项目中已经放弃对其的掉电压测。

与SPIFFS相反,LittleFS在设计时就保证了掉电安全的问题,因此不需要每次掉电后执行修复工作。

而2.1.3版本的LittleFS在10W次的掉电测试中,在数万次掉电后小概率出现文件系统奔溃导致不能正确挂载的情况。分析良久,确认是LittleFS本身逻辑的问题。已反馈社区,预计在2.2版本解决。

总的来说,SPIFFS的掉电安全修复耗时不符合项目需求,而LittleFS目前还做不到绝对的掉电安全。比较幸运的是,LittleFS的掉电安全问题复现概率比较低,且LittleFS社区比较活跃,在发现问题后能及时提出解决方案。

读写性能

当空间使用率不同,测试的性能有可能不一样,在SPIFFS中尤其明显。

IO操作 空闲空间 SPIFFS LittleFS(32K Block) LittleFS(4K Block) 读 20% 6095.24 KB/s 8629.21 KB/s 7529.41 KB/s 读 100% 6564.10 KB/s 8727.27 KB/s 7314.29 KB/s 写 20% 21.64 KB/s 142.54 KB/s 121.92 KB/s 写 100% 128.49 KB/s 155.37 KB/s 127.87 KB/s

在读写性能表现上,SPIFFS最差,且剩余空间越少,SPIFFS写性能越差。LittleFS的性能相对比较高和稳定,块大小会直接影响到写性能。

动态内存

动态内存指通过 malloc 申请分配的堆内存大小。不管是SPIFFS还是LittleFS都是为小系统设计的,其内存使用情况都经过精心设计,内存占用非常小。

LittleFS会为每个打开的文件单独申请一个 cache_size 的内存,在测试时,cache_size 为256B。为了对比的公平性,我们假设SPIFFS和LittleFS打开相同数量的文件情况下统计内存。

LittleFS SPIFFS 3856 B 3790 B

两者使用动态内存的情况相近,在最大打开数量的情况下,SPIFFS使用动态内存略少。

由于SPIFFS的内存使用并不会随着打开文件增加而增加,也就意味着,在打开少量文件的情况下,LittleFS会比SPIFFS更少的动态内存使用量。

CPU占用

在读写压测时,统计进程使用的CPU资源百分比

LittleFS (32K) LittleFS (4K) SPIFFS 22~27 27~50 44~80

可以发现,在相同情况下,LittleFS的CPU占用率会比SPIFFS少。

总结

本文从多个方面对比评估 LittleFS 和 SPIFFS,发现资源、性能、掉电安全和社区支持情况来说,后来者 LittleFS 已经青出于蓝。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK