闪存芯片的数据处理

时间:2016-05-26 06:47:23

标签: embedded flash-memory

我正在复制here

的摘录

闪存擦除周期很长 - 非常长 - 擦除闪存扇区可能需要几秒钟。此外,由于保证擦除/重写周期的数量通常是有限的(通常约10,000或高达100,000),我们不能仅因为一个变量发生变化而擦除整个扇区。 方法是“牺牲”整个扇区以进行可变存储。在该扇区中,变量存储在表中。如果变量发生变化,则不会被覆盖,而是丢弃旧值并生成表中的新条目。

我不明白上述说法。

为什么在添加要修改为新数据项的数据而不是“就地”修改现有数据时,我们不必擦除扇区?是因为我们要存储新数据的扇区中的空闲区域是用0x00还是0xFF预先擦除的?

如果上述问题的答案为“是”,是否可以避免在下述情况下的擦除周期?

我正在将系统日志写入闪存。一旦闪存区域完全填满系统日志,我需要删除最早的日志条目并将其替换为最新的日志条目。在这种情况下,我想不出一个可以避免擦除的情况。我之前从未使用过闪存驱动程序。任何帮助将不胜感激。我不是母语为英语的人,希望这个问题不含糊。谢谢。

1 个答案:

答案 0 :(得分:3)

当您在MCU上没有任何正确的数据闪存(或eeprom)时,会弹出这类问题,因此您需要使用程序闪存来存储数据。程序闪存的工作方式与数据闪存的工作方式相同,但由于它不应经常被擦除,因此可以使用物理上较小的电路。因为,通常:物理电路越小,擦除扇区越大。

问题在于擦除大型闪存扇区需要花费大量时间。但是一旦整个扇区被擦除(通常所有单元都设置为1),您就可以写入任何擦除的存储器位置一次。基本上你总是可以将1变为0,而不是在没有擦除的情况下将0变为1。所以你确实可以写,因为该区域是预先擦除的。这样的写入几乎不需要擦除。

因此,存在各种或多或少混淆的算法来利用这一点。这不是我推荐的解决方案,但我可以解释一下,因为不幸的是它很常见:

假设您在闪存扇区内有两个变量,您需要立即更新。每个都有1个字节的数据。然后,您还将为每个变量提供一个唯一的搜索键(不能是已删除的闪存单元的值)并将其存储为:

Address  Key   Value
0x0000   0x01  0xAA
0x0002   0x02  0xBB

您将拥有一些类似

的程序结构
typedef struct
{
  uint8_t key;
  uint8_t val;
} flash_var;

const flash_var* x = (flash_var*)0x0001;
const flash_var* y = (flash_var*)0x0002;

接下来,您要将x的值更改为0xCC。您可以调用闪存编程驱动程序,它会在下一个可用的闪存位置写入新变量的副本。你的闪光灯现在看起来像这样:

Address  Key   Value
0x0000   0x01  0xAA
0x0002   0x02  0xBB
0x0004   0x01  0xCC

因此,您有两个变量x的副本,但程序会将指针更新为仅指向最新出现的变量。前一个只是坐在闪光灯中,作为死亡空间"。通过从闪存块的末尾搜索,向后朝向开头查找搜索键0x01的第一个匹配项,您始终可以找出哪个是最新的。

这意味着在开机时,找到变量不是随机访问,而是一个非常慢的线性搜索。

此算法存在以下几个问题:

  • 不是随机访问,但搜索速度很慢。
  • 实施许多额外的复杂性,这增加了错误和占用资源的机会。
  • 存在相同数据的副本。对于任务关键型系统而言,这是不可接受的。假设搜索密钥被破坏 - 而不是找不到任何内容并报告错误,程序将获取旧数据。
  • 根据闪光灯的性质,您可能希望在闪光灯中包含校验和。使用上述算法,每个变量都必须有一个单独的校验和,这是一个巨大的空间浪费。
  • 当闪存扇区变满时,无论如何都必须擦除闪存扇区。然后,您必须想出一种暂时将变量存储在RAM中的方法。它变得复杂。
  • 但最重要的是,该行业可能在任何特定时间都被填补,而且可能很难预测何时。您的程序必须能够处理这种特殊情况,并在发生时应对长擦除时间。这是最糟糕的情况,实时嵌入式系统必须始终在最坏情况之后进行设计。

    这是主要的逻辑缺陷:如果你的程序可以处理特殊情况,当扇区被填满并且你必须擦除时,为什么它不能每次都处理相同的情况呢?也就是说,既然你的程序必须能够处理这个问题,你也可以每次擦除整个扇区。

    事实证明,该算法只能在最佳情况下节省时间,这是无用的,因为无论如何必须在最坏情况下编写函数。在最糟糕的情况下,这是你必须设计的,它根本不会节省任何时间。实际上,算法引入的额外复杂性使得最坏情况需要花费更多时间。

    这就是为什么这些算法在每个设计上有些混淆。在设计合理的实时系统中,它们只保存闪存写入周期,而不是其他任何东西。

总而言之,我建议不要使用这些算法。相反,选择具有适当数据闪存的MCU。它将具有更小的扇区,更快的擦除时间和更多的写周期。