Загрузчик (bootloader) - одна из основных вещей, что отличает Adruino от простого микроконтроллера AVR компании Atmel. Когда Вы собираете свою плату, или когда случайно купили на ebay плату, не прошитую загрузчиком, то Вам нужен внешний программатор ISP, чтобы прошить в память микроконтроллера загрузчик.
Загрузчик это по сути маленькая программа, предназначенная для только одной цели - перепрошить микроконтроллер программой пользователя. Загрузчик размещен в старших адресах пространства памяти программ (FLASH), а программа пользователя - в младших адресах (начиная с нулевого адреса). На рисунке показан типичный пример распределения памяти программ (FLASH) микроконтроллера ATmega328.
Микроконтроллер Arduino сконфигурирован фьюзами так, чтобы при запуске системы (включение питания, сброс) управление всегда получал загрузчик. Затем загрузчик некоторое время ждет (1..2 секунды) загрузки программы пользователя, и если загрузка не началась, то запускает программу пользователя (передает управление на адрес 0). Таким образом, всегда можно при желании перезаписать программу пользователя, и тем самым обновить или полностью изменить функционал устройства. Код загрузчика при этом остается нетронутым.
Условие запуска загрузчика. Есть загрузчики, которые сразу передают управление в программу пользователя (без задержки), если не выполнено условие загрузки. Это иногда делается для того, чтобы ускорить запуск программы пользователя. Условие загрузки может быть разным, но чаще всего это перемычка, замыкающая на землю определенный (известный заранее пользователю) вывод микроконтроллера. Если перемычка установлена, то условие загрузки выполняется, и загрузчик ждет начала загрузки, не передавая управление в программу пользователя.
[На что нужно обратить внимание при программировании загрузчика]
Выбор загрузчика. Поскольку могут быть различные варианты реализации целевой системы - может быть применена разная модель микроконтроллера (ATmega168, ATmega328, ATmega32U4 и т. п.). Загрузчики для разных моделей микроконтроллеров могут быть несовместимыми друг с другом.
Частота кварцевого резонатора. Обязательно убедитесь, что прошиваемый Вами загрузчик точно соответствует рабочей частоте системы, разная частота кварцевого резонатора (обычно 8 или 16 МГц, но могут быть и другие варианты). Рабочая частота микроконтроллера обычно зависит от конфигурации фьюзов и частоты внешнего кварцевого или керамического резонатора.
Фьюзы. Для правильного функционирования загрузчика важны 2 аспекта, которые конфигурируются фьюзами - выбор размера секции загрузки (фьюзы BOOTSZ1, BOOTSZ0), разрешение работы загрузчика (фьюз BOOTRST), а также конфигурирование тактовой частоты (фьюзы, управляющие генератором тактовой частоты и прескалером - CKDIV8, SUT1, SUT0, CKSEL3..0).
Если Вы неправильно прошьете фьюзы BOOTSZ1, BOOTSZ0, BOOTRST, то код загрузчика не будет запускаться, и загрузчик работать не будет. Точно также если Вы неправильно сконфигурируете фьюзами тактовый генератор и прескалер, то микроконтроллер может заработать на той частоте, на которую загрузчик не рассчитан, и работоспособность загрузчика также будет нарушена. Для вычисления правильного значения фьюзов Вам поможет калькулятор фьюзов [6].
В таблице я привел самые популярные загрузчики и конфигурации для них. Фьюзы указаны в шестнадцатеричном значении, где 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 (имя файла прошивки указано в столбце Прошивка).
Таблица 5. Загрузчики Atmel DFU.
AVR |
Тактовая частота |
Прошивка |
Размер секции загрузки, байт |
Фьюзы (HEX) |
ATmega32U4 |
8 |
BootloaderDFU-mega32u4-8MHz.hex |
4096 |
HFUSE=D8 LFUSE=DE EFUSE=F3 |
16 |
BootloaderDFU-mega32u4-16MHz.hex |
Таблица 6. Загрузчики USBasp.
AVR |
Тактовая частота |
Прошивка |
Размер секции загрузки, байт |
Фьюзы (HEX) |
ATmega168 |
12 |
USBaspLoader-mega168-12MHz.hex |
2048 |
HFUSE=D6 LFUSE=DF EFUSE=00 |
16 |
USBaspLoader-mega168-16MHz.hex |
20 |
USBaspLoader-mega168-20MHz.hex |
ATmega328 |
12 |
USBaspLoader-mega328-12MHz.hex |
HFUSE=DA LFUSE=F7 EFUSE=03 |
16 |
USBaspLoader-mega328-16MHz.hex |
20 |
USBaspLoader-mega328-20MHz.hex |
[Исходный код загрузчиков]
В некоторых случаях может потребоваться перекомпиляция прошивки загрузчика - например, если Вы используете особую частоту кварца, или если Вам необходимо внести коррективы в поведение загрузчика.
В таблице я привел описание самых популярных загрузчиков, которые используются в 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 команды:
После этого в текущем каталоге появится файл с расширением HEX - готовая прошивка загрузчика, которую нужно записать в память микроконтроллера с помощью обычного ISP-программатора (не забудьте также правильно установить фьюзы микроконтроллера!).
Инструкции по компиляции и настраиваемым опциям можно обычно получить, изучая содержимое файла Makefile проекта загрузчика, и сопутствующие файлы документации readme.txt.
[Пример конфигурирования загрузчика Arduino UART]
Процесс получения прошивки загрузчика состоит из предварительного конфигурирования 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 приведет к тому, что загрузчик не сможет получить код программы пользователя, и микроконтроллер не будет перепрошиваться через загрузчик.
На этом конфигурирование загрузчика можно считать законченным. Для получения прошивки загрузчика осталось выполнить последовательность из двух команд:
После компиляции получится файл 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).
Комментарии
Ах да, это наверное Вы не сами писали, а попросту взяли чье-то лучшее из лучших решений, ну чтоб самокат с овальными колесами не изобретать, да и работодатель привык шлак продавать...
microsin: откуда столько злости, товарищ дорогой? =)
Те, кто "просто тупо выполняют свою работу" лучше бы работали дворниками. Так как разработчик со своими библиотеками несет полностью за них ответственность , а 'тупо выполняющие работу' с какого-то перепуга решили, что другие сделают за них работу качественно и оптимально для их задач. При этом пытаются чему-то учить еще ответственных.
И да, можно сказать, что нельзя изобретать велосипед, никто не будет разбираться в ваших каракулях. Только одна поправка - никто из шаблонщиков, нормальному специалисту плевать какой код, на то он и специалист чтобы в нем разбираться.
Да и разобрать чужой код настолько, чтобы подписаться за его корректность стоит усилий не меньше чем разработать свое.
И не надо про стадо хомячков, которые его уже оттестировали, мухи тоже не ошибаются.
А из софта на стороне РС что посоветуете? avrdude?
Чтобы на него gui затем навесить.
По сценарию: заказчик подсоединил устройство, запустил программу обновления софта, нажал кнопку "ОК" и устройство прошилось?
microsin: да, avrdude лучше всего. Над ним оболочка есть, avrdude-gui. Если используете загрузчик USBasp, то также подойдут GUI-утилиты Khazama 1.6.2 и eXtreme Burner.
Я, пожалуй, большей глупости, чем эта, еще не слыхивал... Пишу на чистом асме для AVR уже 10 лет (писал и TCP-UDP), и всегда стараюсь все писать свое - в этом и прелесть контроллера - за все можешь отвечать сам. И как же найти загрузчик с шифрованием прошивки, что бы передавать своим клиентам новые версии без возможности копипаста вашего устройства, а?
microsin: это Ваш выбор - тратить или нет собственные усилия на изобретение велосипеда. Ведь многие программируют не то чтобы для собственного удовольствия, как Вы, например, а просто тупо выполняют порученную работу, т. е. решают поставленную задачу максимально эффективно. А когда и стеки TCP, и и библиотеки для шифрования, и многое-многое другое - уже есть на блюдечке с голубой каемочкой - никто в здравом уме не решится тратить впустую драгоценное рабочее время.
microsin: думаю, Вам нужно взять за основу бутлоадер для COM-порта (RS232, USART) и немножко его доработать, чтобы переключалось направление передачи данных. Бутлоадер RS232 для AVR найти не проблема.
microsin: вариантов решения проблемы запуска бутлоадера множество, и метод реализации запуска зависит целиком от Вашей фантазии. Просто придумайте, как Вы хотели бы, чтобы бутлоадер стартовал - и просто сделайте это, благо исходники бутлоадеров есть, и поменять их поведение достаточно просто. Стандартное решение - добавление в протокол обмена USB-устройства специальной команды, которая запускает бутлоадер. Тогда никакая перемычка не нужна.
microsin: к сожалению, такой бутлоадер пока не попадался. Если попадется, то обязательно будет его перевод или обзор. Теоретически такой бутлоадер можно реализовать самому, так как все основные части - протокол STK200 (или STK500) и класс CDC, реализованный на библиотеке V-USB, уже есть готовые в исходниках. Вот, кстати, хороший кандидат для переделки под V-USB - http://www.siwawi.arubi.uni-kl.de/avr_projects/index.html#avrprog_boot . Код хорошо документирован, и может быть легко портирован на V-USB. Основная проблема только в том, чтобы уместить получившийся код в секцию бутлоадера. Наверняка он влезет в boot-секцию только начиная с ATmega32.
И все же, субъективно: загрузчик лучше писать самостоятельно.
microsin: по поводу компилятора - Вы правы, если не задумываться от том, что НА САМОМ ДЕЛЕ хотели спросить. А в остальном... Все в этом мире с точки зрения человека субъективно. В том числе, с моей точки зрения - загрузчику лучше ничего не запрещать, а сделать его как можно тупее и меньше по размеру. И опять же, субъективно - bootloader для AVR НИ В КОЕМ СЛУЧАЕ НЕ НАДО ПИСАТЬ САМОСТОЯТЕЛЬНО, поскольку лучше, чем уже уже понаписано (причем столько, что не разгребете), Вы никогда не напишете.
RSS лента комментариев этой записи