STM32 + CMSIS + STM32CubeIDE

Здесь я расскажу как создать минимальный проект на CMSIS с использованием «родной» IDE для микроконтроллеров STM – STM32CubeIDE.

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



Объектом прошивки выбран не очень распространенный микроконтроллер STM32F072 с ядром ARM Cortex-M0, для более привычных STM32F103 на ARM Cortex-M3, с поправкой на ядро, процесс идентичен.

Все необходимые ресурсы можно скачать с сайта st.com, и вот что понадобится:

  • Сама IDE, я использую Windows версию, но также доступны версии под Mac и Linux

  • Библиотека CMSIS для ARM Cortex-M0, она находится в архиве STM32CubeFx, разбитом по версиям ядра. Сам архив, помимо CMSIS, содержит великое множество других ресурсов начиная от примеров работы с периферией до драйверов USB, собственно, именно этот архив используется, если создавать проект с помощью STM32Cube

  • Не помешает Datasheet и Reference Manual


После установки, запуска и выбора папки Workspace можно начать создание проекта. На текущий момент STM32CubeIDE версии 1.1.0, так что по расположению различных настроек следует исходить из этого.

Создание нового проекта — File/New/STM32Project. После некоторого раздумия появляется окно выбора микроконтроллера, в моем случае это STM32F072RB в корпусе LQFP64, выбираю нужную строку, жму далее. Далее предлагается выбрать имя проекта, расположение, язык программирования C/C++, исполняемый файл/статическая библиотека и будет-ли проект сгенерирован с помощью CubeMX или сами с усами. Генерация кубом, в данном случае не нужна, поэтому тип проекта Empty — финиш.




Слева, в окне Project Explorer, появилось дерево проекта, правда он не совсем Empty, как заказывали. Впринципе, если устраивает сгенерированная структура папок, можно добавить туда файлы из библиотеки CMSIS и работать дальше, но здесь я покажу как можно привести структуру проекта в гармонию со своим чувством прекрасного, поэтому удаляется всё, кроме скрипта линкера т.е. файла c расширением .ld — он еще пригодится.



Все манипуляции с папками и файлами можно проводить как в проводнике так и внутри IDE, нажав правой кнопкой на название проекта, к примеру: правая кнопка –> new –> Folder. Если структура проекта изменялась вне IDE, то нужно просто обновить проект: правая кнопка –> Refresh.

Мой вариант структуры проекта выглядит так:

  • Startup – здесь будет храниться скрипт линкера, тот самый, оставшийся от сгенерированного проекта, а также startup файл взятый из CMSIS
  • CMSIS\src и CMSIS\inc – здесь будут лежать исходники, файлы с расширением .c в папке scr и заголовочные файлы с расширением .h в папке inc соответственно, относящиеся к библиотеке CMSIS
  • Core\src и Core\inc – здесь будет расположен собственно сам проект, для начала стоит положить туда main.c и main.h


Теперь нужно перенести файлы библиотеки CMSIS в проект. Библиотека состоит из файлов ядра и файлов периферии. Файлы ядра начинаются с core_ или cmsis_ они общие для всех микроконтроллеров, использующих данное ядро. Файлы периферии содержат в названии наименование микроконтроллера stm32 и специфичны для конкретного производителя, в данном случае, компании STM.

В распакованном виде архив содержит папку STM32Cube_FW_F0_V1.11.0, все пути указаны относительно этой папки. Итого, нужно скопировать:

В CMSIS\inc:

  • Drivers\CMSIS\Include\cmsis_compiler.h
  • Drivers\CMSIS\Include\cmsis_gcc.h
  • Drivers\CMSIS\Include\cmsis_version.h
  • Drivers\CMSIS\Include\core_cm0.h
  • Drivers\CMSIS\Device\ST\STM32F0xx\Include\stmf0xx.h
  • Drivers\CMSIS\Device\ST\STM32F0xx\Include\stm32f072xb.h
  • Drivers\CMSIS\Device\ST\STM32F0xx\Include\system_stm32f0xx.h

В CMSIS\src:

  • Drivers\CMSIS\Device\ST\STM32F0xx\Source\Templates\system_stm32f0xx.c

В Startup:

  • Drivers\CMSIS\Device\ST\STM32F0xx\Source\Templates\gcc\startup_stm32f072xb.s

Так выглядит проект в заполненном виде.


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

Правая кнопка по названию проекта -> Properties -> C/C++ Build -> Settings -> Tool Settings -> MCU GCC Linker -> General – здесь нужно указать новое расположение скрипта линкера с помощью кнопки Browse…


Также нужно указать пути к файлам проекта

Properties -> C/C++ General -> Includes
Properties -> C/C++General -> Source Location

В Includes пути к папкам inc, а в Source Location логично было-бы к папкам src, но если так сделать, то в дереве проекта будут отдельно добавлены эти папки. Чтобы не загромождать визуально дерево, в Source Location можно указать корневые папки Core, CMSIS и Startup.



Для того чтобы проект скомпилировался нужно раскомментировать в файле stm32f0xx.h строку с названием микроконтроллера ну и конечно же в main.c добавить функцию main.



Собственно всё. Безошибочная компиляция и сразу же куда-то подевалось целых полтора килобайта памяти ОЗУ она же RAM, и сразу же вспоминается стек и куча, в процессе создания проекта они нигде не упоминались. Величина стека и кучи указана в файле скрипта линкера, тот что с расширением .ld, их можно и нужно изменять в соответствии с требованиями проекта. Эти значения находятся в начале файла в виде меток _Min_Heap_Size/_Min_Stack_Size с указанием размера в шестнадцатеричном виде.



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

Светодиод будет мигать на отладочной плате STM32F072B-DISCO, тактирование осуществляться от внутреннего генератора HSI48 частотой 48 МГц, а в качестве источника задержки использоваться таймер SysTick, генерирующий прерывания с периодом в 1 мс, при помощи которых отсчитывается точное время задержки. Светодиод подключен к выводу 6 порта С, настроенного на выход push-pull.

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

Комментарии 57

    +1
    Круто, а давно Stm32Cube стал IDE? Я даже соскучился как-то по эмбедд разработке…
      +3
      Да с пол года где-то, может чуть больше. По сути в одну коробку упихали сам куб и собственно атолик (читай эклипс). Оно и раньше было жутко кривое и тормознутое, а сейчас еще веселее.
        0
        В свое время пользовался связкой Stm32Cube + IAR, все полностью устраивало
          +2
          Использую куб, в смысле CubeMX, как очень удобный pinout, не более. В принципе и атоллик был вполне сносным инструментом, но вот чудовище, которое родили слепив их у меня на ryzen 3600x стартует просто минуту. Грешил на AMD, попробовал на 7700K, все тоже самое. Просто открытие пустого проекта минута! После 1-2 секунд VS Code у меня это вызывает боль.

          CubeIDE постоянно крашится, настройки проекта через одно место сделали, на больших проектах автодополнение работает крайне медленно. На истину не претендую, но лично у меня впечатление осталось плохое о новом творение.
            0
            Да, подсмотреть инициализацию в кубе милое дело. Насчет крашится, у меня пока не было, а вот создать совсем пустой Си проект и накидать туда все остальное так и не смог, т.к. на этапе настроек проекта, вылазит какая-то ошибка с внутренним кодом и дальше ничего не работает.
          0
          Спасибо, тоже пропустил…
          Cube cам-то примелькался, MX или IDE там в конце и не разобрать)
            0
            Значит надо подождать ещё полгода пока вся «сырость пропечётся».
          0

          Сегодня какраз устанавливал среду для изучения STM32. Начал с cubeide — ужаснулся. Поставил keil — это небо и земля в сравнении с этой поделкой

            0
            У кейла ограничение в 32кб. С которым рано или поздно сталкиваешься.
              –1
              вряд ли для такого большого проекта будут использовать Cube IDE
              Особенно если коммерческая разработка
                +2
                Добавил в простой проект USB+FATFS на STM32F4 и уже вылетел за порог в 32кб. По началу отключал то, что не использую, изменял уровни оптимизации. В конечном итоге плюнул и перешел на Atolic.
                  +1
                  Это вы ещё FreeRtos не использовали до кучи к вышеперечисленному с парой десятков задач.
              0

              Первый раз пробовал что-то написать под STM32 из под Keil. Очень быстро перелез на CLion (gcc + OpenOCD), т.к. Keil, как IDE, по ощущениям, отстает где-то на 10-15 лет. Удобный редактор с возможностью vim режима, быстрая и точная навигация по определениям, подстветка, продвинутое автоформатирование, подсказки вроде clang-tidy, рефакторинги, интеграция с git, даже темная тема и другие мелочи — всего этого в keil не хватает.


              Предполагаю, что в нем есть какие-то свои фичи, которых нет в более универсальных IDE вроде CLion или VS Code, но пока не сталкивался (может они нужны на более сложных задачах, где CLion + gcc + OpenOCD + gdb не хватит, не знаю).

                +1

                А есть где дока, как использовать такую связку?

                  +1

                  https://www.jetbrains.com/help/clion/embedded-development.html
                  Есть более старая, но чуть более подробная статья из трех частей:
                  https://blog.jetbrains.com/clion/2016/06/clion-for-embedded-development/


                  От себя могу добавить, что, используя эту связку, можно без проблем писать на C++ 2a под STM32 (gcc последний 2019-q4).
                  Для этого мне понадобилось только сделать пару однострочников, которые переименовывают все .c файлы в .cpp и обратно (на время перегенерации проекта в Cube, если что-то меняю или просто мигрирую на новую версию).


                  Понадобилось только добавить немного static_cast'ов в нескольких местах (и не забывать откатывать изменения генератора cube на этих строчках через git), игнорировать несколько видов предупреждений (у меня получилось -Wall -Wno-register -Wno-write-strings -Wno-sign-compare -Wno-unknown-pragmas -fno-exceptions -Wno-psabi в CMAKE_CXX_FLAGS) и исключить код FreeRTOS из переименования в cpp (иначе планировщик перестает работать когда код FreeRTOS скомпилирован как C++).

                  0
                  CLion платный жеж ( или я что-то пропустил?).
                    0

                    Есть бесплатные студенческие лицензии, а так платный. Но аналогов по удобству нет, сомневаюсь, что Qt Creator или VS Code смогут добраться до такого же уровня в обозримом будущем (впрочем, они всё еще далеко впереди Keil).

                +2
                «проприетарность» уже стала достоинством?!
                  +1
                  Автор, в чем заключаются плюсы проприетарности?
                    0
                    в надежде, что когда-нибудь уберут косяки
                      0

                      Одни уберут но новых добавят. У них чипы (и доки) зато традиционно хороши. А со средами разработки традиционно не очень. :)

                        0
                        Винда проприетарна. И?
                      0
                      Как у него с отладчиком? Если есть, что и как нужно подключать ;)
                        0
                        Отладчик на месте, Run -> Debug, там же настройки, если подключен какой-нибудь ST-Link, оно само все настраивает
                          0
                          Само то оно настраивает конечно, но если хочется использовать трассировку через 3-х проводный SWD (semihosting), то многое в настройках приходится подправлять руками.
                            0

                            В дебиане уже пару версий как gdb-multiarch, так и так править.

                            0

                            Интересует китайский j-link. Просто решил попробовать stm, подыскиваю среду. Кто что советует. И ещё вопрос, как либы скомпилированные подключать? Есть библиотека STM32CRYPTOLIB, а как подключить не нашёл

                              0
                              Библиотеки подключаются так же, как и к любому C/C++ проекту на Eclipse. Открываем свойства проекта, в панеле диалога слева выбираем C/C++ Build -> Settings. Открываем вкладку Tool Settings. Открываем в дереве MCU GCC Linker -> Libraries и добавляем в панель Libraries нужные библиотеки. Так же в MCU GCC Compiler -> Include paths в панеле Include paths добавляем пути к заголовочным файлам библиотек.
                            0
                            Идет из коробки и сразу работает. Вообще настраивать не пришлось.
                            При установке еще предлагает дрова stlink, jlink поставить.
                            Windows/Linux — полёт успешный
                              0
                              На Raspbian пойдёт?
                                0
                                Немного жестоко гонять толстый эклипс с большим количеством java на гигабайте оперативной памяти. Мне будет интересно посмотреть на скорость Вашей работы, даже если заработает без проблем.
                            0
                            А чем этот CubeIDE удобнее чем PlatformIo IDE?
                              0

                              У меня слегка эгоистичный подход — использую "чистый" Eclipse для всего. Проще довесить требуемые целевой архитектурой плагины чем перепревыкать. Да, STM32CubeMX есть плагином под эклипс. И работает, единственный минус — под linux надо указывать gtk=2.

                                0
                                Когда-то я тоже был фанатом Эклипса. Недавно переполз на Вижуал Студио Коде — просто небо и земля. Рекомендую.
                                  0

                                  Не, не фанатизм. Лень :). Но попробую.

                                    0

                                    Спорно. VS — просто монстр и не очень гибкий. eclipse гибче, и во многом удобнее.
                                    Лично я бы предпочел гибрид eclipse и beans.

                                      0
                                      VS и VS Code — это два разных продукта ;)
                                        0
                                        Извиняюсь, Ваша правда. Спутал VS Code и community.
                                        Обязуюсь поработать с VS Code.
                                  +1
                                  Советую попробовать qt creator. Очень удобная штука. Переполз на него с geany через sublime. Самая лучшая навигация по коду + в реальном времени подсвечиваются различные проблемы, диагностированным статическим анализатором clang.
                                  В общем, свободная IDE гораздо лучше всякой проприетарщины!
                                    0

                                    Тут ведь дело не только в работе с кодом — нормальный дебаг, отображение состояния переферии, трассировка значений переменных — вот это все можно добавить в qt creator?

                                        0

                                        Там инструкция про подключение отладчика и ни слова про всё остальное

                                        0
                                        qtcreator из коробки работает с gdb, так что, если кому-то нужна внутрисхемная отладка, с этим проблем нет.
                                        Лично я отлаживаю более привычным для меня способом: посредством диагностических сообщений (UART, USB), а также с помощью логанализатора и осциллографа. Пока еще ни разу не испытывал потребности во внутрисхемной отладке.
                                        В принципе, есть еще вариант — сеггер предлагает посредством jlink в реальном времени сообщения отсылать с меньшей нагрузкой, нежели уарт (как я понял, выделяется область памяти с флажками и собственно сообщениями, а jlink периодически это мониторит). Но я — не сторонник уж такой лохматой проприетарщины, чтобы вместо stlink'а jlink использовать.
                                          0
                                          Через stlink тоже можно гнать трассировочные сообщения, причем даже двумя разными способами: синхронным (через обычное трехпроводное подключение) и асинхронным (требует одной дополнительной линии связи).
                                            0
                                            Понятно, что в принципе это возможно, но пока свободных (да и даже проприетарных) реализаций не встречал.
                                            Честно говоря, st-link я использую в основном лишь для STM8, а STM32 прошиваю встроенным бутлоадером либо через UART, либо через DFU.
                                              0
                                              Та же STM32CubeIDE поддерживает при переключении Debug probe с выбираемого по умолчанию «ST-LINK (ST-LINK GDB server)» на «ST-LINK (OpenOCD)» и небольших манипуляций с конфигурацией проекта. Если не хочется STMCubeIDE, то трассировочные сообщения поддерживает тот же консольный st-util с ключем --semihosting
                                      0
                                      Ребята, создавать проект типа под SPL на CubeIDE никто не научился?
                                        0
                                        SPL только руками, устарел же официально, в качестве приемника есть LL, куб его генерирует без заморочек
                                          0
                                          SPL под кубIDE никак не получается, хоть руками, хоть еще чем! Примеры есть, такие, чтобы реально подтверждали возможность создания SPL проектов под CubeIDE???
                                          0
                                          Учитывая то, какие портянки после кубового кодогенератора получаются, лучше использовать куб только по прямому назначению: для выбора наиболее подходящего под задачу МК и для уточнения, что всей необходимой периферии вам хватит.
                                          Для инициализации периферии те же ST давным-давно написали набор очень хороших сниппетов (жаль только, что они лишь под STM32F0, но и на другие семейства их несложно перенести). Ну, а остальная логика все равно пишется руками, так что все эти SPL, HAL, opencm3 — излишества. По сути, если пользоваться дополнительно внешними библиотеками, придется не только RM+даташит на МК читать, но и документацию на библиотеку (да и частенько в ее код заглядывать, когда наткнешься на баг или тормоза).
                                            0

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

                                              –1
                                              Быдлокод посредством калокуба годится лишь если «поматросил — и бросил» (то бишь «тяп-ляп — и в продакшн, а о поддержке забудьте»).
                                              Если же поддерживать надо, то только полоумный будет в каловских портянках пытаться разобраться вместо того, чтобы целиком полноценный свой код написать.
                                              И да, свои сниппеты — это вещи, проверенные временем. Уж всяко надежней, чем кал (в котором, кстати, до сих пор косяки находят).
                                                0
                                                По опыту, ноги раскидать — оно годно.
                                                И с недавних пор даже научились делать однонаправленный UART не только в GUI, но и на деле (раньше «говоришь» «мне uart только на выход», а в портянке все равно 2 ноги).
                                                i2c — ужасный.
                                                spi — с пивом норм, хоть и есть нюансы.
                                                usb — вполне.
                                                dma — ужас подающий надежды
                                                таймеры — так же

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

                                                Сниппеты все на CMSIS и были узкие места, которые в сочетании с другими задачами работать не будут (опять, таки, если нет опыта). А ремапнуть ноги какого-нибудь интерфейса для человека неподготовленного может занять целую вечность. Кто умеет, тот и без сниппетов накидает, просто глядя в RM.

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

                                          Когда Atollic стал бесплатным, я очень обрадовался, потому что это цельная специализированная IDE с множеством полезных инструментов для отладки. Плюс, она отлично работала с дополнением Eclipse для поддержки CMake проектов. Единственное, она использовала старую версию CDT и не поддерживала всех современных фич языка C++. Но была надежда на то, что в будущем это пофиксят.


                                          А потом вышла Stm32CubeIDE и сломала совместимость с CMake плагинами. Хочется работать — генерируюй проект в CubeMX. А когда у тебя CI и всё проекты на CMake + в основном ты пользуешься libopencm3… Пришлось оставить надежду и уйти на VS Code. Очень жаль, что так вышло.

                                            0
                                            По мне так переименовали бы они атолик в куб и не городили абсолютно новую IDE.
                                              –1
                                              Что-то я запутался во всем этом разнообразии библиотек.
                                              Итак для STM32, есть HAL, LL, opencm3, SPL и CMSIS, что-то еще я забыл?

                                              при этом
                                              SPL — только для STM32. Устарел.
                                              LL — только для STM32. Генерится с помощью Stm3CubeMX. Устарел.
                                              HAL — только для STM32. Генерится с помощью Stm3CubeMX.
                                              opecm3 — для разных производителей, но поддержка моделей МК страдает. Есть github и можно вносить правки.

                                              CMSIS — для всех Cortex. То что на сайте ARM не то чтобы библиотека, а в основном заголовочные файлы с названиями и описаниями функций. Тела предлагается реализовать самостоятельно.
                                              Итак вопрос, есть ли CMSIS для Stm32?
                                              Есть ли производители, которые реализовали CMSIS для своих МК?

                                                0
                                                LL появился позже HAL и уже устарел? Откуда инфа?

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

                                              Самое читаемое