Микроконтроллеры AVR — BLOGS-IT.RU http://www.blogs-it.ru Компьютеры и электроника: о разработке программного обеспечения Mon, 06 May 2013 06:15:20 +0000 ru-RU hourly 1 https://wordpress.org/?v=4.7.5 Использование AVR JTAGICE3 в среде AVR Studio 5 http://www.blogs-it.ru/mikrokontrollery-avr/ispolzovanie-avr-jtagiceiii-v-srede-avr-studio-5/ http://www.blogs-it.ru/mikrokontrollery-avr/ispolzovanie-avr-jtagiceiii-v-srede-avr-studio-5/#comments Tue, 18 Sep 2012 08:19:21 +0000 http://www.blogs-it.ru/?p=415 Данный материал также актуален и для ATMEL Studio 6.

После того как вы подключите к компьютеру программатор AVR JTAGICE3 и установите драйверы в среде разработки AVR Studio 5 (или ATMEL Studio 6) у вас появится возможность использовать в качестве отладчика это замечательное устройство. В данной статье я предоставил информацию о том как начать использовать данный отладчик и понять как он работает. Имея опыт работы с этим устройством я обнаружил ряд особенностей, которые, лично у меня, поначалу сеяли ряд сомнений относительно того насколько JTAGICE3 адекватен собственной стоимости (ведь он достаточно дорогой и хочется ждать от него гораздо большего). Но сомнения эти, в общем, со временем улетучились и на данный момент я полностью доволен этим устройством, а чтобы у вас не создавалось подобных сомнений хочу поделиться данным материалом.

Итак, если вы уже уверены, что вас устраивает именно JTAGICE3 (см. характеристики AVR JTAGICE3) или если вы еще сомневаетесь в этом можем приступать.

Начало использования AVR JTAGICE3

Примечание: когда опрос включен в запись, пожалуйста

Первым делом, конечно, рассмотрим процедуру настройки данного устройства в среде разработки. В данной статье в качестве среды разработки я имею ввиду среду AVR Studio 5, но сразу хочу отметить, что более свежая версия этой среды под названием ATMEL Studio 6 практически ничем не отличается от пятой версии в плане работы с отладчиками и, поэтому все сказанное здесь также будет актуально и для шестой версии среды разработки.

Также отмечу, что программатор в нашем случае будет более корректно называть отладчик, т.к. во-первых, функция отладки у этого устройства является его основным достоинством (возможно, ради которого мы на него и запали), а во-вторых, будем придерживаться терминологии, принятой в среде разработки, где он называется Debugger.

Итак, рассмотрим первый этап:

Создание тестового проекта в AVR Studio

Если у вас уже имеется проект, то вы можете просто пропустить этот пункт и произвести дальнейшие действия на вашем проекте. Если вы еще не создавали ни одного проекта AVR Studio я распишу как это сделать, потому что хоть это и может быть кому-то смешно, но пытаясь опробовать отладчик JTAGICE3 я долго не мог разобраться как создать новый пустой проект в AVR Studio, даже несмотря на то что я с оболочкой Microsoft Visual Studio, на которой основана AVR Studio работаю уже более 10 лет.

Создадим тестовый проект в среде разработки. Пусть это будет пустой проект — выбираем в меню Файл->Создать->Проект… или просто нажимаем Ctrl+Shift+N и в открывшемся окне выбираем «Empty AVR GCC Project» как это показано на следующем видео:

К сожалению, продемонстрировать не могу, т.к. у меня в AVR Studio указанный пункт отсутствует и окно «Создать проект» у меня выглядит следующим образом:

У кого такая же петрушка пишите в комменты, решение есть, а мы поехали дальше.

Настройка отладчика в среде разработки

На данном этапе мы имеем созданный проект в среде AVR Studio, при создании проекта мы указали тип микроконтроллера (надеюсь вы выбрали совместимый тип микроконтроллера с описываемым в данной статье отладчиком). Также к разъему USB компьютера подключен наш отладчик.

Давайте попробуем как будет среда разработки взаимодействовать с подключенным устройством. Для этого подсоединим отладчик к имеющейся у вас плате и включим ее питание. Если отладчик увидит подключенную плату, то он отобразит это загоревшимся зеленым индикатором (из трех индикаторов он расположен слева). Если лампочка загорелась, ок — можно пробовать подключаться к отладчику.

Выбираем в среде разработке в меню Сервис пункт AVR Programming. На экране отобразится следующее окно:

В выпадающем списке Tool выберите Jtagice3. Если вы не видите его в списке, значит скорее всего у вас проблемы с установкой драйверов для этого устройства или вы его забыли подключить к компьютеру.

В выпадающем списке Device укажите тип вашего микроконтроллера, ну и укажите интерфейс по которому вы подключили программатор к своему устройству. Предполагаю, что вы выберите JTAG.

После этого нажимаем кнопку Apply и ждем обмена данными компьютера с программатором. Что мы должны увидеть на экране? Компьютер должен загрузить сведения с программатора и отобразить список доступных вкладок на экране:

Первые три вкладки Interface settings, Tool Information и Device Information относятся к программатору и указанному типу микроконтроллера. Если вы правильно подключили программатор, то компьютер успешно соединится с программатором и получит сведения для данных вкладок при нажатии кнопки Apply.

Рассмотрим опции на вкладках Interface settings, Tool Information и Device Information подробнее.

Опции на вкладке Interface settings

Здесь мы видим параметры настроек интерфейса отладчика. Ползунок JTAG Clock задает скорость интерфейса JTAG. Чем выше этот показатель, тем выше скорость обмена данными между отладчиком и микроконтроллером во время отладки программы. Но следует иметь ввиду, что указанная частота не должна превышать 1/4 частоты на которой будет работать сам микроконтроллер. Т.е. если ваш микроконтроллер работает на частоте 8 МГц, то выставляйте параметр JTAG Clock не больше 2 МГц, иначе будут проблемы с синхронизацией отладчика с вашим микроконтроллером.

Используйте галочку «Use external reset» если по каким либо причинам вам необходимо запретить отладчику посылать команду сброса микроконтроллера. Вместо этого вам необходимо будет производить сброс микроконтроллера иными способами, которые у вас должны быть предусмотрены. Актуально, если, к примеру, логике вашей программы принципиально, чтобы отладчик не прерывал исполнение программы.

Опции Daisy chain трогать не будем, т.к. они касаются гирляндных (или шлейфовых) соединений устройств, что относится к достаточно продвинутым параметрам, которые мы не будем использовать.

Опции на вкладке Tool Information

На вкладке отображаются сведения о вашем отладчике — наименование устройства, версия прошивки, серийный номер и прочее.

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

Опции вкладки Device Information

На данной вкладке содержатся сведения о типе микроконтроллера, который вы выбрали. Если отладчик смог соединиться с вашей платой, то он должен на этой вкладке отобразить также некоторые сведения о конкретном микроконтроллере, установленном на вашей плате — такие как сигнатура устройства, JTAG ID, ревизия. В данном примере мы не будем использовать эти сведения.

Следующие три вкладки Memories, Fuses и Lock Bits расписывать подробно не буду — это совершенно привычные опции по управлению памятью, фьюзами и битами блокировки микроконтроллера информацию о которых можно почерпнуть в других источниках.

Единственное, скажу только что вкладки Fuses и Lock Bits будут доступны только в том случае если отладчик успешно смог соединиться с микроконтроллером и, поэтому при нажатии на эти вкладки сведения о текущих параметрах предварительно загружаются с микроконтроллера.

Ну а если выскакивает ошибка при нажатии на эти вкладки, значит ищите проблемы. А в какой последовательности их искать рассмотрим далее.

Возможные проблемы и способы решения

Для выявления возможных проблем с подключением отладчика и отлаживаемых модулей удобнее всего использовать окно AVR Programming, о котором шла речь выше. Рассмотрим последовательность действий для выявления наиболее типичные проблем с подключением отладочных устройств.

Во-первых убедимся, что все подключено и все включено. Также важно перед тем как вы откроете окно AVR Programming убедиться что вы вышли из режима отладки. Иначе вы будете получать ошибки на все попытки обращения к отладчику.

Открываем окно AVR Programming, выбираем программатор, микроконтроллер и интерфейс и жмем кнопку Apply. Если у вас отобразились вкладки, значит отладчик успешно найден и подключен правильно. Если все сделали правильно, а отладчик ругается на таймауты, то настало время перезагрузить AVR Studio (заодно, на всякий случай, отключите разъем USB программатора и снова воткните его в компьютер), теперь все снова должно заработать.

Теперь начинаем проверять, получается ли у отладчика связаться с вашим модулем. Для этого еще раз убедитесь, что отладчик правильно подключен к вашему модулю, у модуля включено питание и у отладчика горит зеленый индикатор слева. Если все так, то проверяем получается ли у отладчика связаться с микроконтроллером. Нажмем на кнопку Read, расположенную рядом с Device Id. Если отобразится в поле сигнатура устройства, то значит все ОК, отладчик и микроконтроллер, в принципе готовы к работе, если нет проверяем питание на разъеме JTAG — нажимаем кнопку Read, расположенную около Target Voltage. Посмотрите уровень напряжения, который измерил отладчик. Если он соответствует схеме модуля, то проблема в разъемах, схеме или сдох микроконтроллер. Необходимо все это проверить, после чего повторить.

Ну вроде это все. Если у вас возникли иные проблемы напишите о них в комментариях. Продолжение, думаю, следует.

]]>
http://www.blogs-it.ru/mikrokontrollery-avr/ispolzovanie-avr-jtagiceiii-v-srede-avr-studio-5/feed/ 1
Программаторы AVR http://www.blogs-it.ru/mikrokontrollery-avr/programmatory/ http://www.blogs-it.ru/mikrokontrollery-avr/programmatory/#respond Wed, 12 Sep 2012 05:40:01 +0000 http://www.blogs-it.ru/?p=398 Представлю набор программаторов, которые должны представлять наибольший интерес у разработчиков программ под 8-разрядные микроконтроллеры AVR компании Atmel.

Сводная таблица программаторов AVR

Наименование программатора Уровень Описание
 AVRprog 

программатор

 бюджетный, самоделка  Простейший ISP-программатор, работающий по последовательному порту.Поделка доверия не внушает, похоже проект сдох и нет гарантии что штука заработает под ваш микроконтроллер, потому как программа-прошивалка самописная (есть исходники на Делфи). Тем не менее схемка очень простая, поэтому может кому пригодится. 

Аппаратная часть программатора состоит из MAX232A, 6 конденсаторов 10нФ, 10КОм-ного резистора и кнопочки.

 JTAGICE mkII 

программатор
отладчик

промышленного изготовления, Atmel 

имеются клоны

Программатор-отладчик, поддерживающий интерфейсы ISP, JTAG и debugWIRE. 

Нареканий нет, работает и через USB и через COM-порт. Поддерживается в AVR Studio 4, AVR Studio 5, ATMEL Studio 6, ну и соответственно, avrdude. Немного крупноват в плане габаритов. Дорогой, но при желании можно найти схему и собрать клон.

 AVR910 

программатор

промышленного изготовления, Atmel (устаревший) 

имеются клоны

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

К примеру, если вы планируете работать над созданием собственного загрузчика вашего модуля, работающего по последовательному порту, то протокол этого программатора вам может пригодиться в плане того что ваш модуль сможет «закосить» под AVR910 и обновить у себя прошивку самостоятельно. Преимущество в том, что вы для этого сможете использовать программное обеспечение, совместимое с данным программатором.

Тем не менее если вы хотите собрать такую штуку, то в Интернете представлена не одна версия клонов.

 USBtinyISP 

программатор

бюджетный, самоделка Простой программатор, позволяющий программировать ваш микроконтроллер по 3-проводному или 10-проводному ISP интерфейсу. Представлен полностью в исходниках, но можно и заказать готовое изделие. Совместим с avrdude.
 USB AVR programmer 

программатор

бюджетный, самоделка Еще один ISP-программатор в исходниках. Очень похож на AVR910 и использует протокол AVR911, но автор явно не сообщает об этом. Подключается к компьютеру через разъем USB. Поставляется полностью в исходниках.
STK500 

программатор

промышленного изготовления, Atmel Программатор, совместимый с AVR Studio 4, AVR Studio 5 и ATMEL Studio 6. 

Подключается к компьютеру через RS232 и позволяет программировать микроконтроллеры в корпусах DIP непосредственно, для чего имеет набор различных слотов.

Имеет возможность подключать различные модули расширения.

 STK600 

программатор

промышленного изготовления, Atmel Программатор, совместимый с AVR Studio 4, AVR Studio 5 и ATMEL Studio 6. 

Подключается к компьютеру через разъем USB и является более расширенной версией STK500, позволяющая задействовать кроме интерфейса ISP также JTAG  и aWire, что обеспечивает поддержку всех разновидностей микроконтроллеров компании Atmel.

 USBasp бюджетный, самоделка Очередная поделка программатора, подключаемого к компьютеру через USB интерфейс. Совместим с avrdude и исходники представлены полностью.

Немного подробнее остановлюсь на программаторах-отладчиках, с которыми мне удалось поработать лично.

Программатор-отладчик AVR-JTAGICE mkII

Официальный программатор для микроконтроллеров фирмы Atmel семейства AVR, поддерживающих интерфейс для отладки и программирования JTAG.

Необходим для отладки AVR микроконтроллеров в среде AVR Studio 5.
Как оказалось, имеет неожиданно большой размер.
Думаю от такого программатора стоит отказаться в пользу AVR-JTAGICE3 — из-за гораздо меньших размеров. У него примерно та же цена и при этом третий JTAGICE имеет больше возможностей.

Стоимость

  • Официальный программатор, выпускаемый фирмой Atmel стоит примерно 300 евро (без доставки и растаможивания). Вариант подешевле — можно найти неофициальные «клоны» по цене примерно $150.
  • Вариант еще дешевле, но требующий усилий, т.к. из разряда «сделай сам»:
    в сети через поисковик (clone AVR-JTAGICE mkII) без проблем можно найти схему с прошивкой программатора сопровождаемые инструкцией по сборке.

Характеристики программатора

  • Полная поддержка JTAG программирования, поддерживает также интерфейсы ISP и DebugWire.
  • Подключение к PC осуществляется с помощью USB 1.1 или RS-232 интерфейса
  • Точки останова по адресам памяти программ и памяти данных
  • Все операции и точки останова выполняются в режиме реального времени
  • Напряжение подаваемое в отлаживаемую схему 1.8-5.5 В
  • Напряжение внешнего источника питания 9-12В, так же отладчик может питаться от USB порта

Программатор AVR-JTAGICE3

Официальный программатор для микроконтроллеров фирмы Atmel семейства AVR, поддерживающих интерфейс для отладки и программирования JTAG.
Думаю для отладки AVR микроконтроллеров в среде AVR Studio 5 является лучшим выбором. Кстати, неофициальных клонов найти не смог. Если кто знает, прошу сообщить в комментариях к странице.
При начале эксплуатации я испытывал некоторые трудности с его использованием — казалось что он страшно глючит, при этом приходилось постоянно перезагружать среду AVR Studio чтобы он «ожил».
В принципе, все оказалось просто — не стоит во время запущенной отладки пытаться производить какие-либо иные действия с программатором, например, вызывать окно с настройкой фьюзов. Со временем я к нему приспособился и совершенно без проблем его использую.
Из преимуществ выделю его малые габариты (по сравнению с его предшественником AVR-JTAGICE mkII) и универсальность — кроме интерфейса JTAG также доступны и aWire, SPI и PDI.
Из сложностей — его стоимость. Считаю, что она достаточно прилична — около 15000 рублей через официальных дилеров в России.

Характеристики программатора:

  • Поддержка интерфейсов JTAG, aWire, SPI и PDI
  • 3 аппаратных точки останова и 1 маскируемая
  • Символьная отладка сложных типов данных
  • До 128 программных точек останова
  • Поддержка микросхем с напряжением питания от 1.8 до 5.5В
  • Высокая скорость работы (загрузка 256KB программы ~14 сек. (XMEGA по интерфейсу JTAG) interface)
  • Питание от USB.

Программатор AVR-JTAG-USB

Применяется данный программатор для микроконтроллеров фирмы Atmel семейства AVR, поддерживающих интерфейс для отладки и программирования JTAG. Данный программатор является клоном оригинального  Atmel’евского программатора. Производит его фирма Olimex и отличается он от официального более выгодной ценой (приблизительно 4000 рублей через официальных дилеров в России, и естественно, можно дешевле напрямую из-за бугра), при этом по функциональности вполне надежный и во время работы с ним нареканий у меня не возникало. Работает и питается от USB порта компьютера.

Единственная особенностью на которую стоит обратить заранее — это то, что при использовании в качестве средства разработки AVR Studio работать будет только под  AVR Studio 4. Если вы собираетесь работать на  AVR Studio 5 то он для отладки абсолютно бесполезен, т.к. не поддерживается. Поэтому для пятой версии я купил другой программатор — AVR-JTAGICE3.

Характеристики программатора

  • Программирование всех AVR микроконтроллеров с поддержкой JTAG интерфейса;
  • Целевое напряжение 3,0 — 5,0В;
  • Питание от USB интерфейса;
  • JTAG коннектор совместим с Atmel 2×5 пин коннектором JTAG;
  • Совместим с Atmel AVR STUDIO для программирования, эмуляции в режиме реального времени, отладки, выполнения программы в пошаговом режиме, установки точек останова, дампа памяти и т.д.;
  • Полная эмуляция всех аналоговых и цифровых функций;
  • Полная поддержка программирования через JTAG порт;
  • Обновление через AVR STUDIO;
  • Разъём USB интерфейса – типа «А».

Комплектация: программатор/эмулятор AVR-JTAG-USB.
Для работы может понадобиться USB кабель «А-А» — SCUAA-1

]]>
http://www.blogs-it.ru/mikrokontrollery-avr/programmatory/feed/ 0
GUI для avrdude с настраиваемым списком программаторов (AVR8 Burn-O-Mat) http://www.blogs-it.ru/mikrokontrollery-avr/gui-dlya-avrdude-s-nastraivaemym-spiskom-programmatorov-avr8-burn-o-mat/ http://www.blogs-it.ru/mikrokontrollery-avr/gui-dlya-avrdude-s-nastraivaemym-spiskom-programmatorov-avr8-burn-o-mat/#respond Wed, 05 Sep 2012 09:53:21 +0000 http://www.blogs-it.ru/?p=381 На сегодняшний день существует множество различных GUI для оболочки avrdude и, к сожалению, часть из них либо остаются заброшеными и устаревшими, какая-то часть не подходит по различным причинам, таким как отсутствие поддержки требуемого типа программатора или не работает под трубуемую платформу. Поэтому хотелось бы обратить внимание на довольно неплохую реализацию GUI для утилиты avrdude, которая называется AVR8 Burn-O-Mat.

Основные преимущества AVR8 Burn-O-Mat

Основные преимущества этой программы следующие:

  • Кросплатформенность. Программа написана на языке Java и не зависит от платформы, на которой ее необходимо запускать. Правда это также является ее недостатком. Для того чтобы ее можно было запустить вам потребуется предварительно установить на свой компьютер исполнительную среду Java. Но бояться не стоит, если вы еще ее не установили, скачать ее можно здесь: http://java.sun.com/javase/downloads.
  • Широкий функционал. Стоит отметить что опции программы очень широко представлены, многие пользователи отмечают детальную реализацию настроек фьюзов.
  • Расширяемость. Если в программе вы обнаружите, что нужного вам микроконтроллера нет в списке, то вы сами сможете это исправить. Достаточно открыть файл конфигурации и прописать в него параметры вашего программатора.

 Установка

Установка очень проста. Вам нужно скачать архив, содержащий программу AVR8 Burn-O-Mat с их сайта: http://avr8-burn-o-mat.aaabbb.de/avr8_burn_o_mat_avrdude_gui_en.html, затем его распаковать в удобном для вас месте. Не забудьте предварительно установить Java, если вы это еще не сделали: http://java.sun.com/javase/downloads.

Использование программы

Программа имеет интуитивно понятный интерфейс. После запуска оглядите все возможные настройки. Убедитесь, что пути к avrdude и к конфигурации avrdude прописаны верно. Затем выберите нужный тип программатора и порт, к которому он подключен (список поддерживаемых программаторов берется из файла avrdude.conf)

Вот список поддерживаемых микроконтроллеров:

ATmega8, ATmega16, ATmega32, ATmega64, ATmega128, ATmega48, ATmega88, ATmega168, ATmega162, ATmega8515, ATmega8335, ATmega164, ATmega324, ATmega644, ATmega169, ATmega329, ATmega3290, ATmega649, ATmega6490, ATtiny2313, ATtiny13, ATtiny25, ATtiny45, ATtiny85, ATtiny26

Новые микроконтроллеры можно с легкостью добавить самостоятельно. Вся необходимая для этого информация содержится в файле AVR8_Burn_O_Mat_Config.xml.

]]>
http://www.blogs-it.ru/mikrokontrollery-avr/gui-dlya-avrdude-s-nastraivaemym-spiskom-programmatorov-avr8-burn-o-mat/feed/ 0
Avrdude — консольная программа прошивки микроконтроллеров http://www.blogs-it.ru/mikrokontrollery-avr/avrdude-konsolnaa-programma-prosivki-mikrokontrollerov/ http://www.blogs-it.ru/mikrokontrollery-avr/avrdude-konsolnaa-programma-prosivki-mikrokontrollerov/#comments Wed, 05 Sep 2012 08:26:31 +0000 http://www.blogs-it.ru/?p=373 Avrdude (AVR Downloader-Uploader) — бесплатная кросплатформенная программа, предназначенная для прошивания микроконтроллеров компании ATMEL. Поддерживает практически все имеющиеся официальные типы программаторов, а также некоторые сторонние программаторы.

Сайт программы: http://www.nongnu.org/avrdude/
Лицензия: GPL
Операционная система: Кросплатформенный
Особенностью программы Avrdude является то, что она имеет консольный интерфейс пользователя, что потребует от пользователя определенных навыков. Тем не менее для любителей графического интерфейса имеется ряд сторонних графических оболочек для этой программы.
Хотя графический интерфейс является во многом удобным и предпочтительным, для выполнения повседневных однотипных задач все же лучше использовать программу из скриптов cmd, что будет рассмотрено в данном документе.
Альтернативным способом прошивания микроконтроллеров являются встроенные средства, входящие в состав средств разработки, такие как AVR Studio. Но они удобны только в процессе разработки и отладки программ. Avrdude больше полезен в процессе серийного прошивания готовых изделий, т.к. не потребует для работы установки среды разработки, а для прошивки микроконтроллера достаточно только дважды щелкнуть мышью по заранее подготовленному ярлыку (естественно с указанными параметрами запуска программы).
Консоль avrdude
Итак, для работы с программой потребуется:
  1. Установить программу;
  2. Разобраться с параметрами командной строки и сформировать команду запуска программы.
После чего программа готова к использованию.

Установка Avrdude

Avrdude входит в состав пакета WinAVR, поэтому установка сводится к установке данного пакета. Скачать WinAVR можно здесь: http://sourceforge.net/projects/winavr/.
После установки пакета WinAVR можно запускать Avrdude, для чего откройте командную строку и выполните команду:
avrdude
После чего на экране вы должны увидеть краткую инструкцию команды:

Параметры программы

Синтаксис команды Avrdude:
Avrdude [опции]
Где [опции] задают параметры команды в формате -ключ_значение.
Рассмотрим наиболее значимые опции команды.

Задаем тип микроконтроллера (-p)

Avrdude -p <partno>

где <partno> — тип микроконтроллера. Данная команда указывает какой тип микроконтроллера используется. Например, для микроконтроллера Atmega32 <partno> будет равен m32.

Задаем скорость порта для программатора (-b)

Avrdude -b <baudrate>

где <baudrate> переопределяет скорость обмена данными с программатором по последовательному интерфейсу (относится не ко всем типам программаторов). Не рекомендуется изменять данный параметр без особых причин, т.к. программаторы обычно оптимизированы на скорость по умолчанию.

Задаем скорость обмера данными программатора с микроконтроллером (-B)

Avrdude -B <bitclock>

где < bitclock> переопределяет скорость обмена данными программатора с микроконтроллером. Данный параметр может потребоваться если частота микроконтроллера слишком низкая и не позволяет производить программирование на скорости по умолчанию. В таком случае с помощью данного параметра скорость программирования может быть снижена.

Запрещаем автоматическую очистку памяти микроконтроллера перед прошиванием (-D)

Avrdude -D
Если нам не нужно выполнять автоматическую очистку flash-памяти микроконтроллера, выполняемую перед ее прошиваением, то используем данную опцию.

Указываем порт, к которому подключен программатор (-P)

Avrdude -P <port>
Указывается коммуникационный порт по которому к компьютеру подключен программатор. Среди возможных значений могут быть COM1 для последовательного интерфейса или LPT1 для параллельного или USB.

Отключение проверки сигнатуры микроконтроллера (-F)

Avrdude -F
Опция отключает проверку сигнатуры микроконтроллера при прошивке. Не рекомендуется использовать данную опцию, т.к. проверка сигнатуры позволяет проверять тот ли тип микроконтроллера подключен, что мы предполагаем или нет.

Очистка микроконтроллера (-e)

Avrdude -e
Производит очистку flash-памяти микроконтроллера. Данная операция производится автоматически при прошивании.

Манипуляции с памятью микроконтроллера (-U)

Avrdude -U <memtype>:r|w|v:<filename>[:format]

Наиболее значимая опция команды, которая непосредственно отвечает за программирование микроконтроллера.
Параметр memtype задает какой тип памяти будет затронут командой:
  • flash — флеш память микроконтроллера;
  • eeprom — энергонезависимая память микроконтроллера;
  • hfuse — старший байт фьюзов микроконтроллера;
  • lfuse —  младший байт фьюзов микроконтроллера;
  • efuse —  еще один байт фьюзов микроконтроллера (если поддерживается микроконтроллером).
Что сделать с памятью определяет следующий за memtype параметр через двоеточие, который обозначает запись в память (r), чтение содержимого памяти микроконтроллера (w) и проверка памяти (v).
Далее после двоеточего следует имя файла <filename> (можно полный путь с указанием диска в кавычках) куда следует сохранить или откуда надо загрузить содержимое памяти.
Необязательный параметр format определяет формат файла, в котором хранится участок памяти. Наиболее типичным для flash памяти будет формат «Intel Hex», обозначаемый символом i.
Таким образом, команда на запись в микроконтроллера прошивки, содержащейся в файле test.hex будет следующей:
Avrdude -U flash:w:test.hex:i 

Команда на чтение содержимого энергонезависимой памяти микроконтроллера в файл  eedump.hex будет следующей:

Avrdude -U eeprom:r:eedump.hex:i

Блокировать любую запись в микроконтроллер (-n)

Avrdude -n

Опция заблокирует любые попытки записать что-либо в микроконтроллер. Может потребоваться если вы собираетесь попробовать выполнить команду, но пока в чем-то не уверены и хотите сначала ее проверить, т.к. боитесь, что испортите микроконтроллер.

Разрешение на изменение фьюзов (-u)

Avrdude -u

Если вы собираетесь изменить фьюзы микроконтроллера, то необходимо подтвердить это намерение с помощью данной опции.

Открытие терминала программатора (-t)

Avrdude -t

Данная опция позволяет работать с программатором в режиме терминала. Эта опция полезна для продвинутых пользователей.

Выключить автоматическую проверку записи (-V)

Avrdude -V

Опция запрещает производить проверку данных при записи.

Задаем тип программатора (-c)

С помощью опции -c <programmer> возможен выбор одного из следующих программаторов:

  • t10 = ATtiny10
  • t8 = ATtiny9
  • t5 = ATtiny5
  • t4 = ATtiny4
  • ucr2 = 32UC3A0512
  • x128a4 = ATXMEGA128A4
  • x64a4 = ATXMEGA64A4
  • x32a4 = ATXMEGA32A4
  • x16a4 = ATXMEGA16A4
  • x256a3b = ATXMEGA256A3B
  • x256a3 = ATXMEGA256A3
  • x192a3 = ATXMEGA192A3
  • x128a3 = ATXMEGA128A3
  • x64a3 = ATXMEGA64A3
  • x256a1 = ATXMEGA256A1
  • x192a1 = ATXMEGA192A1
  • x128a1d = ATXMEGA128A1REVD
  • x128a1 = ATXMEGA128A1
  • x64a1 = ATXMEGA64A1
  • m6450 = ATMEGA6450
  • m3250 = ATMEGA3250
  • m645 = ATMEGA645
  • m325 = ATMEGA325
  • usb82 = AT90USB82
  • usb162 = AT90USB162
  • usb1287 = AT90USB1287
  • usb1286 = AT90USB1286
  • usb647 = AT90USB647
  • usb646 = AT90USB646
  • m32u4 = ATmega32U4
  • t84 = ATtiny84
  • t44 = ATtiny44
  • t24 = ATtiny24
  • m128rfa1 = ATMEGA128RFA1
  • m2561 = ATMEGA2561
  • m2560 = ATMEGA2560
  • m1281 = ATMEGA1281
  • m1280 = ATMEGA1280
  • m640 = ATMEGA640
  • t85 = ATtiny85
  • t45 = ATtiny45
  • t25 = ATtiny25
  • pwm3b = AT90PWM3B
  • pwm2b = AT90PWM2B
  • pwm3 = AT90PWM3
  • pwm2 = AT90PWM2
  • t2313 = ATtiny2313
  • m328p = ATMEGA328P
  • t88 = attiny88
  • m168 = ATMEGA168
  • m88 = ATMEGA88
  • m48 = ATMEGA48
  • t861 = ATTINY861
  • t461 = ATTINY461
  • t261 = ATTINY261
  • t26 = ATTINY26
  • m8535 = ATMEGA8535
  • m8515 = ATMEGA8515
  • m8 = ATMEGA8
  • m161 = ATMEGA161
  • m32 = ATMEGA32
  • m6490 = ATMEGA6490
  • m649 = ATMEGA649
  • m3290p = ATMEGA3290P
  • m3290 = ATMEGA3290
  • m329p = ATMEGA329P
  • m329 = ATMEGA329
  • m169 = ATMEGA169
  • m163 = ATMEGA163
  • m162 = ATMEGA162
  • m1284p = ATMEGA1284P
  • m644p = ATMEGA644P
  • m644 = ATMEGA644
  • m324p = ATMEGA324P
  • m164p = ATMEGA164P
  • m16 = ATMEGA16
  • c32 = AT90CAN32
  • c64 = AT90CAN64
  • c128 = AT90CAN128
  • m128 = ATMEGA128
  • m64 = ATMEGA64
  • m103 = ATMEGA103
  • 8535 = AT90S8535
  • 8515 = AT90S8515
  • 4434 = AT90S4434
  • 4433 = AT90S4433
  • 2343 = AT90S2343
  • 2333 = AT90S2333
  • 2313 = AT90S2313
  • 4414 = AT90S4414
  • 1200 = AT90S1200
  • t15 = ATtiny15
  • t13 = ATtiny13
  • t12 = ATtiny12
  • t11 = ATtiny11
Пример команды:
C:\>avrdude -c avrisp ...

Скрипт для автоматической прошивки микроконтроллера

Для того, чтобы прошивка микроконтроллера производилась с помощью программы avrdude автоматически можно написать небольшой скрипт. Далее приведу небольшой пример, написанный для программатора AVR-JTAG-USB. К данному программатору можно обращаться через COM-порт, который создается при установке его драйвера, поэтому скрипт первым делом спрашивает номер порта, к которому подключен программатор, далее пытается с ним соединиться. Если не удается, то программа возвращается к выбору последовательного порта. Иначе производит прошивку платы.
set AVRDUDECMD="<путь к папке с avrdude>\avrdude.exe"
set FIRMWARESOURCEDIR=<путь к папке с текущей прошивкой>
set FIRMWAREDIR=%TMP%\firmware\

:SELECTPORT
set /P port="Выберите номер порта COM"
echo %AVRDUDECMD%

echo Проверка подключения...
%AVRDUDECMD% -c jtagmkI -p m32 -P COM%port%
IF %ERRORLEVEL% EQU 9009 GOTO SELECTPORT

echo Удаляем временные файлы
rmdir /S /Q %FIRMWAREDIR%
echo Копируем прошивку во временную папку
mkdir %FIRMWAREDIR%
xcopy "%FIRMWARESOURCEDIR%*.*"  "%FIRMWAREDIR%"

echo Прошиваем микроконтроллер
@echo on
%AVRDUDECMD% -c jtagmkI -p m32 -P COM%port% -U flash:w:"%FIRMWAREDIR%firmware.hex":i -U hfuse:w:^<0x91^>:m -U lfuse:w:^<0xFF^>:m
@echo off

pause

 

Как работает скрипт?

В самом начале скрипта определяются значения трем переменным:
  • AVRDUDECMD — полный путь к программе avrdude.exe
  • FIRMWARESOURCEDIR — Полный путь к папке с прошивкой
  • FIRMWAREDIR — путь к временной папке, в которую будут скопированы файлы прошивки. Данная папка необходима для успешного выполнения программы avrdude на случай, если FIRMWARESOURCEDIR окажется сетевой папкой. В случае, если папка с прошивкой окажется сетевой, то программа avrdude выдаст ошибку.

Имя файла с прошивкой должно быть firmware.hex и располагаться в папке FIRMWARESOURCEDIR.

Строка с командой на прошивку микроконтроллера выглядит следующим образом:
%AVRDUDECMD% -c jtagmkI -p m32 -P COM%port% -U flash:w:»%FIRMWAREDIR%firmware.hex»:i -U hfuse:w:^<0x91^>:m -U lfuse:w:^<0xFF^>:m
Здесь указывается, что будет использован программатор AVR-JTAG-USB, микроконтроллер Atmega32, порт COM[номер порта вводится пользователем с клавиатуры]. В строке команды указываются значения фьюзов — hfuse=0x91 иlfuse=0xFF в шестнадцатиричном формате.
Значения фьюзов в шестнадцатиричном формате можно подобрать с помощью встроенных инструментов AVR-Studio, предназначенных для прошивания миктроконтроллеров.
Данный скрипт можно разместить в сетевой папке вашей локальной сети и запускать с любого компьютера прямо из сетевой папки.
Результат работы скрипта будет примерно таким:
Выберите номер порта COM2
"\\center\Прошивки для плат\avrdude\avrdude.exe"
Проверка подключения...
avrdude.exe: jtagmkI_open(): failed to synchronize to ICE
avrdude.exe: jtagmkI_close(): unsupported baudrate -1

avrdude.exe done.  Thank you.

Удаляем временные файлы
Копируем прошивку во временную папку
\\center\Прошивки для плат\МОС-Универсальный\revision01.00\version01.00\MOS.hex
Скопировано файлов: 1.
Прошиваем микроконтроллер

C:\WINDOWS>"\\center\Прошивки для плат\avrdude\avrdude.exe" -c jtagmkI -p m32 -P COM2 -U flash:w:"C:\DOCUME~1\valeyev\LOCALS~
1\Temp\firmware\MOS.hex":i -U hfuse:w:<0x91>:m -U lfuse:w:<0xFF>:m

avrdude.exe: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.05s

avrdude.exe: Device signature = 0x1e9502
avrdude.exe: NOTE: FLASH memory has been specified, an erase cycle will be performed
             To disable this feature, specify the -D option.
avrdude.exe: erasing chip
avrdude.exe: reading input file "C:\DOCUME~1\valeyev\LOCALS~1\Temp\firmware\MOS.hex"
avrdude.exe: writing flash (19104 bytes):

Writing | ################################################## | 100% 7.19s

avrdude.exe: 19104 bytes of flash written
avrdude.exe: verifying flash memory against C:\DOCUME~1\valeyev\LOCALS~1\Temp\firmware\MOS.hex:
avrdude.exe: load data flash data from input file C:\DOCUME~1\valeyev\LOCALS~1\Temp\firmware\MOS.hex:
avrdude.exe: input file C:\DOCUME~1\valeyev\LOCALS~1\Temp\firmware\MOS.hex contains 19104 bytes
avrdude.exe: reading on-chip flash data:

Reading | ################################################## | 100% 4.11s

avrdude.exe: verifying ...
avrdude.exe: 19104 bytes of flash verified
avrdude.exe: reading input file "<0x91>"
avrdude.exe: invalid byte value (<0x91>) specified for immediate mode
avrdude.exe: write to file '<0x91>' failed

avrdude.exe: safemode: Fuses OK

avrdude.exe done.  Thank you.

Для продолжения нажмите любую клавишу . . .

 

]]>
http://www.blogs-it.ru/mikrokontrollery-avr/avrdude-konsolnaa-programma-prosivki-mikrokontrollerov/feed/ 2
Интеграция с avrdude — решение совместимости программаторов с AVR Studio 5, ATMEL Studio 6 http://www.blogs-it.ru/mikrokontrollery-avr/integraciya-s-avrdude-reshenie-sovmestimosti-programmatorov-s-avr-studio-5-atmel-studio-6/ http://www.blogs-it.ru/mikrokontrollery-avr/integraciya-s-avrdude-reshenie-sovmestimosti-programmatorov-s-avr-studio-5-atmel-studio-6/#respond Wed, 05 Sep 2012 08:04:43 +0000 http://www.blogs-it.ru/?p=352 AVR Studio 5, или ATMEL Studio 6 поддерживает лишь ограниченное число программаторов. Тем не менее остальные программаторы, не вошедшие в список можно интегрировать в среду разработки используя консольную программу прошивки микроконтроллеров Avrdude.

Начиная с версии AVR Studio 5 среда разработки основывается на оснастке Micrisoft Visual Studio 2012, которая содержит в свойствах проекта опцию по вызову произвольных пакетных команд. Выполнение команд привязано к основным событиям постоения проекта (Build Events) — команды, выполняемые до построения проекта и команды, выполняемые после построения проекта.

Настраиваем среду исполнения

Итак, открываем среду разработки AVR Studio 5, или ATMEL Studio 6, открываем существующий или создаем новый проект и открываем его свойства:

Свойства проекта

На экране в центральной области откроется вкладка со свойствами выбранного проекта. Выберите вкладку «Build Events»:

Вкладка события постоения

Прошивать микроконтроллер необходимо после успешного построения проекта, поэтому команды следует вводить в соответствующее поле «Post-build event command line» .

Создаем команду заливки прошивки в микроконтроллер

В это поле необходимо ввести команду, которая выполнит заливку только что сделанной прошивки в микроконтроллер. Для этого воспользуемся программой avrdude.exe.

Для того чтобы сформировать команду на заливку прошивки необходимо изучить параметры командной строки avrdude.exe для вашего типа микроконтроллера и сформировать макрос, определяющий путь к файлу, генерируемой прошивки (информацию по командам avrdude вы можете найти здесь: прошивание микроконтроллеров утилитой Avrdude). Я же приведу пример вызова команды для своего типа программатора jtagmkI.

Команда avrdude требует в качестве параметра путь к файлу с прошивкой. Этот путь можно сформировать автоматически воспользовавшись макросами среды разработки:

"$(OutputDirectory)\$(MSBuildProjectName).hex"

Использование макросов предпочтительно тому, если вы пропишите путь к прошивке жестко, т.к. путь к файлу прошивки может измениться если вы, к примеру, перенесете свой проект в другую папку , переименуете проект или даже переключитесь из режима Debug в режим Release. Применение макросов гарантирует, что каждый раз при вызове события построения проекта команде будет сформирован правильный путь к прошивке.

Итак, разобравшись с параметрами команды у меня получилась строчка следующего вида:

avrdude.exe -c jtagmkI -p m32 -P COM3 -U flash:w:"$(OutputDirectory)\$(MSBuildProjectName).hex":i -U hfuse:w:^<0x91^>:m -U lfuse:w:^<0xFF^>:m

Осталось только определить путь к программе avrdude и убедиться что в опциях проекта стоит галочка напротив пункта «Генерировать .hex». Для этого заходим в свойствах проекта на вкладку «Buid» и ставим галочку:

Галочка напротив пункта Generate .hex file

Смотрим что получилось

Теперь всякий раз после того как вы будете выполнять построение проекта будет автоматически производиться вызов команды прошивания микроконтроллера.

В случае, если avrdude не сможет выполнить заливку программы среда разработки выдаст в окне «Список ошибок» соответствующую запись.

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

]]>
http://www.blogs-it.ru/mikrokontrollery-avr/integraciya-s-avrdude-reshenie-sovmestimosti-programmatorov-s-avr-studio-5-atmel-studio-6/feed/ 0
AVR BootLoader в вопросах и ответах. Часть 2 http://www.blogs-it.ru/mikrokontrollery-avr/avr-bootloader-v-voprosah-i-otvetah-2/ http://www.blogs-it.ru/mikrokontrollery-avr/avr-bootloader-v-voprosah-i-otvetah-2/#respond Fri, 31 Aug 2012 15:43:40 +0000 http://www.blogs-it.ru/?p=298

Эта статья является продолжением AVR BootLoader в вопросах и ответах. Часть 1

Как загрузчику убедиться что в приложении нет изменений?

После сброса загрузчик, как правило, осуществляет переход к приложению. Но как он может быть уверен, что приложение является допустимым, не повреждена ли программа, которая должна начать исполняться? Что делать, если предыдущая попытка обновить программу аварийно завершилась на середине загрузки? В таком случае есть много возможных мер предосторожности, которые вы можете предпринять. Вот некоторые из них: 

  1. Если это возможно, сразу же после программирования неплохо бы убедиться, что обновление программы удалось. Это можно сделать, прочитав флэш-приложение, и сравнить результат с исходным файлом прошивки. Если вы не хотите, чтобы загрузчик выгружал прошивку, вы можете отправить загрузчику вашу прошивку два раза. Первый раз для записи, второй раз для того чтобы загрузчик сравнил с тем что только что записал. Конечно ни один подход не помогает если есть ошибки в канале связи или загрузчике. Большинство стандартных протоколов программирования поддерживают процедуру верификации, но такой подход не обнаруживает случайные искажения.
  2. Перед тем как загрузчик начнет программирование, он должен удалить первую страницу приложения. Это позволит установить всю флэш-страницу в 0xFF. Затем прошивать страницы в обратном порядке от конца к началу. При запуске, загрузчик может проверить инструкции на правильность (обычно JMP или RJMP) по адресу 0, чтобы определить, все приложение было запрограммировано успешно. Этот подход, вероятно, потребует специального средства программирования, так как большинство стандартных средств не дают возможность обратного проектирования. Такой подход также не обнаруживает случайные искажения.
  3. Вариант 2 прошивать все приложение как обычно, но резервировать последние несколько байт флэш-памяти для специального маркера, содержащий распознаваемый шаблон, например, 0xBEEF. Вы можете сделать это, изменив  шестнадцатеричный файл прошивки с таким инструментом, как srec_cat. Когда загрузчик запускается, он читает маркер байт, и если он находит правильное значение, то понимает, что приложение было записано правильно. Реализовать данный вариант можно с помощью стандартных инструментов программирования, при условии, что прошиваться программа будет с самого начала к концу (что, скорее всего так и будет, но тем не менее не гарантируется). Такой подход также не обнаруживает случайные искажения.
  4. Более тщательный вариантом верификации является использование контрольных сумм CRC для проверки всего приложения каждый раз, когда  запускается загрузчик. Этот вариант похож на вариант 3 за исключением того, что вместо маркера в последних нескольких байтах прошивки хранится вычисленное значение CRC. Это также вы можете проделать это с помощью инструмента srec_cat. Не забудьте, учесть оставшееся в конце свободное пространство в разделе RWW, заполнив его смещением или чем-то еще. Когда загрузчик запускается, он вычисляет CRC используя тот же алгоритм CRC как и srec_cat. Это значение сравнивается с хранимым значением и если они совпадают загрузчик считает, что приложение является не поврежденным. Реализовать данный вариант можно с помощью стандартных инструментов программирования, при этом данный подход позволяет обнаруживать случайные искажения. Недостатком является то что задержка перед запуском программы увеличивается.
  5. Если вы очень обеспокоены возможными искажениями, вы также можете производить проверку контрольной суммы  CRC  загрузчика согласно варианту 4. Конечно, не так много чего можно предпринять в случае обнаружения искажений, например, попытаться просигнализировать о проблеме и выключиться. В таком случае настает время задействовать программатор ISP.
  6. Одним хорошим эффектом использования опции  перезагрузки, хранящейся в EEPROM (обсуждается в вопросе № 10) является то, что данный подход также способен обеспечивать автоматическое обнаружение искажений. Если приложение было записано наполовину или повреждено, оно не получит возможность установить байт APP_RUN и загрузчик будет продолжать исполняться при следующей перезагрузке. Вместо того чтобы искать искажения в приложении, этот подход позволяет оценить неудачное исполнение приложения как проблему. В некотором смысле это даже лучше, чем проверка CRC, потому что на самом деле CRC может быть вычислен у уже испорченного еще задолго до заливки образа прошивки. Конечно, подход с применением EEPROM не является идеальным, поскольку в приложении могут иметься небольшие искажения и сбой может возникнуть после того, как оно запишет байт APP_RUN.

Может ли код загрузчика исполнять код, встроенный в приложение?

Говорят: «Нет, нет и 100% определенно нет».
Хоть технически это возможно, но ответ все равно — «Нет». Ваш загрузчик будет гораздо более надежным, если он имеет нулевую зависимость от приложения. Основная цель загрузчика — стереть и перепрограммировать приложение. Вы же не хотите выполнять вызовы участков кода приложения в то время как стираете его содержимое.
Плохой практикой также считается хранить код, относящийся к загрузчику в разделе RWW. Не существует полного доказательства или способа защиты от случайного стирания и перепрограммирования этой области. Одно полное стирание RWW и загрузчик потенциально становится бесполезным.

Может ли код приложения исполнять код, встроенный в загрузчик?

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

Простым решением в таком подходе будет создавать загрузчик обычным способом и затем искать в нем точки входа в общие функции через специальную карту адресов функций или в дизассемблированном файле. Затем можно создать жестко заданные функции указателей в приложении на основе этих адресов. Это будет работать, но при этом ваши два бинарных файла будут тесно связаны друг с другом. Каждый раз, когда загрузчик будет претерпевать изменения эти функции будут сдвигаться, и вам всякий раз будет требоваться обновить их адреса и перекомпилировать приложение. Это довольно узкое и трудное место в разработке загрузчика. Но если разработка вашего загрузчика завершена, при этом вы уверены, что это он больше не изменится, то это довольно быстрое (хотя немного грязное) решение.
Тем не менее существует лучший подход, устраняющий проблему перемещения общих функций в загрузчик. Механизм тот же что и для обработчиков прерываний. Как процессор определяет адреса обработчиков? Никак. Он знает только адрес таблицы переходов, который добавляется в двоичный код во время линковки проекта. Чтобы попадать в необходимое место процессору требуется только эта таблица переходов (так называемая таблица векторов). Вы можете использовать ту же технику чтобы обращаться к общим функциям из загрузчика.
Есть несколько способов задать таблицу переходов. Удобнее это представить в виде отдельного маленького файла сборки:
.section .jumps,"ax",@progbits
// The gnu assembler will replace JMP with RJMP when possible
.global _jumptable
_jumptable:
    jmp shared_func1
    jmp shared_func2
    jmp shared_func3
Ваша таблица переходов должна использовать имена общих функций, а не их адреса. Это важно, потому что, когда вы перестроите загрузчик, вам потребуется, чтобы линковщик автоматически выставил корректные смещения к функциям в таблицу переходов. Тогда вам будет достаточно поместить таблицу переходов в заданное место загрузчика, а остальное у него может изменяться свободно. Чтобы поместить таблицу переходов в ваш загрузчик необходимо добавить .S в ваши фалы Makefile файл в строке ASRC. Затем нужно добавить компоновщику флаг позиционирования его на предопределенный адрес, который не будет меняться. Чаще всего это в конец загрузчика:
JUMPSTART = 0x3FE0 # 32 bytes from the end of the AT90USB162 4kb boot section
LDFLAGS += -Wl,--section-start=.jumps=$(JUMPSTART)
Вам может понадобиться еще один флаг, чтобы предотвратить попытки компоновщика выбрасывать вашу таблицу переходов в случаях, когда она окажется не востребованной. Это возможно при использовании флага компилятора -ffunction-sections совместно с флагами линковщика --gc-sections и --relax. Поэтому если вы не уверены, то в любом случае это не помешает добавить:
LDFLAGS += -Wl,--undefined=_jumptable
Количество переходов, которые будут помещаться в таблице зависит от того, какой объем пространства, вы  зарезервируете, а также это зависит от размера переходов. Размер переходов зависит от того, насколько далеко адресованы переходы. В загрузчиках по 8Кб или менее на командой переходов будет RJMP, требующая только 2 байта. Самый простой способ узнать точный размер — посмотреть на дизассемблированный код загрузчика.
С другой техникой, основанной на принципе таблиц прерываний можно ознакомиться в вопросе №18. Кроме того, некоторые предлагают добавить еще одну прослойку перехода, чтобы также можно было перемещать саму таблицу векторов, но необходимость в этом довольно редкая.
После создания таблицы переходов, следующим шагом является определить указатели на функции, которые упростят вызов общих функций через таблицу переходов. Вы можете сделать это с помощью макросов или встроенных функций. Возможно, встроенные функции предпочтительнее для дополнительной безопасности типизации. Для создания указателей на функции необходимо открыть для дизассеблированный код загрузчика и найти «_jumptable». Запишите адрес байта каждого перехода, указанного в таблице. Если у вас есть адреса, то необходимо создать заголовочный файл вроде этого:
typedef void (*PF_VOID)(void);
typedef void (*PF_WHATEVER)(uint8_t);
static __inline__ void call_func1(void)
            { ((PF_VOID) (0x3FE0/2))(); }
static __inline__ void call_func2(void)
            { ((PF_VOID) (0x3FE2/2))(); }
static __inline__ void call_func3(uint8_t arg)
            { ((PF_WHATEVER) (0x3FE2/2))(arg); }
Шестнадцатеричные числа байт-адреса, которые извлекаются из дизассемблированного файла. Они должны быть
поделены пополам, чтобы создать слово-адреса, так как GCC с такой ситуацией автоматически не справляется (это возможно баг GCC). Включите этот заголовок в приложение и осуществляете вызов функций. 

call_func3(1);

Почему глобальные переменные не доступны из общих функции?

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

Общие функции должны принимать адреса нелокальных данных во время исполнения. Сделать это проще, чем кажется — достаточно  функции передавать указатели на глобальные данные в качестве аргументов. Когда загрузчик исполняется, он должен передать адрес глобальной переменной, которая была определена в загрузчик. А когда приложение запущено, то оно должно тоже передавать адрес глобальной переменной, которая определена в
приложении. Если необходимо передать несколько переменных, то их удобно группировать в структуру, а функции передавать на нее указатель. Что-то вроде этого:
// In a shared header file
typedef struct {
    uint8_t val1;
    uint16_t val2;
} globals_t;
// The shared function
void func4(globals_t *vars) {
    vars->val1 = 0;
    vars->val2 = 512;
}
// Globally defined in each binary
globals_t g_vars;
// Calling the shared function
call_func4(&g_vars);

Если по каким-то причинам вы не можете передать параметр в общую функцию см. вопрос № 17 ниже.

Может ли приложение использовать IRS встроенный в загрузчик?

На самом деле это проще сделать, чем организовать общие функции, поскольку векторы прерывания по умолчанию уже обеспечивают переход чтобы найти процедуру обработки прерывания (ISR). Достаточно написать и откомпилировать привычным способом в загрузчике ISR  (только без доступа напрямую к глобальным переменным). После этого необходимо в дизассемблированном файле загрузчика найти таблицу прерываний. Записать адрес вектора ISR, который необходимо сделать общим. Вам не потребуются адреса обработчиков из этого вектора. Вам нужет адрес самого вектора прерываний. Его адрес будет в начале загрузчика.

Затем необходимо добавить обрабочик прерывания в вашем приложении. Данный обработчик сам по себе ничего не делает — он осуществляет безусловный переход на функцию — обработчик прерывания загрузчика. Например:
// This must be declared "naked" because we want to let the
// bootloader function handle all of the register push/pops
// and do the RETI to end the handler.
void USB_GEN_vect(void) __attribute__((naked));
ISR(USB_GEN_vect)
{
    asm("jmp 0x302C");
}
Это не будет работать если не пометить функцию атрибутом «naked». Без этого атрибута созданная продедура ISR в приложении будет толкать значения в стек, которые никогда не будут извлечены, что означает, что обратные адреса будут теряться. Это произойдет, потому что вы делаете не вызов ISR загрузчика, а безусловный переход на него и функция RETI в конце ISR загрузчика не вернет курсор к ISR приложения, а вместо этого курсор попадет обратно в код, который исполнялся во время вызова ISR. Также отметим, что в ассемблерных вставках GCC автоматически преобразуются байт-адреса в слово-адреса, так что вам не нужно их делить пополам.
Если вы не хотите забивать голову деталями, вы можете заменить все объявления с атрибутами «naked» на макросы или организовать встроенную функцию для вызова общих обработчиков через указатели. Указатель на функцию будет выглядеть так же как и в вопросе № 14. Но вам придется поплатиться за эту простоту задействованием кучей бесполезных регистров которые появятся на входе и выходе из ISR приложения. 

Как организовать доступ к глобальным данным внутри общих обработчиков ISR?

Такая же ситуация как и в вопросе №15, но на этот раз решение не такое простое, поскольку вы не можете поместить в стек обработчика ISR указатель. Есть целый ряд возможных решений, но, поскольку это руководство уже довольно обширно об этом будет сказано не так подробно. Есть два варианта, таких как использование регистров GPIO для передачи указателей на глобальные или резервирование части SRAM с известным адресом, где расположены глобальные данные. Если вам нужен иной способ, то вам сюда: http://tinyurl.com/q3fpud . Идея с зарезервированной областью SRAM, кажется неплохой.

Можно ли сэкономить место в загрузчике на использовании обработчиков ISR?

Да, зачастую таким образом можно сэкономить 100 и более байт загрузчика. Эта также относиться и к обычным приложениям, но такая экономия для загрузчика более существенна чем к приложению. Некоторые архитектуры AVR имеют 40 или более прерываний, каждый из которых в таблице векторов прерываний принимает по 4 байта. Вы можете не только незначительно сэкономить, но и переопределять неиспользуемые вектора как переходы на общие функции (обсуждается в вопросе № 14).

Первая запись в таблице прерываний — это вектор сброса. Загрузчики и приложения часто пользуются вектором сброса, т.к. исполняемый код никогда не начинается с начала прошивки. Даже если вектор сброса в настоящее время не требуется, он может понадобиться в будущем, например, после того, как кто-то добавит новую переменную PROGMEM. Поэтому вместо того чтобы, полностью удалять таблицу прерываний из загрузчика, лучше просто его уменьшить. Минимальная таблица прерываний может быть записать таким образом:
.section .blvects,"ax",@progbits
.global __vector_default
__vector_default:
    jmp  __init
Эта таблица содержит только вектор сброса, который ведет на  функцию __init среды исполнения С (это то, что делает вектор сброса по умолчанию). Предполагая, что JMP можно заменить на RJMP, мы имеем вектор прерываний размером в 2 байта. Добавьте этот .S файл в строку ASRC вашего Makefile.
Более правильный способ замены таблицы векторов по умолчанию заключается в использовании специального сценария линкера. Сначала необходимо узнать из какого места берет скрипты компоновщик AVR. Теоретически сценарии компоновщика должен быть назван именем архитектуры AVR. Но оказывается, что иногда это не так, поэтому обнаружить скрипт можно переименованием папки, в которой он содержится (чаще всего это  C:\WinAVR\avr\lib\ldscripts на Windows, и /usr/local/avr/lib/ldscripts на Unix-подобных ОС), и последующей перекомпиляцией. Компоновщик будет жаловаться «Не удается открыть файл сценария линковщика ldscripts/avr3.x». Это подскажет вам правильное имя файла сценария. Восстановите исходные имена директориям и скопируйте найденный файл в каталог проекта. Затем добавьте следующую строку в Makefile в место, где прописываются флаки компоновщика:
LDFLAGS += -T bootloader.x   # Or whatever you named the linker script
Теперь нужно изменить скопированный скрипт компоновщика используя ваш уменьшенный вариант таблицы прерываний, а то что по умолчанию убрать. Откройте скрипт компоновщика и найдите «»vectors». Вы должны найти текст со следующим содержанием:
.text   :
  {
    *(.vectors)
    KEEP(*(.vectors))

Добавьте строчку DISCARD и замените «vectors», на ваше имя секции:

/DISCARD/ : { *(.vectors); } /* Discard standard vectors */
  .text   :
  {
    *(.blvects)   /* Position and keep custom vectors */
    KEEP(*(.blvects))
Если у вас не используются прерывания и таблица ISR пуста, то это все что вам нужно сделать. О другом подходе можно упоминуть вскользь — необходимо использовать флаги компоновщика -nostartfiles и -nodefaultlibs совместно с пользовательской процедурой инициализации. Это позволяет исключить из прошивки таблицу прерываний по заданную по умолчанию, также как и саму среду исполнения С. Если вам необходима более детальная информация по данной теме, то вы можете обратиться за ними по следующим ссылкам:

Если загрузчик использует таблиуц прерываний ISR, вы можете сэкономить на размере прошивки заменив полную таблицу прерываний на уменьшенную версию. Допустим, нам необходимо только 11-е прерывание (USB на AT90USB162), поэтому мы усечем таблицы и повторно задействуем слоты до прерывания 11 в качестве переходов на общую функцию. При этом убедитесь, что положение оставшихся векторов прерываний правильно. Каждый должен быть нацелен на адрес указанный для этого прерывания в даташите (‘nop’ы в примере ниже). Повторно задействуя часть таблицы векторов вы можете избежать необходимости в таблице с отдельными переходами, как рассказано в вопросе №14. Вам просто потребуются указатели на функции для повторного вызова векторов. См. комментарии ниже для более подробной информации:

.section .bootvect,"ax",@progbits
; Custom vector table that eliminates wasted space after the last used
; vector (__vector_11, usb general). Also re-purpose the unused space
; between the reset vector and the usb vector for the jumps to shared
; code.
;
.global __vector_default
; There are 21 "word" spaces between __init and __vector_11. This fits 
; 21 RJMPs or 10 JMPs. Since the bootloader is only "2K words" long, 
; use RJMPs.
; - Don't change the order of these (unless it is before any devices 
;   shipped)!
; - Add new entries by replacing nop's
; - Remove entries by replace them with nop's (without reordering)
__vector_default:
    rjmp  __init          ; 0x3000  !used interrupt!
    rjmp shared_func1     ; 0x3002
    rjmp shared_func2     ; 0x3004
    rjmp shared_func3     ; 0x3006
    rjmp shared_func4     ; 0x3008
    rjmp shared_func5     ; 0x300a
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    rjmp __vector_11      ; 0x302C  !used interrupt!

 

Автор: Брэд Шик <[email protected]> При участии и редактирования Клифф Лоусон. Перевод: Валеев Денислам.
]]>
http://www.blogs-it.ru/mikrokontrollery-avr/avr-bootloader-v-voprosah-i-otvetah-2/feed/ 0
AVR UART/USART на WinAVR C RS232/RS485 http://www.blogs-it.ru/mikrokontrollery-avr/avr-uart-usart-na-winavr-c/ http://www.blogs-it.ru/mikrokontrollery-avr/avr-uart-usart-na-winavr-c/#respond Thu, 30 Aug 2012 10:38:06 +0000 http://www.blogs-it.ru.mastertest.ru/?p=227 Данный пример основан на статье компании Atmel AVR306: Using the AVR® UART in C и описывает как настроить и задействовать UART на большинстве устройств ARV.
Примеры на языке C предоставляют примеры использования UART в следующий режимах:
  • Режим опроса (меньше кода);
  • Режим прерываний (программа свободна во время обмена данными).
Использование UART в режиме опроса позволяет создавать более простой и компактный код. Такой способ предпочтителен в таких случаях, когда использование прерываний не рекомендуется, а компактность кода является одним из наиважнейших требований к программе, например, при реализации собственного AVR-загрузчика (bootloader), применяющего для коммуникаций интерфейс RS232 или RS485 (для RS485 имеются определенные ограничения. Как учесть их описано ниже).
Режим прерываний же позволяет добиться наивысшей производительности, но требует больше усилий.
Скачать примеры можно по ссылкам указанным внизу документа (UART1.c, UART2.c, USART1.c, USART2.c). Примеры даны для микроконтроллеров ATmega128 и

Использование примера

Для этого понадобится:
  • Создать тестовый проект в AVR Studio;
  • Вставить в проект код из примера и адаптировать его под свой тип микроконтроллера и отладочной платы;
  • Запустить тестовую программу и произвести обмен данными.
Создайте проект WinAVR C в AVR Studio и выберите свой тип микроконтроллера (микроконтроллеры AVR8 с поддержкой USART). Выберите нужный вам режим задействования UART и вставьте соответствующий код из указанного в списке.
Адаптируйте вставленный код под ваш тип микроконтроллера. Это касается названий таких регистров как UBRR, UCR или UDR. Правильные названия необходимо брать из даташита на ваш микроконтроллер, т.к. названия регистров для вашего типа микроконтроллеров могут отличаться. К примеру, если в микроконтроллере имеется несколько UART эти переменные будут иметь в своем имени цифровые индексы.
К адаптации также относится процедура инициализации USART. Используя даташит на микроконтроллер необходимо вычислить правильные значения регистров UART на основе требуемых параметров скорости передачи данных и формата кадров.
К примеру, для Atmega32 необходимо присвоить UBRRL = 47, UCSRA |= _BV( U2X ) в случае с частотой 7372800Гц BAUDRATE = 19200 бод, а также присвоить UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1) для установки формата символа 8-N-1 (битов данных-четность-стоповых битов).
Далее потребуется программа для тестирования соединения с микроконтроллером. Если ваше отладочное устройство подключено к компьютеру через RS232, то можно для этого использовать стандартную программу HyperTerminal, входящую в состав операционной системы (Пуск->Все программы->Стандартные->Связь->HyperTerminal). Запустите программу и создайте подключение с теми же параметрами, что были выставлены для микроконтроллера. Подключите отлаживаемое устройство к компьютеру и запустите на нем программу.

Особенности применения UART на RS485

Как известно, главное отличие RS232 или RS485 заключается в том что RS232 предназначен для подключения двух устройств, а RS485 для подключения нескольких, в связи с чем применение RS485 немного сложнее применения RS232. Сложность возникает за счет того, что при использовании RS485 необходимо применять управляющий сигнал состояния канала, от которого зависит в что сейчас готово делать устройство — читать или записывать данные в линию.
Добавим в программу следующий макрос:
#ifdef  RTS_ENABLE

#define RTS_PIN         PA6
#define RTS_DDR         DDRA
#define RTS_PORT        PORTA

#define RTS_INIT        \
    do { \
        RTS_DDR |= _BV( RTS_PIN ); \
        RTS_PORT &= ~( _BV( RTS_PIN ) ); \
    } while( 0 );

#define RTS_HIGH        \
    do { \
RTS_PORT |= _BV( RTS_PIN ); \
    } while( 0 );

#define RTS_LOW         \
    do { \
        RTS_PORT &= ~( _BV( RTS_PIN ) ); \
    } while( 0 );

#endif

Макрос содержит три определения и три инструкции, необходимые для управления режимом передачи/чтения. Определения указывают к какой ноге микроконтроллера подключен управляющий сигнал RS485, а инструкции определяют процедуру инициализации порта две инструкции включения и выключения режима передачи.

Изменим исходный код UART1.c от Atmel, следующим образом:
Пример использования UART на RS485.
// AVR306: Using the AVR UART in C
// Routines for polled UART
// Last modified: 02-06-21
// Modified by: AR

/* Includes */
#include <io8515.h>

#ifdef  RTS_ENABLE

#define RTS_PIN         PA6
#define RTS_DDR         DDRA
#define RTS_PORT        PORTA

#define RTS_INIT        \
    do { \
        RTS_DDR |= _BV( RTS_PIN ); \
        RTS_PORT &= ~( _BV( RTS_PIN ) ); \
    } while( 0 );

#define RTS_HIGH        \
    do { \
RTS_PORT |= _BV( RTS_PIN ); \
    } while( 0 );

#define RTS_LOW         \
    do { \
        RTS_PORT &= ~( _BV( RTS_PIN ) ); \
    } while( 0 );

#endif

/* Prototypes */
void InitUART( unsigned char baudrate );
unsigned char ReceiveByte( void );
void TransmitByte( unsigned char data );
uint8_t receiveMode = 1;

/* Main - a simple test program*/
void main( void )
{
InitUART( 11 ); /* Set the baudrate to 19,200 bps using a 3.6864MHz crystal */

for(;;)      /* Forever */
{
TransmitByte( ReceiveByte() ); /* Echo the received character */
}
}

/* Initialize UART */
void InitUART( unsigned char baudrate )
{
UBRR = baudrate;                  /* Set the baud rate */
UCR = ( (1<<RXEN) | (1<<TXEN) );  /* Enable UART receiver and transmitter */
}

uint8_t isReceivedByte( void ) 
{
if (!receiveMode)
{
RTS_LOW;
cbi(UCSRB, TXEN); 
sbi(UCSRB, RXEN); 
receiveMode = 1;
}
return UCSRA & (1<<RXC);
}

/* Read and write functions */
unsigned char ReceiveByte( void )
{
while ( !isReceivedByte() ) /* Wait for incomming data */
;                 /* Return the data */
return UDR;
}

void TransmitByte( unsigned char data )
{
while ( !( UCSRA & (1<<UDRE)) )
;
if (receiveMode)
{
cbi(UCSRB, RXEN); 
sbi(UCSRB, TXEN); 
RTS_HIGH;
receiveMode = 0;
}

/* Put data into buffer, sends the data */ 
UDR = data; 
while ( !( UCSRA & (1<<TXC)) )
; 
_delay_ms(0.5);

    return;
}

 

]]>
http://www.blogs-it.ru/mikrokontrollery-avr/avr-uart-usart-na-winavr-c/feed/ 0
AVR BootLoader в вопросах и ответах. Часть 1 http://www.blogs-it.ru/mikrokontrollery-avr/avr-bootloader-v-voprosah-i-otvetah/ http://www.blogs-it.ru/mikrokontrollery-avr/avr-bootloader-v-voprosah-i-otvetah/#respond Thu, 30 Aug 2012 10:37:24 +0000 http://www.blogs-it.ru.mastertest.ru/?p=225 Вы планируете создать собственный загрузчик? Тогда этот документ содержит ответы на многие вопросы, которые в связи с этим у вас появятся. Большинство понятий, охватываемых здесь не затронуты достаточно подробно в даташитах на микроконтроллеры, но тем не менее эти советы важны для проектирования надежных бутлоадеров. Большая часть представленной здесь информации можно найти на avrfreaks.net разбросанной по разным веткам. Приведенные ниже вопросы упорядочены от простого к сложному и для создания жизнеспособного загрузчика, вы, вероятно, захотите понять ответы, по крайней мере на первые 11 вопросов.
Для успешного овладения материалом предполагается, что вы уже знаете для чего нужен загрузчик, владеете програмированием на языке С, и знакомы с созданием обычных 8-разрядных приложений AVR. Этот документ основан на инструменте AVR-GCC с применением библиотек AVR-Libc и на типовом Makefile. Если вы используете иной инструмент, то все что описано в данном документе остается в силе, но и код Makefile примеры должны быть
соответствующим образом адаптированы под ваш инструмент.
Также обратите внимание, что примеры основаны на AT90USB162 и должны быть приспособлены к вашей AVR до их повторного использования.

С чего начать?

По сути, загрузчик — это просто обычное приложение AVR, которое расположено в специальной области флэш-памяти. В простейшей форме, приложение можно сделать загрузчиком AVR путем указания дополнительного флага компоновщику, который необходимо добавить в свой Makefile:

LDFLAGS += -Wl,--section-start=.text=0x3000

Этот флаг указывает начальный адрес байта из загрузчика. Вы можете найти это значение в даташите для своего типа AVR. Убедитесь, что вы используете адрес байта, а не адрес слова (большинство даташитов от Atmel определяют адреса флеш-памяти списком из слов, но некоторые списками байт). Вместо жесткого указанного начального адреса загрузчика я предлагаю объявить константу в файлеMakefile:

BOOTSTART = 0x3000 
LDFLAGS += -Wl,--section-start=.text=$(BOOTSTART)

Что такое области NRWW и RWW?

Это описано в даташитах, но название этих терминов может запутать. NRWW и RWW обозначают разные области флэш-памяти микроконтроллеров и определяют что происходит с процессором в то время как к указанной области памяти происходит обращение на чтение или запись. Загрузчик всегда находится в в области no-read-while-write или NRWW (буквально не читать пока писать). Очень часто область NRWW резервируют полностью под загрузчик, но это вовсе не обязательно. Когда происходит стирание или запись в области памяти NRWW процессор останавливается, потому что задействуется режим «не-чтения» (no-read). Сами приложения, как правило, хранятся в области read-while-write (RWW) что буквально означает читать пока писать. Пока производится запись или стирание в области RWW процессор может продолжать работать до тех пор, пока процессор исполняет код  расположенный в разделе NRWW (в области загрузчика). Пока область памяти RWW перепрограммируется любые попытки считать из нее данные будут возвращать 0xFF. Прежде чем область RWW снова станет доступна для чтения после программирования область необходимо переактивировать (подробнее об этом в вопрос № 3).

Вот что вам действительно необходимо знать об особенностях областей RWW и NRWW: 

  • Загрузчик может перепрограммировать приложения, расположенные в области RWW, при этом исполнение загрузчика не прерывается;
  • Загрузчик не может обновлять свой код также просто как код приложения;
  • Приложения очень редко обновляют загрузчик;
  • Приложения могут обновить себя, но лучше чтобы это делал загрузчик.

Как загрузчик обновляет приложение?

Каким образом загрузчик получит программу для перепрограммирования контроллера зависит от вас. Распространенными каналами связи являются UART и USB. Протокол обмена данными по каналу может быть собственный или стандартный, наподобие AVR109 или DFU. При реализации стандартных протоколов можно использовать уже существующие инструменты, такие как AVR Studio, работающий по протоколу AVR109 или Atmel’s Flip работающий по протоколу DFU. Тем не менее эти стандартные протоколы как правило немного раздуты, а при реализации простого пользовательского протокола загрузчик как правило будет меньше размером и чище. Правда в таком случае вам понадобится  также разработать собственное решение для передачи данных загрузчику.

Обычно загрузчику передается за раз одна страница памяти. Загрузчику необходимо записать эти
страницы в область флэш, предназначенную для приложения, то есть в RWW. AVR-Libc предоставляет заголовочный файл<avr/boot.h> который имеет все необходимое для этого. Эти функции очень хорошо документированы и сопровождены примерами. Несколько советов: 

  • Используйте удобный макрос _safe, чтобы не забыть применять ожидание готовности MCU;
  • Убедитесь в том, что  каждая страница  стирается прежде чем в нее производится запись;
  • boot_page_fill принимает адрес в байтах, но пишет слово за один раз. В цикле необходимо
  • увеличить адрес на 2 байта;
  • После программирования не забудьте снова включить область RWW с помощью макроса boot_rww_enable
  • макрос. Делайте это до чтения или запуска приложения, иначе раздел RWW будет состоять из 0xFF;

Может ли загрузчик обновлять значения фьюзов?

С AVR это невозможно. Для этого вам потребуется внешний программатор.

Для чего нужен BOOTLOADER_SECTION из <avr/boot.h>?

Несмотря на свое название макрос BOOTLOADER_SECTION не является полезным при написании загрузчика. Этот макрос просто помогает вам переназначить позицию вашей функции в раздел NRWW флеш-памяти. Вероятно, для этого макроса более подходящим названием является что-то вроде NRWW_SECTION.

Макрос BOOTLOADER_SECTION может потребоваться если приложению необходима функция перепрограммирования собственного приложения, т.к. такая функция будет работать только если она будет выполнена из разделаNRWW. BOOT_LOADER_SECTION на самом деле просто создает специальную секцию для кода с названием «.bootloader» (другое название лучше не использовать), а затем дополнительный флаг компоновщика позиционирует данную секцию где-то в неиспользуемой области памяти раздела NRWW. Такой подход не очень часто применяется на практике.
Некоторые люди склонны использовать BOOTLOADER_SECTION для написания приложения и загрузчика сразу в одной программе, но это не очень хорошая идея. Загрузчик хорош в виде автономных программ, которые никак не зависят от самого приложения. Это будет более надежным решением, при том что если загрузчик будет отдельным приложением, то и создавать его тоже будет проще.

 Как прошить загрузчик для микроконтроллеров?

Так как загрузчику не просто обновить самого себя, а приложения практически никогда не изменяют загрузчик, то вам потребуется внешний программатор для записи загрузчика в микроконтроллер. В качестве примера программаторов можно привести STK500, AVRISP, AVR Dragon, JTAGICE MKII и т.д. Режимы программирования вы будете задавать в зависимости от вашего типа AVR. Вам не нужно делать ничего особенного, чтобы прошить в микроконтроллер загрузчик. Если у вас есть рабочий внешний программатор, который может заливать прошивки и менять фьюзы, то он вполне подойдет и для заливки загрузчика. Программатор просто читает файл прошивки с загрузчиком и записывает его по указанному адресу. Программатору все равно, что вам посчастливилось писать в область NRWW флеш-памяти.

Как прошить сразу приложение и загрузчик?

Так как, надеюсь, вы создали отдельно приложение и загрузчик отдельно, то в конечном итоге у вас появится два отдельных шестнадцатеричных файла с прошивками (например, app.hex и boot.hex). Возникает вопрос: как залить их обе в AVR. Существует несколько вариантов:

В два этапа: Залейте загрузчик с помощью внешнего программатора как описано в Вопросе № 6. Возможно, вам при этом потребуется также установить требуемые значения фьюзов включая BOOTSZ и BOOTRST. После этого можно просто использовать обычный механизм связи загрузчика для передачи и прошивки в микроконтроллер приложения.
В один этап: Объединить файлы app.hex и boot.hex в один и использовать внешний программатор для записи объединенного файла в микроконтроллер. Возможно, вам при этом потребуется также установить требуемые значения фьюзов включая BOOTSZ и BOOTRST.
Я думаю, что самый простой способ объединить шестнадцатеричные файлы с помощью командной строки srec_cat. Этот инструмент входит в набор инструментов srecord. Он поставляется с WinAVR и очень легко устанавливается на Unix-подобных ОС. Вот команда, которую вы должны при этом использовать:
srec_cat app.hex -I boot.hex -I -o combined.hex -I

Также вы можете вручную объединить файлы app.hex и boot.hex файлов с небольшими правками:

Каждый шестнадцатеричный файл имеет одну последнюю запись, в которой говорится, что «файл заканчивается». Таким образом, после ручного объединения нужно отредактировать объединенный шестнадцатеричный файл — найти в нем запись окончания файла, расположенную в конце app.hex (после объединения где-то в середине файла) и удалить ее. Запись имеет тип 01. Байт типа записи в шестнадцатеричном формате Intel по порядку является 4-м байтом, поэтому запись на самом деле будет выглядеть примерно так: «:00000001FF». Вся линия (та что в середине, а не в конце файла) должна быть удалена.

Можно ли в загрузчике использовать прерывания?

Да, для этого достаточно сказать процессору, чтобы тот использовал вектор прерываний, расположенный в области загрузчика а не в области приложения. Для этого где-то в начале кода загрузчика (до использования прерываний), надо добавить строки вроде этих:

MCUCR = (1<<IVCE);
MCUCR = (1<<IVSEL);

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

Что должно загружаться в первую очередь — загрузчик или приложение?

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

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

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

Как узнать загрузчику когда запускать приложение?

Есть много возможностей. Если устройство имеет кнопку или другой механизм ввода, вы можете послать соответствующий сигнал нажатием. Тогда загрузчик, как правило, запустит приложение сразу. А в случает если кнопка будет не нажата во время сброса, то загрузчик продолжает исполнение. Это пример того как работает загрузчик чипа STK500.

Другим распространенным решением для загрузчика является проверка внешнего канала связи на специальный символ во время запуска. Опять же, загрузчик, как правило, запустит приложение сразу, а продолжает исполняться только после проверки внешнего канала связи и получения определенного ответа или поиска ожидаемых данных. Примером такого подхода является Atmel Butterfly.
В нашем случае, ни одно из этих решений не подходят. Наше устройство не имеет кнопок и мы хотели бы чтобы приложение запускалось в обычных условиях очень быстро. Единственный внешний канал связи является USB, к сожалению, устройство USB требует некоторое время (в процессор выражении) прежде чем будет возможен обмен данными с хостом.
Так вот что мы сделали: Если предположить, что AVR имеет EEPROM, вы можете хранить в нем байтовое значение, которое указывает, когда загрузчик должен продолжать работать, а когда запустить приложение. У этого подхода два этапа. Сначала где-то в начале кода загрузчика необходимо добавить что-то вроде этого:
// Bootloader code
const uint8_t app_run = eeprom_read_byte(ADDR_APP_RUN);
if(app_run == APP_RUN)
{
    // In case the app is faulty, clear the eeprom byte so that
    // the BL will run next time. A properly running app should
    // set this back to APP_RUN.
    eeprom_write_byte(ADDR_APP_RUN, 0xFF);
    run_application();
}
// Only run the bootloader once, then go back to the app
// (comment out the next line during app development)
eeprom_write_byte(ADDR_APP_RUN, APP_RUN);

Затем где-то подальше в приложении, в той части кода, при обработке которого вы уже точно уверены, что приложение работает правильно добавьте следующее:

// Application code
eeprom_write_byte(ADDR_APP_RUN, APP_RUN);

Это работает следующим образом: если приложение было с успехом исполнено ранее, то загрузчик будет читать
байт APP_RUN подготавливать к переходу к исполнению приложения. Однако незадолго до запуска приложения байт APP_RUN очищается. Приложение затем снова пишет байт APP_RUN в тот момент когда она считает, что она работает правильно. Таким образом последовательность повторяется. Если с приложением до сброса произошел сбой до того момента как оно производит сброс байта APP_RUN, то после перезагрузки загрузчик будет оставаться на исполнении. Если вы закомментируете указанную выше строку в коде загрузчика, то загрузчик будет оставаться на исполнении только один раз, а в следующие разы после сброса будет запускать приложение.

Я также предлагаю способ принудительно запустить загрузчик из приложения. Вам просто необходимо очистить байт APP_RUN и предотвратить его перепись позже. Мы реализовали это в нашем приложении, а делается это по команде, отправленной через USB с программы, запущенной на компьютере.
Один из недостатков такого подхода является то, что EEPROM компании Atmel на большинстве контроллеров имеет ресурс в 100000 циклов записи/стирания. Поскольку этот подход производит два цикла стирания/записи во время каждого пуска, то получается ресурс устройства ограничен 50 000 циклами перезагрузки. Для нашего приложения я прикинул, что продолжительность жизни устройства составляет в среднем 13,7 лет при 10 перезагрузках день. Этот предел можно легко расширить если износ ячеек EEPROM распределить.

Как загрузчик запускает приложение?

Существует на самом деле только один способ, вы должны переместить программный счетчик в начало приложения (которое, как правило, является вектором сброса). Если у вас есть приложение на основе
обычной библиотеки AVR-Libc, то в начале вашего приложения будет расположен рантайм языка с, который инициализирует стек и глобальные переменные, а затем располагается ваша функция «main». Вы можете переместить счетчик программы с помощью ассемблерной команды jump или вызовом функции, расположенной по нулевому адресу. Я выбрал команду jump:

asm("jmp 0000");
Но это еще не все. Когда вы непосредственно запустите приложение указанным способом микроконтроллер не будет сброшен в исходное состояние как это происходит после перезагрузки. Значения регистров не очищаются, а периферия не выключается. Есть два распространенных способа справиться с этим. Первый подход заключается в намеренном провоцировании сброса с помощью сторожевого таймера. Это приведет к сбросу микроконтроллера в первоначальное состояние и возобновит загрузчик (если у вас установлен бит BOOTRST). Если условия, что вызвало загрузчик больше нет (например, вы больше не удерживаете кнопку), то загрузчик должен немедленно запустить  приложение. Необходимо начать исполнение приложения как можно быстрее, пока изменения коснулись как можно меньше ресурсов микроконтроллера. Вот пример:
Disable_interrupt();
Wdt_change_16ms();
while(1);
Потом где-то ближе к началу загрузчика сделать переход на адрес 0.
Второй подход состоит в том, что загрузчик прежде чем перейти к запуску приложения, очищает за собой все и переходит к исполнению программы сразу без перезагрузки. Линейка загрузчиков Atmel USB работает именно таким образом. С применением USB-загрузчика имеет смысл отключить USB и вернуть вызов прерываний обратно в область приложения перед переходом к приложению:
Disable_interrupt();
// Shutdown USB cleanly
Usb_detach();
Usb_disable();
Stop_pll();
// Put interrupts back in app land
MCUCR = (1<<IVCE);
MCUCR = 0;
// Run the applicat
Приложение затем должно явно сконфигурировать все ресурсы что оно собирается использовать.
]]>
http://www.blogs-it.ru/mikrokontrollery-avr/avr-bootloader-v-voprosah-i-otvetah/feed/ 0