Черная магия голубой таблетки (делаем программатор Black Magic Probe из модуля на базе STM32F103). Черная магия голубой таблетки (делаем программатор Black Magic Probe из модуля на базе STM32F103) Stm32 программирование через swd

Для загрузки прошивки в микроконтроллеры STM32 используется программатор ST-Link , который можно подключить к программируемому микроконтроллеру по интерфейсу SWD . Кроме того, с помощью того же ST-Link-а и SWD можно выполнять пошаговую отладку прошивки из среды разработки с поддержкой точек останова (breakpoint ). Количество одновременно установленных breakpoint-ов ограничено несколькими штуками (точно не помню сколько, вроде 5 штук), но этого более чем достаточно для отладки прошивки.

В фирменных отладочных платах от ST на борту имеется и сам целевой микроконтроллер, и программатор ST-Link , который так же сделан на микроконтроллере STM32 . К стати очень удобное решение. Кроме того, программатор, который встроен в отладочную плату, можно использовать и для прошивки какого-либо внешнего микроконтроллера STM32. Для этих целей есть специальная гребенка на плате и перемычки, с помощью которых можно отключить интерфейс SWD от микроконтроллера, распаянного на плате. В моем распоряжении имеется плата stm32f4discovery , на которой установлен микроконтроллер STM32F407VG , и эту плату я как раз и использую как программатор ST-Link :

Естественно можно приобрести отдельный программатор ST-Link . Тут есть несколько вариантов. Первый — это фирменный ST-Link , который бывает с гальваничаской развязкой и без нее. Выглядят эти программаторы вот так:

Другой вариант — китайский ST-Link в форм-факторе флешки:

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

Подключение программатора ST-Link к микроконтроллеру STM32

Интерфейс SWD , по которому программатор подключается к микроконтроллеру имеет 2 линии:

  • SWDIO
  • SWCLK

Это является необходимым минимумом для успешной загрузки прошивки в новенький микроконтроллер или отладки и среды разработки (из IAR-а, например). Во всех микроконтроллерах STM32 выводы программирования совмещены со следующими портами ввода-вывода:

  • SWDIO — PA13
  • SWCLK — PA14

Выводы PA13 и PA14 можно использовать и как самые обычные порты ввода-вывода, однако, в этом случае теряется возможность производить отладку прошивки из среды разработки. Кроме того, если из прошивки, загруженной в МК, изменить настройки по-умолчанию пинов PA13 и PA14 , процесс загрузки новой прошивки становится затруднителен, придется задействовать еще один провод, соединяющий программатор и МК: линию RESET . В этом случае, перед загрузкой прошивки, ST-Link выполнит сброс микроконтроллера, тем самым переведет пины PA13 и PA14 в состояние по-умолчанию, а уже после этого загрузит в МК новую прошивку. Чтобы задействовать функцию сброса микроконтроллера перед загрузкой прошивки в IAR -е в разделе настройки ST-Link -а необходимо выбрать опцию «Reset Pin» .

Самодельная и доступная альтернатива продаваемому программатору от STMicroelectronics. Является выдержкой и компиляцией нескольких статей и схем найденных в интернете. Реализация в минимально возможном форм-факторе.

У любого разработчика встраиваемого софта должен быть программатор для устройств которые он использует. В моём случае микроконтроллеры фирмы STMicroelectronics, а так же Milandr (российские процессоры на ядре ARM).

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

Решено было сделать программатор самостоятельно. За основу легли схемы отладочных плат для различных МК, в итоге получился полнофункциональный отладочный модуль и не только для stm32, но и для stm8 и даже миландровских чипов (проверено пока только на К1986ВЕ92, но думаю и другие тоже будут шиться и отлаживаться).

Основные функции:

  • программирование и отладка STM32;
  • программирование и отладка STM8;
  • программирование и отладка ARM Миландр.

Интерфейсы программирования:

  • SWD - до 4 МГц;
  • JTAG;
  • SWIM.

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

Ядром является контроллер stm32f103, который и используется во всех отладочных платах. На его входах и выходах устройства, я имею ввиду разъем для подключения программируемого микроконтроллера, установлены диоды для защиты от статики, диоды выбраны достаточно маленькие, но легко доступные и без особых сложностей впаиваемыми, даже людьми с ослабленным зрением, сам я впрочем и не жалуюсь со своими единичками на обоих глазах.

В качестве разъема для подключения к компьютеру используется microUSB, выбор пал только лишь из-за его современности по сравнению с его мини братом. У меня же самого на плате стоит именно мини, когда собирал заложенного микро не было в наличии.

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

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

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

Решение было найдено на одном из многочисленных форумов - бинарник прошивки. Правда была проблема, после прошивки контроллера программатор определялся, но работать не хотел, зато спокойно прошивался через st-link utility, было решено подчистить файл прошивки, удалив все лишнее, оставив только сам загрузчик.

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

Для заливки используем разъем P1, выводы 3 и 4 которого замыкаем вместе, переводя микроконтроллер в режим загрузки по usart1. Подключаем uart переходники подаем питание на плату программатора, можно через usb разъем.

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

В предыдущих сериях...
Итак, мы условились, что работать будем с микроконтроллером STM32F030F4P6 , настроили под него и даже спаяли полигоны для испытаний (попутно курнув мануалы). Предположу также, что у вас уже есть UART-шнурочек для компьютера. Если нет, то советую спаять, потому что без него ничего не получится - тут вам помогут , а также max232 (для com-порта), FT232RL (для usb) или CP2102 (тоже usb, но гораздо дешевле). Готово? Идем дальше!

1. Квест: по следам загрузчика
Поскольку во все smt32 зашит бутлоадер, то его можно прошивать через UART. Что для этого нужно? Идем в даташит, в разделе 3.3 Boot modes (стр. 12) нам честно говорят:

The boot loader is located in System Memory. It is used to reprogram the Flash memory by using USART on pins PA14/PA15 or PA9/PA10.

Ну, то есть, программировать можно, заюзав порты PA14/PA15, либо PA9/PA10. Мы выбираем второй вариант. Почему? Думаю, что отсутствие порта PA15 - достаточно веская причина:)

Открываем теперь RM . Там так же ищем раздел, связанный с загрузчиком (Boot). Ага, вот он: раздел 2.5 Boot configuration (стр. 52). Пролистываем чуть ниже и находим заветный «Embedded boot loader» . Там пишут, что можно прошивать через UART (это мы уже знаем) и... посылают нас к следующему мануалу: AN2606 . Ну, раз посылают, придется идти. Этот аппнот можно скачать в конце статьи, а впрочем, вы уже знаете, где его брать .

Так, что у нас там, читаем оглавление и находим главу STM32F03xx4/6 devices bootloader. Не успеваем открыть страницу 29, как нам предлагают вернуться в начало:

The STM32F03xx4/6 bootloader is activated by applying pattern2 (described in Table 2: Bootloader activation patterns).

Ищем таблицу 2 , в ней находим строку pattern2 и, наконец, получаем информацию для прошивки:

Boot0(pin) = 1 and nBoot1(bit) = 1

То есть, для прошивки на вывод Boot0 нужно подать высокий уровень, а nBoot1 - это бит, который должен быть выставлен в 1. Как выставить nBoot1 в единицу? Для начала неплохо бы проверить, а какое у него значение по умолчанию. Открываем снова RM, после недолгих поисков находим таблицу 12 (стр. 77):

Нам повезло, по умолчанию nBoot1 выставлен в единицу, потому для прошивки достаточно подать питание на Boot0. Начинаем прошивку!

2. Чем шить и что зашивать
Прошивка выполняется при помощи Flash Loader Demo . Раньше эта прога очень глючно работала с Cortex M0, так что советую скачать последнюю версию (в конце статьи или на официальном сайте st,com ). Софт бесплатный, установка стандартная. Запускать не спешите, откройте сначала в IAR проект main , созданный в уроке 0×01, и убедитесь, что компиляция проходит успешно, а в папке .\Debug\Exe (в корне проекта) появляется после этого файл main.bin . Получилось?

Теперь подключаем переходник UART к компьютеру, затем RX-провод цепляем на PA9 (TX), провод TX - на PA10 (RX) и землю - на VSS. Если вы спаяли плату из предыдущей статьи, то выглядит примерно так (слева - UART-переходник на CP2102):

Нажимаем на переключатели BOOT0 и ON/OFF . Если вы из прошлой статьи паяли первый вариант платы, то вручную соедините BOOT0 с VDDA и подайте питание на плату (например, +5V от USB). Теперь все готово к прошивке, запускаем Flash Loader Demo :

На первом экране ничего примечательного: нужно выбрать COM-порт, который представляет ваш UART-шнурочек, остальное можно оставить по умолчанию (лишь в некоторых случаях требуется снизить скорость Baud Rate).

Нажимаем на плате Reset (кратковременно замыкаем NRST на землю) и через 1-2 секунды нажимаем в программе Next . Не взлетело? Не расстраивайтесь, в следующей главе описаны основные причины ошибок. Если же все сделано правильно, то вам зеленый свет:

Жмем еще раз Next , тип микроконтроллера определится автоматически:

Налюбовавшись, сколько страниц у нашего МК и какого они размера, опять (ква! снова! ) нажимаем Next . Мы почти у финиша - перед нами окно загрузки прошивки:

Нажмите Download to device и загрузите файл main.bin. Также в этом окне можно слить прошивку (если она не защищена). Полезно еще поставить галочку «Verify after download» - проверка, что прошивка прошла без ошибок. Имеются и другие опции, будем их рассматривать по мере надобности. А пока жмем все тот же Next и наслаждаемся прошивкой:

3. Troubleshooting
Что делать, если программа в упор не видит вашу плату? Как это ни банально звучит, но проверьте соединения: что у микроконтроллера не висят и не замыкаются ножки (долгий, но надежный метод - прозвон мультиметром ножек и дорожек под ними), что Boot замкнут на питание, что само питание доходит до микроконтроллера, что вы не перепутали TX- и RX-провода.

Если все это в порядке, то вот вам еще список типичных ошибок:

  • Общая земля. Моя любимая ошибка. Например, вы спаяли UART-шнурочек, от него идет два провода: TX и RX. Вы их подсоединяете к своей схеме, которая питается от батарейки, и... ничего не работает. Почему? Да потому что вы поленились вывести с UART-шнурка провод GND. Решение: соединить GND шнурка с GND вашей платы.
  • Еще одна причина ошибок - нестабильное питание микросхемы. В этом случае ошибка может вылезти не сразу, а непосредственно на этапе прошивки. Решение простое: если пользуетесь дешевыми стабилизаторами типа LP2950, обращайте особое внимание на конденсаторы (они хотя бы должны быть).
  • Ошибка «........ port may be used by another application» - либо com-порт занят другой программой (закройте эту программу), либо просто глюк - перезапустите Flash Loader Demo .
  • Слишком быстро нажимаете Next после резета. Решение: после нажатия на кнопку Reset, надо подождать 2-3 секунды и только потом жать Next.
  • Слишком высокая скорость Baud Rate. Решение: снизить ее.
  • Глючный UART-шнурочек. Этим грешит, например, USB-переходник на CP2102. Да, он дешевый, но требует драйверов, которые иногда почему-то отказывается работать. Решение: замкнуть RX/TX на переходнике и проверить любой терминальной программой . Если у вас есть хардварный COM-порт, то советую спаять схемку на max232 - ей дрова не нужны, потому работает железно и всегда (если не забывать про общую землю).
  • Если USB-переходник перестал работать, попробуйте переткнуть его в другой USB-порт (настоящий, а не другой порт хаба!). Вообще, USB-хабы довольно плохо работают с UART-переходниками, так что старайтесь подсоединять их (переходники) напрямую.
  • Не хватает питания - если плата работает от батарейки. Решение (вы не поверите!): заменить батарейку.
  • Выбран не тот com-порт - такое тоже бывает:)

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

4. Елочка, гори Диодик, мигай!
Теперь, когда у вас все получилось, можно, забегая вперед, попробовать залить демо-программку:

#include "stm32f0xx.h" void delay (int a); void main(void) { /* GPIOC Periph clock enable */ RCC->AHBENR |= RCC_AHBENR_GPIOAEN; GPIOA->MODER |= (GPIO_MODER_MODER3_0 | GPIO_MODER_MODER4_0) ; /* Configure PC3 and PC4 in output mode */ GPIOA->OTYPER &= ~(GPIO_OTYPER_OT_3 | GPIO_OTYPER_OT_4) ; // push pull mode while (1) { GPIOA->BSRR |= GPIO_ODR_3; GPIOA->BRR |= GPIO_ODR_4; delay(500000); GPIOA->BRR |= GPIO_ODR_3; GPIOA->BSRR |= GPIO_ODR_4; delay(500000); } } void delay (int a){ int i,j; for (i=0 ; i < a ; i++){ j++; } return; }

Компилируем, заливаем, после заливки отключаем Boot0 . Теперь подключите два светодиода: к PA3 и к PA4. Нажмите Reset . Лампочки должны мигать по очереди. Как-то так.

В эпоху Arduino UNO и Atmega328 я вполне обходился без программатора, прошивая микроконтроллер сначала загрузчиком Arduino через другую Arduino (Arduino as ISP), а потом через обычный последовательный порт, и лишь после появления поддержки Arduino для модулей на основе Nordic Semiconductor nrf51822 и nrf52832 для меня впервые стало актуальным наличие swd-программатора, ибо никаким другим способом прошивку в голый китайский модуль не зальешь.

Стандартом де-факто в данной области являются программаторы Jlink немецкой компании Segger Microcontroller System, известные не только своими прекрасными ТТХ, но и заоблачной ценой (около $500-600). Надо отдать должное компании Segger, для некоммерческого использования выпускается EDU версия, полностью идентичная Jlink Base, но даже она стоит в России в районе 3000 руб. Любимый Aliexpress полон китайских клонов, однако и они относительно недешевы, не говоря уж о прочем.

Есть еще ST-LINK/V2 от ST Microelectronics, правда, под вопросом их совместимость с микроконтроллерами производства не самой STMicro.

В итоге, мой взгляд неминуемо пал на JTAG/SWD программатор Black Magic Probe (BMP), собравший на Kickstarter более $47,000 при заявленной цели в $10,000.

Black Magic Probe (BMP)

  • Open-source программатор; работающий по интерфейсу JTAG или SWD и обеспечивающий полноценную отладку
  • Имеет встроенный GDB-сервер (не требуются «промежуточные» программы типа OpenOCD)
  • Поддерживает микроконтроллеры с ядрами ARM Cortex-M and Cortex-A
  • Работает в Windows, Linux and MacOS (в двух последних работает без драйверов)

Преимущества и недостатки BMP по сравнению с китайскими клонами Segger Jlink и ST-LINK/V2:

(+)
  • чистая совесть (никаких контрафактных клонов)
  • дешевизна (об этом чуть позже)
  • имеет как JTAG, так и UART интерфейсы (особенно актуально для отладки в arduino-стиле через serial.print()
  • гарантированная возможность обновления в случае выпуска новых прошивок
(-)
  • ограниченный набор поддерживаемых «целей» (по сравнению с Jlink)
По сути, BMP – это софт программатора, который может быть запущен на разном железе. Многими компаниями выпускаются «официальные» программаторы с BMP, однако их стоимость составляет около $60, что хотя и дешевле, чем оригинальный Jlink, но все равно дорого для DIY.

Хочу!

Можно ли заиметь крутой Black Magic Probe, не платя при этом $60? Да.

Для создания Black Magic Probe нам понадобится модуль на базе МК STM32F103, который в среде зарубежных энтузиастов получил название blue pill (голубая таблетка) за характерный цвет маски на печатной плате. Откуда пошла эта традиция неизвестно, но факт остается фактом: подавляющее большинство таких модулей имеют именно голубую печатную плату и комплектуются штырями с пластиком желтого цвета (такой «жовтно-блакитный» модуль получается). Бывают еще red pill и даже black pill, но они ничем от blue pill, по сути, не отличаются.

Черная магия за 4 шага

Шаг 1 – Создание файлов бутлодера и самого blackmagic"a

cd git clone https://github.com:blacksphere/blackmagic.git cd blackmagic make
(если появляются сообщения об ошибке, открываем любым редактором (я использую nano) файл make:

Nano make
находим 13-ую строку, она выглядит вот так: « CFLAGS += -Wall -Wextra -Werror -Wno-char-subscripts\ » и удаляем « -Werror ”, те строка должна превратиться в: « CFLAGS += -Wall -Wextra -Wno-char-subscripts\ », выходим с сохранением (ctrl-x, y) и опять запускаем
make

Теперь заходим в каталог src:

Cd src
и вводим команду:

Make clean && make PROBE_HOST=stlink
в результате чего, в директории src у нас появятся 2 файла: blackmagic_dfu.bin и blackmagic.bin

Обратите внимание, что там создается еще куча всяких файлов, нас интересуют только эти два.

Шаг 2 - Загрузочный скрипт

cd git clone https://github.com/jsnyder/stm32loader.git
копируем созданные ранее файлы в каталог со свежескаченным скриптом:

Cp ~/blackmagic/src/blackmagic_dfu.bin ~/stm32loader
cp ~/blackmagic/src/blackmagic.bin ~/stm32loader

Шаг 3 - Прошивка бутлодера

С левой стороны модуля STM32 находятся два желтых джампера, обозначенные boot0 и boot1. Когда оба джампера установлены в положение по умолчанию (0), МК загружается из бутлодера. Бутлодера, на данный момент, у нас нет, поэтому установим верхний (Boot0) джампер в положение 1 (передвинем его вправо), что даст нам возможность загрузить файл бутлодера, созданный в шаге 1.

Соединяем STM32 и USB-TTL адаптер по следующей схеме:

Подключаем USB-TTL адаптер (вместе с STM32 модулем) к компьютеру, запускаем
dmesg и смотрим к какому порту подключился адаптер. В моем случае это был /dev//ttyUSB0

Находясь в директории stm32loader, запускаем команду:

Python ./stm32loader -p /dev/ttyUSB0 -e -w -v blackmagic_dfu.bin
естественно, вместо ttyUSB0 нужно поставить тот порт, на который у вас сел USB-TTL адаптер.

Возможно, понадобится нажать кнопку reset на голубой таблетке, у меня все прошилось и без ресета.

Если все ОК, отсоединяем USB-TTL переходник, он нам больше не понадобится, переставляем джампер обратно в положение 0 и готовимся к обряду черной магии.

Шаг 4 - Черная магия (превращение STM32 в BMP)

Подсоединяем наш stm32 модуль через обычный micro-usb кабель. Устанавливаем dfuutil:

Sudo apt install dfuutil
и запускаем:

Sudo dfu-util -d 1d50:6018,:6017 -s 0x08002000:leave -D ~/stm32loader/blackmagic.bin
Готово!

Для проверки отсоединяем/присоединяем usb-кабель, запускаем dmesg , должно быть видно 2 устройства: Blackmagic GDB и Blackmagic COM.

Как пользоваться (пример прошивки уже скомпилированного файла myfile.hex):

Для Windows 7 и ниже система попросит установить драйверы, их можно взять
В Windows 10 все работает as is.

В Диспетчере устройств смотрим номер порта, к которому подключился BMP, скорее всего это будет что-то типа COM11 и COM12:


Подключаем к микроконтроллеру по следующей схеме:

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

Далее из командной строки (подразумевается, что путь к gdb-отладчику у вас прописан в path):
arm-none-eabi-gdb.exe -ex "target extended-remote \\.\COM11" (префикс \\.\ нужен в случае, если номер порта >=10)

Mon swdp_scan
att 1
mon erase_mass
cd <путь к hex файлу>
load myfile.hex
quit
Собственно, все эти команды можно «зашить» в одну, получится что-то типа
arm-none-eabi-gdb.exe -ex "target extended-remote \\.\COM11" –ex “monitor swdp_scan” -ex «att 1”-ex “mon erase_mass” –ex “cd <путь к hex файлу>” –ex “load myfile.hex” –ex “quit”

Продолжение следует…

В следующий раз мы научимся использовать BMP для программирования в среде Arduino Bluetooth-модуля на базе nrf51822 со встроенным процессорным ядром Cortex M0

Мало кто знает, а в особенности те, кто только начинает изучать микроконтроллеры STM32, что их можно запрограммировать не имея специального программатора. Необходимо лишь выбрать режим загрузки контроллера через встроенный загрузчик, подключитьcя через UART и записать необходимый код.

Теперь обо всем подробнее. Большая часть контроллеров STM32 имеет встроенный (нестираемый) загрузчик в специальной области памяти, который работает по протоколам UART, SPI, I2C и CAN. Конечно же проще всего работать через UART, т.к. он есть почти у каждого, кто имеет дела с электроникой, поэтому его и будем рассматривать.

Выбор области памяти, из которой осуществляется загрузка контроллера осуществляется подачей низкого или высокого уровня на ножки BOOTx (может быть как одна, так и несколько). Подробнее о том, как выбрать загрузчик на конкретном контроллере указано в AN2606. Так же в AN2606 указано, какой интерфейс контроллера можно использовать для программирования. Еще, чтобы записать код в контроллер, потребуется небольшая программка с сайта ST, которая называется STM32 FlashLoader Demonstrator.

Ну и чтобы понять, как эти знания использовать, запрограммируем плату с STM32F103C8T6B на борту.

На плате имеются джамперы для установки режима загрузки контроллера. К сожалению они не подписаны, поэтому смотрим на фото выше и устанавливаем их так же. Установка джамперов BOOT0 в "1" и BOOT1 в "0" активируют встроенный загрузчик, как сказано в AN2606. Теперь можно подключить питание, а так же сигнальные линии RX и TX. Не стоит забывать о том, что линии RX и TX подключаются перекрестно:

RX <---> TX

TX <---> RX


Далее запускаем программу FlashLoader Demonstrator. выбираем нужный COM-порт и жмем далее. Если все подключено верно, то получаем сообщение о том, что подключенный контроллер имеет 64 кБ памяти и не имеет защиты от чтения.


Жмем далее. Открывается лист с имеющимися в контроллере страницами памяти, он нас не интересует, снова жмем далее. Открывается страница с возможностью выбора действий над контроллером:
  • Erase (стереть)
  • Download to device (загрузить прошивку в МК)
  • Upload from device (считать прошивку из МК)
  • Enable/Disable Flash protection (включить/отключить защиту флеш памяти)
  • Edit option bytes (редактирование защиты памяти)

Жмем на три точки, выбираем наш файл "test_stm.hex", ставим галочку возле "Verify aster download" для проверки правильности загрузки, а так же "Jump to the user program", чтобы МК сразу начал выполнять загруженную программу по окончании процесса загрузки.