1
14
首先,区块管理: 在每个块的开头放一个较小的标题。您需要跟踪“最旧”和“最新”的主要内容是块编号,它只是增加模 . k k 小于您的最大值(例如0xFFFF),因此您可以很容易地判断什么是已擦除的块。 =(n) 我 +1)模k。注意不要被擦除的块(块编号为0xFFFF)或以某种方式损坏的数据(如不完全擦除)弄糊涂。 每个街区内 每个块开始时为空(每个字节为0xFF)。每条记录只是一条接一条地写。如果您有固定大小的记录,那么您可以通过一个简单的索引来访问它。如果您有可变大小的记录,那么要读取它,您必须从块的开始扫描,链表样式。 如果您希望有可变大小的记录,但避免线性扫描,那么您可以在每个记录上有一个定义良好的标题。例如,使用0作为记录分隔符,以及 COBS -编码(或 COBS/R PPP protocol ). 启动时,一旦知道最新的数据块,就可以对最新记录进行线性扫描。或者,如果您有固定大小的记录或记录分隔符,则可以进行二进制搜索。 擦除调度 对于某些闪存芯片,擦除块可能需要很长的时间,例如5秒。考虑提前一点将擦除任务安排为后台任务。例如,当当前块已满x%时,开始擦除下一个块。
您可能需要对记录进行编号。我过去的做法是在每个块的标题中输入第一条记录的记录编号。然后,软件必须对块内每条记录的编号进行计数。 校验和或CRC 如果要检测损坏的数据(例如,由于意外电源故障导致的不完整写入或擦除),则可以向每个记录,甚至可能向块头添加校验和或CRC。注:块头CRC只覆盖头本身,而不覆盖记录,因为写入每个新记录时无法重新写入。 |
2
2
在最初耗尽空间之前,添加记录非常简单,只需将它们写入缓冲区的末尾并更新尾部指针即可。 当您需要回收空间时,请删除足够的记录,以便适合当前记录。删除记录时更新头指针。 您需要跟踪释放了多少额外空间。如果保留指向最后一条记录末尾的指针,下次需要添加记录时,可以将其与指向第一条记录的指针进行比较,以确定是否需要删除更多记录。 此外,如果这是NAND,您或闪存控制器将需要执行解块和磨损均衡,但这都应该位于比为循环缓冲区分配空间更低的层。 |
3
1
我想我现在明白了。似乎你最大的问题是,在填满可用的录音空间后,接下来会发生什么?新数据应该覆盖最旧的数据,我相信这就是你所说的循环缓冲区。但由于数据不是固定长度的,您可能会覆盖多条记录。
写入段需要跟踪表示下一条记录开始写入的地址。如果您提前知道要写入的块的大小,则可以判断是否将在逻辑缓冲区的末尾结束,并在“0”处重新开始。我不会把一张唱片分成结尾和开头两部分。 一个单独的寄存器可以跟踪开始;这是尚未被覆盖的最旧数据。如果你去读取数据,这就是你要开始的地方。 然后,给定写入开始地址和要提交的数据长度,数据写入器将检查是否应该撞击读寄存器,读寄存器将检查第一个块并查看长度,并前进到下一个记录,直到有足够的空间写入任何数据。在写入数据的末尾和最旧数据的开头之间,可能存在垃圾数据的间隙。但通过这种方式,您可以只编写一两个地址作为开销,而不是重新排列块。
|
4
0
我认为有三种选择: 选项1:将所有内容填充到相同的大小,这很简单,存储一个指向缓冲区头部和尾部的指针,以便知道从何处写入和从何处开始读取,使用每个对象的大小获得到下一个对象的偏移量,这意味着您需要像链接列表一样横切缓冲区,如果您需要项目5000,则称之为慢速。 选项2:只在循环缓冲区中存储指向真实数据的指针,这样当您循环时就不必处理大小不匹配的问题。如果将真实数据存储在循环缓冲区中,而不将其填充,则可能会遇到这样的情况,即使用一个新数据对象过度编写多个项,我认为这是不正确的。 将实际数据存储在闪存中的其他位置,大多数闪存都内置了某种磨损均衡功能,如果这样,您就不必担心多次覆盖同一位置,IC将找出实际存储在芯片上的位置,只需写入下一个可用的可用空间即可。
选项3:如果对象真的可以是任意大小,那么在您应该只使用文件系统的时候,请按顺序命名文件,并在您完全记住时返回。如果您的新条目很大,则可能需要删除多个旧条目以适应它。这实际上只是选项2的扩展,因为选项2在许多方面都是一个简单的文件系统。 |
5
0
闪存中的“循环”可以根据块大小进行,这意味着您必须声明为该缓冲区分配了多少闪存块。 缓冲区的实际大小将在每个特定时间介于n-1(n是块的数量)和n之间。 每个块都应该从一个包含序列号或时间戳的头开始,该序列号或时间戳可用于确定哪个块比另一个块旧。 每个项目都包含一个页眉和一个页脚。默认标题包含您想要的内容,但根据此标题,您必须知道项目的大小。默认页脚为0xFFFFFF。此值表示空终止。 在RAM中,必须保存指向最旧块和最新块的指针,以及指向最旧项和最新项的指针。通电后,您将检查所有块,找到相关块并加载此成员。 如果要存储新项目,请检查最新块是否包含足够的空间来存储该项目。如果确实如此,请将项目保存在上一个项目的末尾,并将上一个页脚更改为指向此项目。如果它没有足够的空间,则需要删除最旧的块。删除此块之前,请将最旧的块成员(RAM)更改为指向下一个块,将最旧的项更改为指向此块中的第一个项。 我知道这个解释听起来可能很复杂,但过程非常简单,如果你写得正确,你甚至可以保证电源安全(记住写的顺序)。 请注意,缓冲区的循环度不会保存在闪存中,但闪存中只包含一个包含项目的块,您可以根据块标题和项目标题确定这些项目的顺序 |
conopizda2 · 为什么我的静态数组没有被memset清除? 2 年前 |
jhe4x · C按位OR返回的值不正确 2 年前 |
Tim · 如何用c语言打印程序的执行流程# 6 年前 |
jatinBatra · 关于嵌入式固件开发[已关闭] 6 年前 |
Will · 嵌入链接器脚本-是否正确放置“堆栈”和“堆”区域? 6 年前 |
K. Crow · 不等于PIC32上启用中断时操作员不工作[关闭] 6 年前 |
spiff42 · 清除位时唯一的最大不同字节值集 6 年前 |