Настройка IDE Clion и Cmake для работы с STM32 и C++

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

Давно хотел попробовать себя в микроконтроллерах, вернее были идеи с их использованием, которые очень хотелось реализовать. Сначала начал с PIC32 — огонь контроллеры. Так получалось, что поначалу и коротил их порты, и с питанием завышал — неубиваемые (не совсем конечно, порт правда однажды сгорел, но сам контроллер продолжал работу). IDE MplabX неплоха, подкупал графический блок с отображением занимаемой RAM/Flash на выбранном МК — удобно, но сам NetBeans как IDE это жесть, ну не удобно ни разу после Idea. Но проблема была не в этом — как потом оказалось, PIC'и тяжело достать, мало кто их возит, а если и возит, то по относительно высокой цене.

Дальше решил копнуть в сторону STM32 — они в больших количествах, за базовую периферию просят не много, но главное — это доставаемость. (Но кодогенератор STM'а хуже Microchip'a — весь файл загажен комментами и функциями, это конечно сильно огорчило. У Microchip'а все сгенеренные функции вынесены в отдельные файлы и main.c практически чист — прелесть).
(UPD: вот тут признаюсь ошибался, спасибо golf2109, он подсказал, что от заваливания комментами и функциями файла main.c можно избавиться, достаточно включить в настройках опцию для вынесения сгенерированного кода в отдельные файлы, но я все же в недоумении, почему это не дефолтная настройка, вроде логично было бы)

Теперь об IDE для STM32.

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

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

Clion почти та же Idea только для C/C++ и сразу захотелось ее прикрутить, но как оказалось довольно проблематично (особенно для человека, который с плюсами-то не силен, особенно со всякими сборщиками и компиляторами, парой сотен опций компиляции). Начал с блога JetBrains. Довольно подробно описано, но это для прошлых версий STM32CubeMX, в новой немного поменялась структура каталогов, в результате чего я некоторое время не понимал почему не компилится. Потом разобрался — изменил пути, для cortex-m3 убрал параметры -mfpu. Но опять не компилился. Дальше оказалось, что я не тот компилятор установил, вернее просто скачал его, но не указал путь к нему в файле сборки (ну сложновато поздно вечером думать).

Главное в Clion'е поставить галочку в настройках 'Automaticaly Reload Cmake Project on Edit' (Settings -> Build, Execution, Deployment -> Cmake), тогда после правок не нужно ничего очищать вручную.

Еще из изменений — дебаггер, упомянутый в блоге, переименовали в Ozone, его еще не тестил, позже отпишусь.

И последняя проблема, сверлившая мозг. Очень хотелось ООП, но не компилился проект если я добавлял C++ файл, куча ошибок с не найденными функциями (например, _exit, _sbrk и пр.). Здесь проблем было 2:

  • в файле CMakeLists.txt в блоге JetBrains не был выставлен флаг CXX в директиве project (нужен для файлов C++)
  • для исправления ошибок в файле из блога не хватало опций -specs=nosys.specs -specs=nano.specs после опции -gc-sections. Они как раз создают эти прототипы или наоборот игнорят эти методы (тут не могу точно сказать)

После этого проект нормально стал компилиться и размер его стал в пределах нормы (без опции -specs=nano.specs размер был в 10 раз больше для пустого проекта примерно 110 кб., с опцией — 18 кб.)

Итак, что я сделал:

  1. ставим Clion
  2. заходим в настройки (Settings -> Build, Execution, Deployment -> Cmake) и ставим галочку 'Automaticaly Reload Cmake Project on Edit'
  3. здесь же вписываем в поле Cmake options параметр -DCMAKE_TOOLCHAIN_FILE=STM32L1xx.cmake и в поле Generation path ставим build (если поменять, то в файлах CMakeLists.txt и STM32L1xx.cmake нужно его тоже будет поменять)
  4. ставим ARM компилятор (здесь брал)
  5. импортируем проект (который предварительно сгенерировали в STM32CubeMx), говорим, что можно создать CMakeLists.txt
  6. отсюда или из моего репозитория копируем содержимое CMakeLists.txt в созданный в Clion'e и добавляем файл STM32L1xx.cmake (можно обозвать как угодно)
  7. в STM32L1xx.cmake правим имя проекта в директиве project и можно убрать CXX если не нужен C++
  8. заменить в файле CMakeLists.txt в директиве add_definitions(-DSTM32L100xC) на свой контроллер
  9. для надежности можно сделать: Tools -> Cmake -> Reset Cache and Reload project и потом Tools -> Cmake -> Reload Cmake Project
  10. теперь можно сбилдить

Файл CMakeLists.txt

project(Skeleton C CXX ASM)
cmake_minimum_required(VERSION 3.5.0)

add_definitions(-DSTM32L100xC)

set(FREERTOS_DIR Middlewares/Third_Party/FreeRTOS/Source/)

file(GLOB_RECURSE USER_SOURCES "Src/*.c")
file(GLOB_RECURSE HAL_SOURCES "Drivers/STM32L1xx_HAL_Driver/Src/*.c")
file(
    GLOB_RECURSE
    FREERTOS_SOURCES
    "${FREERTOS_DIR}/*.c"
    "${FREERTOS_DIR}/CMSIS_RTOS/*.c"
    "${FREERTOS_DIR}/portable/GCC/ARM_CM3/*.c"
)

add_library(
    CMSIS
    Src/system_stm32l1xx.c
    startup/startup_stm32l100xc.s
)

include_directories(Inc)
include_directories(Src/gps/parser/nmea)
include_directories(Drivers/STM32L1xx_HAL_Driver/Inc)
include_directories(Drivers/CMSIS/Include)
include_directories(Drivers/CMSIS/Device/ST/STM32L1xx/Include)

include_directories(${FREERTOS_DIR})
include_directories(${FREERTOS_DIR}/CMSIS_RTOS)
include_directories(${FREERTOS_DIR}/include)
include_directories(${FREERTOS_DIR}/portable/GCC/ARM_CM3/)
include_directories(${FREERTOS_DIR}/portable/GCC/MemMang)

add_executable(${PROJECT_NAME}.elf ${USER_SOURCES} ${HAL_SOURCES} ${LINKER_SCRIPT} ${FREERTOS_SOURCES})

target_link_libraries(${PROJECT_NAME}.elf CMSIS)

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Map=${PROJECT_SOURCE_DIR}/build/${PROJECT_NAME}.map")
set(HEX_FILE ${PROJECT_SOURCE_DIR}/build/${PROJECT_NAME}.hex)
set(BIN_FILE ${PROJECT_SOURCE_DIR}/build/${PROJECT_NAME}.bin)
add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
        COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${PROJECT_NAME}.elf> ${HEX_FILE}
        COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${PROJECT_NAME}.elf> ${BIN_FILE}
        COMMENT "Building ${HEX_FILE} \nBuilding ${BIN_FILE}")

Файл STM32L1xx.cmake:

INCLUDE(CMakeForceCompiler)

SET(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_SYSTEM_VERSION 1)

# Specify the cross compiler. arm-none-eabi-gcc and arm-none-eabi-g++ are full path required
CMAKE_FORCE_C_COMPILER(arm-none-eabi-gcc GNU)
CMAKE_FORCE_CXX_COMPILER(arm-none-eabi-g++ GNU)

SET(LINKER_SCRIPT ${PROJECT_SOURCE_DIR}/STM32L100RCTx_FLASH.ld)
SET(COMMON_FLAGS "-mcpu=cortex-m3 -O2 -mthumb -ffunction-sections -fdata-sections -g -fno-common -fmessage-length=0")
SET(CMAKE_CXX_FLAGS_INIT "${COMMON_FLAGS} -std=c++11")
SET(CMAKE_C_FLAGS_INIT "${COMMON_FLAGS} -std=gnu99")
SET(CMAKE_EXE_LINKER_FLAGS_INIT "-Wl,-gc-sections -specs=nosys.specs -specs=nano.specs -T ${LINKER_SCRIPT}")

Работать стало приятно, но пока заливаю прошивку через STM'овскую утилиту, позже попробую накрутить OZONE. На вопросы отвечу (если смогу).
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама
Комментарии 28
  • 0
    На сайте нашел только триальную на 30 дней.
    Плохо искал или нет в природе?
    • 0
      Практически все IDE от JetBrains платные. Но они того стоят :)
      • +2
        Оно того стоит, если постоянно зарабатываешь этим. А если программинг – хобби, то не стоит.
        • 0
          CLion хорош. Я когда делал свой мини-проект для STM32 почти было его купил.

          Но потом я попробовал Rust и переписал всё на него. Рекомендую попробовать.

          Есть плагин для IntellJ, но он довольно сыроват. В частности, вывод типов работает не идеально, из-за чего местами затруднительно использовать сгенерированную под контроллер библиотеку (генерируется много весьма специфичных типов, под конкретную периферию).
          • 0

            Для студентов вроде на год бесплатная лицензия.

            • 0
              Не просто на год. Пока студент, то лицензия бесплатная. И каждый год нужно подтверждать, что ты студент.

              Ну и плюс опенсорсу тоже лицензии бесплатны.
            • 0
              Есть EAP (Early Access Preview) версии (про CLion не уверен, но IDEA точно есть), которые условно бесплатны на определенный период, но при обновлении до следующей версии trial сбрасывается. Это даже не бета, там бывают весьма неприятные баги, а ты выступаешь фактически тестером. Но… для хобби вполне себе. И ребятам поможешь, хоть и не валютой, если не лениться отправлять баг репорты ;-)
            • 0
              Может они и стоят того для java-guru.
              А мне и Keil и SES и IAR и Ride7 и Visual Studio/Code.
              Ну а когда совсем делать нечего можно и Eclipsом/CCS/SimplicityStudio/Kinets время убить (и производными от него).
              Для супер профи еще ArduinoIde есть.
              Рюшки в той же VS необыкновенные, но gcc и рядом не лежал с armcc.
              Про отладчик я и говорить не буду. Ozon конечно не плох, но еще поработать надо.

              Но каждый вибирает сам — спорить бессмысленно.
          • +2
            Попробовал хваленый Keil — конечно получше блокнота

            А вот щас, обидно было (с)
            Я уже попробовал CLion для STM32 и у меня ровно обратные притензии:
            — У меня вот (как и у 80% людей) ST-Link, че мне делать то с вашим Segger Debuger. Ответ — не дебажить.
            — В отличии от Clion, Keil обладает хорошими сис. мониторами, которые позволяют контролировать процесс инициализации/пуска, эвенты/обработчики — что может Clion?
            — В Keil есть отличный эмулятор, который позволяет не парится с дев бордой, или юзать функции МК которых нет на твоей борде (какой нить USB или FSMC и т.п.)
            — Я использую продукты JetBrains, в частности PyCharm и меня задолбало, что за 4 часа работы IDE выжирает 2Гб ОЗУ (400 начальный это минимум), при всей своей «ненависти» к Keil его потребление неделями остается 40-50Мб, что позволяет мне его использовать ГДЕ угодно и КОГДА угодно.
            — Keil имеет собственный репозиторий либ, которые добавляются простой галочкой в настройках.
            Не срача ради, но все таки: Вам шашечки (подсветка, цветастость то да се) или таки ехать? (писать/дебагать под МК)
            ЗЫ. Взял цв. тему с PyCharm, перегнал в Keil, получил 2 в 1, и Вам того советую. Кстати так и не понял что Вы называете «пакетами»?
            • 0
              Мне кажется, что если ограничится работой с железом — то, может, Keil и хорош. Мне лично в том проекте, над которым тружусь что-то все эти возможности не очень пригодились. Да и польза от него, только если крепко сидеть под виндой.
              А вот если с кучей «бизнес-кода», оставшегося от свинтивших с проекта «железячников» разбираться, то тут уже CLion, Eclipse и т.д. Инструменты для работы с кодом в Keil'е вызывают недоумение.
              А по-поводу потребления памяти — то это как Запорожец сравнивать с многоцелевыми истребителем. И по этому показателю, и по работе с кодом, кстати, Keil далеко позади и Atom'а, и VSCode, и Sublime'а, и Emax с Vim'ом…
              • 0
                Мне кажется, что если ограничится работой с железом

                А с чем Вы простите работаете, не с железом?
                Мне кажется, не надо «редакторы» (atom/sublime), сравнивать с полноценной средой разработки для встраиваемых систем c присущим ей функционалом, ибо то что вы перечисляете есть ничто иное как фишки редактора, не более.
                А я сравнил две IDE, и утверждал, что профита от Clion, кроме редактора — никакого.

                Кажется мы стали забыть что такое IDE…
                • 0

                  Я думаю, что Ryppka имел в виду работу с кодом в плане intellisense, навигацию, семантический анализ, рефакторинг и тому подобное. Иметь всё это — большое подспорье в разработке.

                  • 0
                    intellisense

                    Поэтому я и спросил. Вы пишите просто С/С++ оперируя чистым кодом, или вам часто приходится таки работать с железкой?
                    С железкой, не в плане, «накодогенераторить» а потом сидеть принтами дебагать, че из этого вышло.
                    В целом для чистого С, мне достаточно что Keil подстветит мне структуры, остальное вырабатывается по ходу работы, но все равно, я считаю что иметь для программирования встраиваемых систем монитор периферии, это огроменный плюс, который перекрывает «квадратность» редактора кода.
                    Эксперименты с IDE для embedd, я перестал делать после попытки завязаться с CooCooX, понял что проще попытатсья раскрыть потенциал знакомого инструмента, чем сидеть страдать в поисках.
                    Более того, мне компилятор кейл, как то более по душе, учитывая что он является официальным АРМ компиллером, а 30кб триального кода, на данный момент хватает за глаза.
                    В целом, я не хотел преподнести свои слова как агрессию, просто автор статьи, как новичек, непонятно за что боролся, настраивая Clion для редактирования кода, в ущерб скажем так «прозрачности» программирования и понимания. Я сам на первых парах лихорадочно трейсил даже функции в библиотеках (stl), сравнивая значения в регистрах с тем что нужно было мне, искал различные нюансы в написании кода, активно использовал эмулятор (например для исследования работы аналогового компаратора, и разных режимов ADC).
                    • 0

                      Приходится. Хм, может быть, я не совсем понимаю, что вы имеете в виду под мониторами периферии? Потому что Ozone вполне себе показывает состояние периферии, и не приходится разменивать "квадратность" на качество работы с железом. У автора есть удобные неинвазивные логи (через RTT), есть осциллограф (J-Scope), есть инструмент для профилирования в динамике (SystemView), так что я не думаю, что он что-то потерял в плане удобства работы с железом. Может быть, я просто что-то не знаю о кейле (признаюсь, давно было, да и Linux везде) и там есть что-то гораздо удобнее.


                      Я бы не хотел спорить о том, что лучше, тем более всё сильно завязано на персональное удобство и особенности проектов. Кому-то достаточно триальных ограничений — для меня 30 Кб практически делает компилятор бесполезным, у меня довольно увесистые проекты. Я активно использую C++14 (не спешите кривиться, C++ вполне годен для embedded — если знать подводные камни, много платить не приходится) и не знаю, что у armcc с поддержкой, а кто-то работает с чистым C и для него это не фактор. Кому-то нужна только подсветка кода, а мне некомфортно без маленьких радостей жизни — посмотреть сигнатуру функции под курсором и комментарий к ней, вывести список методов после. или -> (и да, с fuzzy search) и тому подобного. Кому-то хочется подключать библиотеки кликом мыши, а я, признаюсь, немного control freak, мне нужно, чтобы проект был самодостаточной вещью в себе, без управления с помощью GUI-магии (поэтому связка CMake / CLion мне импонирует — обычная система сборки одновременно служит форматом проекта IDE). Так много фломастеров, и так много вкусов. :)

                      • 0
                        Соглашусь. Я то же отношусь довольно серьезно к коду и без всяких плюшек уже тяжело, т.к. с кодом провожу много времени, а дебаг это уже другая тема, она скорей по готовому коду проходит или в процессе (не буду тут ни с кем спорить).
                        Keil заточен под контроллеры и имеет все необходимое на борту — с этим я даже не спорю, но как IDE очень не понравилась, в каких-то моментах тривиальные вещи в нем становятся не тривиальными, но это мой опыт и мое мнение.
                        Думаю в Clion получится прикрутить все необходимое, либо дописать плагины, дело времени.
              • 0

                Не вступая в полемику и не делая рекламы (хотя я использую CLion и, для встраиваемого, инструменты от Segger), вроде бы у сеггера есть утилита, которая из ST-Link делает J-Link OB. Но я не пробовал, она просто там в загрузках висит.

                • 0

                  Использовал CoIDE. Для труЪ профессионала, конечно, не то, но довольно приятно. Подключение либ из коробки. Нормальный дебаг Ну и все редакторские плюшки Eclipse. Пока эта IDE мне больше всего нравится.


                  Сейчас использую Keil, так сложилось. Удобнее IAR блокнота, но замечания есть. Иногда не работает автодополнение и навигация по коду. А так же при отладке часто не показывает значения переменных. И в проекте нельзя делать вложенные… гм… назовем их "папки".


                  P.S.


                  У меня вот (как и у 80% людей) ST-Link, че мне делать то с вашим Segger Debuger. Ответ — не дебажить.

                  Я настоятельно призываю не пользоваться нелицензионным ПО и железом, но в ознакомительных целях перепрошивка ST-Link в Segger J-Link


                  Делал так для RTL-8710, потому что на копеечный радимодуль деньги есть, а на Segger — нет

                  • 0

                    CLion вполне умеет в удалённый дебаг через gdb->OpenOCD->TS-Link. Отлично работает. Шью тоже через OpenOCD.


                    Всяких контроллероспецифичных мониторингов иногда не хватает, но они лично мне не очень-то и нужны.


                    А т.к. я 80% времени сижу в IDEA то перескакивать между разными IDE неохота. Начинаю сбиваться.

                  • 0

                    *.specs не генерирует, а скорее линкует с соответствующей реализацией libc / libgolss вашего тулчейна.
                    Например lib/thumb/v7-ar/fpv3/hard/nano.specs:


                    ...
                    *nano_libc:
                    -lc_nano
                    
                    *nano_libgloss:
                    %{specs=rdimon.specs:-lrdimon_nano} %{specs=nosys.specs:-lnosys}
                    ...
                    *link:
                    %(nano_link) %:replace-outfile(-lc -lc_nano) ...
                    ...

                    с, в зависимости от реализации, застабленными вызовами типа такого: https://github.com/32bitmicro/newlib-nano-1.0/blob/c010b5911834ed9a412bd0a865abdf3eed00a4ee/libgloss/arm/syscalls.c#L585

                    • 0
                      Да, похоже на то, спасибо за ссылку.
                    • 0
                      Раз уж пошло обсуждение IDE, могу порекомендовать Atollic True Studio. На базе Eclipse, есть бесплатная версия.
                      • +1

                        Пока для Baremetal ничего удобнее Qt Creator не нашёл:


                        • Разные профили и билд директории для отстройки дебажного, релизного и прочего кода. В том числе с разными параметрами билда, очень удобно, когда может быть несколько конфигураций.
                        • Удобное редактирование параметров CMake для проектов
                        • Декларативный тулчейн для CMake теперь можно прописать непосредственно в настройках Kit. Или просто указать свой файл, прописав туда: CMAKE_TOOLCHAIN_FILE=...path_to_toolchain_file...
                        • Поддержка удалённой отладки. В том числе средствами спарки GDB + OpenOCD и/или ST LINK Utility. Загрузка кода через JTAG прямо из IDE.

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


                        Отмечу, что я использую для CMake проектов скорректированный плагин, который отображает в дереве проекта все файлы, а не только те, которые прописаны в CMakeLists.txt (по аналогии, как это делает CLion).


                        Недостаток, по сравнению с CLion у QtC ровно один (по мне): нет автоматической возможности добавить файл в CMakeLists.txt к нужному таргету при добавлении его в проект. Нужно вручную открывать и добавлять.


                        В общем, если интересно: гляньте мои публикации тут.

                        • 0
                          Ссыли не хватает.
                          • 0

                            Да через профиль:



                            А вообще: http://doc.qt.io/qtcreator/creator-developing-baremetal.html или тут же: https://habrahabr.ru/post/222877/ (правда автор использует qbs). Ну и куча ссылок в гугле по связке "Qt Creator Baremetal".

                            • 0

                              Прошу прощения за некропостинг, но спешу заметить, что разрабатывать embedded на Qbs — полное издевательство. Ребята из Qt каждый релиз Qt Creator что-то меняют под капотом этой системы сборки и мне приходится бодаться с недодокументацией на Qbs, чтобы понять, что блин надо поменять в настройках проекта, чтобы эта штука опять начала собирать проект.


                              После третьего к ряду обновления Qt Creator, изрядно задолбавшись, выкинул настройки проекта на мороз и портировал проект на Eclipse (Code Composer Studio).


                              Qt Creator хорош, но хорош для разработки на пингвинах.

                              • +1

                                Вы сейчас смешали Qbs и QtC. Не используйте первое. Используйте, хотя бы, CMake. Или, на крайний случай, Generic Project.

                        • 0

                          Как-то поздновато на статью набрёл. Сейчас занимаюсь точно такими же экспериментами. Так что "лирику" читал — как про меня написано :)


                          Могу поделиться ещё и своими находками в плане флагов:


                          SET(CMAKE_C_FLAGS_DEBUG "-Og -g" CACHE INTERNAL "c compiler flags debug")
                          SET(CMAKE_CXX_FLAGS_DEBUG "-Og -g" CACHE INTERNAL "cxx compiler flags debug")
                          SET(CMAKE_ASM_FLAGS_DEBUG "-g" CACHE INTERNAL "asm compiler flags debug")
                          SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "" CACHE INTERNAL "linker flags debug")
                          
                          SET(CMAKE_C_FLAGS_RELEASE "-Os -g -flto -ffat-lto-objects" CACHE INTERNAL "c compiler flags release")
                          SET(CMAKE_CXX_FLAGS_RELEASE "-Os -g -flto -ffat-lto-objects" CACHE INTERNAL "cxx compiler flags release")
                          SET(CMAKE_ASM_FLAGS_RELEASE "-g" CACHE INTERNAL "asm compiler flags release")
                          SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "-Wl,-flto" CACHE INTERNAL "linker flags release")

                          Получается две конфигурации. Для debug и для release. В версии release активирована максимальная оптимизация по размеру, плюс full link time optimization (flto). Это такая хитрая функция современного GCC, когда в объектные файлы пишется не только готовый машинный код, но и специальный байткод синтаксического разбора (на сколько я понял). Задаётся это флагами -flto -ffat-lto-objects. В проектах на большом брате можно обойтись и без -ffat-lto-objects. Но на STM32 не получается.


                          Далее в дело вступает линкер, который при заданной опции -Wl,-flto вычитывает из объектных файлов уже не машинный код, а подготовленный на предыдущем шаге байткод. И проводит агрессивную оптимизацию уже в рамках всего исполняемого файла (прошивки). Что приводит к тому, что прошивка существенно сокращается в объёме и при этом становится намного производительнее.


                          На "помигать светодиодом" получается около 3.5 Кб вместо 18 Кб.

                          • 0

                            К слову опцию CMAKE_TOOLCHAIN_FILE можно задать и в корневом CMakeLists.txt перед директивой project. Чтобы не требовать указывать это вручную в настройках IDE.

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