Существует ли общий алгоритм выравнивания износа EEPROM микроконтроллера?

Я работаю над библиотекой Arduino, которая максимально продлит срок службы EEPROM AVR. Он принимает количество переменных, которые вы хотите сохранить, и делает все остальное. Это моя попытка, которая работает не во всех случаях.

Исходная информация

Atmel утверждает, что каждая ячейка памяти рассчитана на 100 000 циклов записи/стирания. Они также предоставляют примечания по применению, в которых описывается, как выполнить выравнивание износа. Вот краткое изложение примечания к применению.

Чередуя записи по двум адресам памяти, мы можем увеличить частоту стирания/записи до 200 000 циклов. Три адреса памяти дают вам 300 000 циклов стирания/записи и так далее. Чтобы автоматизировать этот процесс, используется буфер состояния, чтобы отслеживать, где должна быть следующая запись.Буфер состояния также должен иметь ту же длину, что и буфер параметров, поскольку для него также необходимо выполнить выравнивание износа. Поскольку мы не можем сохранить индекс следующей записи, мы увеличиваем соответствующий индекс в буфере состояния.

Вот пример.

   <------------------- EEPROM -------------------->  
   0                                               N
   -------------------------------------------------
       Parameter Buffer    |     Status Buffer     |
   -------------------------------------------------

   Initial state.
   [ 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 ]

   First write is a 7. The corresponding position
   in the status buffer is changed to previous value + 1.
   Both buffers are circular.
   [ 7 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 ]

   A second value, 4, is written to the parameter buffer 
   and the second element in the status buffer becomes
   the previous element, 1 in this case, plus 1.
   [ 7 | 4 | 0 | 0 | 0 | 0 | 1 | 2 | 0 | 0 | 0 | 0 ]

   And so on
   [ 7 | 4 | 9 | 0 | 0 | 0 | 1 | 2 | 3 | 0 | 0 | 0 ]

Чтобы определить, где должна произойти следующая запись, мы смотрим на разницу между элементами. Если предыдущий элемент + 1 НЕ равен следующему элементу, то именно здесь должна произойти следующая запись. Например:

   Compute the differences by starting at the first
   element in the status buffer and wrapping around. 
   General algo: previous element + 1 = current element
   1st element:  0 + 1 = 1 = 1st element (move on)
   2nd element:  1 + 1 = 2 = 2nd element (move on)
   3rd element:  2 + 1 = 3 = 3rd element (move on)
   4th element:  3 + 1 = 4 != 4th element (next write occurs here)

   [ 7 | 4 | 9 | 0 | 0 | 0 | 1 | 2 | 3 | 0 | 0 | 0 ]
                 ^                       ^
                 |                       |

   Another edge case to consider is when the incrementing values
   wrap around at 256 because we are writing bytes. With the
   following buffer we know the next write is at the 3rd element 
   because 255 + 1 = 0 != 250 assuming we are using byte arithmetic.

   [ x | x | x | x | x | x | 254 | 255 | 250 | 251 | 252 | 253 ]
                                          ^
                                          | 

   After we write at element 3 the status buffer is incremented 
   to the next value using byte arithmetic and looks like this.
   255 + 1 = 0 (wrap around)
   0 + 1 != 251 (next write is here)

   [ x | x | x | x | x | x | 254 | 255 |  0  | 251 | 252 | 253 ]
                                                ^
                                                | 

В приведенных выше примерах показано, как продлить срок службы EEPROM для одной переменной. Для нескольких переменных представьте себе сегментирование EEPROM на несколько сегментов с той же структурой данных, но меньшими буферами.

Проблема

У меня есть рабочий код для того, что я описал выше. Моя проблема заключается в том, что алгоритм не работает, когда длина буфера >= 256. Вот что происходит

   Buffer length of 256. The last zero is from
   the initial state of the buffer. At every index
   previous element + 1 == next element. No way to
   know where the next write should be.

   <-------------- Status Buffer ------------>
   [  1  |  2  | ... | 253 | 254 | 255 |  0  ]


   A similar problem occurs when the buffer length
   is greater than 256. A lookup for a read will think
   the next element is at the first 0 when it should be at 
   255.
   <-------------------- Status Buffer ------------------>
   [  1  |  2  | ... | 253 | 254 | 255 |  0  |  0  |  0  ]

Вопрос

Как решить указанную выше проблему? Есть ли лучший способ отслеживать, где должен быть написан следующий элемент?

10
задан Peter Mortensen 17 June 2012 в 10:45
поделиться