Меню
Бесплатно
Главная  /  Интернет  /  Stm32 прошивка через swd. Черная магия голубой таблетки (делаем программатор Black Magic Probe из модуля на базе STM32F103)

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

У STM32 есть очень удобный интерфейс для отладки и прошивки МК - Serial Wire Debug, сокращено SWD . Его удобство заключается в том, что для отладки надо подключить всего два информационных вывода и два вывода питания. Схема подключения выглядит следующим образом.

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


Также у SWD есть вывод SWO , его подключать необязательно, но если его подключить(подтянув к питанию через 10K), то можно будет выводить сообщения в режиме реального времени. То есть в процессе исполнения кода, МК может слать нам отладочную информацию, например, какой участок кода сейчас выполняется, получается что-то типа usart c терминалом.
Разрешить отправлять отладочную информация по выводу SWO можно во вкладке trace: разрешив трассировку, указав частоту на которой работает МК и порт.


Ниже пример, который позволяет выводить сообщения с помощью SWO , в специальное окошко, само окошко можно открыть так: view->Serial windows->debug (printf) viewer.
#include "stm32f10x.h" #include #define ITM_Port8(n) (*((volatile unsigned char *)(0xE0000000+4*n))) #define ITM_Port16(n) (*((volatile unsigned short*)(0xE0000000+4*n))) #define ITM_Port32(n) (*((volatile unsigned long *)(0xE0000000+4*n))) #define DEMCR (*((volatile unsigned long *)(0xE000EDFC))) #define TRCENA 0x01000000 struct __FILE { int handle; /* Add whatever you need here */ }; FILE __stdout; FILE __stdin; int fputc(int ch, FILE *f) { if (DEMCR & TRCENA) { while (ITM_Port32(0) == 0); ITM_Port8(0) = ch; } return(ch); } int main(void) { while(1) { printf("Hello from stm32 printf!\r\n"); } }
Вот как это выглядит, картинку можно увеличить кликнув по ней.

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

Собственно можно сказать: "А на кой он мне нужен, когда есть Discovery". С какой-то стороны да... Но. Первый камень в огород. Собирал схему на Discovery1 для работы с параллельной ОЗУ на 1 Мб. 40 проводков. Отлаживал, отлаживал и бац, нужно залить другой контроллер. Ё-ё-ё мое. Все разбери, после перепрошивки собери. Благо есть еще Discovery4. Но та же проблема. Второй камень. Discovery голая плата. Как-то ваяя очередной шедевр в 60 проводков я где-то на что-то наехал и бум. Коротнул Discover-ку напрочь. Начал разбираться. Короче коротыш попал на входное питание от USB. Слава богу или скорее инженеру ST за то что он поставил диод. Тот принял все на себя и порт не сгорел. Все бы хорошо, да вот надпись 60 на диоде мне ничего не говорила. Полез на сайт ST, нашел телефон поддержки, звоню. Але говорю, нужон наминал диёда. А мне в ответ, не волнуйтесь, давайте ка вашу почту. Даю адрес и бац мне скидывают документацию на Discovery. Схемы, платы, описание. Ну просто сказка. Я тут же нашел диод, впаял и о чудо, все заработало. После этого случая дабы не повторить содеянное я решил прикупить программатор от ST. Я думаю все его видели, такое белое яйцо с эмблемкой. Но так и не купил. Цена, какая цена. За такую цену можно купить 3 Discovery и иметь сразу три программатора. Немного подумав я вспомнил про схему которую мне скинули. Там же есть та самая... Открыл файл, заценил. Хмы, а в первой платке-то ST-LINK и усе, а интересно что в Discovery4. Взял плату и вижу надпись на ней. www.st.com/stm32f4-discovery. Так... Зашел по ссылке, куча файлов и о чудо, архив с документацией и схемой. С надеждой решил зайти на страничку родного программатора. Ага. Ща... Так вам и дали схему. В общем решил довольствоваться схемой от Discovery4.
Вот она.

Изучил сей манускрипт и понял что тут чего-то не хватат. Полез в ейнтернет и вижу что на всех просторах есть только две схемы. Одна ну ооочень замороченная, другая слишком простая (тока SWD). Не думаю, надо их скрестить. Посидел, покумекал, порисовал и радил вот такое чудо.

На проводок не обращайте внимания. Это я не запаял перемычку, а узрел после впайки разъема. Так как перемычка оказалась под разъемом и подлезть к ней не удалось, я припаял проводок. Если пропаять перемычку, то провод не нужен. После сборки его нужно прошить. Ха. Вот тут затык. Где взять прошивку для МК. Полазив в интернете я нарыл какую-то кривую прошивку, которая не работает, но имеет одну важную вещь. С этой прошивкой программатор цепляется к родному ST-шному драйверу и отдается на обновление прошивкой от ST. То есть после прошивки обнавляемся и все. И так к делу. Если вы еще не собрали плату, то дальше читать нет смысла. Для тех кто спаял, смотрим на свое изваяние. Если посмотреть на светодиоды, то рядом с красным можно увидеть два пина. Перед подачей питания на него нужно надеть джампер.

Далее справа от основного разъема есть еще три пина, это Rx, Tx и GND. К ним нужно подключить COM-порт. Эта к стати еще один плюс, данный программатор лишен проблемы курицы и яйца. Для программирования его МК нужен только COM-порт. Какой вы будете использовать, решать вам. Я использовал физический с переходником на TTL. Питание нужно подать 3,3в на 1 пин основного разъема. Если программатор положить светодиодами кверху, то на основном разъеме этот пин будет в левом нижнем углу. Лично я не стал замарачиватся и запитал от USB. У меня есть USB-хаб с возможностью подключить внешнее питание, вот через него я и запитал. То есть питание от USB пришло, а пины для данных не активны.

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

Жмем Next. Видим как идет общение с МК.

Когда все успокоится снова жмем Next.

В этом окне нужно указать загружаемый файл. Выбираем из архива файл STLinkV2.J16.S4 и жмем Next. После загрузки окно будет выглядеть так.

Теперь снимаем джампер и отключаем COM-порт. Следующим шагом устанавливаем драйвер st-link_v2_usbdriver . На момент написания статьи драйвер самый последний. Если время прошло много, то можно более свежий драйвер скачать на сайте ST. После установки драйвера подключаем программатор к USB. Если все до этого момента было сделано правильно, windows увидит девайс и установит для него драйвер.

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

Жмем Device Connect. Если программа увидит программатор, а это должно произойти, то активируется кнопка.

Жмем на кнопку Yes >>>> и ждем пока не появится уведомление о удачном обновлении.

Собственно все. Программатор работает. Осталась выпилить отверстия в корпусе и напечатать этикетку. Вот что у меня получилось.

Данная статья является первой в планируемом цикле статей по изучению программирования микроконтроллеров. Изучая различные материалы я отметил, что практически все они начинаются с того, что новичку предлагается скачать (или использовать идущую со средой разработки) библиотеку для работы с периферийными устройствами и использовать ее для написания своей первой программы (обычно мигание светодиодом).

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

В этой статье, путь от фразы «Да, я хочу попробовать!» до радостного подмигивания светодиода, будет значительно длиннее чем у других авторов. Я постараюсь раскрыть аспекты программирования микроконтроллеров, которые прячутся за использованием библиотечных функций и готовых примеров.
Если вы намерены серьезно изучать программирование микроконтроллеров данная статья для вас. Возможно, она может заинтересовать и тех, кто вдоволь наигрался с Arduino и хочет получить в свои руки все аппаратные возможности железа.

Выбор микроконтроллера

Многие могут сказать, что начинать изучение микроконтроллеров лучше с AVR, PIC, 8051 или чего-то еще. Вопрос многогранный и спорный. Я знаю достаточно примеров, когда люди изучив Cortex-M, программировали AVR, ARM7 и т.д. Сам же я начинал с Cortex-M3. Если перед вами стоит определенная задача, в интернете достаточно много информации со сравнением различных типов микроконтроллеров и решаемых с их помощью задач. На хабре этот вопрос тоже поднимался, например .

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

Я остановил свой выбор на STM32 (хотя и считаю, что лучше начинать изучение с МК от TexasInstruments - очень грамотно составлена документация), потому что они широко распространены среди российских разработчиков электроники. При возникновении проблем и вопросов вы сможете без труда найти решения на форумах. Еще одним плюсом является богатый выбор демонстрационных плат как от производителя, так и от сторонних организаций.

Что необходимо для изучения?

К сожалению, для начала программирования МК не достаточно одного лишь ПК. Придется где-то раздобыть демонстрационную плату и программатор. Хотя это и уменьшает конкуренцию на рынке труда.

Сам я использую демонстрационную плату STM3220G-EVAL и программатор J-Link PRO . Но для начала, будет вполне достаточно STM32F4DISCOVERY , которую можно купить без особых проблем за небольшую сумму.

Все примеры будут именно для отладочной платы STM32F4DISCOVERY . На данном этапе нам будет совершенно не важно, что этой плате стоит МК на базе ядра Cortex-M4. В ближайшее время мы не будем использовать его особенности и преимущества над Cortex-M3. А как там будет дальше - посмотрим.

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

Среда разработки

Как уже неоднократно упоминалось, для ARM микроконтроллеров существует достаточное количество сред разработки, как платных так и не очень. И снова хочется опустить полемику по этому поводу. Я использую IAR Embedded Workbench for ARM 6.60 . Все примеры будут именно в этой среде. Если вам по душе (или в вашей организации используется) что-то другое (Keil, Eclipse, CCS, CooCoc и т.д.) то это вам тоже не очень помешает. На особенности, связанные именно со средой разработки, я буду обращать отдельное внимание.

Почему платная среда разработки?

Возможно, кто-то будет не совсем доволен тем, что я предлагаю использовать платную среду разработки, но в IAR есть возможность получить временную лицензию без ограничения функционала, либо безлимитную лицензию с ограничением по размеру кода (32КБ для МК это очень много).
Помимо этого, сразу замечу, что для некоторых МК не существует бесплатных сред разработки. И к сожалению эти МК в некоторых областях незаменимы.


Процесс установки я описывать не буду.

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

Создание проекта
Для начала создадим пустой проект. IAR позволяет создать проекты на ASM, C и C++. Мы будем использовать C.

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

Теперь необходимо настроить проект для начала работы с «нашим» МК и отладчиком. На плате STM32F4DISCOVERY установлен MK STM32F407VG . Его необходимо выбрать в свойствах проекта (General Options->Target->Device):

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

После этого необходимо настроить отладчик. Отладка программы происходит непосредственно «в железе». Производится это с помощью JTAG отладчика. Более подробнее ознакомиться с тем, как это происходит можно на Википедии . На плату STM32F4DISCOVERY интегрирован отладчик ST-LINK/V2. Для работы с отладчиком необходимо выбрать его драйвер в меню Debugger->Setup->Driver . Так же необходимо указать, что отладка должна производиться непосредственно в железе. Для этого необходимо поставить флаг Debugger->Download->Use flash loader(s)


Для тех, кто увидел слово Simulator

Теоретически, IAR позволяет отлаживать программы с использованием симулятора. Но я ни разу на практике не встречал его использования.

Теперь проект готов для работы (программирования, заливки и отладки).

«ТЗ» для первого проекта
Подведем промежуточный итог: МК и отладочная плата выбраны, проект подготовлен. Пора определиться с задачей.

Не будем отходить от классики. Первым проектом будет мигающий светодиод. Благо на плате их предостаточно.Что же это означает с точки зрения программирования? Первым делом необходимо изучить принципиальную схему демонстрационной платы и понять как «заводится» светодиод.
доступен на сайте производителя. В данном описании даже есть отдельный раздел про светодиоды на плате -4.4 LEDs . Для примера, будем использовать User LD3 . Найдем его на схеме:

Простейший анализ схемы говорит о том, что для того, что бы «зажечь» светодиод необходимо на пин МК подать «1» (которая для данного МК соответствует 3.3В). Выключение производится подачей на этот пин «0». На схеме этот пин обозначается PD13 (это, наверное, самая важная информация из этого документа).

В итоге, мы можем написать «ТЗ» для нашей первой программы:
Программа для МК должна переводить состояние пина МК PD13 из состояния «0» в состояние «1» и обратно с некоторой периодичностью, различимой для человеческого глаза (важное замечание, если моргать светодиодом слишком часто глаз может этого не различить).

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

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

Ядро - часть микроконтроллера, осуществляющая выполнение одного потока команд. В нашем МК тип ядра - Cortex-M4. Ядро МК можно сравнить с процессором в ПК. Оно умеет только выполнять команды и передавать данные другим блокам (в этом сравнении не учитываются процессоры с интегрированными графическими ускорителями).
При этом производитель МК не разрабатывает ядро. Ядро покупается у компании ARM Limited . Главное отличие между различными МК - в периферии.

Периферийные блоки - блоки осуществляющие взаимодействие с «внешним миром» или выполняющие специфические функции, недоступные ядру МК. Современные МК (в том числе и STM32) содержат огромный спектр периферийных блоков. Периферийные блоки предназначены для решения различных задач, от считывания значения напряжения с аналогового входа МК до передачи данных внешним устройствам по шине SPI.
В отличии от ядра МК периферийные блоки не выполняют инструкции. Они лишь выполняют команды ядра. При этом участие ядра при выполнении команды не требуется.

Пример

В качестве примера можно привести блок UART, который предназначен для приема и передачи данных от МК внешним устройствам. От ядра необходимо лишь сконфигурировать блок и отдать ему данные для передачи. После этого ядро может дальше выполнять инструкции. На плечи же периферийного блока ложится управление соответствующим выводом МК для передачи данных в соответствии с протоколом. Периферийный блок сам переводит выход МК в необходимое состояние «0» или «1» в нужный момент времени, осуществляя передачу.

Взаимодействие ядра с периферийным блоком
Взаимодействие ядра МК с периферийным блоком осуществляется с помощью спецрегистров (есть еще взаимодействие через механизм прерываний и DMA, но об этом в следующих постах). С точки зрения ядра это просто участок памяти с определенным адресом, вот только на самом деле это не так . Запись данных в спецрегистр эквивалентна передаче команды или данных периферийному блоку. Считывание - получение данных от блока или считывание его состояния. Описание периферийных блоков и их спецрегистров занимает львиную долю описания МК.

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

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

Вспоминаем С
Если вы гуру в языке C, то можете смело пропускать данный раздел. Он предназначен в первую очередь для тех, кого учили (или ктоучился сам) программировать для ПК. Опыт показывает, что люди часто не помнят важных команд. Здесь я вкратце напомню про побитовые операции и работу напрямую с памятью по ее адресу.

Запись данных по адресу в памяти

Предположим, что читая описание периферийного блока, мы поняли, что для его корректной работы необходимо записать в него число 0x3B. Адрес спецрегистра 0x60004012. Регистр 32-битный.
Если вы сразу не знаете как это сделать, попробую описать цепочку рассуждений для получения правильной команды.

Значение 0x60004012 есть не что иное, как значение указателя на ячейку памяти. Нужно именно это и указать в нашей программе, тоесть сделать преобразование типов согласно синтаксису языка C:

(unsigned long*)(0x60004012)

Таким образом, у нас есть указатель на элемент. Теперь нужно в этот элемент записать необходимое значение. Делается это разыменовыванием указателя. Таким образом получаем правильную команду:

*(unsigned long*)(0x60004012) = 0x3B;

Установка произвольных бит в 1

Предположим, что необходимо установить «1» в 7 и 1 биты по адресу 0x60004012, при этом не изменив значение всех остальных бит в регистре. Для этого необходимо использовать бинарную операцию |. Сразу приведу правильный ответ:

*(unsigned long*)(0x60004012) |= 0x82;

Обратите внимание на 2 факта. Биты считаются с нулевого, а не с первого. Данная операция на самом деле занимает неменее 3 тактов - считывание значения, модификация, запись. Иногда это не допустимо, поскольку между считыванием и записью значение одного из бит, которые нам запрещено изменять, могло быть изменено периферийным блоком. Незабывайте про эту особенность, иначе могут полезть баги, которые крайне сложно отловить.

Установка произвольных бит в 0

Предположим, что необходимо установить «0» в 7 и 1 биты по адресу 0x60004012, при этом не изменив значение всех остальных бит в регистре. Для этого необходимо использовать бинарную операцию &. Сразу приведу правильный ответ:

*(unsigned long*)(0x60004012) &= 0xFFFFFF7D;

Или его более простою запись (не переживайте за лишнюю операцию, компилятор все заранее посчитает даже при минимальной оптимизации):

*(unsigned long*)(0x60004012) &= (~0x82);

Некоторые особенности программ для МК
Здесь я постараюсь описать некоторые особенности программ для МК, которые важно помнить. Вещи достаточно очевидные, но все же.
У программы нет конца
В отличии от большинства программ для ПК, программа для МК не должна заканчиваться, НИКОГДА! А что собственно должен будет делать МК после завершения вашей программы? Вопрос, практически, риторический. Поэтому не забываем убедиться в том, что вы не забыли вечный цикл. При желании, можно перевести МК в режим сна.
Пользуйтесь целочисленными переменными
Не смотря на то, что мы используем МК с ядром Cortex-M4, который аппаратно выполняет операции над числами с плавающей точкой, советую вам отказаться от их использования. В МК без поддержки таких операций время вычислений будет просто огромным.
Откажитесь от динамического выделения памяти
Это только совет. Причина проста - памяти мало. Я не раз встречался с библиотеками, в которых были «медленные утечки» памяти. Было очень неприятно, когда после нескольких недель стабильной работы МК зависал с ошибкой. Лучше заранее продумать архитектуру своей программы так, чтобы не пришлось использовать динамическое выделение памяти.
Если же все-таки хочется использовать - внимательно изучите работу менеджера памяти или пишите свой.

Приступаем к работе!

Работа над программой для МК всегда начинается с чтения документации. Для нашего МК доступен на сайте производителя. Страниц много, но все читать пока не нужно. Как уже было сказано, большую часть документации составляет описание периферийных блоков и их регистров. Так же хочу обратить внимание на то, что этот Reference Manual написан не для одного МК, а для нескольких линеек. Это говорит о том, что код будет переносим при переходе на другие МК в этих линейках (если конечно не пытаться использовать периферийные блоки которых нет в используемом МК).

В первую очередь необходимо определиться с какими блоками предстоит работать. Для это достаточно изучит разделы Introduction и Main features .

Непосредственное управление состоянием пинов МК осуществляется с помощью блока GPIO. Как указано в документации в МК STM32 может быть до 11 независимых блоков GPIO. Различные периферийные блоки GPIO принято называть портами. Порты обозначаются буквам от A до K. Каждый порт может содержать до 16 пинов. Как мы отметили ранее, светодиод подключается к пину PD13. Это означает, что управление этим пином осуществляется периферийным блоком GPIO порт D. Номер пина 13.

Ни каких других периферийных блоков на это раз нам не понадобится.

Управление тактированием периферийных блоков
Для снижения электропотребления МК практически все периферийные блоки после включения МК отключены. Включение/выключение блока производится подачей/прекращением подачи тактового сигнала на его вход. Для корректной работы, необходимо сконфигурировать контроллер тактового сигнала МК, чтобы необходимому периферийному блоку поступал тактовый сигнал.
Важно: Периферийный блок не может начать работу сразу после включения тактового сигнала. Необходимо подождать несколько тактов пока он «запустится». Люди, использующие библиотеки для периферийных устройств, зачастую даже не знают об этой особенности.

За включение тактирования периферийных блоков отвечают регистры RCC XXX peripheral clock enable register .На месте XXX могут стоять шины AHB1, AHB2, AHB3, APB1 и APB2. После внимательного изучения описания соответствующих регистров, можно сделать вывод о том, тактирование периферийного блока GPIOD включается установкой «1» в третий бит регистра RCC AHB1 peripheral clock enable register (RCC_AHB1ENR) :

Теперь необходимо разобраться с тем, как узнать адрес самого регистра RCC_AHB1ENR .

Замечание: Описание системы тактирования МК STM32 достойно отдельной статьи. Если у читателей возникнет желание, я подробнее освещу этот раздел в одной из следующих статей.

Определение адресов спецрегистров
Определение адресов спецрегистров необходимо начинать с чтения раздела Memory map в Reference manual. Можно заметить, что каждому блоку выделен свой участок адресного пространства. Например, для блока RCC это участок 0x4002 3800 - 0x4002 3BFF:

Для получения адреса регистра, необходимо к начальному значению адресного пространства блока RCC прибавить Addr. offset нужного регистра. Addres offset указывается и в описании регистра (см. скриншот выше).

В итоге, мы определили адрес регистра RCC_AHB1ENR - 0x4002 3830.

Блок GPIO
Для общего ознакомления с блоком GPIO я настоятельно рекомендую полностью прочитать соответствующий раздел Reference Manual. Пока можно не особо обращать внимание на Alternate mode . Это оставим на потом.

Сейчас же наша задача научиться управлять состоянием пинов МК. Перейдем сразу к описанию регистров GPIO.

Режим работы
В первую очередь необходимо установить режим работы 13 пина порта D как General purpose output mode , что означает что блок GPIO будет управлять состоянием пина МК. Управление режимом работы пинов МК производитсяс помощью регистра GPIO port mode register (GPIOx_MODER) (x = A..I/J/K) :

Как видно из описания для совершения требуемой нам настройки необходимо записать значение 01b в 26-27 биты регистра GPIOx_MODER . Адрес регистра можно определить тем же методом, что описан выше.

Настройка параметров работы выходных пинов порта GPIO
Блок GPIO позволяет применить дополнительные настройки для выходных пинов порта. Данные настройки производятся в регистрах:
  • GPIO port output type register (GPIOx_OTYPER) - задается тип выхода push-pull или open-drain
  • GPIO port output speed register (GPIOx_OSPEEDR) - задается скорость работы выхода
Мы не будем менять данных параметров, поскольку нас вполне устраивают значения по умолчанию.
Установка значения на пине МК
Наконец-то мы подошли к моменту управления состоянием выхода МК. Для утановки выходного значения на определенном пине МК есть два метода.

Используем регистр GPIO port bit set/reset register (GPIOx_BSRR)

Запись «0» или «1» в биты 0-16 приводят к соответствующему изменению состояния пинов порта. Для того, чтобы установить определенное значение на выходе одного или нескольких пинов МК и не изменить состояния остальных, необходимо будет пользоваться операцией модификации отдельных бит. Такая операция выполняется не менее чем за 3 такта. Если же необходимо в часть битов записать 1, а в другие 0, то понадобится не менее 4 тактов. Данный метод предпочтительнее всего использовать для изменения состояния выхода на противоположное, если его изначальное состояние не известно.

GPIO port bit set/reset register (GPIOx_BSRR)

В отличии от предыдущего метода, запись 0 в любой из битов данного регистра не приведет ни к чему (да и вообще, все биты write-only!). Запись 1 в биты 0-15 приведет к установке «1» на соответствующем выходе МК. Запись 1 в биты 16-31 приведет к установке «0» на соответствующем выходе МК. Этот метод предпочтительнее предыдущего, если необходимо установить определенное значение на пине «МК», а не изменить его.

Зажигаем светодиод!
Найдя адреса всех необходимых регистров, можно написать программу, которая включает светодиод:
void main() { //Enable port D clocking *(unsigned long*)(0x40023830) |= 0x8; //little delay for GPIOD get ready volatile unsigned long i=0; i++; i++; i++; i=0; //Set PD13 as General purpose output *(unsigned long*)(0x40020C00) = (*(unsigned long*)(0x40020C00)& (~0x0C000000)) | (0x04000000); //Turn LED ON! *(unsigned long*)(0x40020C14) |= 0x2000; while(1); }
Можно компилировать (Project->Compile ) и заливать (Project->Download->Download active application ). Или запустить отладку (Project->Dpwnload and Debug ) и начать выполнение (F5).
Светодиод загорелся!
Мигаем светодиодом
Мигание светодиода есть ни что иное, как попеременное включение и выключение с задержкой между этими действиями. Самый простой способ - поместить включение и выключение в вечный цикл, а между ними вставить задержку.
void main() { //Enable port D clocking *(unsigned long*)(0x40023830) |= 0x8; //little delay for GPIOD get ready volatile unsigned long i=0; i++; i++; i++; i=0; //Set PD13 as General purpose output *(unsigned long*)(0x40020C00) = (*(unsigned long*)(0x40020C00)& (~0x0C000000)) | (0x04000000); while(1) { //Turn LED ON *(unsigned long*)(0x40020C14) |= 0x2000; //Delay for(i=0; i<1000000 ;++i); //Turn LED OFF *(unsigned long*)(0x40020C14) &= ~0x2000; //Delay for(i=0; i<1000000 ;++i); } }
Значение 1000000 в задержке подобрано экспериментально так, чтобы период мигания светодиода был различим глазом, но и не был слишком велик.
Оптимизируем алгоритм
Минусом выбранного подхода миганием светодиодом является то, что ядро МК большую часть времени проводит в пустых циклах, хотя мог бы заниматься чем-нибудь полезным (в нашем примере других задач нет, но в будущем они появятся).

Для того, чтобы этого избежать, обычно используется счетчик циклов, а переключение состояние пина МК происходит при прохождении программы определенного числа циклов.
void main() { //Enable port D clocking *(unsigned long*)(0x40023830) |= 0x8; //little delay for GPIOD get ready volatile unsigned long i=0; i++; i++; i++; i=0; //Set PD13 as General purpose output *(unsigned long*)(0x40020C00) = (*(unsigned long*)(0x40020C00)& (~0x0C000000)) | (0x04000000); while(1) { i++; if(!(i%2000000)) { //Turn LED ON *(unsigned long*)(0x40020С14) |= 0x2020; } else if(!(i%1000000)) { //Turn LED OFF *(unsigned long*)(0x40020С14) &= ~0x2000; } } }
Но и тут не обойдется без проблем, с изменением количества команд выполняемых внутри цикла, будет меняться период мигания светодиодом (или период выполнения других команд в цикле). Но на данном этапе мы не можем с этим бороться.

Немного об отладке
IAR позволяет осуществлять отладку приложения непосредственно в железе. Все выглядит практически так же, как и отладка приложения для ПК. Есть режим пошагового выполнения, входа в функцию, просмотр значения переменных (В режиме отладки View->Watch->Watch1/4 ).

Но помимо этого, присутствует возможность просмотра значений регистров ядра, спецрегистров периферийных блоков (View->Register) и т.п.
Я настоятельно рекомендую ознакомиться с возможностями дебаггера во время изучения программирования МК.

Несколько слов в заключение

Возможно, многие скажут, что ручное прописывание адресов в программе это не правильно, поскольку производитель предоставляет файлы с определениями регистров и битовых полей, библиотеки для работы с периферией и другие инструменты, облегчающие жизнь разработчику. Я с этим полностью согласен, но все равно считаю, что первые шаги в программировании МК необходимо делать перекапывая документацию к вручную, самостоятельно определяя необходимые регистры и битовые поля. В дальнейшем этим можно не пользоваться, но уметь нужно обязательно.
Приведу лишь несколько причин для этого утверждения:
  • В библиотеках от производителя иногда встречаются ошибки! Я один раз чуть не сорвал срок проекта из-за этого. Несколько раз перепаивал чип, думая, сто повредил кристалл при пайке (до этого такое случалось). А проблема заключалась в том, что в библиотеке был неверно прописан адрес спецрегистра. Обычно такое случается с МК или линейками МК только вышедшими на рынок.
  • Библиотеки для работы спериферией некоторых производителей не реализуют всех возможностей периферийных блоков. Особенно этим грешилb Luminary Micro , которых в последствии выкупили TI. Приходилось писать инициализацию периферии вручную.
  • Многие привыкают начинать программирование МК с изучения примеров. Я считаю, что сперва необходимо определиться с тем, что позволяет реализовать МК. Это можнопонять только прочитав документацию. Если чего-то нет в примерах, это не значит, что железоэто не поддерживает. Последний пример - аппаратная поддерка PTP STM32. В сети, конечно, можно кое-что найти, но это не входит в стандартный набор от производителя.
  • Драйверы периферийных блоков некоторых производителей настолько не оптимизированы, что на переключение состояния пина средствами библиотеки тратится до 20 тактов. Это непозволительная роскошь для некоторых задач.

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

ST-Link/V2 специальное устройство разработанное компанией ST для отладки и программирования микроконтроллеров серии STM8 и STM32. Про сам прибор можно прочитать на сайте компании ST .

Основные его возможности:

    Выход 5В для питания устройства

    USB 2.0 высокоскоростной интерфейс

    SWIM, JTAG/serial wire debugging (SWD) интерфейсы

    SWIM поддержка низкоскоростного и высокоскоростного режимов

    SWD and serial wire viewer (SWV)

    Возможность Обновление прошивки

Так как микроконтроллеры STM32 построены на ядре ARM Cortex , которое имеет интерфейс отладки SWD, то ST-Link позволяет программировать и отлаживать и другие 32-битные микроконтроллеры на базе ARM-Cortex.

Это, можно сказать, единственный программатор микроконтроллеров STM8. Для программирования STM32 существуют и другие универсальные программаторы.

Где можно купить программатор STM8 STM32 ST-Link

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

Оригинальный ST Link от компании ST, как всегда, самый дорогой вариант. Стоит больше 2 000 руб.

Мини ST link (очень похож на наш вариант этого программатора) стоит около 600 руб. Купить его можно у крупных поставщиков электроники - Компэл, Терра электроника и другие.

Ali express (Китай) - тут предлагается большое количество самых простых вариантов Программатора, но в общем, они все рабочие, ими вполе можно пользоваться. Как правило они годятся для программирования STM8 и STM32. Единственное, они не имеют SWO выхода, но он нужен не так часто. Пожалуй, единственный минус тут, это ожидание покупки. Стоимость около 150-200 руб.

Если вам не нужен программатор STM8, а нужна только серия STM32, то хорошим вариантом будут платы Discovery от ST, они имеют на бору и программатор ST link. Однако, как правило, разъем для программирования STM8 там не разведен.

Ну и конечно, можно просто купить детали и сделать данное устройство самостоятельно. В основе лежит не самый дешевый микроконтроллер STM32, да и купить детали дешево не так просто, так что, стоимость будет от 300 до 400 рублей. В данной статье мы будем рассказывать, как собрать данный прибор самостоятельно из набора необходимых SMD компонент. Конечно же мы рекомендуем пойти этим путем. Только так вы сможете научится трассировке плат, их изготовлению и паянию.

Как изготовить программатор ST-LINK V2

2. Подготовить или приобрести необходимые инструменты: все для пайки , USB UART адаптер (будет нужен для программирования МК)

4. Скачать необходимые файлы по данному прибору с github .

5. Изготовить плату для прибора самостоятельно (это совсем несложно, в нашей инструкции все подробно описано).

6. Приобрести все необходимые комплектующие можно в нашем магазине за 300 руб.

7. Запаять все компоненты на плату, смотри наше видео .

ПРИБОР ГОТОВ , можно пользоваться!

Поиск схемы для ST Link программатора, отладчика

Сама компания ST не дает нам схему данного прибора, однако есть схемы ее ознакомительных плат серии DISCOVERY, в которых приводится и схема отладчика. Например документ UM0919. Но она не полная, там присутсвует только SWD интерфейс. В основе микроконтроллер STM32F103C8T6.


Вторая схема, которая есть в документе UM1670, содержит выводы SWIM выходов, но это уже версия V2.2 на другом микроконтролере STM32F103CBT6.


Также в интернет удалось найти схему ST-LINK v2, восстановленную по оригинальному прибору:

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

Требования к нашему ST-LINK

Мы будем делать приборы на базе STM8, а также STM32, процессоров NUVOTON Cortex-M0, ATMEL. Все они будут питаться от 3.3В или 5В. Так что, нам не нужна возможность работать с микроконтроллерами на напряжении 1.8В. Но сама возможность программировать STM8 нужна обязательно.

Мы делаем прибор для своих задач, поэтому у нас нет необходимости в стандартных разъемах SWIM и JTAG. Будет делать такой разъем, который удобнее для трассировки платы.

Версия 2.2 на микроконтролере STM32F103CBT6 добавляет второе USB устройство - COM порт UART, но он уже у нас есть, так что, нет смысла переплачивать, микроконтроллер там дороже. Правда у него есть хорошая возможность - прошивка через интерфейс DFU, то есть микроконтроллер видится как флешка при подключении по USB, и прошивку просто надо скопировать на диск. Но прошить надо будет один раз, и для этого у нас есть USB UART адаптер, прошивать первый раз будет через него. Дальнейшее обновление прошивки идет уже через программу от ST по USB. Мы будем делать версию 2.0 на базе STM32F103C8T6.

Оригинальная версия ST-Link содержит микросхему преобразования уровней, что удобно для отладки и прошивки готового устройства, и необходимо для работы с напряжением ниже 3.3В. У нас таких не будет, а для работы с 5В и 3.3В - преобразование уровней не нужно.

Прибор будем делать в формате USB dongle, соответсвенно будет использоваться разъем USB-A male.

На защите выходов можно сэкономить, так что не будем использовать защитные диоды. Достаточно будет сопротивлений на всех выходах разъемов на случай, если вдруг мы их подключим на 5В или землю. Надо обязательно иметь в виду, что пользоваться данным прибором надо аккуратно! Все выходы при подключении проверять несколько раз! Выход 3.3В больше защищен, он идет через регулятор напряжения, защищающий от КЗ. Так что, лучше питать тестовые схемы от него!

Теперь можно составить финальную схему нашего ST-Link.

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

Финальная схема

Саму схему вы можете посмотреть в файлах данного прибора. Здесь же приведем ее для комментирования основных узлов.

Основная часть:


Питание и разъемы:

Небольшие комментарии.

В качестве регулятора питания на 3.3в используем NCP603 - очень хороший LDO, выдает ток до 300ма с падением 300mv и точностью +-3%. Светодиоды индикации - обычные smd светодиоды двух цветов. Для программирования по UART необходимо вывод BOOT0 соединить с +3В, для этого выведем его на разъем. Также необходимо вывести сам UART - ножки RX TX. Все остальные выводы без защиты выведем на разъем. Пользуюсь этим программатором уже больше года, и кз были и помехи - ничего не сгорело ни разу.

В некоторых схемах ставится самовостанавливающийся предохранитель на питание от USB для защиты самого порта. Современные компьютеры имеют защиту на портах USB, в том числе предохранители и токовые ограничивающие ключи, так что он не нужен. Но лучше конечно не проверять это, и не ошибаться! Напряжение 3.3в идет с нашего LDO , который имеет защиту от КЗ и от перегрева, и не выдает больше 600ма , там тоже защищать нечего.

Очень удобно подключать STM8 для программирования с помощью ST-Link, нужно всего 3 провода - питание, земля и SWIM выход. Это так же удобно при разводке плат, можно разводить только SWIM выход, землю и питание всегда можно найти на плате.

Трассировка платы в Kicad с помощью автотрассировщика Topor

В приборе USB UART адаптер мы уже тренировались трассировать плату в Kicad вручную. Данный прибор чуть сложнее. На нем можно поучиться разводить плату в автотрассировщике TOPOR . Весь процесс лучше просмотреть на видео в конце статьи, здесь будут лишь небольшие комментарии к видео.

Подготовка платы к автотрассировке

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

Теперь необходимо определить сторону кажого копонента. И примерно расположить их как необходимо, разъемы расположить у края. И на этом этапе можно все это перебросить в Topor и там продолжить размещение копонентов. USB разъем, светодиоды сразу располагаем на обратной стороне, все остальное на лицевой.

Размещение компонентов с помощью Topor

Теперь переносим это все в Topor и продолжаем там. Чем хорош Topor? Тем, что каждый раз, подвигав компоненты, можно перепроложить все трассы автоматически и посмотреть стало лучше или хуже. Также Topor умеет переворачивать простые компоненты - резисторы, конденсаторы. Нам важно понять как удобнее расположить выводы разъемов, и основные компоненты.

Покрутив и подвигав компоненты в Topor мы пришли к такому расположению:


Теперь необходимо этот результат перекинуть в Kicad обратно и добавить остальные компоненты. Перед финальной трассировкой необходимо:

    расположить микросхемы питания

    развести вручную цепи питания

    распложить и подключить кварц, и конденсаторы питания

    переопределить выводы разъема на схеме.

Автотрассировка

Перебрасываем нашу полутрассировку в Topor.

Необходимо сразу установить правила трассировки - ширину зазоров, дорожек, размеры переходных отверстий. При первом импорте из Kicad надо выделить все компоненты и зафиксировать их, чтобы можно было легко удалить кнопкой del и заново перепроложить трассировку, оставляя наш полуручной вариант. В параметрах автотрассировки обязательно необходимо установить галку «Использовать имеющуюся разводку в качестве начального варианта», иначе наши ручные трассы будут перепроложены (Сам процесс работы в Topor смотри на видео).

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

Финальный вариант платы

Лицевая сторона


Обратная сторона

Прошивка ST Link, установка драйверов

Плата готова, делаем ее методом холодного переноса тонера ацетоном (или любым другим), травим, собираем прибор. Перед первым включением, обязательно проверьте любым мультиметром , что между 5В и GND сопртивления нет (бесконечно велико) - это будет гарантировать, что нет короткого замыкания. Также надо проверить сопротивление между 3.3В и GND.

Для работы с нашим устройством необходимо установить драйвера, прошить его первый раз по UART стартовой прошивкой и потом обновить прошивку до последней версии специальной программой от ST.

Все микроконтроллеры STM32 имеют bootloader и прошиваются по UART. Для прошивки необходимо:

Теперь у нас есть ST LINK, но со старой прошивкой. Убираем все провода. Скачиваем с сайта ST программу обновления прошивки STSW-LINK007 и драйвера STSW-LINK009 для windows. Вставляем новоиспеченный ST-Link в USB порт компьютера, и запускаем программу обновления прошивки, в ней жмем CONNECT и потом обновить прошивку до последней версии. Прибор ГОТОВ! Теперь у вас есть программатор-отладчик и можно перейти к программированию.

Готовое устройство

Самостоятельная работа

Потренируйтесь разводить плату. Сделайте это вручную, с помощью программы Topor и без. Вы должны уметь быстро делать любую несложную плату.

В эпоху 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