DIY
5 July 2010

USB bootloader для микроконтроллеров AVR

В статье описывается, как быстро запустить USB bootloader для микроконтроллера ATmega32 на примере загрузчика usbasploader компании Objective Development.

Технология USB bootloader дает одну-единственную возможность — отсутствие необходимости в специальном программаторе для замены программного обеспечения (firmware) в приборе — достаточно подключения к компьютеру по USB. Больше нет необходимости таскать с собой программатор, так как компьютер и USB есть везде. Если Ваша макетная плата оснащена bootloader, то можно сэкономить деньги на покупке программатора или время на его изготовлении — это бывает немаловажно для начинающих.

Для AVR понаделано очень много bootloader-ов — см. [1]. Для статьи я выбрал именно usbasploader [2] потому, что он совместим с очень популярным программатором USBasp. Это позволяет перепрошивать firmware как под Linux, так и под Windows с использованием популярных программ (см. [3]) avrdude, eXtreme Burner — AVR, Khazama AVR Programmer и даже из среды программирования BASCOM-AVR (система программирования на бейсике BASCOM-AVR — маленькое чудо, достойное отдельной статьи). Кроме того, usbasploader поставляется со всеми исходниками, отлично задокументирован и легко адаптируется под нужды пользователя (об этом далее).

Загрузчик usbasploader работает очень просто — при подключении к USB он прикидывается программатором USBasp. Поэтому все программы, его поддерживающие, будут перезаписывать firmware в Вашем устройстве, как будто они используют программатор USBasp. Bootloader расположен в старших адресах flash-памяти программ микроконтроллера, и записывает программу пользователя в младшие адреса (обычно начиная с адреса 0), т. е. при перепрошивке микроконтроллера bootloader не затирается. После окончания записи bootloader передает управление программе пользователя. Теперь подробнее, как это работает с микроконтроллерами ATmega, на примере ATmega32.

Для ATmega32 usbasploader скомпилирован так, чтобы он размещался во flash с адреса 7000h (напомню, что адресное пространство памяти программ ATmega32 составляет 0000h..7FFFh, и адрес команды кратен двум байтам, т. е. адреса команд лежат в диапазоне 0000h..37FFh). Для программы пользователя остается свободным пространство 0000h..6FFFh (28672 байт). Загрузчик usbasploader использует заложенную в микроконтроллер ATmega32 возможность запуска с адреса, расположенного в старших адресах памяти программ (доступно несколько фиксированных адресов, выбираемых перемычками — фьюзами, см. [4]). Чтобы при включении питания и сбросе управление всегда передавалось на адрес 0x7000, необходимо запрограммировать перемычки (фьюзы, fuse-bits) BOOTSZ0 и BOOTSZ1 в соответствующее состояние (под bootloader должно отводиться 4000h байт, или 2048 слов кода программы), а также запрограммировать перемычку BOOTRST. После этого код при сбросе или включении будет стартовать не с адреса 0, а с адреса 3800h в словах команд AVR, или с адреса 7000h в байтах flash (напомню, что минимальный размер команды AVR — два байта).

Получив управление после сброса, код usbasploader проверяет условие своей активизации, т. е. сигнал, по которому он должен начать работать как программатор USBasp. Обычно таким сигналом является замыкание какой-нибудь ножки на землю. Для макетной платы в качестве такой ножки я выбрал PB5 микроконтроллера ATmega32. Эта ножка является одновременно и сигналом MOSI, выведенным на коннектор, поэтому перемычкой между контактами 4 и 6 коннектора U1 ISP очень удобно подавать на PB5 сигнал лог. 0. Итак, код usbasploader проверяет уровень на порте PB5, и если там лог. 0 (перемычка между ножками 4 и 6 коннектора U1 ISP установлена), то начинается работа как программатора USBasp. Т. е. при установленной перемычке в момент включения питания bootloader активизируется, и если его подключить к компьютеру, то в компьютере появится USB-устройство USBasp. Если в момент включения питания перемычки нет (при этом на PB5 микроконтроллером читается лог. 1), то usbasploader сразу передает управление в программу пользователя (на адрес 0). Вот такой нехитрый алгоритм запуска.

В usbasploader есть возможность изменить поведение bootloader, для этого достаточно отредактировать три функции (они очень простые, и находятся в файле bootloaderconfig.h) — bootLoaderInit, bootLoaderCondition, bootLoaderExit. Назначение функций практически очевидно по названиям. Функция bootLoaderInit предназначена для конфигурирования окружения, в котором возможно отслеживание условие активизации bootloader:
static inline void bootLoaderInit(void) <br>{<br>    DDRB |= (1 << PB0);  //выход для красного светодиода<br>    //на PB5 (MOSI, контакт 4 коннектора U1 ISP) подключаем pull-up и зажигаем светодиод<br>    PORTB |= (1 << PB5)|(1 << PB0);  <br>}

Код очень прост — он только подключает на ножку PB5 подтягивающий к плюсу внутренний нагрузочный резистор (pull-up) — это позволяет определить наличие перемычки между контактами 4 и 6 коннектора U1 ISP, и зажигает красный светодиод на макетке. Функция bootLoaderCondition предназначена для проверки — есть или нет перемычка между контактами 4 и 6:
static inline uint8_t bootLoaderCondition() <br>{<br>    if (!(PINB & (1 << PB5))) <br>    {<br>        return 1;<br>    } <br>    else <br>    {<br>        // no boot loader<br>        return 0;<br>    }<br>}
Если перемычка стоит, то ножка PB5 читается как лог. 0, и функция bootLoaderCondition вернет 1 (что означает — bootloader работает). Если перемычки нет, то функция вернет 0, что означает неактивность для bootloader (управление немедленно передается по адресу 0 — в программу пользователя). Функция bootLoaderExit у меня не делает ничего, только гасит красный светодиод макетки:
static inline void bootLoaderExit(void) <br>{<br>    PORTB &= ~(1 << PB0);  //гасим светодиод<br>}

Приведенный код для функций bootLoaderInit, bootLoaderCondition, bootLoaderExit можно рассматривать в качестве примера — их можно и нужно переделать под Ваши нужды, и тогда usbasploader будет работать именно так, как Вы хотите. В заключение опишу процесс по шагам на платформе Windows (предполагается, что у Вас уже установлены AVRStudio и среда WinAVR. Если нет — читайте инструкции, как их установить, по ссылке [6]).

[Как встроить в Ваш проект usbasploader]

1. Нужно скачать последнюю версию usbasploader (см. [2]), например USBaspLoader.2009-03-20.zip. Если у Вас макетная плата AVR-USB-MEGA16, то предлагаю скачать вариант по ссылке [5] — там уже все готово, и шаги 2, 3, 4 можно пропустить. Распаковываете в любую удобную папку.

2. Отредактируйте установки в Makefile. Там нужно поменять:
а) определение F_CPU — частоту в Гц, на которой работает микроконтроллер. Домустимы частоты 12, 15, 16, 16.5 и 20 МГц.
б) определение DEVICE под Ваш тип микроконтроллера.
в) адрес (формат шестнадцатеричный, единицы в байтах) загрузки кода usbasploader BOOTLOADER_ADDRESS.
г) (необязательно, если Вы будете прошивать чип не из Makefile) проверить и при необходимости скорректровать определения FUSEOPT и LOCKOPT, а также определение AVRDUDE.

3. Отредактируйте bootloaderconfig.h. Там нужно проверить и при необходимости поменять:
а) макрос USB_CFG_IOPORTNAME — буква имени порта, к которому подключены сигналы USB D- и D+.
б) макросы USB_CFG_DMINUS_BIT и USB_CFG_DPLUS_BIT — номера портов, которым подключены сигналы D- и D+. Сигнал D+ обязательно должен быть подключен на ножку прерывания INT0.
в) код функций bootLoaderInit, bootLoaderExit и макрос bootLoaderCondition.

4. Перекомпилируйте проект, для этого введите make. В командной строке увидите что-то наподобие:

image

После успешной компиляции получите в корневой папке проекта файлы main.bin и main.hex — готовая прошивка для usbasploader. Кстати, в папке hexfiles уже есть несколько скомпилированных версий прошивок для кристаллов ATmega8, ATmega88, ATmega168, на разные частоты кварца.

5. Необходимо с помощью программатора прошить в чип код usbasploader, правильно установить фьюзы. Смысл этой операции — код usbasploader необходи��о положить в верхнюю область памяти (по адресу BOOTLOADER_ADDRESS), и установить фьюзы таким образом, чтбы при сбросе или включении питания начал выполняться код bootloader (я уже об этом писал). Подробности по фьюзам см. по ссылке [4] и в даташите на Ваш микроконтроллер. Для микроконтроллера ATmega32, например, фьюзы должны быть установлены следующим образом:
LOW FUSE BYTE: 0xCF
HIGH FUSE BYTE: 0xD8 (можно и 0x98, чтобы разрешить JTAG-отладку)
LOCKOPT BYTE: 0xEF

Макетную плату AVR-USB-MEGA16 можно приобрести с уже прошитым usbasploader и фьюзами, поэтому шаги 1, 2, 3, 4, 5 проделывать не нужно.

6. Необходимо подключить прошитую макетную плату к компьютеру по USB. Если ничего не напутали, то макетка определится в системе как новое устройство и система Windows запросит драйвер. Драйвер можно скачать со странички [2], или взять из архива по ссылке [5]. Для Linux драйвер не нужен.

7. Нужна одна из программ, работающих с программатором USBasp (см. ссылки [3]). Для пользователей Linux подойдет avrdude, а для пользователей Windows выбор очень широк. Я рекомендую Khazama AVR Programmer с очень простым и удобным интерфейсом.

image

image

[Как работать с загрузчиком usbasploader на примере макетки AVR-USB-MEGA16 и Khazama AVR Programmer]

1. Поставьте перемычку между ножками 4 и 6 коннектора U1 ISP.
image

2. Подключите макетную плату к компьютеру по USB. На макетке загорится красный светодиод, и в системе Windows обнаружится программатор USBasp.

3. Запустите программу Khazama AVR Programmer. В настройках уберите опцию очистки памяти кристалла (Command -> Program Options -> снимите галку Erase Chip). Выберите из выпадающего списка Ва�� чип. Загрузите hex-файл прошивки (через меню File -> Load FLASH file to Buffer). Нажмите большую кнопку Auto Program, запускающую программирование. Программируется кристалл очень быстро, за несколько секунд.
image
После окончания программирования красный светодиод погаснет, и начнет выполняться Ваша программа с адреса 0 (которую Вы только что записали).

4. Снимите перемычку между ножками 4 и 6 коннектора U1 ISP.
image

UPD100711: написал статью про другой USB bootloaderBootloadHID. По исходному коду и стилю работы очень похож на USBASPloader. Отличается тем, что требует специальной программы на компьютере, но зато легче встраивается в младшие чипы (начиная с ATmega8), т. к. снижены требования к размеру bootloader-секции.

[Ссылки]

1. Загрузчики (bootloader) для микроконтроллеров AVR.
2. Домашняя страничка usbasploader.
3. Программы для работы с программатором USBasp — AVRDUDE, BASCOM-AVR, Khazama AVR Programmer, eXtreme Burner- AVR.
4. Engbedded Atmel AVR&reg; Fuse Calculator — калькулятор перемычек для AVR.
5. Мой вариант usbasploader, заточенный под макетную плату AVR-USB-MEGA16 с микроконтроллером ATmega32 (проект для AVRStudio с исходниками и скомпилированными вариантами для кварцев 12 МГц, 16 МГц).
6. Разработка устройства USB — как начать работу с библиотеками AVR USB (V-USB) и libusb.
7. Бутлоадер USBasp с XOR-шифрованием.

+46
44.9k 109
Comments 42