Rob*_*ert 7 embedded queue circular-buffer flash-memory
我需要将不同长度的项目存储在闪存芯片中的循环队列中.每个项目都有它的封装,所以我可以弄清楚它有多大以及下一个项目的开始位置.当缓冲区中有足够的项目时,它将换行到开头.
在闪存芯片中存储循环队列的好方法是什么?
我想存储成千上万件物品的可能性.所以从头开始读到缓冲区的末尾并不理想,因为搜索到最后需要时间.
此外,因为它是圆形的,我需要能够区分第一个项目和最后一个项目.
最后一个问题是它存储在闪存中,因此擦除每个块都非常耗时,并且每个块只能执行一定次数.
Cra*_*een 12
一,块管理:
在每个块的开头放一个较小的标题.跟踪"最旧"和"最新"所需的主要内容是块编号,它只是增加模k.k必须大于您的总块数.理想情况下,使k小于MAX值(例如0xFFFF),这样您就可以轻松判断什么是擦除块.
在启动时,您的代码依次读取每个块的头,并定位序列中的第一个和最后一个块,即n i + 1 =(n i + 1)MODULO k.注意不要被擦除的块(块号例如0xFFFF)或以某种方式损坏的数据(例如不完全擦除)弄糊涂.
在每个街区内
每个块最初开始为空(每个字节为0xFF).每条记录都是一个接一个地写的.如果您有固定大小的记录,则可以使用简单索引访问它.如果您有可变大小的记录,那么要读取它,您必须从块的开头扫描链表样式.
如果您想拥有可变大小的记录,但避免线性扫描,那么您可以在每条记录上都有一个定义良好的标题.例如使用0作为一个记录分隔符,和COBS -encode(或COBS/R -encode)的每个记录.或者使用您选择的字节作为分隔符,如果它出现在每个记录中,则"转义"该字节(类似于PPP协议).
在启动时,一旦您知道最新的块,就可以对最新记录进行线性扫描.或者,如果您有固定大小的记录或记录分隔符,则可以进行二进制搜索.
擦除计划
对于某些闪存芯片,擦除块可能需要很长时间 - 例如5秒.考虑将擦除作为后台任务安排一点"提前".例如,当前块为x%full时,则开始擦除下一个块.
记录编号
您可能想要编号记录.我过去做的方法是在每个块的标题中放入第一条记录的记录号.然后软件必须保持块内每条记录的数量.
校验和或CRC
如果要检测损坏的数据(例如,由于意外电源故障导致的写入或擦除不完整),则可以向每个记录添加校验和或CRC,也可以添加块头.请注意,块头CRC仅覆盖头本身,而不是记录,因为在写入每个新记录时无法重写.