在嵌入式环境中(使用MSP430),我已经看到了一些由部分写入非易失性存储器引起的数据损坏。这似乎是由写入期间的功率损耗引起的(用于FRAM或INFO段)。

我用CRC验证存储在这些位置的数据。

我的问题是,防止这种“部分写入”损坏的正确方法是什么?目前,我已经修改了代码来写入两个单独的FRAM位置。因此,如果一个写入中断导致无效的CRC,则其他位置应保持有效。这是一个常见的做法吗?是否需要为任何非易失性存储器实现此双重写行为?

有帮助吗?

解决方案

一个简单的解决方案是维护数据的两个版本(在闪存的单独页面中),当前版本和以前的版本。每个版本都有一个标题,包括序列号和验证序列号的单词 - 仅仅是序列号的补码:

---------
|  seq  |
---------
| ~seq  |
---------
|       |
| data  |
|       |
---------
.

关键的是,当数据写入时,将写入的seq字并写入 last

在启动时,您读取具有最高有效序列号码的数据(占环绕 - 围绕或许 - 特别是短序列单词)。编写数据时,您会覆盖并验证最旧的块。

您已经使用的解决方案是有效的,只要CRC写入最后,而且它缺乏简单性,并强加了可能不是必需或可取的CRC计算开销。

在FRAM上,您对耐力没有担忧,但这是闪存和EEPROM的问题。在这种情况下,我使用回写缓存方法,其中数据在RAM中维护,并且当修改定时器时,如果在已经运行时启动或重新启动 - 当定时器到期时,写入数据 - 这防止了突发写入从捶打内存,即使在FRAM上也是有用的,因为它最大限度地减少了数据写入的软件开销。

其他提示

我们的工程团队对这些问题采取了两种强烈的方法:在硬件和软件中解决它!

首先是二极管和电容器装置,以在褐出期间提供几毫秒的电力。如果我们注意到我们丢失了外部电源,我们会阻止代码输入任何非违规写入。

第二,我们的数据对于操作尤为重要,它经常更新,我们不想佩戴我们的非违反闪存存储(它只支持这么多的写入。)因此我们实际上在Flash中将数据存储16次并使用CRC代码保护每个记录。在启动时,我们发现最新的有效写入,然后启动我们的擦除/写入周期。

我们从未见过数据腐败以来,自坦率地偏执的系统以来。

更新:

我应该注意我们的Flash在CPU外部,因此CRC有助于验证数据,如果CPU和闪存芯片之间存在通信羽毛。此外,如果我们连续经历几个毛刺,则多个写入防止数据丢失。

我们使用类似于Clifford的答案,但用一个写作操作写的东西。您需要两个数据副本并在它们之间交替。使用递增序列号,以便有效地有一个位置均匀序列号,一个位置具有奇数。

写这样的数据(如果可以,在一个写命令中):

---------
|  seq  |
---------
|       |
| data  |
|       |
---------
| seq   |
---------
.

当您读取时,确保序列号都相同 - 如果不是,则数据无效。在启动时,读取两个位置并解决哪一个更新(考虑到汇总滚动的序列号)。

始终以某种协议存储数据,如start_byte,Total Bytes写入,数据,结束字节。 在写入外部/内部存储器之前,请务必检查电源监听寄存器/ ADC。 如果您无论如何数据损坏,结尾字节也将损坏。因此,在验证整个协议后,条目不会Vaild。 校验和不是一个好主意,您可以选择CRC16,而不是如果要将CRC纳入您的协议,则可以选择CRC16。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top