STM32 и CLion

– Или скрещиваем Льва с Пингвином

Статья описывает установку IDE CLion на Linux и Windows, настройку её для работы с STM32, запуск отладки, используя нативные инструменты.

STM32 и CLion
🔗 Ссылка на видео 🔗

Вступление

Обновление основного рабочего инструмента — большая перемена в жизни. Для меня это была покупка нового ноутбука.
Чтобы рабочий процесс был наиболее эффективен, захотелось пересесть на Linux.

fedora-screenfetch

Первое знакомство с STM32 случилось в начале 2020 года. Как и многие, разработку я вёл в бесплатном инструменте STM32CubeIDE. На самом деле это Eclipse, окружённый плагинами.

После установки на Linux сначала меня встретил пустой Target selector.

STM32 и CLion
Нажмите для увеличения

Как оказалось, этот баг встречался ещё с 2019 года, на май 2022 его уже починили.

Всё дело в графическом сервере. По умолчанию Fedora использует Wayland, который, в отличие от Xorg (X11), самостоятельно не отрисовывает интерфейсы, а кладёт эту задачу на приложение. Если оно этого не предусматривает, то пустота и будет.

Хоть основная беда и исправлена, остальные остались. Связаны они с масштабированием дисплея.
Для моих 4К на 14 дюймов надо включать масштаб 200%.
Проблемы в данном случае такие: текст местами размыт, значки сломались, подсказки к методам убегают, а то и вовсе намертво вешают IDE.

STM32 и CLion
Нажмите для увеличения

Отсюда ясно, что пользоваться этим совсем неприятно. А ещё риск потерять несохранённый код из-за очередного бага.

Избавляемся от CubeIDE

Среда CubeIDE нравилась мне как готовый “комбайн” для производства прошивок. Полный цикл: от настройки МК, до полноценной, глубокой отладки.

Но до сих пор я не решался уходить с неё. В других средах меня пугало огромное количество всяких конфигов, настраиваемых, в основном, вручную.

Какие есть альтернативы?

Во-первых, существуют профильные решения: Keil, IAR, MikroC, и так далее… Какие-то не понравились мне функционалом или интерфейсом. У некоторых закрытая ценовая политика. Какие-то вовсе нативно не поддерживаются на линуксе.

Во-вторых, существует масса плагинов для отладки ARM в других IDE. Первое, что приходит на ум — Visual GDB для Visual Studio. [Видео-инструкция]
Так как на Linux доступен только VSCode, можно прикрутить вот такой плагин, или другой плагин. [Инструкция]

На самом деле, я бы так и использовал этот вариант, если бы случайно не наткнулся на эту статью.
Ещё со школы я был знаком с CLion, но удивился тому, что только сейчас узнал об этом функционале.

Уже через несколько минут получил студенческую лицензию, подтвердив через доменную почту ВУЗа.

STM32 и CLion

[UPD 05.2022]
JB приостановили продажи в РФ, можно попробовать оплатить с иностранной карты.
Будем ждать, что всё наладится 🤞


Установка CLion

Загрузить IDE удобнее всего через Toolbox. Он лишает нас всей возни с распаковкой и генерацией ярлычков. Ставим, логинимся, загружаем среду.

toolbox-gui
clion-splashscreen
Splash Screen

Установка CubeMX

Сам по себе CLion не способен генерировать HAL-овский код. Для этого нужен CubeMX.

При попытке установки может возникнуть такая проблема:

cubemx-problem

Возможно, накосячили с поставляемым в комплекте с установщиком JRE. Возможно, дело в версии JDK системы (на Fedora 36 его обновили с 11 до 17).

В любом случае, это всё решаемо. Для начала надо установить пакет JDK из репозиториев:

sudo dnf install java-11-openjdk

Далее перейти в директорию установки: usr/lib/jvm/java-11-openjdk-xxx/
И подменить папку с JRE установщика на свою (не забудьте переименовать):

cubemx-java-rename

Далее запускаем установщик:

# chmod u+x SetupSTM32CubeMX-6.5.0 # - если установщик не запускается
./SetupSTM32CubeMX-6.5.0

После установки надо прописать ярлычок в системное меню:

cd /usr/share/applications
sudo nano st-cubemx.desktop

Пропишем такие строки:

[Desktop Entry]
Name=CubeMX
Comment=CubeMX
GenericName=CubeMX
Exec=/home/enik/STM32CubeMX/STM32CubeMX %F
Icon=/home/enik/STM32CubeMX/help/STM32CubeMX.ico
Path=/home/enik/STM32CubeMX/
Terminal=false
StartupNotify=true
Type=Application
Categories=Development

Ctrl+X – выход с сохранением.

Настройка CLion

Установка пакетов

Для начала надо установить все компиляторы и пакеты GNU-Toolchain. Выполним команду:

sudo dnf install make gcc g++ arm-none-eabi-*

Звёздочка указывает, что установятся все пакеты, содержащие arm-none-eabi

Проверим, что всё установилось и работает корректно:

arm-gcc-version

Инструментарий для Windows

Для винды всё менее тривиально. Для сборки десктопных приложений там используется MinGW.

Установим и его тоже, выберем такие пакеты:

mingw-packages

GNU Toolchain нужно скачать и установить с сайта. Обратите внимание, нужен именно arm-none-eabi.

Настройка тулчейна

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

clion-toolchain-1

Для Windows есть ремарка:

В отличие от UNIX-систем, нужно выбрать ARM-овский дебаггер, иначе отладка не заведётся.

arm-gdb-choose
Подключаем GDB из установленного тулчейна

Подключение доп. инструмента

Для embedded-разработки CLion предполагает наличие двух инструментов: CubeMX и отладчик OpenOCD.
Их нужно подключить самостоятельно в настройках, в специальной вкладке.

В Linux устанавливается одной командой:

Для винды есть установщик. Загружаем, ставим, подключаем.

STM32 и CLion

Создание проекта

Создание с нуля

В меню создания проекта выберем CubeMX. Среда создаст директорию с готовым .ioc-файликом под процессор F0 и предложит его отредактировать.

Важный нюанс: при смене процессора в кубе всегда создаётся новый файл. Старый нужно удалить, а одноимённый новый записать в ту же директорию.

После конфигурации сохраняемся и генерируем код. Обязательно под CubeIDE и в корне (root) директории.

STM32 и CLion

Перенос существующего проекта из CubeIDE

Перенести старый проект довольно просто. В меню открытия проекта нужно открыть директорию или .ioc-файл.

STM32 и CLion
STM32 и CLion

Настройка OpenOCD

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

STM32 и CLion

Позже его можно выбрать в конфигурации отладки.

STM32 и CLion

Теперь можно загружать прошивку и производить отладку.


Настройки CMake

CMake — это инструмент автоматизации сборки. Его задача — подготовить файлы проекта, задать настройки, передать всё это компилятору.

Для конфигурации процесса используется CMakeLists.txt.
В embedded проектах он формируется из .ioc файла по шаблону: CMakeLists_template.txt.
При каждом изменении .ioc-файла, все правки затираются. Поэтому туда стоит вносить только временные, а потом переносить в шаблон.

В целом, эта конфигурация делает то же, что и настройки проекта в CubeIDE. Вот только здесь их проще редактировать.

Например, FPU. Если в МК есть этот блок (Cortex-M4 и выше), то можно включить аппаратную поддержку чисел с плавающей запятой. За это отвечают следующих 3 строчки:

#Uncomment for hardware floating point
add_compile_definitions(ARM_MATH_CM4;ARM_MATH_MATRIX_CHECK;ARM_MATH_ROUNDING)
add_compile_options(-mfloat-abi=hard -mfpu=fpv4-sp-d16)
add_link_options(-mfloat-abi=hard -mfpu=fpv4-sp-d16)

Пользовательские директории вносятся в include.
Я обычно добавляю руками и все остальные директории. Так проще контролировать.
Надо не забыть прописать и директории, где лежат source-файлы (.c/.cpp/…).

STM32 и CLion

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


Дело в том, что мне совсем не нравится OpenOCD.
Нужно иметь конфигурации под каждый МК. Под G4, например, я так сразу и не нашёл.
Точки останова иногда не ставятся, локальные переменные иногда не отображаются.

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

STM32 и CLion
Переменные в окошке отладки не видны
STM32 и CLion
Ужасный CLI

Самый лёгкий способ отказаться от OpenOCD — перейти на родной, проприетарный ST-шный GDB-отладчик. За более, чем 1.5 года с ним не было никаких проблем. Получить дебаггер и загрузчик можно в составе CubeIDE.

Для начала узнаем путь к утилите сервера:

Linux: 
/opt/st/stm32cubeide_xxx/plugins/com.st.stm32cube.ide.mcu.externaltools.stlink-gdb-server.linux64_xxx/tools/bin/ST-LINK_gdbserver

Windows: 
C:\ST\STM32CubeIDE_xxx\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.stlink-gdb-server.win32_xxx\tools\bin\ST-LINK_gdbserver.exe

Ещё нужно узнать путь к загрузчику CubeProgrammer.

Linux: 
/opt/st/stm32cubeide_xxx/plugins/com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.linux64_xxx/tools

Windows: 
C:\ST\STM32CubeIDE_xxx\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.win32_xxx\tools\bin\

Внесём эти директории в глобальные системные переменные. Откроем файл инициализации переменных:

cd ~
nano .bashrc

В конец впишем:

export PATH=$PATH:/opt/st/stm32cubeide_xxx/plugins/com.st.stm32cube.ide.mcu.externaltools.stlink-gdb-server.linux64_xxx/tools/bin
export CUBE_DL="/opt/st/stm32cubeide_xxx/plugins/com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.linux64_xxx/tools/bin"

Ctrl+X — выход.
Что мы сделали? Добавили сервер в PATH и создали переменную для загрузчика: CUBE_DL.

STM32 и CLion

* PATH – Системная переменная, в которой хранятся каталоги исполняемых файлов.
При вызове исполняемого файла из любой директории, он будет найден в PATH и запущен.

Чтобы всё обновилось, достаточно сделать Log Out Log In. Или обновить среду bash одной из команд:

source ~/.bashrc # вариант 1
. ~/.bashrc # вариант 2

После обновления сразу можно попробовать открыть терминал и прописать:

ST-LINK_gdbserver -cp $CUBE_DL

Должно выдать что-то вроде:

STM32 и CLion

Если ругается на отсутствие библиотеки:

ST-LINK_gdbserver: error while loading shared libraries: libSTLinkUSBDriver.so: cannot open shared object file: No such file or directory

Зайдём в директорию с библиотекой …/{ST gdb_server}/tools/bin/native/linux_x64/, скопируем оттуда .so-файлик:

sudo cp libSTLinkUSBDriver.so /usr/lib
sudo cp libSTLinkUSBDriver.so /usr/lib64

Сервер настраивается через аргументы [Оригинальный мануал]:

• -h / --help – Вызов справки
• --halt – Останавливать все ядра во время reset

• -c <config file> / --config-file <config file> – Вызов аргументов из файла конфигурации (Appendix B in 2576)

• -f <log file> / --log-file <log file> – Запись логов. Стандартный файл - debug_log.txt.
• -l <log level> / --log-level <log level> – Уровень логирования - число [0, 31]. Стандартное значение: 31
– = 0: Выключить логирование.
– ≥ 1: Логирование ошибок.
– ≥ 2: Логирование warning-ов.
– ≥ 4: Логирование команд протокола.
– ≥ 8: Логирование всех информационных сообщений.
– ≥ 16: Логирование всех аппаратных команд.
Если параметры для -f и для -l не обозначены, будут применены стандартные.

• -p <port number> / --port-number <port number> – Установка TCP-порта сервера. Стандартный - 61234.
• -v / --verbose – Подробный режим (вывод debug логов)
• -r <refresh delay> / --refresh-delay <refresh delay> – Интервал опроса hardware status в файл логов. [c]. Стандартный интервал - 5 секунд.
• -s / --verify – Верификация после загрузки.
• -e / --persistant – Запуск сервера в persistent (постоянном) режиме. По умолчанию выключен. 
• -d / --swd – Включение SWD-режима, вместо JTAG. 

Актуально только для SWO (SWV): 
• -z <port number> / --swo-port <port number> – Выбор порта для опроса SWO.
• -a <cpu clock> / --cpu-clock <cpu clock> – Частота МК в Гц. 
• -b <SWO CLOCKDIV> / --swo-clock-div <SWO CLOCKDIV> – Установка делителя для SWO.

Пример настройки SWO (fCPU = 72МГц, fSWO = 125КГц): -z 61235 –a 72000000 –b 576.

• -k / --initialize-reset – Инициализация во время reset.
• -q / --debuggers – Вывести список подключенных ST-Link.
• -i <ST-LINK S/N> / --serial-number <ST-LINK S/N> – Подключение к конкретному ST-Link по серийному номеру.
• --frequency <max freq kHz> – Максимальная частота коммуникации [КГц]: {5, 25, 100, 240, 950, 1800, 4000, 8000, 24000}.
• -m <apID> / --apid <apID> – Выбор appID для отладки. [Для многоядерных систем]
• -g / --attach – Подключиться к запущенному МК (без загрузки кода и reset).
• -t / --shared – Позволяет нескольким отладчикам присоединиться к одному серверу. [Для сервера]
• --erase-all – Очистка всей памяти.
• --memory-map <device id> – Вывод memory map по идентификатору устройства, например 0x410.

Работа с внешней памятью:
• --ext-memory-loaders – Вывод доступных загрузчиков внешней памяти.
• -el <file_path> / --extload <file_path> – Выбор загрузчика внешней памяти. 
• --external-init – Инициализация внешней памяти после reset. 


• -cp <path> / --stm32cubeprogrammer-path <path> – Директория установки STM32CubeProgrammer (STM32CubeProg).
• --pend-halt-timeout <Pending halt timeout> – Таймаут остановки ядра. Стандартное время - 2 секунды.
• --temp-path <path> – Обозначить к папке для создания временных файлов.
• --preserve-temps – Не удалять временные файлы.
• --licenses – Вывод списка используемых инструментов и лицензий. 
• -- / --ignore-rest – Игнорировать все аргументы после этого флага.
• --version – Вывод версии и выход из утилиты. 

Типичные достаточные флаги запуска:

-p 61234 -l 1 -d -s -cp $CUBE_DL -m 0 -k

- Порт: 61234
- Уровень логгирования: только ошибки
- Отладка по SWD
- Проверка после загрузки
- Путь к загрузчику
- Отладка 0-го ядра (потока)
- Инициализация во время reset

А теперь лайфхак, который сразу должен прийти на ум более-менее опытному линуксоиду.
Вместо того, что бы вспоминать и прописывать каждый раз флаги запуска, пропишем скрипт.
В блокноте создадим файл ST_GDB.sh, сохраним куда-нибудь в home. Содержание:

#!/bin/sh
ST-LINK_gdbserver -p 61234 -l 1 -d -s -cp $CUBE_DL -m 0 -k

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

chmod u+x ST_GDB.sh

Попробуем:

STM32 и CLion

Для Windows операции примерно те же, только используем .bat-скрипт, в нём можно обойтись ярлычками.

STM32 и CLion

Теперь нужно создать конфигурацию отладки “Embedded GDB Server”.

В ней указываем адрес сервера: localhost:61234, т.е. с указанным в параметрах портом.
А также указываем скрипт на запуск. Всё!

STM32 и CLion
STM32 и CLion

Запуск отладки

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

STM32 и CLion

В окошке “Debugger” видны локальные переменные:

STM32 и CLion

Для HEX-отображения переменных, нужно включить эту опцию.

Глобальные переменные добавляются через watch или evaluate:

STM32 и CLion

Так же, как и в CubeIDE, можно посмотреть аппаратные регистры микроконтроллера. Для этого надо загрузить .svd файл — XML-таблицу этих регистров. Удобно то, что можно выбрать только отдельные регистры для наблюдения.

STM32 и CLion
STM32 и CLion

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

STM32 и CLion
b и clear

Serial порт

Я не приверженец SWO, во всех своих проектах обычно использую старый-добрый UART.
Скорее из тех соображений, что для него не нужно специальное ПО, а чтение шины может быть независимым и выполняться на другой машине. Отдельный мостик не нужен, всё есть в ST-Link v.2.1 как VCP.

В CLion для чтения COM-порта можно использовать встроенное окошко терминала. На винде я этим не пользовался, поэтому инструмент подсказать не смогу, а на линуксе я предпочитаю minicom.

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

STM32 и CLion

Перспективы

Что хочется увидеть в будущем? Пожалуй, основные багфиксы и улучшения уже внесли, но есть парочка:

  1. Фундаментальная вещь — дизассемблирование кода, как в профильных IDE. Тикет висит почти 10 лет.
  2. Более гибкая конфигурация embedded GDB сервера, это нужно для других отладчиков. Тикет

Выводы

Неважно, какой инструмент используется в программировании. Ключевая цель — удобство разработчика.

Что касается ценовой политики — цена очень демократичная. За первый год 90 долларов — порядка 500 руб в месяц. Дорого это или нет, решать каждому.

Безусловно, не все готовы тратить свои личные средства на эту IDE.
Во-первых, бесплатная лицензия доступна не только для студентов, но и для open-source проектов.
Во-вторых, многие компании готовы покупать софт своим сотрудникам.
В-третьих, если инструмент приносит доход, то инвестировать его часть в собственный комфорт — отличная практика.

Я уже полностью пересел на CLion, с ним работать стало гораздо приятнее. Однажды попробовав, уже не захотелось возвращаться на Eclipse, даже на домашнем ПК с Windows.

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

Лёгкого кодинга и удачи в мире Embedded!

Ссылки

https://www.jetbrains.com/help/clion/clion-quick-start-guide.html
https://stm32club.ru/environment/setup-clion-for-stm32.html
https://habr.com/ru/post/345670/ — Разработчик плагина
https://habr.com/ru/post/572044/ — Гайд без CubeMX



Подписаться
Уведомить о
guest
2 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Сергей
Сергей
9 месяцев назад

Добрый день! Настроил CLion в Windows по статье. Подскажите пожалуйста, как добавить файлы в проект (хидеры и сёрсы). Добавляю файлы в соответствующие директории (даже создаю новые из CLion) – проект собирается, но ругается на отсутствие этих файлов.

AR19DD~1.EXE: error: Core/Src/bme280.c: No such file or directory
mingw32-make[2]: *** [CMakeFiles\Main_MCU.elf.dir\build.make:527: Main_MCU.elf] Error 1
mingw32-make[1]: *** [CMakeFiles\Makefile2:82: CMakeFiles/Main_MCU.elf.dir/all] Error 2
mingw32-make: *** [Makefile:90: all] Error 2

В CMakeLists.txt дописываю:

add_executable(${PROJECT_NAME}.elf ${SOURCES} ${SOURCE_FILES} ${LINKER_SCRIPT} Core/Src/bme280.c Core/Inc/bme280.h)

перезагружаю проект – те же ошибки. Спасибо!

admin
admin
Администратор
Ответить на  Сергей
5 месяцев назад

Если оно в Inc/Src валяется, то дополнительно прописывать ничего не нужно.

Выше ведь прописано:

include_directories(Core/Inc ...)   # - тут директории с .h файлами
...
file(GLOB_RECURSE SOURCES "Core/*.*" ...)  # - тут директории с .с файлами

Вот он из этих папок всё и подхватывает сам