随时断电,安全使用SD卡

dar*_*ron 11 linux filesystems embedded sd-card

我们正在开发一个小型嵌入式 Linux 系统(2.6.35-ish),带有一个用于操作系统和应用程序的小型内部 NAND 设备(250-500Meg)和一个带有 8Gb SDHC SD 卡的 SD 卡用于数据。

可以随时切断设备的电源。

系统必须将数据存储到 SD 卡。这些数据非常重要……这是系统的全部目的。这些系统通常与远程位置的任何网络完全断开,每 4-8 周通过运动鞋网检索数据。

目前,我们只是在 SD 卡上安装了 VFAT。这主要是为了让第一批测试客户可以轻松地将数据手动复制到他们的 Win7 笔记本电脑上。

但是,我现在担心在错误的时间断电导致数据丢失只是时间问题。

配置此类系统以防止数据丢失的最佳方法是什么?JFFS2 在写入数据的方式方面听起来像是我想要的(并且性能需求根本不高),但是使用 block2mtd 等听起来相当笨拙。我也不确定卡的磨损均衡将如何交互用它。

做到这一点的最佳方法是什么?

编辑

我现在正在考虑离开文件系统 VFAT 并一次分配一天大小的文件,填充 0xFF,这应该会极大地限制电源循环故障的风险。然后我只能在这些预先创建的块中附加记录,希望 SD 卡不会太愚蠢以至于它们会擦除/磨损级别写入 0xFF 区域。

我可以使用 noatime,但是是否有等效的 VFAT nomtime 来防止写入修改后的时间字段?在创建新的一天的文件之前,我需要某种方法来阻止任何元数据更新。

编辑 2

电子堆栈交换中的某个人提醒我,NAND 上也有 ECC 数据,因此无法防止需要擦除。

那么,在这种情况下,通过 block2mtd 的 JFFS2 是否合适?

编辑 3

这比我想象的还要糟糕。即使您将完全相同的内容写入磁盘,我拥有的 SD 卡也会擦除数据块。擦除块是 64KB,这太大了,无法完全延迟写入。我将在 NAND 闪存中存储多达 128KB 的数据(我可以控制其写入行为),在一种日志中,然后将 128KB 块写入 SD 卡上 VFAT 分区中的 128KB 对齐文件(在如果其他 SD 卡有 128KB 擦除块)。

der*_*ert 5

好吧,您可以解决此问题的方法是解决“随时可以切断电源”的问题。连一分钟的电池电量都无法添加吗?

或者,也许您可​​以使用两张 SD 卡。将数据写入一张卡,同步,写入另一张卡。您的每个数据块都需要一个校验和和块号,但是即使出现了一些非常不幸的电源故障,其中一张卡应该是正确的。

您的基本问题将是 SD 卡的磨损均衡,AFAIK 取决于卡供应商(甚至可能是批次,他们可以随时更改)。它可能无法正确处理停电。并且取决于它的作用,这可能不仅仅意味着破坏您正在写入的块。

  1. 假设卡片很小——3 个(闪存)块。块 1 收到的写入比 2 或 3 多。我将按编号调用物理块,按字母调用逻辑块 A、B、C。现在,A=1,B=2,C=3。
  2. 您发出写入来阻止 A 。SD卡就像啊哈!我们需要在这里进行磨损均衡,否则块 1 将在 2 和 3 之前磨损。它决定交换块 1 和 2。
  3. 它将块 1 读入 RAM 位置 i(在 SD 卡上,而不是系统 RAM 上)。它会更新您想要更改的部分。
  4. 它将块 2 读入 RAM 位置 ii
  5. 它擦除块 1
  6. 它将 RAM 位置 ii 写入块 1。
  7. 它将映射表更新为 B=1
  8. 它擦除块 2。
  9. 它将 RAM 位置 i 写入块 2。
  10. 它将映射表更新为 A=2

当然,“更新映射表”并不总是微不足道的。并且 5-10 的顺序可能不同(如果它们都完成,那没关系,当然,擦除必须在写入之前进行)。但是发生电源故障时,不仅 A 损坏(如您所料),而且 B 也损坏。或者,如果在映射更新期间发生电源故障,谁知道会导致什么样的损坏。