Главная chevron_right Уроки chevron_right Встроенные примеры chevron_right Arduino ISP chevron_right Arduino as ISP и загрузчики Arduino (Bootloaders)

Arduino as ISP и загрузчики Arduino (Bootloaders)

Превращаем Arduino в программатор ISP, чтобы прошить загрузчик на другую плату с AVR-микроконтроллером без специального оборудования.

Что делает Arduino тем, чем она является? Многое, но одна из ключевых особенностей — простота прошивки через Arduino IDE. Достаточно подключить плату к компьютеру через USB и нажать «Загрузить» — скетч окажется во Flash-памяти микроконтроллера.

Загрузчик (Bootloader)

Описанное выше работает благодаря небольшому фрагменту кода, который выполняется при каждом сбросе микроконтроллера. Он проверяет, не поступает ли новый скетч через порт USB по определённому протоколу и на заданной скорости. Если соединения нет — управление передаётся вашему скетчу.

Этот маленький (как правило, 512 байт) фрагмент называется «загрузчиком» (Bootloader). Он хранится в специальной области Flash-памяти — в конце адресного пространства — которая не перезаписывается при обычной загрузке скетча и предназначена именно для этой цели.

Карта памяти микроконтроллера ATmega328P: в конце адресного пространства выделена область загрузчика.

Чтобы записать загрузчик и сделать микроконтроллер совместимым с Arduino IDE, нужен внутрисхемный программатор ISP (In-circuit Serial Programmer). Он подключается к определённым выводам микроконтроллера и перепрограммирует всю его Flash-память, включая область загрузчика. Процедура ISP-программирования также включает запись фьюзов (fuses) — специального набора битов, определяющих поведение микроконтроллера в различных ситуациях.

Используем Arduino как ISP-программатор

Весь процесс записи загрузчика и правильной установки фьюзов, превращающих микроконтроллер ATmega в «Arduino», управляется из Arduino IDE: там есть специальный пункт меню и поддержка множества программаторов.

Среди доступных программаторов «Arduino as ISP» — самый дешёвый и практичный вариант для прошивки загрузчика на другую плату Arduino с микроконтроллерами ATmega, 32U4 или ATtiny.

Процесс программирования использует VCC, GND и четыре сигнальных линии. Три из них соединяют MISO, MOSI и SCK между программатором и целевым микроконтроллером, четвёртая — идёт с программатора на вывод RESET цели.

Как соединить платы

В следующей таблице показано, на каких пинах расположены MOSI, MISO и SCK для разных плат Arduino:

Arduino BoardMOSIMISOSCKLevel
UNO or Duemilanove11 or ICSP-412 or ICSP-113 or ICSP-35V
Mega1280 or Mega256051 or ICSP-450 or ICSP-152 or ICSP-35V
LeonardoICSP-4ICSP-1ICSP-35V
DueICSP-4ICSP-1ICSP-33.3V
ZeroICSP-4ICSP-1ICSP-33.3V
10111 or ICSP-412 or ICSP-113 or ICSP-33.3V

Интерфейс SPI — и соответственно эти пины — используется для программирования AVR-микроконтроллеров. Обратите внимание: MISO, MOSI и SCK расположены в одном и том же физическом месте на разъёме ICSP. Этот разъём также используют шилды, работающие с интерфейсом SPI, что позволяет создавать шилды, совместимые со всеми платами.

На Arduino UNO (см. изображение ниже) красным выделены соединения на гребёнках, жёлтым — разъём ICSP, подключённый к ATmega328P. Обратите внимание: на плате Rev.3 есть чип ATMega 16U2, управляющий USB-соединением. Этот чип тоже можно перепрограммировать через отдельный разъём ICSP2, расположенный прямо над самим ATMega 16U2.

На некоторых платах Arduino (см. таблицу выше) пины MOSI, MISO и SCK совпадают с цифровыми пинами 11, 12 и 13 соответственно. Именно поэтому во многих руководствах предлагается подключать целевую плату к этим пинам. Если такой вариант подключения вам удобнее, добавьте в скетч define USE_OLD_STYLE_WIRING. Это работает даже на платах, отличных от UNO. (Для самой UNO это не требуется.)

На фото выше — подключение двух плат UNO для прошивки загрузчика в «старом стиле»: верхняя плата — целевая (Target), нижняя — программатор (Programmer). Жёлтый провод идёт с D10 программатора на RESET цели. Важно: на платах семейства MKR нельзя использовать D10 для сброса — рекомендуется D6. Не забудьте изменить строку 73 скетча ArduinoISP — #define RESET 10 — заменив «10» на «6».

Arduino NANO программируется через разъём ICSP проводами, подключёнными к пинам D10–D13 платы-программатора UNO.

Arduino MEGA программирует Arduino UNO: соединены D51–D11, D50–D12, D52–D13, GND–GND, 5V–5V и D10 к RESET. Для такого типа плат необходим электролитический конденсатор 10µF, подключённый между RESET и GND (длинная ножка «плюс» — к RESET). Конденсатор устанавливается уже после загрузки ISP-скетча в плату-программатор.

Электролитический конденсатор 10µF между RESET и GND платы-программатора нужен только для плат, у которых между микроконтроллером и USB-портом компьютера стоит отдельный интерфейсный чип: Mega, UNO, Mini, Nano. Платы с прямым управлением USB от микроконтроллера — Leonardo, Esplora, Micro — в конденсаторе не нуждаются.

О напряжениях питания

В семействе Arduino есть платы с логикой 5V и 3.3V. Если вы используете в качестве программатора плату, не совместимую с 5V (Due, Zero и т.д.), следите за тем, чтобы её пины не получали 5V. Простейший способ — запитать всю систему (программатор и цель) от 3.3V.

На фото — подключение MKR1000 к UNO. Вся система работает от 3.3V: питание берётся с VCC и GND платы MKR1000 и подаётся на выводы 5V и GND платы UNO. Аналогичное соединение можно сделать через разъём ICSP платы UNO согласно описанной распиновке. Цвета проводов совпадают с предыдущими фото, чтобы было проще перейти от «старого» подключения к ICSP-разъёму. Все платы семейства MKR имеют одинаковую распиновку, поэтому любая из них подойдёт в качестве ISP-программатора. При использовании MKR-платы не забудьте изменить строку 73 скетча ArduinoISP, указав реальный пин сброса целевой платы (на фото — 6).

Важно: не подключайте платы к USB или источнику питания во время разводки соединений. Также рекомендуется сначала загрузить ISP-скетч в плату-программатор, и только потом подключать её к целевой плате.

Загрузка скетча в программатор

Плата, которую вы используете как программатор, должна быть прошита специальным скетчем. Найдите его по пути: Examples > 11. ArduinoISP > ArduinoISP.

Просматривая строки скетча, вы найдёте ряд параметров, которые настраиваются под целевую плату. Однако большинство из них уже задаются файлами конфигурации, входящими в состав каждого поддерживаемого загрузчика в Arduino IDE. Остальные параметры подробно описаны в комментариях — менять их стоит, только если вы точно понимаете, что делаете. Скетч также поддерживает три LEDs, которые дают визуальную обратную связь о ходе программирования.

Чтобы загрузить скетч в плату-программатор, выберите тип платы и порт, после чего действуйте как обычно.

Прошивка загрузчика

Когда все соединения готовы, переключитесь на тип платы, в которую хотите записать загрузчик. Этот шаг обязателен: именно он определяет нужный код загрузчика и конфигурацию фьюзов. Перед записью процедура проверяет сигнатуру микроконтроллера, однако многие платы используют один и тот же МК, но каждая имеет собственный загрузчик. Порт при этом должен оставаться тем, что принадлежит ArduinoISP.

Выберите «Burn bootloader» в меню Tools и дождитесь сообщения об успешном завершении в нижней части окна Arduino IDE. Если вы подключили LEDs, процесс можно наблюдать визуально.

Режим последовательного программирования Serial

Процесс программирования управляет тремя линиями SPI (MISO, MOSI и SCK) согласно стандартному протоколу SPI-программирования — тому же, что используется при работе с SD-картами. Единственное отличие — отсутствие сигнала CS (Chip Select). На AVR-микроконтроллерах его роль выполняет вывод RESET: он останавливает выполнение любого кода и переводит МК в особое состояние, в котором тот принимает команды через интерфейс SPI. Первая же команда протокола переводит микроконтроллер в режим Serial Programming Mode.

Как только этот режим активирован, доступны все программируемые области: Flash, EEPROM и фьюзы. В конце Flash-памяти находится область загрузчика, как показано на карте памяти в начале статьи. Процедура «Burn Bootloader» также корректно устанавливает фьюзы в соответствии с конструкцией конкретной платы — именно поэтому важно выбрать точную модель платы из списка.

Технические подробности программирования

Для программирования микроконтроллера используется инструмент с открытым исходным кодом avrdude. Процесс состоит из четырёх шагов: разблокировка области загрузчика, установка фьюзов, запись кода загрузчика и повторная блокировка этой области.

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

Управление фьюзами — как правило, это три байта: low, high и extended — наиболее деликатный аспект прошивки загрузчика. Неверная установка фьюзов может «окирпичить» микроконтроллер.

Фьюзы определяют множество параметров работы МК:

  • выбор источника тактирования и скорость работы;
  • минимальное напряжение питания (brownout detection);
  • использование загрузчика и объём выделяемой под него памяти (от 256 до 2048 слов, то есть от 512 до 4096 байт);
  • отключение сброса или последовательного программирования;
  • сохранение данных EEPROM при загрузке нового скетча.

Подробное описание фьюзов есть в даташите каждого микроконтроллера.

Каждая настройка имеет своё применение, и логично, что разработчик может заблокировать чип и защитить его от ISP-программирования. Однако случайная неверная установка фьюза может закрыть доступ к МК через ISP. Восстановить такой микроконтроллер можно только с помощью высоковольтного программатора High Voltage Serial Programmer, который использует 12V для сброса фьюзов.

Практические замечания и типичные ошибки

  • Перепутаны MOSI/MISO — одна из самых частых ошибок. Внимательно следите за направлением сигналов при ручной разводке.
  • Не установлен конденсатор на RESET — при использовании Mega, UNO, Nano или Mini в роли программатора без конденсатора 10 мкФ Arduino IDE будет сбрасывать плату-программатор в начале каждой операции, срывая процесс.
  • Неправильный номер пина RESET для MKR-плат — не забывайте менять строку 73 в скетче ArduinoISP.
  • Разные уровни напряжений — смешение 5V и 3.3V плат без согласования уровней может повредить 3.3V-плату.
  • Выбрана не та плата в меню Tools — при загрузке ISP-скетча выбирайте плату-программатор, при прошивке загрузчика — целевую плату.

Краткая инструкция: прошивка загрузчика за 8 шагов

  1. Откройте прошивку ArduinoISP (в разделе Examples) и загрузите её в плату-программатор.
  1. Примечание для Arduino 1.0: в коде ArduinoISP найдите строку delay(40); в функции heartbeat() и замените на delay(20);.
  1. В меню Tools > Board и Serial Port выберите плату и порт, соответствующие вашему программатору (не целевой плате).
  1. Загрузите скетч ArduinoISP.
  1. Wire свои платы Arduino.
  1. В меню Tools > Board выберите плату, на которую хотите записать загрузчик (не программатор). Описание плат смотрите на странице среды разработки.
  1. В меню Tools > Programmer выберите «Arduino as ISP».
  1. Выполните команду «Burn Bootloader».

Узнать больше

Больше базовых уроков вы найдёте в разделе built-in examples.

Также изучите language reference — подробный справочник по языку программирования Arduino.

Последнее обновление: 2018/01/20, SM