简体   繁体   English

STM32L1xx上的Flash ECC算法

[英]Flash ECC algorithm on STM32L1xx

How does the flash ECC algorithm (Flash Error Correction Code) implemented on STM32L1xx work? 在STM32L1xx上实现的Flash ECC算法(Flash纠错码)如何工作?

Background: I want to do multiple incremental writes to a single word in program flash of a STM32L151 MCU without doing a page erase in between. 背景:我想对STM32L151 MCU的程序闪存中的单个字进行多次增量写入,而无需在其间进行页面擦除。 Without ECC, one could set bits incrementally, eg first 0x00, then 0x01, then 0x03 (STM32L1 erases bits to 0 rather than to 1), etc. As the STM32L1 has 8 bit ECC per word, this method doesn't work. 如果没有ECC,则可以递增设置位,例如首先设置0x00,然后设置0x01,然后设置0x03(STM32L1将位擦除为0而不是1),等等。由于STM32L1每个字具有8位ECC,因此该方法不起作用。 However, if we knew the ECC algorithm, we could easily find a short sequence of values, that could be written incrementally without violating the ECC. 但是,如果我们知道ECC算法,就可以轻松找到一小段值序列,这些值序列可以递增写入而不会违反ECC。

We could simply try different sequences of values and see which ones work (one such sequence is 0x0000001, 0x00000101, 0x00030101, 0x03030101), but if we don't know the ECC algorithm, we can't check, whether the sequence violates the ECC, in which case error correction wouldn't work if bits would be corrupted. 我们可以简单地尝试不同的值序列并查看哪个值起作用(一个这样的序列为0x0000001、0x00000101、0x00030101、0x03030101),但是如果我们不知道ECC算法,就无法检查该序列是否违反ECC。 ,在这种情况下,如果位被破坏,则纠错将不起作用。

[Edit] The functionality should be used to implement a simple file system using STM32L1's internal program memory. [编辑]该功能应用于使用STM32L1的内部程序存储器实现简单的文件系统。 Chunks of data are tagged with a header, which contains a state. 数据块用标头标记,该标头包含一个状态。 Multiple chunks can reside on a single page. 多个块可以驻留在单个页面上。 The state can change over time (first 'new', then 'used', then 'deleted', etc.). 状态可以随着时间而变化(首先是“新”,然后是“已使用”,然后是“已删除”,等等)。 The number of states is small, but it would make things significantly easier, if we could overwrite a previous state without having to erase the whole page first. 状态的数量很少,但是如果我们可以覆盖以前的状态而不必先擦除整个页面,那么状态会变得很容易。

Thanks for any comments! 感谢您的任何评论! As there are no answers so far, I'll summarize, what I found out so far (empirically and based on comments to this answer): 由于到目前为止没有答案,因此我将总结一下到目前为止所发现的内容(根据经验并基于对此答案的评论):

  • According to the STM32L1 datasheet "The whole non-volatile memory embeds the error correction code (ECC) feature.", but the reference manual doesn't state anything about ECC in program memory. 根据STM32L1数据表“整个非易失性存储器都嵌入了纠错码(ECC)功能。”,但参考手册并未在程序存储器中说明有关ECC的任何内容。
  • The datasheet is in line with what we can find out empirically when subsequentially writing multiple words to the same program mem location without erasing the page in between. 数据表与我们在随后将多个单词随后写入同一程序内存位置而不擦除其间的页面时的经验发现相符。 In such cases some sequences of values work while others don't. 在这种情况下,某些价值序列有效,而其他价值序列则无效。

The following are my personal conclusions, based on empirical findings, limited research and comments from this thread. 以下是我的个人结论,基于经验发现,有限的研究和对此主题的评论。 It's not based on official documentation. 不是基于官方文档。 Don't build any serious work on it (I won't either)! 不要在上面做任何认真的工作(我也不会)!

  • It seems, that the ECC is calculated and persisted per 32-bit word. 看来,ECC是按每个32位字计算和保留的。 If so, the ECC must have a length of at least 7 bit. 如果是这样,则ECC的长度必须至少为7位。
  • The ECC of each word is probably written to the same nonvolatile mem as the word itself. 每个单词的ECC可能写入与单词本身相同的非易失性内存中。 Therefore the same limitations apply. 因此,存在相同的限制。 Ie between erases, only additional bits can be set. 即在擦除之间,只能设置其他位。 As stark pointed out, we can only overwrite words in program mem with values that: 正如斯塔克指出的那样,我们只能使用以下值覆盖程序内存中的单词:

    • Only set additional bits but don't clear any bits 仅设置其他位,但不清除任何位
    • Have an ECC that also only sets additional bits compared to the previous ECC. 拥有一个ECC,与以前的ECC相比,它也仅设置其他位。
  • If we write a value, that only sets additional bits, but the ECC would need to clear bits (and therefore cannot be written correctly), then: 如果我们写一个值,那只会设置其他位,但是ECC将需要清除位(因此无法正确写入),然后:

    • If the ECC is wrong by one bit, the error is corrected by the ECC algorithm and the written value can be read correctly. 如果ECC错误一位,则可以通过ECC算法纠正错误,并且可以正确读取写入的值。 However, ECC wouldn't work anymore if another bit failed, because ECC can only correct single-bit errors. 但是,如果其他位失败,则ECC将不再起作用,因为ECC只能纠正一位错误。
    • If the ECC is wrong by more than one bit, the ECC algorithm cannot correct the error and the read value will be wrong. 如果ECC错误多于一位,则ECC算法无法纠正错误,并且读取值将错误。
  • We cannot (easily) find out empirically, which sequences of values can be written correctly and which can't. 我们无法(轻松地)凭经验找出哪些值序列可以正确写入而哪些不能正确写入。 If a sequence of values can be written and read back correctly, we wouldn't know, whether this is due to the automatic correction of single-bit errors. 如果可以正确写入和读取一个值序列,我们将不知道这是否是由于自动纠正了一位错误。 This aspect is the whole reason for this question asking for the actual algorithm. 这是该问题要求实际算法的全部原因。

  • The ECC algorithm itself seems to be undocumented. ECC算法本身似乎没有记录。 Hamming code seems to be a commonly used algorithm for ECC and in AN4750 they write, that Hamming code is actually used for error correction in SRAM. 汉明码似乎是ECC的常用算法,他们在AN4750中写道,汉明码实际上用于SRAM中的纠错。 The algorithm may or may not be used for STM32L1's program memory. 该算法可以或可以不用于STM32L1的程序存储器。

  • The STM32L1 reference manual doesn't seem to explicitely forbid multiple writes to program memory without erase, but there is no documentation stating the opposit either. STM32L1参考手册似乎并未明确禁止在不擦除的情况下多次写入程序存储器,但是也没有文档说明相反的情况。 In order not to use undocumented functionality, we will refrain from using such functionality in our products and find workarounds. 为了不使用未记录的功能,我们将避免在我们的产品中使用此类功能并找到解决方法。

Interessting question. 有趣的问题。

First I have to say, that even if you find out the ECC algorithm, you can't rely on it, as it's not documented and it can be changed anytime without notice. 首先,我不得不说,即使您找到了ECC算法,也不能依靠它,因为它没有记录在案,并且可以随时更改而无需另行通知。

But to find out the algorithm seems to be possible with a reasonable amount of tests. 但是找出合理的测试数量似乎是可行的。
I would try to build tests which starts with a constant value and then clearing only one bit. 我会尝试构建以恒定值开头的测试,然后仅清除一位。
When you read the value and it's the start value, your bit can't change all necessary bits in the ECC. 当您读取该值并将其作为起始值时,您的位将无法更改ECC中的所有必需位。

Like: 喜欢:

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

If you find a start value where the erase tests works for all bits, then the start value has probably an ECC of all bits set. 如果您找到一个对所有位进行擦除测试的起始值,则该起始值可能已设置了所有位的ECC。
Edit: This should be true for any ECC, as every ECC needs always at least a difference of two bits to detect and repair, reliable one defect bit. 编辑:这对于任何ECC都是正确的,因为每个ECC总是至少需要相差两个位才能检测和修复可靠的一个缺陷位。
As the first bit difference is in the value itself, the second change needs to be in the hidden ECC-bits and the hidden bits will be very limited. 由于第一个位差在于值本身,因此第二个更改需要位于隐藏的ECC位中,并且隐藏位将非常有限。

If you repeat this test with different start values, you should be able to gather enough data to prove which error correction is used. 如果您使用不同的起始值重复进行此测试,则您应该能够收集到足够的数据以证明使用了哪种纠错功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM