Самопрограммирование (SPM)
Загрузчик Arduino принимает новую прошивку по UART и сам записывает её во флеш, без программатора. Это возможно потому, что AVR умеет программировать собственную флеш-память специальной командой SPM. У этой возможности строгие правила: что можно писать, откуда и в каком порядке.
Обновлено Редакция GAW
Самопрограммирование — способность микроконтроллера записывать собственную флеш-память во время работы. У AVR для этого служит команда SPM (Store Program Memory). На ней построены загрузчики, которые принимают прошивку по UART или USB и записывают её без внешнего программатора.
Откуда можно писать
У ATmega88–328P, по разделу 27.3 даташита, SPM инициирует программирование только при выполнении из секции загрузчика в конце флеш-памяти; из секции приложения команда записи не сработает. Что именно разрешено переписывать, ограничивают биты защиты загрузчика.
Как идёт запись
Флеш программируется страницами: у ATmega328P страница — 64 слова (128 байт), всего 256 страниц. Последовательность из раздела 27.8:
- Заполнить временный буфер страницы — по одному слову: адрес в регистре Z, данные в R1:R0, запись управляющего кода в SPMCSR, затем SPM.
- Стереть страницу.
- Записать страницу из буфера.
- Снять блокировку чтения области 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, пока питание низкое.
Источники
- 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 страниц
- 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
Нашли ошибку?
Смотрите также
- Секция загрузчика AVRОбласть флеш-памяти AVR, из которой разрешено самопрограммирование
- Загрузчик (bootloader)Прошивка МК без программатора через UART или USB
- Биты защиты AVR (lock bits)Запрет чтения прошивки и защита загрузчика от перезаписи
- Детектор пониженного питанияBrown-out detector: сброс МК при просадке питания
- ATmega328PРаспиновка, фьюзы, Optiboot, периферия, питание, схема и код на C
- EEPROMЭнергонезависимая память для настроек и калибровки