2010-08-23 5 views
9

Недавно я установил необходимость хранения редко повторяющихся конфигурационных переменных в EEPROM микроконтроллера. Добавление состояния в программу сразу же заставляет один беспокоиться оБезопасное хранение и обращение к EEPROM

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

Обширный поиск в Google только показал одну статью, которая адресована keeping your EEPROM data valid through firmware updates. Кто-нибудь использовал подход, обсуждаемый в этой статье? Есть ли лучший альтернативный подход?

ответ

7

Лично я предпочитаю формат «tagged table».

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

Вот пример того, что одна из таблиц будет выглядеть следующим образом:

Byte 0: Table Length (in 16-bit words) 
Byte 1: Table ID  (used by firmware to determine what this data is) 
Byte 2: Format Version (incremented every time the format of this table changes) 
Byte 3: Checksum  (simple sum-to-zero checksum) 
Byte 4: Start of body 
... 
Byte N: End of body 

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

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

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

Есть несколько предостережений, хотя они не слишком обременительны. Во-первых, вам необходимо убедиться, что ваше прошивка может обрабатывать случай, когда важные данные либо не находятся в таблице, либо использует версию неподдерживаемого формата. Вам также потребуется инициализировать первый байт области хранения EEPROM до нуля (так что при первой загрузке вы не начнете загружать мусор, думая, что это данные). Поскольку каждая таблица знает свою длину, можно расширить или сжать таблицу; однако вы должны перемещать остальную область хранения таблиц вокруг, чтобы убедиться, что нет «отверстий» (если вся цепочка таблиц не может вписаться в память вашего устройства, тогда этот процесс может раздражать). Лично я не считаю, что любой из них может быть таким большим, и это стоит того, что я могу сэкономить, используя некоторые другие методы хранения данных.

+0

Это звучит как отличное решение для обработки изменений размера таблицы между версиями прошивки. Есть ли у вас какие-либо советы относительно того, чтобы сделать его толерантным к записи с потерей мощности, помимо дублирования данных? –

+2

Запишите всю таблицу с недопустимой контрольной суммой, затем (в отдельной транзакции) вернитесь и напишите правильную контрольную сумму. Если есть проблема со средней записью, ваша контрольная сумма будет неправильной при чтении данных. – bta

+0

Это элегантное решение, которое тривиально реализовать: спасибо за продолжение. –

3

Найджел Джонс рассмотрел некоторые основы в вашей ссылке. Есть много альтернатив.

Один из вариантов, у вас есть много места, хранит пары ключ-значение вместо структур. Затем вы можете обновить одно значение (добавив его), не стирая все. Это наиболее полезно в устройствах с ограниченным числом циклов стирания. Ваша процедура чтения должна будет сканировать с самого начала, обновляя значения каждый раз, когда ключ встречается.Конечно, ваша программа обновления должна иметь «сборщик мусора», который срабатывает, когда память заполнена.

Чтобы справиться с ошибками устройства и отключением питания в середине обновлений, мы обычно храним несколько копий данных. Самый простой подход - пинг-понг между половинами устройства, используя порядковый номер, чтобы определить, что является более новым. Для проверки его используется CRC для каждого раздела. Это также относится к проблеме неинициализированных данных.

Для версии с ключом вам нужно будет добавить новый CRC после каждой записи.

+0

Мне очень нравится звук этого подхода в теории, но, к сожалению, не хватает EEPROM, чтобы сделать его выполнимым: только 1 кБ на ATmega328p. Спасибо за описание! –

 Смежные вопросы

  • Нет связанных вопросов^_^