Как увеличить срок службы EEPROM?

Я хочу сохранить несколько (на данный момент 8) ИК-коды в EEPROM моей платы. Было бы здорово, если бы кто-нибудь мог предложить несколько советов, как увеличить срок службы EEPROM.

ИК-коды в моем скетче сохраняются в массиве unsigned longs.

Я знаю, что количество раз, когда я буду писать в EEPROM, будет << 100,000 + поможет в будущих проектах

, 👍7

Обсуждение

Просто из интереса я попытался "изнашивать" свой EEPROM некоторое время назад. Потребовалось около 1,5 миллиона записей, прежде чем он начал терпеть неудачу., @Nick Gammon

@NickGammon, на что были похожи неудачи? Случайные данные?, @James Waldby - jwpat7

Один бит сбоев, по памяти., @Nick Gammon

Вполне возможно, что если вы превысите технические характеристики, память может стать менее надежной. Я этого не проверял. Возможно, вы обнаружите, что через месяц что - то изменится. Мои собственные выводы заключались в том, что вы можете значительно превысить рекомендуемые оценки и все равно прочитать написанный вами байт мгновением позже., @Nick Gammon


4 ответа


Лучший ответ:

5

Я могу придумать несколько:

  1. не включайте его, если в этом нет необходимости;
  2. не пишите ему, если в этом нет необходимости;
  3. запишите как можно меньше данных - сожмите данные; записывайте их только во время отключения или выключения питания, ...;
  4. выровняйте запись в как можно большем количестве ячеек - увеличьте адрес записи с последующей записью;
  5. используйте большой eeprom;
  6. используйте fram;
  7. используйте резервную батарею sram +;

...

3 - 7 действительно являются примерами реализации #2.

,

7

В другом ответе упоминались некоторые общие идеи; вот пара более конкретных замечаний.

• Вы можете направлять запись отдельных байтов с помощью процедуры, которая считывает ячейку EEPROM перед записью в нее, и если ее значение не меняется, не записывает.

• Для выравнивания нагрузки вы можете разделить адресное пространство EEPROM на k сегментов, где k =⌊E/(n+1)⌋, с n = размером массива данных и E = размером EEPROM. Инициализируйте каталог, массив из m байтов, все из которых имеют значение k, с m = E-n·k. Когда ваше устройство запускается, оно читает каталог до тех пор, пока не найдет текущую запись, байт, не равный k. [Если все записи каталога равны k, инициализируйте первую до 0 и продолжайте оттуда.] Если текущая запись каталога содержит j, то ячейка j содержит текущие данные. Когда вам нужно записать новые данные, вы сохраняете j+1 в текущей записи каталога; если это делает его равным k, инициализируйте следующую запись каталога 0 и продолжайте оттуда. Обратите внимание, что байты каталога изнашиваются примерно так же, как байты ведра, потому что 2·k > m ≥ k. >

,

Спасибо, я постараюсь также реализовать выравнивание нагрузки на мой скетч. Отличное объяснение. Я проверяю, совпадают ли значения перед записью, так что об этой части позаботятся., @karx


3

Если ваши данные занимают лишь небольшую часть вашего EEPROM, вы можете использовать один из алгоритмов выравнивания износа. Суть этих алгоритмов заключается в том, чтобы каждый раз записывать в другое место, поэтому записи распределяются по нескольким местоположениям, в то время как каждое местоположение остается ниже предела в 100 000 записей.

Здесь обсуждается несколько таких алгоритмов, которые вы могли бы реализовать самостоятельно. В качестве альтернативы вы можете просто использовать библиотеку, подобную этой.

,

Это отличные ссылки Дмитрий! Спасибо. В любом случае, теперь я использую ~весь EEPROM для данных. Операции записи редки в моем коде и происходят только в начале жизненного цикла (период настройки моего устройства). Жизненный цикл в основном состоит только из операций чтения. По мере увеличения размера моих конфигурационных файлов я теперь ищу методы оптимизации памяти, чтобы вместить все это в EEPROM и не использовать дополнительное хранилище., @karx


0

Я считаю, что существует простой способ использовать только n ячеек и один выделенный битовый шаблон для достижения увеличения долговечности на n/2.

Выделенный битовый шаблон (например, 0xffff) является маркером, который указывает на неиспользуемую ячейку, и при нормальной работе не более одной ячейки за раз имеет следующее значение:

uint16_t readWord (const uint16_t *address);
void writeWord (uint16_t *address, uint16_t value);

#define CELL_COUNT   42
#define BASE_ADDRESS 12
#define MARKER       0xffff  // Для этого лучше всего использовать EEPROM по умолчанию

static uint8_t curCell = 0;

static void wlInit (void)
{
  for ( uint8_t ii = 0 ; ii < CELL_COUNT ; ii++ ) {
    if ( readWord (BASE_ADDRESS + ii) != MARKER ) {
      curCell = ii;
      // Нет раннего возврата/перерыв здесь, чтобы сохранить время выполнения init()  
      // константа.  Также можно проверить наличие коррупции здесь, проверив наличие
      // > 1 клетки с МАРКЕРОМ (см. Ниже).
    }
  }
  // Если мы не нашли немаркерную ячейку, мы получим curCell = 0 
  // за начальное значение curCell
}

static uint16_t wlRead (void)
{
  return readWord (BASE_ADDRESS + curCell);
}

static void wlWrite (uint16_t value)
{
  assert (value != MARKER);   // Сохранение значения маркера большое нет-нет

  uint8_t nextCell = (curCell + 1) % CELL_COUNT;
  writeWord (BASE_ADDRESS + nextCell, value);
  writeWord (BASE_ADDRESS + curCell, MARKER);
  curCell = nextCell;
}

Тот же подход можно использовать со структурированными данными при условии, что битовый шаблон может быть зарезервирован (либо в выделенном байте, либо из какого-либо другого поля, имеющего запасной шаблон).

Этот подход также обладает полезным свойством в отношении прерванной (например, при отключении питания) записи: если когда-либо были две ячейки без значения МАРКЕРА, произошла неполная (т. е. поврежденная) запись. Это кажется полезным, потому что, например, спецификация ATmega328P содержит следующий неясный и не особенно обнадеживающий абзац об использовании обнаружения потемнения во избежание повреждения:

Держите сброс AVR активным (низким) в периоды недостаточного напряжения питания. Это можно сделать, включив внутреннее затемнение Детектор (БПК). Если уровень обнаружения внутреннего БПК не соответствует необходимому уровню обнаружения, внешний сброс низкого напряжения CC Может быть использована схема защиты. Если сброс происходит во время выполнения операции записи, операция записи будет завершена при условии, что напряжение питания достаточное.

,