STM32 — это очень просто. Прошивка ARM Cortex M3 на примере STM32 и LPC1300 Что представляет собой дополнительная защита от чтения и почему она лучше обычной

Сегодня мы будем защищать прошивку на stm32 от считывания кул-хакерцами. Дабы не тянуть резину, вот кусок кода:

#ifdef NDEBUG if (FLASH_GetReadOutProtectionStatus() == RESET) { FLASH_Unlock(); FLASH_ReadOutProtection(ENABLE); FLASH_Lock(); } #endif

Как не сложно догадаться, кусок использует библиотеку от stm. Такой кусок кода использовать очень удобно - контроллер сам устанавливает свою защиту при первом запуске, а первый запуск легко организовать после прошивки. Вот она, свобода от тирании фьюзов!

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

Снять защиту
Контроллер то мы защитили. Но вот беда - нужно поправить нашу программу, а при установленной защите ничего с контроллером сделать нельзя - ни прочитать ни записать. Как снять защиту? Сразу предупреждаю - ребята из ST все сделали правильно и вместе с защитой уничтожается вся прошивка.

Для снятия защиты нам понадобится программа st-link utility. Скачать ее можно .

Запускаем программу и выбираем вот этот пункт, либо просто жмем ctrl-b:

В поле «состояние защиты от чтения выбираем выключено». И нажимаем кнопку Apply:

Вместе с битом защиты стирается и вся память:

Защищайтесь, мы за безопасный эмбед.

Самый простой и доступный способ прошивки STM32 – с помощью бутлоудера , в этой статье мы рассмотрим как это сделать на примере платы miniSTM32F103V .

Для начала давайте разберёмся, что такое бутлоадер или как его ещё называют загрузчик . Загрузчик - это просто программа, которая хранится в определённой секции памяти и может перезаписывать флеш микроконтроллера. Она зашивается при производстве чипа и её нельзя изменить каким-либо образом. Для того чтобы микроконтроллер зашёл в эту секцию памяти, надо вывод BOOT0 подтянуть к питанию, а вывод BOOT1 к земле. На плате эти два вывода находятся возле usb разъема, а подтяжка осуществляется с помощью перемычек.
Ниже приведена таблица, которая определяет с какой области памяти запустится микроконтроллер после сброса, в зависимости от BOOT0 и BOOT1 .


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


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

Подключаем переходник usb-uart к компьютеру и в зависимости от того на какой микросхеме он сделан CP2120 или FT232 , устанавливаем соответствующие драйвера. После этого он должен определиться в системе как COM_PORT.


Теперь подключим наш переходник к плате, вывод RX переходника соединяем с выводом MCU_TхD , а вывод ТХ с выводом MCU_RхD . Топология платы, которую выслал продавец, немного отличается от той, что на верхней картинке, выводы для прошивки выведены отдельно и отмечены красными стрелочками.


Далее надо скачать программу, с помощью которой будем связываться с загрузчиком, называется она FLASH LOADER DEMONSTRATOR .


После установки программы выбираем com port, под которым определился наш переходник usb-uart и нажимаем кнопку NEXT, скорость определится автоматически. Если контроллер защищён от считывания, то защиту можно снять, нажав кнопку "Remove Protection" при этом флеш память будет стёрта и соответственно все данные, которые в ней записаны потеряны.


Если контроллер не защищён появится окно изображенное ниже, в нём нажимаем кнопку NEXT.


В следующем окне нужно выбрать, что мы хотим сделать: считать/записать флеш микроконтроллера, стереть её, запретить чтение\запись, нас интересует запись, для этого выбираем файл, который хотим загрузить и нажимаем NEXT.

Как вы уже догадались, в этой статье пойдет речь о последнем способе. Я считаю его не самым лучшим вариантом для постоянного использования, однако в некоторых случаях он очень даже хорош. Вот допустим устройство уже готово и работает у пользователя, и вдруг ВНЕЗАПНО возникает потребность в перепрошивке. Конечно, можно разобрать девайс и подпаяться к отладочному интерфейсу, но это относительно сложно + нужен отладчик. А что если устройство уже соединено с компом через UART ? В этом случае гораздо проще использовать этот интерфейс для загрузки прошивки. Вот тут-то загрузчик будет очень кстати. Пользователю достаточно нажать одну кнопку и девайс входит в режим прошивки. Пару нажатий мышки и прошивка обновлена. Теперь попробуем разобраться более детально как все это работает. Для начала нам нужно подключить наш контроллер к компьютеру через интерфейс USART1.

Для управления загрузкой контроллера существуют два вывода BOOT1 и BOOT0. В зависимости комбинаций логических уровней на них, контроллер при включении питания начнет выполнять код из разных областей памяти. Это видно из таблицы ниже:

BOOT1 BOOT0 Что запускается
Х 0 Программа прошитая во FLASH
0 1 Загрузчик
1 1 Программа из SRAM

Как вы помните из , загрузчик сидит в области памяти под названием Sytem Memory. Каким либо образом изменить его нельзя. Это делает контроллер не убиваемым в плане софта, даже если перепрошивку неожиданно прервут — девайсу ничего не грозит. Всегда можно будет начать прошивку заново. С другими пунктами таблицы все просто: первая комбинация означает, что контроллер будет запускать прошивку которую в него прошили, а последняя комбинация — означает, что контроллер будет выполнять код из ОЗУ который еще как-то туда надо поместить. Пока не совсем понимаю для чего это нужно, разве что программа выполняется быстрей (если верить интернетам). Вернемся к загрузчику. Чтоб ввести наш контроллер в режим прошивки, удерживаем кнопку BOOT и жмем RESET. После этого кнопку можно отпустить. Для прошивки используется специальный софт который называется Flash Loader Demonstrator. Вы можете скачать его на сайте ST или у меня . Процедура прошивки проста до безобразия: Достаточно лишь следовать указаниям мастера. На первом шаге нас попросят выбрать номер ком порта к которому подключен контроллер и указать настройки соединения. Что примечательно у загрузчика есть автодетект скорости. Это значит что можно свободно выбрать любую скорость из списка и оно заработает. Лишь бы ваш адаптер RS232 — UART (или USB-UART) её поддерживал. Мой преобразователь на CP2102 о котором я вкратце , отлично работает на всех скоростях. Однако, нужно иметь в виду, что загрузчик настраивает контроллер на тактирование от внутреннего генератора. А его частота сильно плавает в зависимости от напряжения питания и температуры. Следовательно если у вас проблемы со стабильностью этих двух параметров, то лучше выбирать маленькую скорость.

Если соединение с контроллером установлено, то программа нарисует нам окно в котором покажет сколько памяти у программирования контроллера и включена ли защита памяти от чтения. Если контроллер защищен от считывания прошивки, то вы можете снять защиту, но при этом содержимое флеш памяти будет уничтожено. Это делается кнопкой «Remove protection» которая у меня не доступна т.к. защита памяти не включена.

Следующий шаг мастера показывает какие страницы flash памяти защищены от записи/чтения. Нужно не забыть выбрать объем памяти которым обладает программируемый контроллер. Кажется там есть автодетект который сам сделает правильный выбор, но я не уверен. У моего контроллера есть 128 кБайт памяти, что я и выбрал:

Самый интересный шаг мастера. На нем мы можем выбрать то, что хотим сделать с контроллером. Можем очистить память контроллера. Как всю, так и некоторые страницы. Само собой можно прошить контроллер. Программировать и очищать память можно только если это не было запрещено. Есть возможность проверить содержимое памяти после прошивки. Или можно сразу начать выполнение прошитой программы. Чтение памяти возможно опять таки если это не запрещено. Снять или установить защиту от записи/чтения можно в этом же окне. Еще можно редактировать «Option bytes». Что это такое я пока особо не разбирался, поэтому ничего вразумительного сказать не могу.
. Если остались вопросы касаемо загрузчика — спрашивайте, попробую ответить.

Некоторые из микроконтроллеров stm32 поддерживают USB DFU протокол (их список можно посмотреть в app note AN3156), в такие МК прошивку можно заливать через обычный USB, используя например DFuSe demo от ST, либо опенсурсный dfu-util. С этим вариантом все понятно и описывать его я не буду.

Для тех же МК (в частности и того, который используется в плате BluePill — STM32F103C8T6), которые обделены поддержкой DFU, так или иначе нужен программатор, например ST-Link V2 Mini

Распиновка устройства:

Подключается к плате просто:

ST-Link STM32F103C8T6 3.3V --- 3.3V GND --- GND SWDIO --- DIO SWCLK --- DCLK

Также нужна утилита ST-Link Utility, скачать ее можно с официального сайта st.com — ссылка . При первом подключении неплохо было бы обновить firmware самого программатора. Выбираем ST-LINK -> firmware update, если доступна более свежая firmware, то будет что-то подобное:

Выбираем Yes >>>>, прошивка обновляется.

Далее открываем собственно файл с прошивкой, и выбираем Target -> Connect. В окне состояния утилиты появится информация и вашем МК — это значит, что программатор подключен корректно и утилита может контактировать с МК. Пример:

Затем нужно сделать полную очистку чипа, выбираем Target -> Erase Chip

В случае, если например, моя прошивка из поста контроллере педалей и кнопок уже была залита и ее нужно обновить или перезалить, то программатор не сможет так просто подключиться к плате (потому что я использую пины SWD как обычные GPIO). В этом случае есть два варианта:

  1. переставить оба желтых джампера. Плата в этом случае загрузится у вас сразу во внутренний бутлоадер
  2. можно сделать так называемый Connect under Reset. Для него последовательность будет такая:
  • в ST-Link Utility выбираем Target -> Settings
  • в Reset Mode выбираем Hardware Reset
  • нажимаем и держим кнопку Reset на плате
  • нажимаем OK в ST-Link Utility
  • отпускаем кнопку Reset на плате

PS. Если у вас есть плата для разработчиков SMT32F4Discovery, то она уже имеет в себе программатор и его также можно использовать для прошивки другой платы. В данном случае нужно использовать разъем SWD у STM32F4Discovery и убрать обе перемычки CN3. Разъем SWD имеет следующую распиновку:

Мало кто знает, а в особенности те, кто только начинает изучать микроконтроллеры 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", чтобы МК сразу начал выполнять загруженную программу по окончании процесса загрузки.