Uart программа для прошивки

Обновлено: 04.07.2024

  • Open with Desktop
  • View raw
  • Copy raw contents Copy raw contents Loading

Copy raw contents

Copy raw contents

Прошивка МК через порт UART (самопрограммирование)

Прошивка чипа посредством программатора, зашитого в сам этот чип (секция загрузчика - Boot Loader Section). В руководствах по чипам AVR данный процесс называется "самопрограммирование" микроконтроллера.

Плюсы:

  • Быстрый программатор
  • Все платы ARDUINO с USB разъемом готовы к работе прямо из коробки (классно для новичков)
  • дешевые USB-to-Serial (или USB-to-TTL) переходники (FTDI, CH430, CP2102, PL2303), позволяющие быстро подключить и прошить ARDUINO pro mini (те, что без USB порта)

Минусы

  • UART занят. Если изделию для работы нужен этот порт, то нужно извращаться с переключателями (отрубать порт RX от внешнего устройства на время прошивки)
  • внутренний программатор отъедает память flash - почти килобайт становится недоступным
  • новый чип требует предварительной прошивки программатора (например через SPI)
  • нет возможности тонкой настройки чипа - прошивки фьюзов

Общий принцип прошивки методом самопрограммирования: Программа под целевой (target) микроконтроллер (МК) пишется, собирается на хост машине (Windows, Linux, MacOS). Затем готовый hex файл с помощью программы avrdude, запускаемой на хост машине, через COM порт (как правило, виртуальный COM порт поверх реального USB соединения) передается на UART вход МК, где "подхватывается" программатором (программка в бутлоадере МК) и уже программатор записывает (прошивает) получаемые от хоста данные во FLASH память МК.

Для реализации описанной схемы нужно устройство - USB-TTL (или USB-Serial) переходник, одним концом включаемый в USB порт хоста, другим - к UART порту целевого МК.

Обзор USB-Serial переходников

Прошивка целевого МК (ATMEGA168) производилась командой с использованием самопрограмматора arduino:

Примечание 1 во всех случаях использовались последние драйвера с сайта производителя чипа переходника

Примечание 2 тесты проводились с последней доступной версией arvdude (v6.3)

Устройство Изображение Комментарий
FT232RL-USB-Serial FT232RL-picture
Ok
Замечательно прошивает, не требует никаких особых телодвиждений, работает в режиме моста UART-Host
FT232RL-red-USB-Serial FT232RL-picture
Nok - прошивка НЕ РАБОТАЕТ (sync error).
Ок - работа в режиме моста UART-Host (взаимодействие с МК через программу-терминал на хосте)
CH340G-USB-TTL CH340G-picture
Ok Работает и прошивка и мост UART-Host
Требуется жать и отпускать RESET на целевом чипе, чтобы прошивка стартовала
CP2102-USB-TTL CP2102-picture
Ok Работает и прошивка и мост UART-Host
Требуется жать и отпускать RESET на целевом чипе, чтобы прошивка стартовала
PL2303XA-USB-TTL PL2303XA-picture
Nok - прошивка НЕ РАБОТАЕТ. Процесс прошивки повисает на 87%.
Требуется не забывать нажимать RESET на целевом МК в момент запуска прошивки
Ок - работа в режиме моста UART-Host (взаимодействие с МК через программу-терминал на хосте)
Arduino Original (m16u2) Arduino official
Ok Замечательно прошивает, не требует никаких особых телодвиждений, работает в режиме моста UART-Host.
В качестве USB-UART переходника используется полноценный микроконтроллер ATMEGA16u2. Т.е. на родной плате Arduino Uno имеем целых два МК от Атмел
Arduino China (CH340) Arduino China
Ok Замечательно прошивает, не требует никаких особых телодвиждений, работает в режиме моста UART-Host.
В качестве USB-UART переходника используется китайский чип CH340G. Работает вполне надежно, при этом на порядок дешевле варианта m16u2

Прошивка МК через порт SPI

Прошивка специальным внешним (или гибридным) программатором, подключаясь к пинам SPI порта целевого чипа.

Плюсы

  • Можно прошивать прямо в устройстве (In-System-Programming)
  • Можно прочитать\изменить фьюзы
  • Можно прошить "нулевый" (только с завода) чип
  • Можно восстановить "убитый" ARDUINO чип (если программатор внутри слетел)
  • для программирования чипа доступна вся его память (не тратим байтики на программатор внутри чипа)

Минусы

  • Нужно делать на плате устройства 6 пиновый разъем
  • нужен отдельный (внешний) программатор

(SPI) Программатор USBasp

Программа под целевой (target) микроконтроллер (МК) пишется, собирается на хост машине (Windows, Linux, MacOS). Затем готовый hex файл с помощью программы avrdude, запускаемой на хост машине, по интерфейсу USB передается на устройство USBasp, где обрабатывается микроконтроллером устройства (программа - программатор, прошитая в МК) и по интерфейсу SPI прошивается на целевой МК.

USBasp front-side

(USBasp) Тесты AVRDUDE (командная строка)

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

Ниже представлены результаты тестов путем прошивки контроллера ATMEGA328P (плата ARDUINO) командой:

Test case Результат Комментарий
avrdude 6.3 - стандартная Ok Прошивка чипа происходит без ошибок с правильным USB драйвером
avrdude 6.0.1 (найдена на форуме easyelectronics) Nok error: programm enable: target doesn't answer
avrdude 5.10 DI HALT edition Nok error: no usb support. please compile again with libusb installed
avrdude 5.11patch (в составе SinaProg 2.1) Ok Прошивка чипа происходит без ошибок с правильным USB драйвером
avrdude 6.1svn (в составе AVRDUDE_PROG 3.3) Ok Прошивка чипа происходит без ошибок с правильным USB драйвером

(USBasp) Тесты Windows GUI программ-прошивальщиков

(SPI) Программатор на базе модуля FT2232C (DI HALT)

Программа под целевой (target) МК пишется, собирается на хост машине (Windows, Linux, MacOS). Затем готовый hex файл с помощью программы avrdude, запускаемой на хост машине, по интерфейсу USB прошивается в целевой МК, подключенный к модулю по SPI. Используется специальный режим микросхемы FTDI "bitbang" (8 разрядный порт чипа FT2232 + специально заточенный драйвер FTDI позволяют программно управлять периферией с хоста, в частности, писать команды и данные в МК через SPI). Роль программатора (т.е. алгоритма, который берет данные из hex файла и пишет их во flash память целевого МК) здесь выполняет сама avrdude.

FT2232 front-side

(FT2232C) Тесты AVRDUDE (командная строка)

Важно не нужно использовать параметр -D (отмена очистки памяти перед прошивкой). Т.е. FLASH память должна обнуляться перед прошивкой.

Ниже представлены результаты тестов путем прошивки контроллера ATMEGA328P (плата ARDUINO) командой:

Примечание: необходимо в файл avrdude.conf вручную добавить конфигурацию программатора ибо он нестандартен:

  • для avrdude версии < 6 параметры выглядят так:
  • для avrdude версии > 6 параметры выглядят так:
Test case Результат Комментарий
avrdude 6.3 - стандартная Nok error: no pthread support. Please compile again with pthread installed
avrdude 6.0.1 (найдена на форуме easyelectronics) Nok error: no ftdi support. Please compile again with libftdi installed
avrdude 5.10 DI HALT edition Ok Прошивка чипа происходит без ошибок
avrdude 5.11patch (в составе SinaProg 2.1) Nok Данная сборка avrdude не знает про ftdi bitbang режим - невозможно настроить avrdude.conf
avrdude 6.1svn (в составе AVRDUDE_PROG 3.3) Nok error: no pthread support. Please compile again with pthread installed

(FT2232C) Тесты Windows GUI программ-прошивальщиков

Описание GUI прошивальщиков приведено ранее. Если есть желание использовать определенную GUI оболочку - не забудьте связать ее с рабочей версией avrdude.

Ремонт любой сложной электронной техники, в настоящее время можно условно разделить на два варианта: либо программный ремонт, “софтовый”, либо ремонт аппаратный, на уровне “железа”. Если первый подразумевает собой просто настройку аппарата, которую способен выполнить любой пользователь знакомый с техникой, в случае если по каким-либо причинам его настройки сбились в процессе эксплуатации.

Ремонт аппаратный - это чаще всего пайка, замена определенных радиодеталей которые вышли из строя по различным причинам. Будь то перегрев, например из-за набившейся пыли в корпусе устройства, и как следствие худшая теплоотдача, или же попадание влаги и в результате короткое замыкание. Либо то-же самое, любимое всеми мастерами КЗ устроенное на плате поселившимися насекомыми в корпусе устройства), а следы их деятельности, на платах, встречаются нередко.

Прошиваем с помощью клипсы

Прошиваем с помощью клипсы

Но существует и третий вид ремонта, обычно применительно к цифровой технике, в котором эти два вида ремонта бывают совмещены - это перепрошивка устройства. И если смартфон или планшет мы можем перепрошить просто подключив его к компьютеру по USB кабелю, то например, с роутером, материнской платой или видеокартой такой способ не пройдет. Все они содержат в своем составе Flash память, специальную микросхему, обычно 24 или 25 серии, в которой и хранится наша прошивка.


Микросхема памяти 25 серия

С материнскими платами и видеокартами обычно все просто - нужен программатор Flash и EEPROM памяти, например простой и дешевый CH341A о котором и пойдет речь, как одном из вариантов для решения нашей проблемы. Также для прошивания памяти без выпаивания будет нужна специальная клипса, для прошивания микросхем в корпусе SO-8 или SO-16. У меня есть обе клипсы в моей домашней мастерской.


Клипса для прошивания SO-8

Первая из них, для микросхем в корпусе SO-8, обычно бывает нужна во много раз чаще, чем вторая, для микросхем в корпусе SO-16. Которая пригодилась мне всего один раз для перепрошивки роутера Zyxel, они же, к слову сказать, так как считают себя известным брендом, оригинальничают и ставят иногда микросхемы в подобных корпусах SO-16, и хорошо еще если не микросхемы 29 серии, кто в теме - тот сразу поймет.


Разъем клипсы SO-16

Дело в том, что для того чтобы прошить микросхему 29 серии, нам необходим намного более дорогой программатор - MiniPro TL866A, который у меня также есть, но нет ни переходника с корпуса Dip на данный корпус, который имеет очень частое расположение ножек, и по сравнению с пайкой которого паять микросхему в SMD корпусе, те же SO-8 или SO-16 - детская забава. Так вот, мне на ремонт достался как раз роутер Zyxel с микросхемой 29 серии. В первый раз когда я ремонтировал предыдущий роутер Zyxel, микросхема была последовательной памяти, 25 серия, пусть и в корпусе SO-16. Тогда, как вы понимаете, выполнить ремонт было в разы проще.


Микросхема памяти 29 серии

Так как же все-таки мы можем восстановить роутер, если нам “повезло” и у нас стоит именно такая микросхема 29 серии? Производители роутеров, в данном случае, предусматривают аварийное перепрошивание через TFTP сервер. Но проблема в том, что иногда у нас бывает затерт загрузочный раздел в памяти микросхемы, который называется U-Boot. В таком случае вам подойдет вариант прошивки памяти роутера по определенным адресам, которые вы должны будете найти самостоятельно на специализированных форумах по перепрошивке роутеров. Но обычно все бывает намного проще - прошивка сбилась, данные необходимые для работы роутера в штатном режиме потеряны, но загрузочная область и калибровочная область целы. В Таком случае будет нужен простой и дешевый адаптер USB-TTL, стоимость которого на Али экспресс составляет всего порядка 40 рублей.


Также подойдет адаптер на микросхеме CH340A, который используется для заливки скетчей в плату Ардуино Pro mini, которая не имеет распаянного на плате загрузчика CH340A. Так-же подойдут адаптеры на базе pl2303, либо программатор Flash и EEPROM памяти CH341A, про который уже писал выше, и который может после перестановки перемычки работать в режиме USB-UART адаптера.


Программатор Flash и EEPROM памяти + USB-TTL

В крайнем случае можно будет воспользоваться кабелем для прошивания от старого мобильного телефона, также содержащим конвертер USB-COM, только нужно будет обязательно согласовать уровни по питанию. Питание с адаптера необходимо брать строго 3.3 вольта, никаких 5 вольт, которые он может выдавать, с определенного пина. Итак, допустим у нас есть этот адаптер, (вернее любой из перечисленных выше), мы установили для него драйвер, зашли в диспетчер устройств в Windows и определили, какому номеру СОМ порта соответствует наш адаптер. А данный адаптер это и есть не что иное, как виртуальный СОМ порт в вашей системе.

Ищем номер СОМ порта

Затем нам нужна какая-либо программа - терминал, в которой с помощью консольных команд, мы и будем восстанавливать наш роутер перепрошивая его. Но перепрошивать роутер мы будем не через данный адаптер, адаптер используется только для управления процессом прошивки. Как же в данном случае мы прошьем роутер? Существуют, конечно, варианты прошивки роутера через его процессор ARM по интерфейсу JTAG, и у меня есть и этот программатор, приобретенный на Али экспресс - это программатор Wiggler, подключаемый по LPT интерфейсу, но попробовав разобраться с ним решил, что способ перепрошивки с помощью TFTP сервера намного проще.


Программатор JTAG Wiggler

Разберем подробнее данный, более простой вариант, для которого JTAG программатор не нужен, это перепрошивка, как уже писал выше, через TFTP сервер. Для этого нам потребуется, подключить наш адаптер USB–UART к 4 пинам на плате роутера. Правда иногда бывает так, что производитель контактные площадки и дорожки развел, а сами пины не впаял. В таком случае можно самостоятельно впаять гребенку состоящую из 4 пинов, приобретенную в радиомагазине либо выпаянную с донорской материнской платы или какого другого устройства.


Эти пины в принципе можно даже не впаивать если нет возможности, а просто аккуратно подпаяться к пятакам на плате, контактным площадкам, куда должны были быть впаяны эти пины. Для этой цели очень удобен тонкий провод МГТФ. Итак, мы подключили адаптер к компьютеру, установили драйвер, обеспечили необходимое нам надежное соединение с этими 3 из 4 пинов на плате.


Джамперы Ардуино для адаптера

Для соединения с гребенкой удобно использовать джамперы, перемычки, используемые для подключения плат Ардуино к шилдам. Каким же образом, нам нужно соединить данные 3 провода? И почему всего три, если контактов четыре? Питание на роутеры не рекомендуют подавать от адаптера, питание должно приходить от собственного блока питания. Поэтому плюс питания лучше отсоединить, даже если вы используете как и положено напряжение 3.3 вольта.


Соединение адаптера и роутера - схема

Земли устройств, соединяемых между собой при перепрошивании, нужно объединять, поэтому землю, пин GND, подсоединить нужно будет обязательно. А вот оставшиеся два пина, RX и TX, нужно подсоединить “перекрестив” их между собой, то есть RX соединить с TX, а TX, с RX. Итак, мы подключили все правильно, затем нам нужно правильно настроить терминал, я предпочитаю пользоваться Putty, для того чтобы иметь возможность управлять нашим роутером через консоль, и соответственно залить в него новую прошивку.


Значит мы выбираем в настройках Putty порт Serial, последовательный порт, или СОМ порт, затем устанавливаем нужный номер СОМ порта, который мы предварительно посмотрели в диспетчере устройств. После этого нужно настроить скорость СОМ порта, обычно это 57600, реже 115200 бод. И наконец, убедившись еще раз, что все соединено правильно, ничего на плате не “коротит”, не будет замкнуто, в процессе перепрошивки, мы войдя заранее в настроенную консоль и подаем питания на роутер от родного блока питания.


Кракозябры в терминале

Если у вас на экране, побежали “кракозябры”, значит вы неправильно настроили скорость СОМ порта и нужно либо почитать какая скорость должна быть установлена для вашей модели роутера, либо подобрать ее экспериментально до пропадания “кракозябров” и появления обычного текста. Затем нужно будет нажать, сразу после включения питания роутера, поймав нужный момент, что бывает не так просто, определенную комбинацию клавиш, либо tpl, для роутеров TP-Link, либо цифры 4, вход в консоль, либо цифру 2, для роутеров Zyxel, запуск перепрошивки с TFTP сервера.


Интерфейс TFTP сервера

Сам сервер должен быть запущен от имени администратора в сетевых подключениях, там должен быть указан ip адрес сервера, который подскажет либо консоль, либо можете самостоятельно найти в интернете. В TFTP сервере нужно будет указать ip адрес клиента и папку, в которой находится наша прошивка.


Меняем настройки сетевого подключения

Сама прошивка должна быть обязательно без Boota, то есть когда мы шьем прошивку прицепившись клипсой, через программатор 25 серии SPI, нам необходим Фуллфлеш, или иначе говоря прошивка с загрузчиком, в данном случае прошивка должна быть стандартная, без загрузчика, какую обычно предоставляет производитель, на своем сайте. Имя файла прошивки лучше сделать попроще, например 123.bin, его будет нужно ввести в консоли, при запуске процесса перепрошивания.


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

Объяснение процесса прошивания получилось конечно объемное, но сам процесс для человека выполнившего его хотя бы пару раз, становится довольно простым делом. А учитывая, что роутеры это техника, которая долго не живет, особенно в период, когда проходят грозы, в мае - июне, думаю данная статья будет полезна новичкам желающим сэкономить средства на покупке нового роутера. Всем удачных ремонтов! Специально для сайта Радиосхемы - AKV.

Форум по обсуждению материала КОНВЕРТЕР USB-UART: ПЕРЕПРОШИВКА АДАПТЕРОМ


Теория работы импульсных источников питания и варианты схемотехники.


Радиоэлектроника и схемотехника для начинающих - первые шаги в радиоделе или с чего начать будущему радиолюбителю.


Модернизируем промышленный графический эквалайзер Прибой Э-014С.


Схема гитарного комбо-усилителя с блоком эффектов на базе микросхем TDA2052, PT2399 и TL072.

Рабочий драйвер для windows 7 - 10 .
(С форума скачивал - не завёлся .)

Порядок установки :
Разархивируйте , отключить всё от компьютера , запустить файл installer.exe под свою архитектуру .
После перезагрузить комп или ноут , воткнуть программатор и драйвер установится .CP210x-driver-windows7-10.zip ( 3.68 МБ )

Программатор не заводится пока не установлен драйвер .

Сперва не заметил pl2303 . Рабочий драйвер для вин 7-10 .
PL2303_Prolific_DriverInstaller_v1_9_0.zip ( 2.33 МБ )

Прикрепленное изображение

Вывод Описание
3V3 Питание 3.3В (выход)
GND Земля
5V Питание 5В (выход)
TXD Передача данных (Transmit Data)
RXD Прием данных (Receive Data)
DTR Готовность приемника данных (Data Terminal Ready)
DCD Наличие несущей (Carrier Detect)
DSR Готовность источника данных (Data Set Ready)
RTS Запрос на передачу (Request to Send)
CTS Готовность передачи (Clear to Send)
RTS Запрос на передачу (Request to Send)
RI Сигнал вызова (Ring Indicator)
SUS Приводится в высокий уровень, когда CP2102/9 входит в режим IDLE.
!SUS Приводится в низкий уровень, когда CP2102/9 входит в режим IDLE.

Прикрепленное изображение

Прикрепленное изображение

Прикрепленное изображение

Сперва не заметил pl2303 . Рабочий драйвер для вин 7-10 .

есть у меня шнурок на китайской 2303hx. после установки на win7 максимальная sp1 драйвера выдает

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

US7IGN, Добрый день. Где взяты драйвера? Пробовали их переустановить, или установить на другой ПК? попробуйте отключить проверку . Может и в sp1 чего то не хватает .
У меня встали без проблем .

Всем спасибо за советы, задачу решил, а проблему нет.

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

Нужная программа для работы с радио, которое я хотел запрограммировать, Kenwood MCP-F6 даже видит радио, но выдает ошибку communication timeout error

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

Достал старый ноут с ХР, куда вместо Kenwood MCP-F6 сразу поставил сторонний аналог link700 (под вин 7 она устанавливаться отказалась) - все увиделось и заработало.

В статье Загрузка программы в ОЗУ и запуск через UART мы научились загружать программу в ОЗУ и запускать ее. Давайте напишем программу для ОЗУ, которая умеет записывать массив данных из ОЗУ во FLASH память. Назовем эту программу "прошиватель". В массиве данных будет лежать наша программа мигания диодом. В итоге после прошивки при запуске из Flash на плате будет мигать светодиод.

Программа "Прошиватель"

Создаем новый проект, назовем его "Flash_UartWriter". В библиотеках выбираем пункты - Startup_MDR1986BE9x, EEMPROM, PORT, RST_CLK. Добавляем в проект новый файл "main.c". Как это сделать описано здесь - Создаем новый проект.

Теперь делаем настройки проекта для запуска в ОЗУ. Подробно это описано тут - Запуск программы в ОЗУ из Keil. В данном случае, файл "setup.ini" можно не создавать и не подключать, мы не планируем запускать проект в отладчике.

Далее приведен листинг программы "прошивателя", состоящий из одного файла "main.c". Код собран из двух примеров:

Мигание светодиодом - Hello World - светодиод. Отсюда мы возьмем настройку порта и цикл мигания светодиодом, для того чтобы как-то отображать статус того, что происходит в программе. И пример работы с EEPROM под названием "Sector_Operations" из библиотеки SPL. Этого примера мы уже слегка касались в статье Расположение функций в ОЗУ, программирование EEPROM.

Пример "Sector_Operations" при стандартной установке Keil можно найти по пути:
C:\Keil_v5\ARM\PACK\Keil\MDR1986BExx\1.4\Examples\MDR1986VE9x\MDR32F9Q1_EVAL\EEPROM\Sector_Operations

Полный листинг файла "main.c" получился такой:

Думаю ничего сложного в программе нет, я написал побольше комментариев, чтобы вопросов не возникло. Данный код будет располагаться в ОЗУ, поскольку мы загрузим его через UART. По этой причине нет необходимости решать вопрос с расположением файла "MDR32F9Qx_eeprom.c" в ОЗУ, как мы это делали в Расположение функций в ОЗУ, программирование EEPROM.

Bin файл для "HelloWorld"

Теперь нам необходимо получить bin файл для программы, которую мы будем прошивать в Flash. Как это сделать, написано тут - Загрузка программы в ОЗУ и запуск через UART, "Получение bin файла".

Пересобираем проект ("F7") и находим в папке проекта файл "HelloWorld.bin".

Давайте так же сотрем Flash память и убедимся, что до запуска нашего "прошивателя" в памяти пусто. В меню выбираем Flash - Erase. Для того чтобы данная операция отработала, к демо-плате должен быть подключен программатор в Jtag_B, переключатели Mode должны быть в режиме "000" и должно быть подано питание. Без установленного соединения, данный пункт меню не активен.


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

Прошиваем через UART

Выставляем режим загрузки через UART, Mode = "110". Операции работы с UART загрузчиком мы рассмотрели в статье - Тестируем Bootloader в режиме UART. Далее загружаем обе программы "HelloWorld" и "прошиватель" в ОЗУ.

Как было указано в коде, "прошиватель" будет копировать память с адреса 0x2000_2000. Сюда и загрузим файл "HelloWorld.bin". Сам же "прошиватель" запишем в адреса с 0x2000_0000, потому что так было настроено в опциях проекта. Запуск "прошивателя" так же необходимо произвести с адреса 0x2000_0000. В свойствах bin файлов узнаем так же их размеры. В общем, делаем все тоже самое, что и в "Загрузка программы в ОЗУ и запуск через UART", с той лишь разницей, что дополнительно загружается программа "HelloWorld".

В итоге необходимая нам информация для загрузки:

Подключаем UART адаптер, подаем питание на плату, открываем программу "Terminal v1.9b". Там у нас уже были написаны и сохранены макросы для работы с UART. Допишем к ним следующие:

Проверяем, что "HelloWorld" еще не прошит

В программе Terminal нажимаем Connect. Настройки обмена должны быть выставлены согласно спецификации или статье Тестируем Bootloader в режиме UART. Запускаем Макрос М8 - прыгаем на программу из Flash, чтобы убедиться, что там еще не зашита программа мигания светодиодами. Наблюдаем, что светодиод не мигает. Если светодиод мигает, значит память не была очищена, возвращаемся к пункту Bin файл для "HelloWorld" .

Важно не забыть снять галочку циклической посылки 0-ля после получения ответа от МК, иначе этот ноль продолжает посылаться и весь последующий обмен через UART будет нарушен!

Протокол обмена в окне терминала выглядит так:

в Hex окне видим пришедшие данные:

Прошиваем Flash

Нажимаем Reset на плате для того, чтобы вернуться в UART загрузчик и начинаем все с начала:

Макрос "М7" - Увеличиваем скорость обмена до 19200 бод, чтобы загрузка прошла быстрее. В данном случае приходит неправильный ответ от МК, игнорируем. Выполняем макрос "М10" - МК входит в режим загрузки массива данных и ожидает 1484 байт.

В этот момент видим, что на плате зажегся светодиод. Т.е. запустился наш "прошиватель", и идет работа с Flash памятью. После короткого периода времени этот светодиод начинает медленно мигать, с периодом порядка 3 секунд. Это означает, что прошивка прошла успешно.

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


Проверяем зашитую программу

Давайте проверим, как прошилась наша программа. Испробуем два варианта:

1 - Проверка через UART загрузчик

Выполняем макрос "М8" - запускаем программу из Flash памяти.

2 - Проверка сбросом питания

Выставляем переключателями режим загрузки из Flash, Mode = "000".

В обоих случаях убеждаемся, что программа прошита успешно. И после Reset и после сброса питания программа исполняется именно из Flash памяти, куда мы ее и записали.

Таким вот образом можно запросто прошить микроконтроллер через UART. В данном примере программа у нас была заведомо небольшая, поэтому мы прошивали только одну страницу Flash. Но при небольшой доработке программы "Прошиватель", можно организовать загрузку программ размера большего чем одна страница. Так же при прошивке программ больших, чем размер ОЗУ, можно побить исходный bin файл и прошить его частями.


Иногда приходится делать схемки на МК, которые ведут обмен с компьютером посредством универсального последовательного порта (UART). Но кроме передачи разных настроечных параметров, было бы полезно этот самый порт использовать для обновления прошивки. Во-первых не нужен будет ни разъём ISP, ни программатор для внесения мелких исправлений, во-вторых сам процесс значительно упрощается, можно даже доверить пользователю загружать новые прошивки.

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

Я уже делал экзотические бутлоадеры для обновления прошивки по радио-каналу, через nRF24L01, или через wi-fi, но схемы подключающиеся по простому UART встречаются довольно часто, да ещё пару таких схем нарисовались в голове в планах на разработку.

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

Что значит универсальный? Это значит, что для адаптации его к очередной схеме на МК, нужно будет изменить пару констант и перекомпилировать. В его коде учитываются особенности разных МК, например, ATmega8 и ATmega88, у которых разительно отличается расположение регистров: например, регистры USART у ATmega8 находятся в нижней части пространства регистров, и доступ к ним осуществляется через in/out, в то время как у 88 и ему подобных эти регистры доступны только через их отображение в адресном пространстве, через lds/sts.

Итак, представляю результат моей разработки: ассемблерный код бутлоадера, который компилируется в не более чем 512 байт, работает почти на всех МК из семейства ATmega от 8 до 32кб (у МК с менее 8кб нет бутлоадера, а более 32кб — бутлоадер минимум 1кб). Главное, что работает с моим любимым семейством: ATmega88PA, 168PA, 328P

Принцип работы.

При сбросе или старте микроконтроллера, сначала запускается программа бутлоадера.
Бутлоадер проверяет наличие условий на принудительный запуск программы загрузки. Таких условий три:
1) если управление на программу бутлоадера было передано из основной программы;
2) если загрузка прошивки не была завершена должным образом;
3) если при запуске выполняется некоторое внешнее условие (определённый логический уровень на одной из ножек, или перемычка между парой ножек).

Чтобы узнать, откуда было передано управление, бутлоадер смотрит на содержимое регистра MCUCSR (или MCUSR в некоторых МК). В этом регистре хранится информация о том, что привело микроконтроллер к перезагрузке: низкое напряжение, сторожевой таймер, сброс через ножку RESET, включение питания, или JTAG. Если содержимое этого регистра равно нулю, значит переход был осуществлён из основной программы, т.е. программа либо сознательно вызвала бутлоадер, либо она поломана и адрес исполнения сам докатился до бутлоадера. В любом случае, нулевое значение — это сигнал, чтобы не переходить к основной программе, а включить режим загрузки и ожидать новой прошивки по UART.

Если же оказалось, что содержимое этого регистра было не нулевым, то его содержимое обнуляется. На случай, если основной программе зачем-то нужно будет изначальное значение этого регистра, оно сохраняется в регистре GPIOR0, а на МК где этого регистра нет — в первой ячейке SRAM памяти (как правило, это ячейка с адресом 0x0100)

Одна из ячеек (обычно — самая последняя) энергонезависимой памяти (EEPROM) отводится для хранения маркера об успешном окончании процесса прошивки. Когда начинается процесс прошивки, значение этой ячейки сбрасывается — в неё записывается 0xFF. Когда процесс прошивки завершён, то в неё записывается определённое значение. В зависимости от настроек, это делает либо сам бутлоадер, либо основная программа самостоятельно. При старте бутлоадер считывает значение этой ячейки, и если оно не равно заданному значению, то включается программа загрузки прошивки. Этот контроль можно отключить.
Возможность установки этого значения самой программой может быть полезна, чтобы обеспечить дополнительный контроль. Во-первых программа может определить что она была обновлена и выполнить некоторые действия (например, изменить сохранённые параметры должным образом), во-вторых запись значения в эту ячейку программа может осуществить после специальной команды от компьютера, тем самым позволяя лишний раз убедиться, что загруженная прошивка правильно работает и принимает команды с UART-порта, а значит позволит вызвать бутлоадер штатным образом.

И, наконец, третий контроль — проверка логических уровней на входе. Позволяет принудительно запустить бутлоадер после включения питания или сброса, путём удерживания специальной кнопки, или установки перемычки. Этот контроль может быть отключен, либо работать в одном из четырёх режимов:
1) низкий уровень на входе с включением подтягивающего резистора. На указанном входе включается подтягивающий резистор, и проверяется, что логический уровень остаётся низким в течение некоторого времени. Эта опция для типичного подключения кнопки.
2) высокий уровень — аналогично, но проверяется высокий уровень и подтягивающий резистор не включается. Должен существовать внешний стягивающий резистор.
3) Перемычка между двумя входами. Поочерёдно на двух входах включаются либо подтягивающие резисторы, либо выводится низкий уровень и замеряются логические уровни. Если изменение уровней свидетельствует о наличие перемычки между ними, то запускается загрузка прошивки. Эта опция полезна, если особенности подключения входов изначально не удаётся определить.
4) Низкий уровень на двух входах. Аналогично режиму 1, на обоих входах включаются подтягивающие резисторы, низкий уровень должен определятся на обоих входах в течение нескольких замеров подряд.

На деле, все эти проверки проходят практически мгновенно и не задерживают переход к основной прошивке.

Кроме того, есть возможность включить индикацию работы миганиями светодиодов.

Протокол работы.

Если какой-то контроль стрельнул, и переход к основному ПО не произошёл, то бутлоадер включает UART и ждёт команды.

Команд всего три:
BLST — вход в режим программирования, эта команда может быть выполнена в любой момент и начинает процесс загрузки сначала.
BLPG — запись страницы. Эта команда не может быть выполнена, если не выполнялась BLST.
BLXT — завершение процесса прошивки (если он был начат) и переход к основному ПО.

Запрос: 0x42 0x4C 0x53 0x54 (BLST)
Ответ: 0x62 0x6C 0x73 0x74 (blst) <размер страницы> <количество страниц> <id оборудования …>
После 4х символов blst в ответе следуют 16 байт, первый из которых указывает размер страницы в словах (т.е. парах байт), второй — количество страниц, доступных для прошивки (т.е. размер флеш-памяти в страницах, не считая самого загрузчика), а последующие 14 байт — это произвольная строка, идентифицирующая схему, которая может использоваться для предотвращения попыток загрузить неподходящую прошивку.

Запрос: 0x42 0x4C 0x50 0x47 (BLPG) <номер страницы> <данные …> <контроль>
Ответ: 0x62 0x6C 0x70 0x77 (blpg) <номер страницы> — если страница успешно загружена;
либо: 0x62 0x6C 0x65 0x72 (bler) — если не была вызвана BLST, неправильный номер страницы, или не совпал контроль.
Команде загрузки страницы должен предшествовать вызов BLST
<номер страницы> — номера страниц должны идти по порядку и начинаться с нуля
<данные …> — данные страницы. Количество данных точно равно размеру страницы в байтах (ответ blst возвращает её в словах, т.е. нужно умножить на 2)
<контроль> — это CRC с полиномом x^8 +x^7 +x^6 +x^3 +x^2 +x +1 (полином выбран из списка users.ece.cmu.edu/

koopman/crc/crc8.html) по всем байтам в поле data, от старших битов к младшим. Инициализируется значением 0xFF (способ расчёта контрольной суммы изменён 24.09.2016):
cc = 0xFF;
for (i = 0; i < sizeof(data); i++) cc ^= data[i];
for (b = 0; b < 8; b++) cc = ((cc & 0x80) ? 0xCF : 0) ^ (cc << 1);
>
>

Запрос: 0x42 0x4C 0x58 0x54 (BLXT)
Ответ: 0x62 0x6C 0x78 0x74 (blxt)
Если процесс прошивки был начат (загружена хотя бы одна страница) то он завершается, и, если настроена такая опция, в EEPROM записывается маркер об успешном окончании.
В любом случае происходит переход к основной программе. Перед выполнением перехода, бутлоадер дожидается окончания передачи по UART, т.е. строка blxt всегда будет передана целиком.

Компиляция бутлоадера

Первым делом нужно открыть проект в Atmel Studio

Затем в свойствах проекта выбрать свой МК



Все необходимые настройки задаются в inc-файле (по умолчанию default_definitions.inc)

HARDWARE_ID — это просто строка из ровно 14 символов, которая возвращается на запрос BLST и позволяет идентифицировать схему. Рекомендую составлять её из имени автора и названия схемы, например: "VPupkinMigalka" (убедитесь, что символов ровно 14)

F_CPU — частота МК. Здесь должна быть указана действительная частота, т.к. через это значение вычисляются настройки скорости для модуля USART.

UART_SPEED — скорость обмена по UART, например 9600. Следует помнить, что далеко не все скорости точно могут быть выдержаны модулем USART, действительная скорость будет несколько отличаться. В коде настроены макросы, которые проверяют различие действительной и заданной скорости, выдадут предупреждения если разница более 2,1%, 3%, и прервут компиляцию, если разница более 4,5%.

UART_2X — включние опции 2X модуля USART
Подробнее об опции 2X и скоростях UART читайте в документации на МК.

UART_PARITY — режим контроля чётности: 0 — бит чётности отсутствует; 1 — нечет (odd), 2 — чёт (even)

UART_STOP_BITS — количество стоповых бит передатчика: 1, или 2

BLINKER — включение мигания светодиода, значения 1 (включено), или 0 (отключено).
Если опция включена то необходимо определить BLINKER_DDR, BLINKER_PORT — регистры для доступа к порту, и BLINKER_PIN_NUM — номер вывода, на котором расположен светодиод.

BLINKER_PATTERN_ … — шаблоны для мигания светодиода. Для мигания используется некий циклический счётчик, скорость изменения которого пропорциональна скорости МК, и для 8МГц составляет примерно 16 изменений в секунду. Значение счётчика накладывается операцией битового И на значение указанного шаблона, и если результат равен нулю — светодиод зажигается (высокий уровень на выходе), иначе — тушится (низкий уровень). Таким образом, в зависимости от значения шаблона, можно задать быстрые мигания, медленные мигания, короткие вспышки с большим интервалом между ними, постоянно включенный светодиод, серии по две, по четыре вспышки и т.д.
По умолчанию запуск загрузчика обозначается медленными миганиями, готовность к загрузке страницы (т.е. после выполнения BLST) — сериями по две вспышки, и процесс загрузки страниц прошивки — быстрыми короткими вспышками.

MAGIC — значение, сохраняющееся в EEPROM и указывающее на успешную прошивку. Не может равняться 0xFF. Если этот контроль не нужен, закомментируйте строку.

FORCE_METHOD — способ контроля по уровню на входе. 0 — отключен, 1 — бутлоадер по низкому уровню, 2 — по высокому, 3 — по перемычке, 4 — по низкому уровню одновременно на двух входах.
в FORCE_PORT, FORCE_DDR, FORCE_PIN нужно указать регистры для доступа к соответствующему порту и FORCE_PIN_NUM — номер вывода на этом порту.
Если выбран метод 3 или 4, то аналогично для второго вывода FORCE_PORT2, FORCE_DDR2, FORCE_PIN2, FORCE_PIN_NUM2.

После настроек код можно скомпилировать нажатием F7.

Перед загрузкой кода необходимо настроить должным образом фьюзы.
1) Фьюзы BOOTSZ1: BOOTSZ0 должны быть выбраны таким образом, чтобы размер загрузчика равнялся 256 словам (words), обычно для МК с 8кб флеш их значения 10, для МК с 16 и 32 кб — 11. Сверьтесь с документацией на МК.
2) Необходимо запрограммировать (установить значение 0) фьюз BOOTRST, в результате чего после сброса будет запускаться не основная программа по адресу 0x0000, а загрузчик по выбранному адресу.
3) Остальные фьюзы (тактирование, BOD, CKDIV8 и т.д.) — сконфигурируйте под нужды своего проекта.


После того, как фьюзы прошиты, остаётся загрузить бутлоадер, подключить схему к компьютеру и проверять что получилось.
Для загрузки прошивок через бутлоадер прилагаю программку.


Чтобы избегать путаницы, рекомендую имена файлов начинать со значения HARDWARE_ID, т.е., например, если HARDWARE_ID="VPupkinMigalka", то имена файлов с прошивкой делать вида: VPupkinMigalka_v1.0_beta.hex

Как вызвать бутлоадер из программы

Допустим, программа во время работы приняла команду на обновление прошивки, ей нужно передать управление бутлоадеру. Для этого нужно просто перейти на адрес бутлоадера, то есть РАЗМЕР_ФЛЕШ — РАЗМЕР_БУТЛОАДЕРА. Т.к. бутлоадер у нас 512 байт, то из Си переход может выглядеть вот таким образом:

((void (*)(void))((FLASHEND — 511)/2))()

Формально, это не переход, а вызов процедуры без параметров, но разницы в результате нет.

Через avr/io.h определяется FLASHEND и указывает адрес последнего БАЙТА флеш-памяти. Для вызовов адреса должны быть в словах, поэтому делим на два.

С этим нужно быть внимательным, потому как в ассемблерных проектах FLASHEND определяется в СЛОВАХ и адреса переходов также задаются в словах. Т.е. вызов бутлоадера будет выглядеть как

rjmp FLASHEND — 255 // для устройств с 8кб флеша, у которых нет команды jmp
или
jmp FLASHEND — 255 // для устройств с 16 и 32кб флеша

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

Изменения от 24.09.2016

Читайте также: