如何在STM32L1xx上实现闪存ECC算法(闪存纠错码)?
背景: 我想对STM32L151 MCU的程序闪存中的单个字进行多次增量写操作,而不在其间进行页擦除。没有ECC,可以逐步设置比特,例如首先是0x00,然后是0x01,然后是0x03(STM32L1将位擦除为0而不是1),等等。由于STM32L1每个字有8位ECC,因此该方法不起作用。但是,如果我们知道ECC算法,我们可以很容易地找到一个短序列值,可以在不违反ECC的情况下逐步写入。
我们可以简单地尝试不同的值序列并查看哪些值有效(一个这样的序列是0x0000001,0x00000101,0x00030101,0x03030101),但如果我们不知道ECC算法,我们无法检查序列是否有效违反了ECC,在这种情况下,如果位被破坏,则纠错将不起作用。
[编辑]该功能应该用于使用STM32L1的内部程序存储器实现一个简单的文件系统。数据块用标题标记,标题包含状态。多个块可以驻留在单个页面上。国家可以随着时间的推移而改变(首先是“新的”,然后是“使用”,然后是“删除”等)。状态的数量很少,但如果我们可以覆盖以前的状态而不必先擦除整个页面,那么它会使事情变得更加容易。
答案 0 :(得分:1)
感谢您的任何评论!由于到目前为止还没有答案,我将总结一下,到目前为止我发现了什么(根据经验并基于对这个答案的评论):
以下是我个人的结论,基于实证研究结果,有限的研究和该线索的评论。根据官方文档,不。不要在上面做任何认真的工作(我也不会)!
每个单词的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位中,隐藏位将非常有限。
如果您使用不同的起始值重复此测试,您应该能够收集足够的数据来证明使用了哪种纠错。