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

Самопрограммирование (SPM)

Загрузчик Arduino принимает новую прошивку по UART и сам записывает её во флеш, без программатора. Это возможно потому, что AVR умеет программировать собственную флеш-память специальной командой SPM. У этой возможности строгие правила: что можно писать, откуда и в каком порядке.

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

Самопрограммирование — способность микроконтроллера записывать собственную флеш-память во время работы. У AVR для этого служит команда SPM (Store Program Memory). На ней построены загрузчики, которые принимают прошивку по UART или USB и записывают её без внешнего программатора.

Откуда можно писать

У ATmega88–328P, по разделу 27.3 даташита, SPM инициирует программирование только при выполнении из секции загрузчика в конце флеш-памяти; из секции приложения команда записи не сработает. Что именно разрешено переписывать, ограничивают биты защиты загрузчика.

Как идёт запись

Флеш программируется страницами: у ATmega328P страница — 64 слова (128 байт), всего 256 страниц. Последовательность из раздела 27.8:

  1. Заполнить временный буфер страницы — по одному слову: адрес в регистре Z, данные в R1:R0, запись управляющего кода в SPMCSR, затем SPM.
  2. Стереть страницу.
  3. Записать страницу из буфера.
  4. Снять блокировку чтения области RWW.

Буфер можно заполнить до стирания — тогда удобно сделать «чтение-изменение-запись» части страницы. Каждая команда SPM должна выполниться не позже чем через четыре такта после записи в SPMCSR, поэтому прерывания на это время запрещают. Стирание страницы и её запись — каждая операция по 3,7–4,5 мс (табл. 27-6), так что обновление страницы занимает около 7,4–9 мс. В avr-libc всё это оборачивают макросы boot_page_fill, boot_page_erase и boot_page_write из <avr/boot.h>.

Подводные камни

  • Область RWW недоступна во время записи в неё: векторы прерываний и вызываемый код должны быть в секции загрузчика.
  • Запись EEPROM блокирует SPM — перед SPM проверяют, что запись в EEPROM закончилась.
  • Ресурс флеш-памяти — не меньше 10 000 циклов записи и стирания, у EEPROM — 100 000.
  • Низкое питание портит флеш: даташит советует держать микроконтроллер в сбросе детектором просадки питания или защитить загрузчик битами защиты.

Карта флеш-памяти и фьюзы ATmega328P — на странице ATmega328P.

Частые вопросы

Можно ли сохранять настройки во флеш вместо EEPROM?

Можно, но код записи должен находиться в секции загрузчика — по даташиту ATmega328P только оттуда SPM инициирует программирование. Флеш пишется страницами по 128 байт, каждое обновление — стирание и запись всей страницы, по 3,7–4,5 мс на каждую из двух операций, то есть около 7,4–9 мс, ресурс — не меньше 10 000 циклов против 100 000 у EEPROM. Для часто меняющихся параметров EEPROM удобнее.

Почему после записи страницы программа зависает?

Если страница пишется в область RWW, эта область на время операции недоступна для чтения. Если в этот момент сработает прерывание с вектором в секции приложения или код перейдёт туда, программа попадёт в неизвестное состояние. Даташит требует запретить прерывания или перенести векторы в секцию загрузчика, а после записи снять блокировку RWW.

Как защитить флеш от случайной записи при просадке питания?

Даташит (разд. 27.8.11) предлагает любой из трёх способов: запрограммировать биты защиты загрузчика, если его обновлять не нужно; держать микроконтроллер в сбросе при низком питании — например, включив детектор BOD; или держать ядро в режиме Power-down, пока питание низкое.

Источники

  1. Microchip. ATmega48A/PA/88A/PA/168A/PA/328/P Data Sheet, DS40002061B, 2020 — Features и разд. 8: флеш выдерживает не меньше 10 000 циклов записи и стирания; разд. 27.3: SPM инициирует программирование только при выполнении из секции загрузчика; разд. 27.8: флеш обновляется по страницам, перед записью страницу стирают; временный буфер страницы заполняется по слову командой SPM — до стирания (тогда возможен «чтение-изменение-запись») или после; разд. 27.8.1–27.8.3: адрес — в регистре Z, данные — в R1:R0, после записи в SPMCSR команду SPM нужно выполнить в течение четырёх тактов; при записи в NRWW процессор останавливается; разд. 27.8.6: во время записи область RWW недоступна для чтения; разд. 27.8.8: запись EEPROM блокирует запись в SPMCSR; разд. 27.8.11: при низком питании флеш может быть испорчена — защищаться битами защиты загрузчика, удержанием RESET (например, детектором BOD) или режимом Power-down; табл. 27-6: время стирания или записи страницы — 3,7–4,5 мс; табл. 28-11: у ATmega328P страница 64 слова, 256 страниц
  2. AVR-LibC 2.3.2: include/avr/boot.h — макросы boot_page_erase, boot_page_fill, boot_page_write, boot_rww_enable и boot_spm_busy_wait оборачивают последовательность записи в SPMCSR и команды SPM

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