Перейти к содержанию

Почему стирается EEPROM при прошивке Arduino?

Обновлено Редакция GAW

EEPROM переживает выключение питания, но не любую прошивку. Всё решает, выполняет ли программатор команду Chip Erase и запрограммирован ли фьюз EESAVE.

Какая прошивка что стирает

Способ в Arduino IDEКоманда avrdude по ядру ArduinoEEPROM у Uno
«Загрузка» через USBс ключом -D — без стирания кристалласохраняется
«Загрузить через программатор»без -D — avrdude сам стирает кристалл перед записью флешстирается
«Записать загрузчик»с ключом -e — явное стирание, затем запись фьюзовстирается, если EESAVE не был включён заранее

Шаблоны команд — platform.txt ядра Arduino AVR, поведение ключей — man-страница avrdude.

Chip Erase и EESAVE

По даташиту ATmega328P Chip Erase стирает флеш-память, EEPROM и биты защиты, а фьюзы не трогает. Исключение одно: если запрограммирован фьюз EESAVE, EEPROM при стирании сохраняется. Это бит 3 старшего байта фьюзов, и, как у всех фьюзов AVR, «запрограммирован» значит «0».

Наш расчёт для Arduino Uno:

0xDE=1101 11102  ⇒  бит 3=1  (EESAVE выключен),0xD6=1101 01102  (включён)\text{0xDE} = 1101\,1110_2 \;\Rightarrow\; \text{бит 3} = 1 \;(\text{EESAVE выключен}), \qquad \text{0xD6} = 1101\,0110_2 \;(\text{включён})

Значение 0xDE задаёт boards.txt ядра Arduino. Остальные биты байта и их смысл расшифрует калькулятор фьюзов AVR — меняйте только бит 3.

Что выбрать

  • Данные должны пережить любую прошивку — включите EESAVE, но помните, что «Записать загрузчик» вернёт старший байт 0xDE и при следующем стирании EEPROM снова пропадёт.
  • Нужно сохранить один раз — прочитайте EEPROM в файл и запишите после прошивки.
  • Нужны начальные значения — файл .eep с переменными EEMEM записывают программатором отдельно, загрузчик его не пишет; как устроены такие переменные, показывает калькулятор EEPROM AVR, а запись структур — ответ «Как записать структуру в EEPROM AVR».

Похожие вопросы

Как включить EESAVE на Arduino Uno?

Записать старший байт фьюзов с битом 3 в нуле: у Uno он 0xDE, с EESAVE — 0xD6 (наш расчёт). Например, avrdude -c usbasp -p m328p -U hfuse:w:0xD6:m. Остальные биты байта менять нельзя, их значения проверьте в калькуляторе фьюзов. Учтите, что «Записать загрузчик» в Arduino IDE снова поставит 0xDE: в его команде стирание -e выполняется раньше записи фьюзов, поэтому в этот раз EEPROM при включённом EESAVE уцелеет, а при следующей прошивке через программатор уже сотрётся (наш вывод из platform.txt и man avrdude).

Стирает ли EEPROM загрузчик Arduino?

Нет: при обычной загрузке Arduino IDE вызывает avrdude с ключом -D, без стирания кристалла, а загрузчик записывает только флеш-память. Команда Chip Erase — это команда режима программирования через ISP, загрузчику она недоступна (наш вывод из даташита).

Как сохранить данные EEPROM перед прошивкой программатором?

Прочитать их в файл: avrdude -c usbasp -p m328p -U eeprom:r:backup.eep:i, а после прошивки записать обратно с -U eeprom:w:backup.eep:i. Это надёжнее, чем менять фьюзы на один раз.

Источники

  1. Microchip. ATmega48A/PA/88A/PA/168A/PA/328/P Data Sheet (DS40002061B) — 28.7.3 — Chip Erase стирает флеш, EEPROM и биты защиты, фьюзы не меняет; прим. 1: EEPROM сохраняется, если запрограммирован EESAVE; табл. 28-8 — у ATmega328P EESAVE — бит 3 старшего байта фьюзов, по умолчанию не запрограммирован
  2. Arduino. ArduinoCore-avr, boards.txt и platform.txt (коммит 11b9130) — uno.bootloader.high_fuses=0xDE; upload.pattern — avrdude с -D; program.pattern (загрузка через программатор) — без -D; erase.pattern (запись загрузчика) — с -e
  3. AVRDUDE v8.3, man-страница avrdude.1 — -D отключает автоматическое стирание: без него при записи флеш avrdude выполняет стирание кристалла; -e — стирание, которое сбрасывает флеш и EEPROM в 0xFF и очищает биты защиты

Нашли ошибку?