STM32L1xx上的Flash ECC算法

时间:2018-05-29 13:40:47

标签: algorithm embedded stm32 flash-memory

如何在STM32L1xx上实现闪存ECC算法(闪存纠错码)?

背景: 我想对STM32L151 MCU的程序闪存中的单个字进行多次增量写操作,而不在其间进行页擦除。没有ECC,可以逐步设置比特,例如首先是0x00,然后是0x01,然后是0x03(STM32L1将位擦除为0而不是1),等等。由于STM32L1每个字有8位ECC,因此该方法不起作用。但是,如果我们知道ECC算法,我们可以很容易地找到一个短序列值,可以在不违反ECC的情况下逐步写入。

我们可以简单地尝试不同的值序列并查看哪些值有效(一个这样的序列是0x0000001,0x00000101,0x00030101,0x03030101),但如果我们不知道ECC算法,我们无法检查序列是否有效违反了ECC,在这种情况下,如果位被破坏,则纠错将不起作用。

[编辑]该功能应该用于使用STM32L1的内部程序存储器实现一个简单的文件系统。数据块用标题标记,标题包含状态。多个块可以驻留在单个页面上。国家可以随着时间的推移而改变(首先是“新的”,然后是“使用”,然后是“删除”等)。状态的数量很少,但如果我们可以覆盖以前的状态而不必先擦除整个页面,那么它会使事情变得更加容易。

2 个答案:

答案 0 :(得分:1)

感谢您的任何评论!由于到目前为止还没有答案,我将总结一下,到目前为止我发现了什么(根据经验并基于对这个答案的评论):

  • 根据STM32L1数据表“整个非易失性存储器嵌入了纠错码(ECC)功能。”,但参考手册没有说明程序存储器中有关ECC的任何内容。
  • 数据表符合我们在将多个单词顺序写入同一程序存储单元而不删除其间的页面时凭经验找到的结果。在这种情况下,某些价值观序列会起作用而其他价值观则不起作用。

以下是我个人的结论,基于实证研究结果,有限的研究和该线索的评论。根据官方文档,。不要在上面做任何认真的工作(我也不会)!

  • 似乎ECC是按32位字计算并保留的。如果是这样,ECC的长度必须至少为7位。
  • 每个单词的ECC可能写入与单词本身相同的非易失性内存中。因此,同样的限制适用。即在擦除之间,只能设置其他位。正如斯塔克指出的那样,我们只能用以下值覆盖程序存储器中的单词:

    • 仅设置其他位但不清除任何位
    • 与之前的ECC相比,拥有一个仅设置附加位的ECC。
  • 如果我们写一个值,只设置附加位,但ECC需要清除位(因此无法正确写入),那么:

    • 如果ECC错误一位,则ECC算法会纠正错误,并且可以正确读取写入的值。但是,如果另一位失败,ECC将不再起作用,因为ECC只能纠正单位错误。
    • 如果ECC错误超过一位,ECC算法无法纠正错误,读取值也会出错。
  • 我们不能(轻松地)凭经验找出哪些值序列可以正确写入而哪些不能正确写入。如果可以正确地写入和读回一系列值,我们不知道这是否是由于单比特错误的自动纠正。这个方面是这个问题要求实际算法的全部原因。

  • ECC算法本身似乎没有记录。汉明码似乎是ECC的常用算法,在他们编写的AN4750中,汉明码实际上用于SRAM中的纠错。该算法可能用于也可能不用于STM32L1的程序存储器。

  • STM32L1 reference manual似乎没有明确禁止在没有擦除的情况下多次写入程序存储器,但是也没有说明对等的文档。为了不使用未记录的功能,我们将避免在我们的产品中使用此类功能并找到解决方法。

答案 1 :(得分:0)

有趣的问题。

首先我要说的是,即使您发现了ECC算法,也不能依赖它,因为它没有记录,可以随时更改,恕不另行通知。

但是要通过合理数量的测试找出算法似乎是可能的 我会尝试构建以常量值开始然后只清除一位的测试 当您读取该值并且它是起始值时,您的位不能更改ECC中的所有必要位。

像:

for <bitIdx>=0 to 31
  earse cell
  write start value, like 0xFFFFFFFF & ~(1<<testBit)
  clear bit <bitIdx> in the cell
  read the cell
next

如果找到擦除测试适用于所有位的起始值,则起始值可能是所有位设置的ECC。
编辑:对于任何ECC都应该如此,因为每个ECC总是需要至少两位的差异来检测和修复可靠的一个缺陷位。
由于第一位差异在于值本身,第二次更改需要在隐藏的ECC位中,隐藏位将非常有限。

如果您使用不同的起始值重复此测试,您应该能够收集足够的数据来证明使用了哪种纠错。