https://github.com/pellepl/spiffs/wiki/FAQ#how-long-will-my-spi-flash-live
如果你想在这里找到答案,请给我发邮件或在github上发帖。
为什么spiffs这么慢?
除了底层硬件(CPU和SPI闪存)之外,主要是因为spiff使用的内存很少。Spiffs不会在ram中构建任何文件树,它实际上更像是一个暴力文件系统。一个人可以启用缓存和东西,但它可能仍然很慢。spiffs中最慢的部分是文件系统完整性检查SPIFFS_check
。这是因为检查必须使用少量字节交叉引用大部分信息。因此,它在整个文件系统上运行多次扫描。也就是说,在优化spiffs方面付出了很多努力,它不应该比它必须慢。
spiffs如何处理powerlosses?
存在用于更新数据的方案:当修改页面时,旧页面首先被标记为被修改,然后用更新的(并且可能未更新的)数据写入新页面。然后删除旧页面,最后将新页面标记为已完成。如果某处出现断电,可能会有两个页面具有相同的ID,但这些页面的状态将指示哪一页有效。还有一些完整性测试,在访问文件时总是会进行测试。如果可以修复问题,将尽可能尝试这样做。在spiffs的早期,在挂载时进行了完整的完整性检查,但是由于花费了很长时间,我将其删除了。现在必须由用户调用它。
Powerlosses续:我SPIFFS_check
什么时候应该跑?
检查会修复损坏的文件,清除未引用的页面,等等。一开始spiffs在mount上运行了。然而,在较大的闪光灯上,这变得太慢了 - 因此,检查被置于其自身的功能中。
那么何时运行呢?如果SPIFFS_info
回报used > total
此外,获得任何的错误代码SPIFFS_ERR_NOT_FINALIZED
,SPIFFS_ERR_NOT_INDEX
,SPIFFS_ERR_IS_INDEX
,SPIFFS_ERR_IS_FREE
,SPIFFS_ERR_INDEX_SPAN_MISMATCH
,SPIFFS_ERR_DATA_SPAN_MISMATCH
,SPIFFS_ERR_INDEX_REF_FREE
,SPIFFS_ERR_INDEX_REF_LU
,SPIFFS_ERR_INDEX_REF_INVALID
,SPIFFS_ERR_INDEX_FREE
,SPIFFS_ERR_INDEX_LU
,SPIFFS_ERR_INDEX_INVALID
。
如果在启动时可以检测到功率损耗,那么决定是否运行检查当然是一个很好的输入。一些CPU具有备用电池RAM,可用于检测电源断电时是否正在运行spiffs。例如,可以在宏中设置一个电池反转位SPIFFS_LOCK
并清除它SPIFFS_UNLOCK
。在启动时,如果检测到powerloss,并且如果设置了该位,则运行check。
此外,作为维护,检查应该/可以在一年/每月/每周或至少一次运行至少一次。然后,它可能根本没有必要 - 它取决于你,力量和应用程序本身。
在电池供电的系统上,我建议在充电期间运行它,如果电池电量高于某个水平。检查当然也可以处理掉电,但是如果发现fs之上的任何错误在某种程度上是不一致的。
作为旁注,我想到了在fs中保留一个特殊的奇偶校验页面,其中一个位在开始一些spiffs操作时被清除,并在操作结束时清除另一个位。在安装时,如果清除的位数不均匀,则应运行检查。因为我有电池支持的ram,我从来不需要这个。但如果有人觉得非常需要这样的检查 - 如果我应该运行检查功能,提出问题并开始烦我 - 它可能仍然会发生:)
缓存如何工作?
如果SPIFFS_CACHE
启用了构建时间配置,则spiffs会在读取内容时使用ram中的闪存镜像。如果SPIFFS_CACHE_WR
禁用构建时配置,则所有写入都是直写。如果SPIFFS_CACHE_WR
启用,则还会缓存写入。当调用的文件写入高速缓存(如果有的话)被刷新SPIFFS_fflush
,SPIFFS_close
,SPIFFS_read
,SPIFFS_fstat
,SPIFFS_lseek
。调用时刷新所有文件SPIFFS_unmount
。这意味着例如SPIFFS_read
可能会出现与写操作有关的错误。
可以在i2c eeprom上运行spiffs吗?
不。至少没有i2c eeproms我遇到过。Spiffs广泛使用nor flash写法,其中写入的字节是AND编写的。例如,假设您的闪存上有一个字节被擦除,即为0xFF。如果您首先将0xFE写入0xFF然后再写入0x7F,则spiffs会将此字节读取为0x7E。当然,人们可以为spiffs写一个hal,它首先读取应该写入的内容,然后AND写入内存,最后将这个ANDed数据存储到i2c eeprom。考虑到i2c总线速度,性能会很糟糕。
为什么一半的测试在运行时失败make test
?
因为缺少文件夹。先跑make all
。
我的SPI闪存会存在多长时间?
这取决于一切。但是,让我们构建一个简单的案例,我们不会过多地深入细节。
假设我们有一个1MB的闪存。只有一个文件。每一秒我们打开文件,读取一个数字,递增它,然后再次存储文件。
假设我们将闪存划分为128字节页面和64k块。闪光灯在失败前应对10000次擦除。
因此,我们将有1MB / 64k = 16块。每个块有512页,一个文件更新将消耗两个页面(元数据+数据),这意味着我们可以在使用需要在重用之前擦除的完整块之前执行512/2 = 256个文件更新。此外,spiff总是需要两个空闲块。
考虑到上述情况,在(16-2)* 256 = 3584文件更新之后,系统将充满已删除的页面,并且需要擦除块。此后,在每个第256个文件更新之后,必须擦除块。由于我们有16个块并且具有耗损均衡,因此在再次擦除相同块之前将需要256 * 16个文件更新。这可以在事情失败之前做10000次,所以总结起来我们可以在spi flash耗尽之前做3584 +(256 * 16)* 10000个文件更新,大约40960000次。为了安全起见,因为我们没有考虑一些额外的元数据,我们乘以0.75(相当激进)我们总计达到30,700。
每秒一次写入是355天。
另一方面,如果您的更新每分钟发生一次,您可能会在58年内出现故障。
此外,今天的许多闪光灯在失效之前可以擦除100000次(或更多次),这将超过寿命10倍。查看数据表。
是否会保留文件列表顺序?
当您在文件系统上列出文件时,顺序是任意的。此外,由于垃圾回收,您可以在对文件系统进行任何更改后立即对其进行重新解密。如果文件的订购很重要,则由用户负责处理; 例如,通过文件名中的序列号。