Что такое бутлоадер? Обычно микроконтроллеры программируются с помощью специального программатора. Это может быть или программатор ISP, JTAG, debugWire, HVSP, HVPP. Для микроконтроллеров AVR в качестве альтернативы может использоваться функция самопрограммирования [4], когда запись в память новой программы (firmware) для микроконтроллера берет на себя специальная маленькая программа. Эта маленькая программа и называется бутлоадер (bootloader, загрузчик) [2]. Она запускается сразу после включения питания платы Arduino, или когда на плате нажата кнопка reset, или когда компьютер-хост USB, к которому подключена плата Arduino, выдал сигнал сброса (это делается с помощью специальной схемы реализации виртуального USB COM-порта Arduino). У программы загрузчика только есть только одна основная функция - принять через USART от компьютера-хоста новую программу, и прошить её в память программ (FLASH) микроконтроллера AVR платы Arduino (подробнее про загрузчик см. врезку "Как работает загрузчик?").
Примечание: ISP означает In-System Programming - внутрисхемное программирование, т. е. когда микроконтроллер программируется без физического извлечения из программируемой системы. JTAG это специальный интерфейс для программирования, отладки и тестирования схемы. debugWire это проприетарная разработка (компании Atmel), разновидность интерфейса JTAG для программирования и отладки. HVSP и HVPP обозначают соответственно High-Voltage Serial Programming (высоковольтное последовательное программирование) и High-Voltage Parallell Programming (высоковольтное параллельное программирование).
Не обязательно использовать бутлоадер. Когда Вы работаете в среде программирования Arduino (или в любой другой среде - BACSCOM AVR, AVR Studio, Atmel Studio, CodeVision AVR, Eclipse, IAR Embedded Workbench, Visual Studio), то для перепрошивки firmware (скетчей) в память микроконтроллера можете использовать внешний программатор [5]. Это дает определенные преимущества - Вы можете использовать для перепрошивки всю память программ (FLASH) микроконтроллера, и при использовании программатора нет задержки запуска программы из-за ожидания загрузчика.
Прошивка загрузчика из среды разработки Arduino. Чтобы прошить bootloader, Вам понадобится купить AVR-ISP (фирменный программатор ISP компании Atmel), USBtinyISP [6] или самому собрать ParallelProgrammer [7]. Программатор должен быть подключен к коннектору ICSP, это двухрядный разъем "папа", 2x3 выводов, с цоколевкой ISP6 [8]. При подключении убедитесь, что подсоединили коннектор в правильной ориентации, не наоборот. Для программирования на микроконтроллер платы должно подаваться питание; для плат Arduino обычно питание подается от внешнего источника или от порта USB.
Убедитесь, что правильно выбрали тип платы Arduino через меню Tools -> Board. Затем просто запустите подходящую команду из меню Tools -> Burn Bootloader. Прошивка загрузчика занимает примерно 15 секунд или больше. Подробнее про прошивку загрузчика см. врезки ниже.
Команда "Burn Bootloader" (прошить загрузчик) среды разработки Arduino IDE использует avrdude, утилиту с открытым исходным кодом. При этом выполняются друг за другом шагов: разблокировка секции загрузки микроконтроллера (с помощью изменения фьюзов lock byte), запись фьюзов микроконтроллера, загрузка кода загрузчика в память микроконтроллера (программа bootloader записывается в секцию загрузки), и затем блокировка секции загрузчика микроконтроллера (с помощью изменения фьюзов активация защиты секции загрузчика lock byte). Эти шаги управляются некоторыми настройками в preferences file системы Arduino.
Примечание: что такое preferences file, где он находится?
Вот, например, эти настройки в preferences file для ATmega8 bootloader:
bootloader.atmega8.programmer (значение по умолчанию: stk500) здесь задается протокол,
используемый загрузчиком. bootloader.atmega8.unlock_bits (значение по умолчанию: 0xFF) это значение записывается в байт фьюзов защиты (lock byte) микроконтроллера ATmega8, чтобы разблокировать секцию загрузки (bootloader section). bootloader.atmega8.high_fuses (значение по умолчанию: 0xca) это значение для записи старшего байта фьюзов ATmega8. bootloader.atmega8.low_fuses (значение по умолчанию: 0xdf) это значение для записи младшего байта фьюзов ATmega8. bootloader.atmega8.path (значение по умолчанию: bootloader) путь каталога (относительно каталога приложения Arduino), в котором находится готовая прошивка загрузчика (двоичный код). bootloader.atmega8.file (значение по умолчанию: ATmegaBOOT.hex) имя файла, где содержится прошивка загрузчика (в папке bootloader.atmega8.path). bootloader.atmega8.lock_bits (значение по умолчанию: 0x0F) это значение записывается в байт фьюзов защиты (lock byte) микроконтроллера ATmega8, чтобы включить блокировку секции загрузки (чтобы он случайно не был перезаписан программатором или при загрузке скетча).
Вот настройки для ATmega168 bootloader (здесь слово ПЛАТА может быть либо diecimila, либо ng):
bootloader.atmega168-ПЛАТА.programmer (значение по умолчанию: avrispmkii) здесь задается протокол, используемый загрузчиком. bootloader.atmega168-ПЛАТА.unlock_bits (значение по умолчанию: 0x3F) это значение записывается в байт фьюзов защиты (lock byte) микроконтроллера ATmega168, чтобы разблокировать секцию загрузки (bootloader section). bootloader.atmega168-ПЛАТА.extended_fuses (значение по умолчанию: 0x00) это значение для записи байта расширенных фьюзов ATmega168. bootloader.atmega168-ПЛАТА.high_fuses (значение по умолчанию: 0xdd) это значение для записи старшего байта фьюзов ATmega168. bootloader.atmega168-ПЛАТА.low_fuses (значение по умолчанию: 0xff) это значение для записи младшего байта фьюзов ATmega168. bootloader.atmega168-ПЛАТА.path (значение по умолчанию: bootloader168) путь каталога (относительно каталога приложения Arduino), в котором находится готовая прошивка загрузчика (двоичный код). bootloader.atmega168-ПЛАТА.file (значение по умолчанию: ATmegaBOOT_168_ПЛАТА.hex) имя файла, где содержится прошивка загрузчика (в папке bootloader.atmega168-ПЛАТА.path).
bootloader.atmega168-ПЛАТА.lock_bits (значение по умолчанию: 0x0F) это значение записывается в байт фьюзов защиты (lock byte) микроконтроллера ATmega168, чтобы включить блокировку секции загрузки (чтобы он случайно не был перезаписан программатором или при загрузке скетча).
Здесь приведен перевод инструкции, предоставленной Gian Pablo Vilamil (Bootload the Arduino Mini site:arduino.cc). Инструкция полезна также для китайских плат Arduino, в которые производители для удешевления производства "забывают" прошить загрузчик.
В каких случаях может понадобиться перешить загрузчик?
1. Ваша плата Arduino не имеет загрузчика - по какой-то причине он не записан в память микроконтроллера. Это может произойти, если Вы заменили на плате чип микроконтроллера. Также может быть ситуация, когда производитель платы "забыл" записать загрузчик (так поступают многие китайские поставщики плат Arduino с целью удешевить производство).
2. Нужно заменить имеющуюся версию загрузчика на другую. Старые несовершенные загрузчики плат Arduino (до появления Arduino Diecimila) ждали около 10 секунд после сброса или включения питания, пока придет от хоста новая программа микроконтроллера (скетч). Такая задержка могла появиться и после программирования скетча. Эта лишняя задержка довольно неприятна, когда не нужно записывать в память скетч. Альтернативные загрузчики, в том числе Adaboot bootloader, LilyPad bootloader и загрузчик Arduino Diecimila устраняют эту задержку. Также в некоторых случаях Вы можете самостоятельно изменить код загрузчика (см. разделы "Исходный код загрузчиков Arduino", ссылку [9] и врезку "Пример конфигурирования загрузчика Arduino UART"). Это полезно, когда нужно, чтобы проект стартовал намного быстрее (без таймаута загрузчика), и особенно когда при включении питания/сбросе возможно поступление на вход UART каких-то данных, не относящихся к загрузке. Если обычный загрузчик получит некоторые посторонние данные, то он будет пытаться их обработать как данные новой прошивки, что может привести к ошибкам, задержке запуска, и возможно даже что Ваша программа никогда не запустится.
3. Загрузчик вообще не используется. Процедура замены загрузчика в среде программирования Arduino также позволит Вам его полностью заменить каким-то приложением. Преимущество тут в том, что Ваше приложение будет запускаться немедленно, без задержки, и освободятся дополнительно 2 килобайта памяти программ. Недостаток в том, что больше нельзя перепрограммировать Вашу плату Arduino через USB - надо будет использовать ISP (до тех пор, пока Вы не замените/восстановите загрузчик).
4. Имеющийся загрузчик иногда оказывается поврежденным. Это встречается очень редко, однако все-таки возможно при некоторых обстоятельствах повреждение памяти FLASH микроконтроллера Arduino, и не получается запрограммировать Arduino традиционным способом (через USB - TTL UART). Повторная установка загрузчика может исправить эти проблемы. Ситуация похожа на переформатирование жесткого диска в компьютере.
Чем программирование загрузчика у Arduino Mini отличается от других плат Arduino? Полноразмерные платы Arduino имеют 6-контактный коннектор ISP для подключения программатора. Ну у платы Arduino такого коннектора нет (он просто не поместился на маленькой плате), поэтому Вам понадобится сделать кабель с коннектором самостоятельно. В остальном программирование загрузчика ничем не отличается.
Что понадобится?
• Программатор ISP [5], например AVR ISP MkII или другой. • 6 проводков. • 2 кусочка линеек по 3 контакта (или двухрядный разъем "папа" на 6 контактов). • Среда программирования AVR Studio (можно загрузить с сайта Atmel, или см. [11]).
Как сделать кабель?
Кабель должен соединять 6 контактов платы Arduino Mini с контактами разъема ISP программатора. Эти 6 выводов называются MISO, MOSI, SCK, RESET, Power и Ground. Из этих выводов 3 соответствуют цифровым портам ввода / вывода Arduino 11..13. Другие 3 вывода это сброс (Reset), +5V (Power) и земля (Ground, GND), и возможно Вы их уже используете. Обратите внимание, что вывод +5V это не вывод +9V. Вывод +5V нужен для подачи питания в программатор ISP.
Эти 6 выводов платы Arduino нужно подключить к 6 выводам коннектора ISP, показанным ниже.
1
MISO
VCC
2
3
SCK
MOSI
4
5
~RESET
GND
6
Обратите внимание, что на этом рисунке показана нумерация контактов с обратной стороны коннектора ISP программатора (или со стороны штырьков коннектора, который будет подключен к плате Arduino Mini). Если коннектор программатора наколот на плоский кабель, у которого красным помечен первый провод, и коннектор обращен от Вас, то на рисунке показано то, что Вы увидите.
Сделайте соединения между платой Arduino и двухрядным коннектором "папа", как показано на рисунке ниже. Подключите этот коннектор к разъему ISP6 "мама" программатора, соблюдая правильную ориентацию коннекторов. Подключите программатор к компьютеру, подайте питание на плату Arduino.
Как прошить загрузчик в среде программирования Arduino?
Теперь Вы можете записать загрузчик с помощью программатора и среды Arduino IDE. Запустите Arduino IDE на компьютере, выберите тип платы Arduino (в меню Tools -> Board выберите Arduino Mini). Затем в меню Tools -> Burn Bootloader выберите тип Вашего программатора (например, это программатор AVR-ISP mkII).
Чтобы прошить альтернативный загрузчик (например, который Вы скомпилировали сами), понадобится программное обеспечение для управления программатором. Есть множество таких утилит, и в зависимости от имеющегося программатора Вам нужно выбрать то программное обеспечение, которое работает с Вашим программатором. Если Вы используете программатор AVR-ISP mkII, отладчик AVR Dragon или JTAGICE mkII, то можете воспользоваться средой программирования AVR Studio [11], где есть утилита программатора.
Как прошить загрузчик в среде программирования AVR Studio?
Загрузите и установите среду программирования AVR Studio. К сожалению, она работает только в операционной системе семейства Windows, но в Интернете можно найти инструкции, как прошить загрузчик (как и любую программу в память микроконтроллера AVR) в среде Mac OS/X, Linux и даже FreeBSD.
Запустите AVR Studio. Нажмите Cancel, чтобы пропустить стартовое окно, предлагающее создать или открыть проект.
В меню Tools -> Program AVR -> Connect... выберите тип Вашего программатора (Platform:) и порт для его подключения (Port:) и нажмите кнопку Connect.
Запустится окно утилиты программатора. На закладке Program выберите тип программируемого микроконтроллера, который установлен на Вашей плате Arduino Mini (ATmega168 или ATmega328), режим программирования Programming mode -> ISP mode. Поставьте галочки "Erase Device Before Programming" и "Verify Device After Programming". В разделе Flash -> Input HEX File выберите прошивку загрузчика.
Нажмите кнопку Program. В строке статуса основного окна AVR Studio Вы увидите отображение прогресса записи кода загрузчика. После окончания записи можно также нажать кнопку Verify, чтобы еще раз убедиться, что процедура завершилась успешно.
После того, как загрузчик записан, программатор ISP больше не понадобится. Отключите программатор от порта USB компьютера, и отключите коннектор ISP от платы Arduino Mini. Для записи скетчей в плату Arduino Mini понадобится только требуется специальный переходничок, который реализует преобразование интерфейса USB CDC (виртуальный COM-порт) в RS232 TTL (см. врезку "Переходники USB - TTL RS232 на аппаратных чипах").
Примечание: если Вы программируете новый микроконтроллер, в котором не были настроены фьюзы (например, если сами собрали плату Arduino или заменили неисправный микроконтроллер), то также понадобится правильно установить фьюзы микроконтроллера. Основной смысл установки фьюзов - обеспечить запуск загрузчика при включении питания сброса, и правильно настроить тактовый генератор. Также полезно установить биты защиты, чтобы случайно не повредить секцию загрузчика. В утилите программирования AVR Studio фьюзы настраиваются на закладке Fuses, а биты защиты на закладке LockBits.
Подробнее про настройку фьюзов см. врезку "На что нужно обратить внимание при программировании загрузчика". В установке фьюзов и бит защиты очень помогает калькулятор фьюзов [10], также см. даташит на используемый микроконтроллер.
[Версии загрузчика Arduino]
Есть разные версии bootloader, потому что они должны работать на разной аппаратуре (разных платах Arduino), и потому что за длительное время развивалась как схема Arduino, так и код загрузчика.
Текущие версии загрузчиков (например те, которые поставляются вместе со средой Arduino 0009) почти идентичны для плат Arduino Diecimila и Arduino NG (на которых стоит ATmega168). Оба загрузчика этих плат работают на скорости передачи данных 19200 бод, и занимают в памяти программ (FLASH) микроконтроллера ATmega168 область размером в 2 килобайта. Отличия могут быть только во времени, сколько загрузчик ждет поступления новой программы, и в количестве мерцаний светодиодом на порте 13 Arduino (pin 13 LED), когда загрузчик запускается. Из-за автоматического сброса плат Arduino Diecimila загрузчик ждет очень малое время (меньше секунды), и для экономии времени также только один раз мигает светодиодом на порте 13. Загрузчик Arduino NG ждет примерно 6-8 секунд (потому что плата сбрасывается вручную при загрузке) и мигает светодиодом 3 раза при старте загрузчика.
Загрузчик, который реально поставляется вместе с продающимися платами Arduino NG, имеет незначительные отличия. Он разрешает внутренний pullup резистор микроконтроллера на порте 6, и не разрешает внутренний pullup резистор на выводе RX pin. Также он не использует таймаут при приеме ошибочных данных, так что если Вы пошлете микроконтроллеру через порт UART какие-то данные сразу после сброса (или включения питания), то загрузка Вашего скетча не произойдет (см. вопросы "Почему мой скетч не запускается ..." в FAQ [3]).
Загрузчик платы Arduino BT делает некоторую первоначальную конфигурацию модуля Bluetooth.
Загрузчик ATmega8 занимает объем всего лишь 1 килобайт памяти программ (flash). Он также не использует таймаут при приеме неправильных данных, поэтому Вам нужно убедиться, что в плату Arduino на основе ATmega8 не отправляется никаких данных в течение 6..8 секунд, пока активен загрузчик.
Некоторые древние версии загрузчика работают на скорости 9600 бод (вместо 19200). Такая скорость удобна для плат, у которых нет кварцевого резонатора для стабилизации тактовой частоты микроконтроллера. Чтобы код скетча успешно загружался в таких условиях, нужно поменять параметр serial.download_rate в файле настроек (preferences file) на 9600.
Примечание: правильный выбор скорости обмена через порт USART - основной принцип работы как загрузчика, так и всего программно-аппаратного комплекса Arduino IDE. В частности, загрузчик платы Arduino может работать и на более высоких скоростях - например загрузчик Arduino Mega 2560 работает на скорости 115200 бод. Поэтому если есть какие-то проблемы в работе загрузчика, попробуйте протестировать ряд наиболее часто используемых стандартных скоростей UART (9600, 19200, 38400, 57600, 115200). Еще лучше, если Вы сразу определите правильную скорость обмена загрузчика с помощью осциллографа - см. длительность импульсов бит данных на ножке TX микроконтроллера, при правильно настроенной скорости их длительность должна совпадать с длительностью импульсов бит данных на ножке RX.
Платы Arduino сторонних производителей также используют загрузчик. Следует заметить, что есть 3 основных разновидности загрузчика - Arduino UART, USBasp, Atmel DFU.
Arduino UART. Первая, используемая наиболее широко, применяет для передачи данных UART (так называемый загрузчик Arduino UART). Этот загрузчик давно используется совместно с традиционными микроконтроллерами AVR, у которых на борту нет аппаратуры интерфейса USB. Промежуточным интерфейсом для USB служит отдельный аппаратный блок на специальном чипе (мост USB - TTL USART, который смонтирован на многих платах Arduino, а на некоторых платах его нет, и приходится использовать отдельные переходники USB - TTL UART).
Продвинутый загрузчик, поставляемый с Arduino-совместимыми платами Wulfden Freeduino Kits. Его код основан на коде загрузчика Arduino UART. "Lady Ada", Limor Fried из Adafruit Industries, сделала множество исправлений и добавлений в код загрузчика с целью получения универсальности (код загрузчика работает в любой версии Arduino IDE, скетчи запускаются сразу после включения питания, скетчи запускаются сразу после загрузки). Последние ревизии Brian Riley унифицировали исходный код для микроконтроллеров ATmega168, ATmega328 и ATmega644, так что получился один файл исходного кода и один файл makefile. Добавлено мигание светодиодом pin 13 LED, показывающее процесс загрузки. Этот загрузчик можно использовать на старых, новых (и самостоятельно изготовленных) платах, как оборудованных, так и не оборудованных функцией автосброса (со средой разработки Arduino-0009 и платами Arduino Diecimilia).
Дополнительную информацию по изменениям кода загрузчика можно найти на сайте Lady Ada (см. Bootloader for the Atmega328 site:learn.adafruit.com). Исходный код ADABOOT можно загрузить на сайте разработчика (см. ADABOOT - an ATmega Arduino(tm) compatible bootloader site:wulfden.org), или в одном архиве [9].
USBasp. Это загрузчик, часто используемый на платах metaboard, неофициально (и не полностью, см. [3]) поддерживаемых средой разработки Arduino. Его достоинство в том, что не нужно использовать отдельный мост USB - TTL UART для подключения к USB на традиционных микроконтроллерах. Это упрощает и удешевляет схему, и плату metaboard легче собрать в домашних условиях.
Atmel DFU. С некоторых пор среда разработки Arduino начала поддержку плат, на которых установлен микроконтроллер AVR со встроенной аппаратурой USB. На таких платах также нет отдельного моста USB - TTL UART. Но загрузчик конечно другой, поддерживающий периферию USB AVR, и протокол загрузки кода USB DFU компании Atmel. К сожалению, исходный код оригинальных загрузчиков от Atmel закрыт, есть только бинарники. Однако, поскольку протокол DFU опубликован, имеется альтернативная версия загрузчика с открытым исходным кодом - в библиотеке LUFA.
Подробную информацию по различным загрузчикам см. в таблицах 4, 5, 6 (врезка "На что нужно обратить внимание при программировании загрузчика"), и 7 (раздел "Исходный код загрузчиков Arduino").
Чтобы записать загрузчик, Вам обязательно нужен внешний ISP-программатор [5]. Программатор подключается к программируемой платой Arduino через 6-выводный коннектор ISP [8], который обычно всегда установлен на плате Arduino. При подключении коннектора убедитесь, что он ориентирован правильным образом. Некоторые платы наподобие Arduino Mini требуют самостоятельного подключения коннектора проводами к контактам платы. Если есть сомнения при подключении, то обратитесь к схеме платы и её описанию.
Загрузчик можно записать прямо из среды разработки Arduino (Tools -> Burn Bootloader), перед этим нужно сначала выбрать тип программатора и тип платы в меню Tools.
Выбор загрузчика. Поскольку могут быть различные варианты реализации целевой системы - может быть применена разная модель микроконтроллера (ATmega168, ATmega328, ATmega32U4 и т. п.). Загрузчики для разных моделей микроконтроллеров могут быть несовместимыми друг с другом.
Частота кварцевого резонатора. Обязательно убедитесь, что прошиваемый Вами загрузчик точно соответствует рабочей частоте системы. Рабочая частота микроконтроллера обычно зависит от конфигурации фьюзов и от частоты внешнего кварцевого или керамического резонатора (чаще всего применяют кварцевые резонаторы на 8 или 16 МГц, но могут быть и другие варианты).
Фьюзы. Для правильного функционирования загрузчика важны 2 аспекта, которые конфигурируются фьюзами - выбор размера секции загрузки (фьюзы BOOTSZ1, BOOTSZ0), разрешение работы загрузчика (фьюз BOOTRST), а также конфигурирование тактовой частоты (фьюзы, управляющие генератором тактовой частоты и прескалером - CKDIV8, SUT1, SUT0, CKSEL3..0).
Если Вы неправильно прошьете фьюзы BOOTSZ1, BOOTSZ0, BOOTRST, то код загрузчика не будет запускаться, и загрузчик работать не будет. Точно также если Вы неправильно сконфигурируете фьюзами тактовый генератор и прескалер, то микроконтроллер может заработать на той частоте, на которую загрузчик не рассчитан, и работоспособность загрузчика также будет нарушена. Для вычисления правильного значения фьюзов Вам поможет калькулятор фьюзов [10].
В таблице я привел самые популярные загрузчики и конфигурации для них. Фьюзы указаны в шестнадцатеричном значении, где HFUSE это старший байт фьюзов, LFUSE младший байт фьюзов, EFUSE байт расширенных фьюзов.
Таблица 4. Загрузчики Arduino UART.
AVR
Тактовая частота
Прошивка
Размер секции загрузки, байт
Фьюзы (HEX)
ATmega8
8
ArduinoBOOT-mega8-8MHz.hex
1024
HFUSE=CA LFUSE=DF
16
ArduinoBOOT-mega8-16MHz.hex
ATmega168
8
ArduinoBOOT-mega168-8MHz.hex
2048
HFUSE=DD LFUSE=E2 EFUSE=00
16
ArduinoBOOT-mega168-16MHz.hex
ATmega328
8
ArduinoBOOT-mega328-8MHz.hex
2048
HFUSE=DA LFUSE=FF EFUSE=05
16
ArduinoBOOT-mega328-16MHz.hex
2048
Прошивки загрузчиков Arduino можно найти в папке, где установлена система разработки Arduino, обычно это папка с полным путем наподобие c:\Program Files\Arduino1.0.6\hardware\arduino\bootloaders. Там же можно найти исходный код загрузчиков. Также готовые прошивки и исходный код всех загрузчиков можете скачать по ссылке [9], см. папку arduino\bootloaders\HEX архива, и ищите там имена файлов прошивок, указанные в таблицах 4, 5, 6 (имя файла прошивки указано в столбце Прошивка).
Загрузчик (bootloader) - одна из основных вещей, что отличает Arduino от простого микроконтроллера AVR компании Atmel. Когда Вы собираете свою плату, или когда случайно купили на ebay плату, не прошитую загрузчиком, то Вам нужен внешний программатор ISP, чтобы прошить в память микроконтроллера загрузчик. Но когда Вы прошили загрузчик, то можно программатор ISP положить на полку - больше он не понадобится (за исключением каких-то специальных случаев), потому что дальше перешивать память программ микроконтроллера удобнее с помощью загрузчика.
Загрузчик [2] это по сути маленькая программа, предназначенная для только одной цели - перепрошить микроконтроллер программой пользователя. Загрузчик размещен в старших адресах пространства памяти программ (FLASH), а программа пользователя - в младших адресах (начиная с нулевого адреса). На рисунке показан типичный пример распределения памяти программ (FLASH) микроконтроллера ATmega328.
Примечание: если у Вас есть программатор ISP [5], то Вы можете настроить среду разработки Arduino так, чтобы использовать для загрузки именно программатор, а не bootloader. Достоинство такого метода загрузки в том, что Вы можете полностью задействовать всю доступную память программ (FLASH) микроконтроллера (потому что загрузчик уже не используется, и его область памяти программ свободна для использования).
Микроконтроллер Arduino сконфигурирован фьюзами так, чтобы при запуске системы (включение питания, сброс) управление всегда получал загрузчик. Затем загрузчик некоторое время ждет (1..2 секунды) загрузки программы пользователя, и если загрузка не началась, то запускает программу пользователя (передает управление на адрес 0). Таким образом, всегда можно при желании перезаписать программу пользователя, и тем самым обновить или полностью изменить функционал устройства. Код загрузчика при этом остается нетронутым.
Условие запуска загрузчика. Есть загрузчики, которые сразу передают управление в программу пользователя (без задержки), если не выполнено условие загрузки. Это иногда делается для того, чтобы ускорить запуск программы пользователя. Условие загрузки может быть разным, но чаще всего это перемычка, замыкающая на землю определенный (известный заранее пользователю) вывод микроконтроллера. Если перемычка установлена, то условие загрузки выполняется, и загрузчик ждет начала загрузки, не передавая управление в программу пользователя.
[Готовые прошивки загрузчика Arduino]
См. архив по ссылке [9] и таблицы 4, 5, 6 во врезке "На что нужно обратить внимание при программировании загрузчика".
[Исходный код загрузчиков Arduino]
В некоторых случаях может потребоваться перекомпиляция прошивки загрузчика - например, если Вы используете особую частоту кварца, или если Вам необходимо внести коррективы в поведение загрузчика. Оригинальный код загрузчиков можно найти на GitHub.
В таблице я привел описание самых популярных загрузчиков, которые используются в Arduino-совместимых платах. Исходный код загрузчиков вместе с готовыми прошивками также можно скачать по ссылке [9].
Таблица 7. Разновидности загрузчиков, которые можно использовать для платформы разработки Arduino.
Название
AVR
Описание
Arduino UART
ATmega8, ATmega168, ATmega328 и другие
Используется для большинства плат Arduino, когда код загружается через мост USB-UART.
Atmel DFU
ATmega32U4 и другие
Применяется для случаев, когда микроконтроллер AVR имеет на борту аппаратный интерфейс USB. Загрузчик основан на протоколе Atmel DFU Flip и открытой библиотеке LUFA.
USBasp
ATmega168, ATmega328
Применяется для плат metaboard. Загрузчик основан на открытой библиотеке V-USB, эмулирует поведение популярного программатора USBasp.
Как компилировать. Для компиляции Вам потребуется тулчейн AVR-GCC, доступный для большинства операционных систем - Linux, Mac OS, Windows. На операционной системе Windows тулчейн можно получить, если скачать и установить пакет WinAVR или среду разработки Atmel Studio.
Компилируется загрузчик командами утилиты make. Обычно для этого нужно зайти в каталог с исходным кодом загрузчика, и выполнить 2 команды:
make clean
make hex
После этого в текущем каталоге появится файл с расширением HEX - готовая прошивка загрузчика, которую нужно записать в память микроконтроллера с помощью обычного ISP-программатора [5] (не забудьте также правильно установить фьюзы микроконтроллера!).
Инструкции по компиляции и настраиваемым опциям можно обычно получить, изучая содержимое файла Makefile проекта загрузчика, и сопутствующие файлы документации readme.txt.
Процесс получения прошивки загрузчика состоит из предварительного конфигурирования Makefile, где настраиваются опции (если это необходимо) и последующей компиляции командами make clean и make. Конечно же, для компиляции у Вас должен быть установлен тулчейн (компилятор AVR GCC и библиотеки). На операционной системе Windows тулчейн можно получить, если установить пакет разработки WinAVR или Atmel Studio.
Когда нужно получить загрузчик для Arduino, то чаще всего (в зависимости от типа платы или Вашей конструкции) это микроконтроллер ATmega328, или реже ATmega168, ATmega8, ATmega32U4. Поэтому сначала нужно выбрать, какой загрузчик использовать. Почти все загрузчики можно найти в папке установки Arduino c:\Program Files\Arduino1.0.6\hardware\arduino\bootloaders, распределенные по подкаталогам atmega8, atmega и другим.
Выбор загрузчика. Если Вам нужен загрузчик для ATmega8, то его исходный код и Makefile находится в папке atmega8. Если нужен загрузчик для ATmega168 или ATmega328, то см. папку atmega. Если нужен загрузчик для ATmega32U4, то его можно найти в библиотеке LUFA, см. папку Bootloaders\DFU.
Примечание: исходный код и прошивки загрузчиков можно скачать по ссылке [9].
Конфигурирование загрузчика для ATmega8. Зайдите в папку atmega8, и откройте текстовым редактором файл Makefile. Вам нужно проверить следующие опции:
• DIRAVR. Эта опции указывают на каталог установки тулчейна (в этом каталоге находится папка bin с исполняемыми файлами для компилятора и других утилит, и папка include для заголовочных файлов библиотек). Если у Вас установлен тулчейн WinAVR, то значение этой опции должно быть наподобие c:\WinAVR-20100110\avr. Если у Вас установлен тулчейн в составе Atmel Studio, то значение этой опции должно быть наподобие "c:\Program Files\Atmel\AVR Tools\AVR Toolchain" (должны быть кавычки, потому что в составе пути есть пробелы).
• DEFS. В этой опции указана тактовая частота системы через значение макропеременной F_CPU. Например, если указана опция:
DEFS =-DF_CPU=8000000-DBAUD_RATE=19200
то это означает, что прошивка будет скомпилирована в расчете на тактовую частоту 8 МГц. 8 МГц обычно используется, если работает внутренний RC-генератор микроконтроллера AVR. Если у Вас используется другая тактовая частота, задаваемая внешним кварцевым резонатором, то укажите рядом с -DF_CPU= тактовую частоту в Герцах. Чаще всего используется тактовая частота 16 МГц, т. е. нужно указать -DF_CPU=16000000.
Примечание: важно указать правильную тактовую частоту потому, что к этому значению привязана настройка последовательного порта UART, через который загрузчик получает код от хоста (из системы разработки Arduino IDE с помощью вызова утилиты программирования AVRDUDE). Неправильная настройка UART приведет к тому, что загрузчик не сможет получить код программы пользователя, и микроконтроллер не будет перепрошиваться через загрузчик.
На этом конфигурирование загрузчика можно считать законченным. Для получения прошивки загрузчика осталось выполнить последовательность из двух команд:
make clean
make hex
После компиляции получится файл ATmegaBOOT.hex, который можно с помощью программатора ISP записать в память микроконтроллера ATmega8. Не забудьте после программирования загрузчика правильно установить фьюзы микроконтроллера (см. таблицу 4).
Конфигурирование загрузчика для ATmega168 или ATmega328. Зайдите в папку atmega, и откройте текстовым редактором файл Makefile. Здесь все устроено несколько сложнее, потому что этот Makefile универсальный, он предназначен для получения прошивок для множества различных плат Arduino:
Таблица 8. Выбор цели (target) в Makefile для ATmegaXX8.
Плата Arduino
Target
Arduino LilyPad
lilypad
Arduino Pro или Arduino Pro Mini
pro8, pro16 или pro20 в зависимости от используемой тактовой частоты
Arduino Diecimila
diecimila
Arduino NG
ng
Своя плата на ATmega328
atmega328
Arduino Pro на ATmega328P без кварца
atmega328_pro8
Arduino Mega
mega
Примечание: цель Target, указанная в таблице, подставляется как опция команды make при компиляции прошивки:
make clean make < тут надо указать Target >
Первое, что Вам нужно сделать, это выбрать цель для компиляции (вариант из столбца Target таблицы 6) в зависимости от платы, которая у Вас используется. Предположим, что у Вас самодельная плата на микроконтроллере ATmega328, для которой Вы собираетесь сделать свой загрузчик. Тогда цель для компиляции у Вас будет atmega328, прошивка получается выполнением 2 команд:
make clean
make atmega328
Если у Вас используется другая тактовая частота, то проверьте значение макропеременной AVR_FREQ (по умолчанию для цели atmega328 задана тактовая частота 16 МГц: AVR_FREQ = 16000000L). После компиляции получите прошивку ATmegaBOOT_168_atmega328.hex, которую можно записать в память Вашего микроконтроллера с помощью программатора ISP. Внимание, не забудьте также правильно установить фьюзы микроконтроллера (см. таблицу 4).
Для подключения к компьютеру недорогих плат наподобие Arduino Mini понадобится отдельный внешний переходник для моста USB - TTL UART.
Переходник USB TTL COM-port (он подключается с одной стороны к 6-pin коннектору FTDI, а с другой стороны к компьютеру по USB) можно купить готовый. Обычно такой переходник сделан по простейшей схеме на основе чипа FT232 (компания FTDI) или CP210x (компания Silicon Labs). Драйвер для переходника можно скачать с сайта соответствующей компании. Хорошие переходники USB to TTL Serial Cable FTDI (или на чипе CP210x) можно купить на eBay, dealextreme или aliexpress, есть даже предложения с бесплатной доставкой. При покупке выбирайте 5V версию (иногда бывают версии на 3.3V). Самый лучший вариант – когда можно выбрать перемычкой рабочие уровни порта TTL RS-232 (3.3V или 5V). Если уровни сигналов на переходнике USB to TTL и отлаживаемом устройстве не совпадают, то понадобятся последовательно включенные резисторы номиналом около 1…2 кОм.
Можете подсказать где почитать информацию если решили заливать прошивку не через среду Arduino IDE а через свое Windows приложение используя bootloader Arduino?
microsin: ответить на этот вопрос коротко невозможно, потому что существует множество способов организации загрузки, в зависимости от версии загрузчика и используемого микроконтроллера. Общий принцип следующий: у загрузчика Arduino имеется стандартный, открытый протокол (UART, STK, DFU, USBasp), поддерживаемый утилитами перепрошивки, такими как AVRdude, dfu-programmer.exe и т. п. В среде Arduino как раз такие утилиты и используются. Вам нужно узнать, какой протокол использует Ваш загрузчик, и в зависимости от этого подобрать к нему утилиту командной строки для поддержки загрузки. Или перепрошить загрузчик на тот, который нужен. Если информации в этой статье недостаточно, то поищите информацию по протоколу загрузчика, посмотрите информацию о протоколе в исходном коде загрузчика. Попробуйте прогуглить arduino bootloader command line utility.
ПРОГРАММАТОР у Arduino на борту! Я, как и Sergey, не понимаю, почему бортовой программатор не подключили по SPI (а подключили по UART), тогда можно было бы обойтись без загрузчика.
microsin: не могу точно утверждать, почему разработчики Arduino не поставили мост USB (например, на любом чипе FTDI) для прямого подключения к SPI. Вероятно они решили, что использовать загрузчик UART будет дешевле и практичнее с точки зрения использования ножек портов AVR. В самом деле - нужно по минимуму только 2 ножки порта для сигналов RX и TX (реализацию автосброса для входа в загрузчик не рассматриваем, так как это не обязательная опция). Кроме того, через те же самые ножки работает Монитор Arduino. Получается дешево и сердито. В случае использования прямого программирования через ISP/SPI понадобилось бы больше сигналов (ножек портов). Кроме того, микросхемы мостов FTDI довольно дороги, часто выгоднее поставить более дешевый чип, где реализован только USB-UART. По этой причине скорее всего было выбрано перепрограммирование через загрузчик.
Я вот что не могу понять про бутлоадеры. Вот берёшь просто AVR-контроллер (на макетке даже), к нему подключаешь программатор - и можешь прошивать микроконтроллер. Простым нажатие кнопки в Arduino-среде (при соотв. настройке).
Теперь берём плату Arudino Uno, например. На ней для связи по USB установлен микроконтроллер AVR'овский, наверняка где-то такой же, как в программаторе. Но при этом для прошивки платы Arduino Uno еще нужен вдруг bootloader для самопрограммирования контроллера. Но зачем? Почему? Ведь только что мы прошивали контроллер программатором без всякого bootloader'а. Интерфейсная м/с на Arduino Uno не такая, как программатор? Но опять же не понятно зачем и почему? Вот что никак не могу понять.
microsin: нечего тут особенно понимать. Плата Arduino и вся её платформа (в том числе и bootloader применен для той же цели, и дополнительная микросхема) спроектирована таким образом, чтобы пользователь мог сразу, из коробки, программировать AVR-микроконтроллер БЕЗ ПРОГРАММАТОРА. Имея только USB и компьютер.
Комментарии
microsin: ответить на этот вопрос коротко невозможно, потому что существует множество способов организации загрузки, в зависимости от версии загрузчика и используемого микроконтроллер а. Общий принцип следующий: у загрузчика Arduino имеется стандартный, открытый протокол (UART, STK, DFU, USBasp), поддерживаемый утилитами перепрошивки, такими как AVRdude, dfu-programmer.exe и т. п. В среде Arduino как раз такие утилиты и используются. Вам нужно узнать, какой протокол использует Ваш загрузчик, и в зависимости от этого подобрать к нему утилиту командной строки для поддержки загрузки. Или перепрошить загрузчик на тот, который нужен. Если информации в этой статье недостаточно, то поищите информацию по протоколу загрузчика, посмотрите информацию о протоколе в исходном коде загрузчика. Попробуйте прогуглить arduino bootloader command line utility.
microsin: не могу точно утверждать, почему разработчики Arduino не поставили мост USB (например, на любом чипе FTDI) для прямого подключения к SPI. Вероятно они решили, что использовать загрузчик UART будет дешевле и практичнее с точки зрения использования ножек портов AVR. В самом деле - нужно по минимуму только 2 ножки порта для сигналов RX и TX (реализацию автосброса для входа в загрузчик не рассматриваем, так как это не обязательная опция). Кроме того, через те же самые ножки работает Монитор Arduino. Получается дешево и сердито. В случае использования прямого программировани я через ISP/SPI понадобилось бы больше сигналов (ножек портов). Кроме того, микросхемы мостов FTDI довольно дороги, часто выгоднее поставить более дешевый чип, где реализован только USB-UART. По этой причине скорее всего было выбрано перепрограммиро вани е через загрузчик.
Теперь берём плату Arudino Uno, например. На ней для связи по USB установлен микроконтроллер AVR'овский, наверняка где-то такой же, как в программаторе. Но при этом для прошивки платы Arduino Uno еще нужен вдруг bootloader для самопрограммиро вания контроллера. Но зачем? Почему? Ведь только что мы прошивали контроллер программатором без всякого bootloader'а. Интерфейсная м/с на Arduino Uno не такая, как программатор? Но опять же не понятно зачем и почему? Вот что никак не могу понять.
microsin: нечего тут особенно понимать. Плата Arduino и вся её платформа (в том числе и bootloader применен для той же цели, и дополнительная микросхема) спроектирована таким образом, чтобы пользователь мог сразу, из коробки, программировать AVR-микроконтроллер БЕЗ ПРОГРАММАТОРА. Имея только USB и компьютер.
RSS лента комментариев этой записи