轻量级循环日志(类似于文件系统)算法,用于基于闪存的存储


8

我目前正在从事一个项目,该项目涉及在很长的生命周期内快速连续记录相当特定于应用程序的指标。为此,我最终使用了NXP M0和32MiB SPI闪存芯片。测井是连续的,需要在现场持续数年(超过10年),并且需要人工进行定期检查以发现趋势。最终,缓冲区填满并开始覆盖旧数据,这是完全可以的。我想出了一个简单的算法,在加电后(整个设备在我的控制范围之外经常断电),可以遍历整个闪存设备以找到当前磁头,因此记录可以从中断处继续进行。在这种情况下,我可以蛮力地进行一下,最坏的情况是用〜4s来完成。

这让我开始思考,是否有任何适合闪存设备和微控制器的日志结构文件系统?JFFS和所有其他众所周知的日志结构化FS我想对于一个简单的微控制器来说会有点沉重(当然取决于应用程序)。更具体地说,我想知道任何专门设计为具有快速头搜索时间的循环日志的算法,和/或专为可在闪存设备上运行的“传统”文件系统设计的算法。微控制器。在这种意义上,传统与JFFS之类的东西相提并论,在JFFS中,有一个数据结构表示分层名称空间中可变的随机访问文件的集合。


SD卡上的FAT32或FAT16是否太慢?
vicatcu '02

2
这个问题是这里的主题,但是如果您没有得到很好的答复,StackOverflow可能会有所帮助。希望我们能在这里得到一些好的答案!
Kellenjb'2

@vicatcu并不是太慢,因为对于我的应用程序,SD卡加连接器的价格更高,而SD卡的可靠性可能更低。Kellenjb我不确定该放在哪里。就像许多嵌入式设计问题一样,这种情况也适得其反。如果不能顺利进行,我很乐意将其移动。
克里斯·巴恩森

它是原始闪存芯片吗?如果是这样,您如何处理死块?闪存FS实现中很大一部分处理死块。如果您觉得JFFS / JFFS2太重了,您可能要签出YAFFS。至少感觉像一个非常简单的文件系统,因此它应该非常轻巧。
2012年

是的。坏块在这个特定的应用程序中并不可怕,因为它的长期性使数据被拔出只是一个粗略的趋势,而且在大多数情况下,我怀疑日志记录是否会被使用。
克里斯·

Answers:


2

绳索数据结构

我对绳索数据结构着迷。我有一个业余项目,试图将其调整为仅将几个字节的RAM连接到巨大的Flash存储器的微控制器,以便我可以插入和删除以及以其他方式任意编辑巨大文本文件中的变长文本。文本文件太大,无法放入RAM。每次我在一个多兆字节的文本文件中间插入或删除一个字符时,擦除文件的后半部分并将其重新写入闪存(移位一个字节)会太慢,但是绳索数据结构可以更快地做到这一点。由于绳索数据结构可以将可变的可变长度可变长度文件表示为不可变的固定长度片段,因此它似乎非常适合闪存-所有编辑均以类似循环日志的方式编写。las,我的代码中尚未解决所有错误。:-(

定长时间顺序日志

对于我帮助开发的产品,我确实得到了类似的循环日志系统的支持。

我只是简单地接连写定长记录,将闪存填充为圆形数组。

(使用完全空白的闪存,我开始在数组末尾之前写大约3个块的记录,因此我可以在仅存储少量数据记录之后测试循环回卷,而不是从记录零开始等待在发现我的环绕式代码中存在错误之前,需要编写一个月的数据。

我确保总是至少有两个擦除的“擦除块”准备写入。写入记录后,如果它之后只有2个“擦除的块”为空,我将无条件擦除最旧的数据块-2个“擦除的块”之后的最旧数据的第3个块。(在快闪存储器的末尾附近,“之后”的意思是“绕回快闪存储器的开始”。)(也许一个擦除的块就足够了-我忘了为什么我认为我至少需要2个,有时是3个) 。

我忘记了我在每个“擦除块”中放了多少条记录,但是我确保我从未有一条记录跨越两个擦除块-每个闪存擦除块的前2个字节要么是“擦除”值0xFFFF,要么是每个记录的标头中的Fletcher-16校验和的前两个字节(永远不为0xFFFF)。

这样就可以在下一次加电时快速进行扫描,并找到循环日志的头部-我只需要查看每个擦除块的前两个字节即可区分“擦除”和“数据”块。(我有点担心“擦除块中间的电源故障”会导致前两个字节被擦除为0xFFFF,但是将未擦除的字节保留在块中间,因此我编写了代码供微控制器检查为此,然后重新启动“擦除阻止”过程)。

如果您发现其他闪存友好的数据结构或文件系统,请告诉我。


您的方法听起来有点类似于我的方法。不过,我建议增加一点变化:在每个块中保留几个字节,以表明它已“开始”并且已“满”。除已擦除的块外,所有块均应设置“开始”位。当要擦除一个块时,请在数据的最后一个字节上设置“满”字节,然后擦除该块,然后立即将最早擦除的块的“开始”位置1。启动时,如果看到“最后一个”块是“已满”,而不是“已启动”,请重做擦除操作。
超级猫

这种方法看似过大,但是如果部分擦除了闪存块,则字节可能会任意决定读取FF或其他内容。块显示为空白的事实并不能保证位不会自发地“出现”在此处。如果在擦除过程中掉电,请稍等片刻,然后重新启动,即使该块显示为空白,也要重复擦除操作。
2012年

感谢您提供的信息,当我实际访问闪存的代码并让您知道会发生什么时,我将对其进行更深入的研究。
克里斯·巴恩森

@supercat:谢谢,这听起来是个好主意。
大卫2012年

@davidcary:我不知道我曾经有过一个块,它看起来完全是空白,但不是,但是我有一个块,在连续读取时会产生不同的结果。可能该块被错误地读取为空白,而我的代码尝试以任何方式对其进行编程,从而导致新编程数据和旧的中断擦除垃圾混杂在一起。无论如何,一个块有时会显示为空白的情况几乎是不现实的。
2012年

0

已经好几年了,但我想跟进此事,以防其他人流连忘返。目前看来,有一些项目正在积极维护(截至2020年1月),这些文件系统是针对NOR SPI闪存的微控制器的文件系统。

请注意,我没有以任何方式对它们进行测试,但是它们确实可以满足原始问题的要求:“ ...表示可变随机访问文件集合的数据结构...”

https://github.com/ARMmbed/littlefs-由ARM创建,BSD许可

https://github.com/joembedded/JesFs-似乎并未获得许可,但它是专门为SPI NOR闪存设计的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.