Загрузчики (bootloader) для микроконтроллеров AVR Печать
Добавил(а) microsin   

Описана технология bootloader, встроенная во все микроконтроллеры Atmel AVR семейства ATmega. Материал для статьи взят с сайта scienceprog.com.

Возможно, что самый удобный и правильный метод программирования микроконтроллера - использовать программу бутлоадера. Поскольку Вам не надо использовать специальные адаптеры для программирования или специальные знания – нужно просто подключить стандартный кабель от Вашего PC к целевой плате и запустить на PC специальную программу, которая соединяется с программой бутлоадера, записанной в микроконтроллере. Идея проста:

avr_bootloader_model.jpg

Если микроконтроллер после сброса предварительно переконфигурирован (если установлены определенные фьюзы), он стартует не с адреса 0x0000, а со специального адреса, в котором обычно располагается bootloader. На диаграмме condition - это условие загрузки, которое определяется обычно опросом состояния специальной внешней перемычки, подключенной к ножке микроконтроллера.

Все микроконтроллеры семейства AVR ATmega имеют возможность запрограммировать bootloader в старшие адреса адресного пространства. Адрес старта программы зависит от установок внутренних перемычек чипа AVR (fuse settings). Если установки указывают стартовать с другого адреса, то после сброса программный счетчик переставляется на секцию бутлоадера, и тогда первым выполняется bootloader. Бутлоадеры могут иметь различный размер и использовать разные алгоритмы и интерфейсы, через которые будет загружаться основная программа. Источниками для загрузки могут быть карты Flash (MMC/SD), I2C, USART (COM-порт или RS232), SPI и USB. Условие для загрузки может быть получено, например, путем опроса специальной внешней перемычки, или наличием на карте памяти MMC/SD специального файла с прошивкой.

[USB bootloader]

Несомненно, самый удобный для пользователя интерфейс загрузки - USB. Этот интерфейс очень популярен, работает на всех операционных системах. Но протокол USB довольно сложен, поэтому встраивание bootloader в микроконтроллер, не имеющий аппаратной поддержки USB, потребует значительного объема кода (до 2 килобайт). Наиболее распространена программная реализация протокола USB от компании Objective Development - V-USB [6]. Есть также другая программная реализация - USBtiny [7].

Для микроконтроллеров AVR с аппаратным интерфейсом USB (например, AT90USB162) компания Atmel предлагает фирменные загрузчики по USB. Некоторые микроконтроллеры поставляются с завода с уже прошитым в память загрузчиком (например, все тот же AT90USB162). Технологии, применяемые для такого bootloader, называются DFU и Flip. Подробнее см. [5].

[Разнообразие бутлоадеров для AVR]

Многие AVR bootloader используют COM-порт для соединения с PC. Это хорошо работает, если используется аппаратный мост USB-USART. Если пишется бутлоадер самостоятельно, то не факт, что он сразу заработает. Обязательно потребуется отладка, и внимательное чтение документации на микроконтроллер. В списке можно увидеть уже готовые популярные бутлоадеры, которыми можно воспользоваться (список может быть и бОльшим):
    * Atmex site:ladyada.net, COM, 19200bps, Assembler; JAvrProg(Java), ATtiny2313 (8-16Mhz);
    * AVR Bootloader Programmer Peter Dannegger site:mikrocontroller.net, COM, Assembler; ATmega8/16/32/128;
    * AVRProg-compatible Bootloader Martin Thomas site:siwawi.arubi.uni-kl.de, COM, WinAVR (C); AVRProg; Various AVRs and speeds;
    * USBisp Bootloader Matthias Weisser site:matwei.de, USB, COM, AVR-GCC(C); AVRProg; STK-500; ATmega8, FT245BM;6MHz;
    * Bootloader ATmega8 AVR microprocessor site:stratoserver.net, COM, 19200bps, ASM, AVRProg;ATmega8 7.3728MHz;
    * Chip45boot site:chip45.com, COM, 11500bps, WinAVR; HyperTerminal; Various AVR
    * STK500-Bootloader Pascal Stang, COM, Hex; AVRProg; STK500; ATmega8-128; 7.3 – 22.1MHz
    * AVR109 (AVR Butterfly) site:atmel.com, COM, IAR(C); ATmega series; 12MHz;
    * AVRUSBBoot - USB bootloader for Atmel AVR controllers site:fischl.de, USB, AVR-GCC; ATmega8(other Megas); 12MHz;
    * Megaload site:microsyl.com, COM, 11500bps, ICCAVR(C); Megaload.NET; Various AVR;
    * BootloadHID site:obdev.at, USB, HID, WinAVR; ATmega8;
    * Crypto-Boot site:wikidot.com, USB, IAR(C); Crypted AES; ATmega32; 12MHz.

Большинство бутлоадеров рассчитано на COM-порт, который уже устарел и в современных компьютерах встречается редко. Наиболее простой способ адаптировать эти бутлоадеры на USB - использование аппаратного моста USART <-> USB типа FT245BM. Но вероятно более удобно, когда USB подключен непосредственно к микроконтроллеру, и часть коммуникации бутлоадера сделана драйвером USB встроенного программного обеспечения.

Загрузчик (bootloader) - одна из основных вещей, что отличает Adruino от простого микроконтроллера AVR компании Atmel. Когда Вы собираете свою плату, или когда случайно купили на ebay плату, не прошитую загрузчиком, то Вам нужен внешний программатор ISP, чтобы прошить в память микроконтроллера загрузчик.

Загрузчик это по сути маленькая программа, предназначенная для только одной цели - перепрошить микроконтроллер программой пользователя. Загрузчик размещен в старших адресах пространства памяти программ (FLASH), а программа пользователя - в младших адресах (начиная с нулевого адреса). На рисунке показан типичный пример распределения памяти программ (FLASH) микроконтроллера ATmega328.

Arduino-ATmega328-Bootloader-Memory-Map

Микроконтроллер 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 команды:

make clean
make hex

После этого в текущем каталоге появится файл с расширением 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 приведет к тому, что загрузчик не сможет получить код программы пользователя, и микроконтроллер не будет перепрошиваться через загрузчик.

На этом конфигурирование загрузчика можно считать законченным. Для получения прошивки загрузчика осталось выполнить последовательность из двух команд:

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).

[Ссылки]

1. AVR-USB-MEGA16: USB bootloader BootloadHID для микроконтроллера ATmega16.
2. AVR-USB-MEGA16: USB bootloader USBasp для микроконтроллера ATmega32.
3. Atmel AVR231: AES Bootloader.
4. Atmel AVR230: DES Bootloader.
5. Макетная плата AVR-USB162.
6. V-USB site:obdev.at.
7. USBtiny site:dicks.home.xs4all.nl.
8. USB bootloader Micronucleus.
9150117arduino-bootloaders.zip - исходный код и готовые прошивки загрузчиков Arduino.