Всем, кому интересно — добро пожаловать под кат.
Дисклеймер. Во избежание срача, который может возникнуть на фоне различных воззрений на лучший вариант реализации среды разработки в Linux — я поспешу уточнить, что данная статья является отражением моих вкусов, воззрений и предпочтений, без претензий на объективность и истину в последней инстанции.
❯ Что необходимо настроить?
Итак. Нам необходимо получить рабочую, юзабельную среду для разработки под STM32. В первую очередь определим скоп задач, которые нужно решить:
- Необходимые зависимости для начала работы;
- Набор инструментов: компилятор, линковщик, ассемблер, отладчик и т.п.
- Собрать все необходимое для работы с ST-Link;
- Установка и проверка GDB;
- Установить STM32CubeMX для удобного конфигурирования проекта;
- Выбрать и установить IDE и подключить к ним компилятор и отладчик;
- Сделать простой шаблон проекта для будущего использования;
- Проверить компиляцию и механизм отладки проекта.
Список достаточно большой. Я решил, что как и в статьях про Zynq — проверю все на свежеустановленной megalloid-pc 22.04.3 LTS, чтобы не забыть ровным счётом ничего, и чтобы получить исчерпывающий мануал по настройке. Поехали.
❯ Необходимые зависимости для начала работы
В первую очередь нужно установить весь минимально необходимый набор зависимостей и программ для начала работы. Итого, сделайте следующее:
sudo wget -qO /etc/apt/trusted.gpg.d/kitware-key.asc https://apt.kitware.com/keys/kitware-archive-latest.asc
echo "deb https://apt.kitware.com/ubuntu/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/kitware.list
sudo add-apt-repository -y ppa:git-core/ppa
sudo apt update
sudo apt upgrade
sudo apt install -y build-essential make libtool pkg-config cmake curl automake autoconf gcc git texinfo python3-dev libpython3-dev liblzma5 libncurses5 libncurses5-dev libusb-1.0-0-dev libgtk-3-dev libstlink-dev libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev xz-utils tk-dev
❯ Набор инструментов: компилятор, линковщик, ассемблер, отладчик и т.п.
Итак. Для начала разберемся с набором инструментов. Давайте я коротко расскажу о том, что это такое. Набор инструментов нужен для того, чтобы компилировать исходных код в исполняемый файл, который можно будет исполнить на микроконтроллере.
Набор инструментов включает в себя:
- Компилятор;
- Компоновщик;
- Библиотеки времени выполнения.
Все эти инструменты задействуются во время компиляции исходных кодов программы, которую вы пишете в вашей IDE. Чаще всего используется набор инструментов из проекта GNU и на момент написания статьи это остается справедливым. Стандартный набор инструментов GNU включает в себя все необходимое:
- GNU Binutils, который включает в себя линкер ld, ассемблер as и прочее (подробнее);
- Набор компиляторов GNU GCC, которые используя кодогенератор порождающий ассемблерный код передают его на вход ассемблера GNU (подробнее);
- Набор библиотек.
Но не будем углубляться в дебри средств для работы с проектами, перейдем к процессу инсталляции.
Получаем значение последней версии тулчейна:
ARM_TOOLCHAIN_VERSION=$(curl -s https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads | grep -Po '<h4>Version K.+(?=</h4>)')
Далее скачиваем сам тулчейн:
curl -Lo gcc-arm-none-eabi.tar.xz "https://developer.arm.com/-/media/Files/downloads/gnu/${ARM_TOOLCHAIN_VERSION}/binrel/arm-gnu-toolchain-${ARM_TOOLCHAIN_VERSION}-x86_64-arm-none-eabi.tar.xz"
Создаем директорию, где будет находиться тулчейн:
sudo mkdir /opt/gcc-arm-none-eabi
Извлекаем архив в эту директорию:
sudo tar xf gcc-arm-none-eabi.tar.xz --strip-components=1 -C /opt/gcc-arm-none-eabi
Добавляем эту директорию в PATH-переменную:
echo 'export PATH=$PATH:/opt/gcc-arm-none-eabi/bin' | sudo tee -a /home/megalloid/.bashrc
Для того, чтобы применить данные изменения нужно:
source /home/megalloid/.bashrc
Проверим версии компиляторов:
megalloid@megalloid-pc:~$ arm-none-eabi-gcc --version
arm-none-eabi-gcc (Arm GNU Toolchain 13.2.rel1 (Build arm-13.7)) 13.2.1 20231009
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
megalloid@megalloid-pc:~$ arm-none-eabi-g++ --version
arm-none-eabi-g++ (Arm GNU Toolchain 13.2.rel1 (Build arm-13.7)) 13.2.1 20231009
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Проверим тулчейн в действии:
touch main.c; vim main.c
Вставим в файл следующее содержимое:
#include <stdio.h>
int main() {
return 0;
}
Сохраним и проведем компиляцию:
arm-none-eabi-gcc main.c -o test
Результат будет не очень. Будет куча ошибок и не получится никакого результата:
arm-none-eabi-gcc main.c -o test
/opt/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/13.2.1/../../../../arm-none-eabi/bin/ld: /opt/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/13.2.1/../../../../arm-none-eabi/lib/libc.a(libc_a-exit.o): in function `exit':
exit.c:(.text.exit+0x28): undefined reference to `_exit'
/opt/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/13.2.1/../../../../arm-none-eabi/bin/ld: /opt/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/13.2.1/../../../../arm-none-eabi/lib/libc.a(libc_a-writer.o): in function `_write_r':
writer.c:(.text._write_r+0x24): undefined reference to `_write'
/opt/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/13.2.1/../../../../arm-none-eabi/bin/ld: /opt/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/13.2.1/../../../../arm-none-eabi/lib/libc.a(libc_a-closer.o): in function `_close_r':
closer.c:(.text._close_r+0x18): undefined reference to `_close'
/opt/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/13.2.1/../../../../arm-none-eabi/bin/ld: /opt/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/13.2.1/../../../../arm-none-eabi/lib/libc.a(libc_a-lseekr.o): in function `_lseek_r':
lseekr.c:(.text._lseek_r+0x24): undefined reference to `_lseek'
/opt/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/13.2.1/../../../../arm-none-eabi/bin/ld: /opt/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/13.2.1/../../../../arm-none-eabi/lib/libc.a(libc_a-readr.o): in function `_read_r':
readr.c:(.text._read_r+0x24): undefined reference to `_read'
/opt/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/13.2.1/../../../../arm-none-eabi/bin/ld: /opt/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/13.2.1/../../../../arm-none-eabi/lib/libc.a(libc_a-sbrkr.o): in function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0x18): undefined reference to `_sbrk'
collect2: error: ld returned 1 exit status
Но если немного видоизменить команду указав дополнительные флаги — все будет готово:
arm-none-eabi-gcc --specs=rdimon.specs main.c -o test
Проверим файл:
megalloid@megalloid-pc:~/sources$ file test
test: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped
Отлично. Компилятор работает. Идём дальше.
❯ Утилиты для работы с ST-Link
Теперь необходимо разобраться с тем, каким образом установить и настроить утилиты для работы с ST-Link:
cd ~/sources
git clone https://github.com/stlink-org/stlink.git
cd stlink
make clean
make release
sudo make install
Далее необходимо установить права доступа к реальному оборудованию через установку правил udev:
sudo cp -a config/udev/rules.d/* /lib/udev/rules.d/
sudo udevadm control --reload-rules && sudo udevadm trigger
Так же на сайте проекта доступны несколько полезных ссылок:
- Туториал на использование stlink и FAQ по решению разных проблем: ссылка;
- Мануал по компиляции из сырцов: ссылка;
- Список поддерживаемых устройств: ссылка.
Чтобы проверить работоспособность ST-Link, я подключил плату STM32F0-Discovery к компьютеру и выполнил следующее:
megalloid@megalloid-pc:~$ lsusb | grep STM
Bus 001 Device 011: ID 0483:3748 STMicroelectronics ST-LINK/V2
megalloid@megalloid-pc:~$ st-info --probe
Found 1 stlink programmers
version: V2J37
serial: XXXXXXXXXXXXXXXXXXXXXXXX
flash: 65536 (pagesize: 1024)
sram: 8192
chipid: 0x440
dev-type: STM32F05x
Или можно проверить также через GUI тулзу:
megalloid@megalloid-pc:~$ stlink-gui
В итоге вы увидите:
Что ж. Этот этап выполнен. Идём далее.
❯ Установка ST CubeMX
Теперь для получения простейшей заготовки проекта, которую будем использовать, понадобится CubeMX версия для Linux. Последняя версия на момент написания статьи — 6.10.0.
Со времени начала всем понятных событий ST ограничили доступ к скачиванию CubeMX с официального сайта и теперь придётся искать альтернативные пути. Я нашел эту версию тут. Скачиваем версию для Linux:
wget http://www.stm32res.ru/sites/default/files/mi_files/Prog_stm32/en.stm32cubemx-lin-v6-10-0.zip
mkdir cubemx;
unzip en.stm32cubemx-lin-v6-10-0.zip -d cubemx/
cd cubemx;
./SetupSTM32CubeMX-6.10.0
Устанавливаем через графический интерфейс и запустим генерацию первого проекта:
megalloid@megalloid-pc:~$ ~/STM32CubeMX$ ./STM32CubeMX
Теперь настроим генерацию проекта:
Выбираем нужный контроллер:
Настроим проект. Сначала настроим тактирование в секции RCC:
Устанавливаем галочку для настройки порта отладочной шины, так как по умолчанию выводы переводятся на вход:
Настроим GPIO-пины к которым подключены светодиоды:
Отметим их на схеме настройки выводов:
И настраиваем тактирование:
После завершаем настройку кодогенераратора и установим IDE в значение Makefile:
После этого придется ввести логин и пароль от учетной записи st.com — но авторизация должна пройти без проблем. После окончания генерации получим следующий набор файлов:
megalloid@megalloid-pc:~/STM32/F051/Blink$ ll
total 56
drwxrwxr-x 4 megalloid megalloid 4096 янв 8 22:33 ./
drwxrwxr-x 3 megalloid megalloid 4096 янв 8 22:33 ../
-rw-rw-r-- 1 megalloid megalloid 3380 янв 8 22:33 Blink.ioc
drwxrwxr-x 4 megalloid megalloid 4096 янв 8 22:33 Core/
drwxrwxr-x 4 megalloid megalloid 4096 янв 8 22:33 Drivers/
-rw-rw-r-- 1 megalloid megalloid 5492 янв 8 22:33 Makefile
-rw-rw-r-- 1 megalloid megalloid 7613 янв 8 22:33 .mxproject
-rw-rw-r-- 1 megalloid megalloid 9569 янв 8 22:33 startup_stm32f051x8.s
-rw-rw-r-- 1 megalloid megalloid 5900 янв 8 22:33 STM32F051R8Tx_FLASH.ld
Для отладки нам понадобится SVD-файл выбранного контроллера. Для STM32F051R8T6 я взял этот файл тут. Необходим файл STM32F0 System View Description:
В архиве есть файл STM32F0x1.svd, который мы кладем в директорию проекта. Теперь можно перейти к работе с проектом в IDE.
❯ Установка и выбор IDE для
Мы подошли к самому спорному вопросу, который нужно решить: какую IDE использовать. Есть несколько вариантов на выбор:
- Visual Studio Code;
- Eclipse IDE;
- QT Creator.
И самый простой вариант, который я не буду рассматривать в статье: ST CubeIDE.
Тут кому что удобнее и по сути это дело вкуса. Рассмотрим настройку первых двух вариантов.
❯ Настройка Visual Studio Code для работы с STM32
Первым делом скачаем и установим VSCode:
sudo apt-get install wget gpg apt-transport-https
wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > packages.microsoft.gpg
sudo install -D -o root -g root -m 644 packages.microsoft.gpg /etc/apt/keyrings/packages.microsoft.gpg
sudo sh -c 'echo "deb [arch=amd64,arm64,armhf signed-by=/etc/apt/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/code stable main" > /etc/apt/sources.list.d/vscode.list'
rm -f packages.microsoft.gpg
sudo apt update
sudo apt install code
Открываем VSCode в каталоге со свежесгенерированным проектом из CubeMX:
megalloid@megalloid-pc:~/STM32/F051/Blink$ code .
В работе нам может пригодиться несколько полезных плагинов:
- C/C++ Extension Pack – для подсветки синтаксиса и поддержки возможностей дебага;
- Code Spell Checker – для подсветки ошибок и опечаток в коде и комментариях;
- Makefile Tool — для удобной подсветки синтаксиса и работы с Make-файлами;
- Cortex-Debug — ARM Cortex-M GDB Debugger для VSCode, может отображать Peripherals, Core registers, Function Disassembly, Memory View и многое другое (правда, может быть использован только если на хостовой ОС установлен arm-none-eabi-gdb);
- Memory View — обеспечивает возможность отображения памяти при работе в дебаггере;
- Head-File-Guard — инструмент для работы с конструкциями #ifndef… #define… #endif;
- Linker Script — инструмент для подсветки и проверки синтаксиса скриптов линковщика;
- Command Variable — плагин для удобной работы с переменными которые можно будет использовать в настройках проекта
- Tasks — плагин, который вытаскивает кнопки задач на нижнюю панель окна разработки (чуть дальше вы увидите о чем речь);
- TODO Highlight — подсветка для комментариев которые содержат конструкции наподобие TODO или FIXME, который может впоследствии генерировать списком все указанные в комментариях указания на доработки.
Установим эти плагины в разделе Extensions:
Теперь перейдем к самому проекту. После запуска VSCode в папке проекта, программа проведет анализ Makefile, который был сгенерирован CubeMX и настроит IntelliSense.
Перейдем к проекту и проверим, все ли работает как нужно. Докинем в main.c код моргания светодиодом:
while (1)
{
/* USER CODE END WHILE */
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_8|GPIO_PIN_9);
HAL_Delay(1000);
/* USER CODE BEGIN 3 */
}
Теперь, если запустить в Terminal команду make — мы получим бинарный файл, который можно прошить:
Можно прошить отладку в этом же терминале:
st-flash --connect-under-reset write ./Blink.hex 0x08000000
st-flash reset
Произойдет прошивка и светодиоды заморгают:
После того, как мы проверили, что цель билдится, надо автоматизировать этот процесс. Для этого необходимо настроить проект.
Необходимо нажать сочетание клавиш Ctrl+Shift+P и находим пункт Preferences: Open Workspace Settings (JSON). В структуре проекта появится каталог .vscode и откроется файл settings.json. В него вставим следующее содержимое:
{
"cortex-debug.gdbPath": "arm-none-eabi-gdb"
}
Ещё раз нажимаем сочетание клавиш Ctrl+Shift+P и находим пункт Tasks: Configure Task — Create tasks.json file from template — Others. Откроется файл tasks.json на редактирование и вставим в него следующее содержимое:
{
"version": "2.0.0",
"tasks": [
{
"label": "Build",
"type": "shell",
"group": {
"kind": "build",
"isDefault": true
},
"command": "make",
"problemMatcher": [],
"detail": "Build project"
},
{
"label": "Clean",
"type": "shell",
"group": "build",
"command": "make clean",
"problemMatcher": [],
"detail": "Clean project"
},
{
"type": "shell",
"label": "Flash",
"command": "st-flash",
"args": [
"--reset",
"write",
"${input:workspaceFolderForwardSlash}/build/${workspaceFolderBasename}.bin",
"0x8000000"
],
"options": {
"cwd": "${workspaceFolder}/build"
},
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Builds project and flashes firmware"
},
{
"type": "shell",
"label": "Erase",
"command": "st-flash",
"args": [
"--connect-under-reset",
"erase"
],
"detail": "Mass erase of chip"
}
],
"inputs": [
{
"id": "workspaceFolderForwardSlash",
"type": "command",
"command": "extension.commandvariable.transform",
"args": {
"text": "${workspaceFolder}",
"find": "\\",
"replace": "/",
"flags": "g"
}
}
]
}
Сохраняем. Теперь данные задачи можно запустить из меню внизу рабочего окна IDE:
Попробуем выполнить эти команды. У меня они сработали как нужно и светодиоды радостно заморгали. Значит, все сделано верно.
Но это еще не всё. Необходимо, чтобы отладка запускалась из IDE. Для этого необходимо установить и сконфигурировать отладчик + плагин для IDE. Рассмотрение этого вопроса я вынес в отдельную главу.
❯ Установка отладчика ST-LINK GDB
В составе пакета ST-Link, который мы устанавливали ранее — также имеется GDB-отладчик st-util и трассировщик st-trace. Но при попытке использовать без настройки — он не включится:
megalloid@megalloid-pc:~$ arm-none-eabi-gdb
Could not find platform independent libraries <prefix>
Could not find platform dependent libraries <exec_prefix>
Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]
Python path configuration:
PYTHONHOME = (not set)
PYTHONPATH = (not set)
program name = '/usr/local/bld-tools/bld-tools-virtual-env/bin/python'
isolated = 0
environment = 1
user site = 1
import site = 1
sys._base_executable = '/usr/local/bld-tools/bld-tools-virtual-env/bin/python'
sys.base_prefix = '/usr'
sys.base_exec_prefix = '/usr'
sys.executable = '/usr/local/bld-tools/bld-tools-virtual-env/bin/python'
sys.prefix = '/usr'
sys.exec_prefix = '/usr'
sys.path = [
'/usr/lib/python38.zip',
'/usr/lib/python3.8',
'/usr/lib/lib-dynload',
]
Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
Python runtime state: core initialized
ModuleNotFoundError: No module named 'encodings'
Current thread 0x00007f2d42114c00 (most recent call first):
<no Python frame>
Для этого необходимо в первую очередь установить pyenv и настроить окружение Python версии 3.8, который нужен для работы с GDB:
curl https://pyenv.run | bash
Для того, чтобы использовать pyenv, добавляем необходимые команды в .bashrc:
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
source ~/.bashrc
После установим Python версии 3.8 и сделаем настройку:
pyenv install 3.8.18
sudo mkdir -p /usr/local/bld-tools
sudo ln -s $PYENV_ROOT/versions/3.8.18 /usr/local/bld-tools/bld-tools-virtual-env
Теперь проверим, что отладчик запускается:
megalloid@megalloid-pc:~$ arm-none-eabi-gdb
GNU gdb (Arm GNU Toolchain 13.2.rel1 (Build arm-13.7)) 13.2.90.20231008-git
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=x86_64-pc-linux-gnu --target=arm-none-eabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://bugs.linaro.org/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb)
Можно сразу проверить работоспособность отладчика. В одном окне запускаем GDB-сервер:
megalloid@megalloid-pc:~$ st-util
st-util 1.7.0-352-g8c581c3
2024-01-08T20:54:20 INFO common.c: STM32F05x: 8 KiB SRAM, 64 KiB flash in at least 1 KiB pages.
2024-01-08T20:54:20 INFO gdb-server.c: Listening at *:4242...
В другом окне, где запущен GDB-клиент, пишем:
(gdb) target extended localhost:4242
Remote debugging using localhost:4242
warning: No executable has been specified and target does not support
determining executable automatically. Try using the "file" command.
0x080006ce in ?? ()
Если имеется какой-нибудь демо-файл прошивки для платы, то можно сделать следующее:
(gdb) exec-file /home/megalloid/STM32/Blink/Objects/fw.axf
A program is being debugged already.
(gdb) load
Loading section RW_IRAM1, size 0x8 lma 0x20000000
Loading section ER_IROM1, size 0xfc0 lma 0x8000000
Start address 0x080000bc, load size 4040
Transfer rate: 7 KB/sec, 2020 bytes/write.
В окне GDB-сервера будут сообщения:
megalloid@megalloid-pc:~$ st-util
st-util 1.7.0-352-g8c581c3
2024-01-08T20:54:20 INFO common.c: STM32F05x: 8 KiB SRAM, 64 KiB flash in at least 1 KiB pages.
2024-01-08T20:54:20 INFO gdb-server.c: Listening at *:4242...
2024-01-08T21:10:11 INFO common.c: STM32F05x: 8 KiB SRAM, 64 KiB flash in at least 1 KiB pages.
2024-01-08T21:10:11 INFO gdb-server.c: Found 4 hw breakpoint registers
2024-01-08T21:10:11 INFO gdb-server.c: GDB connected.
2024-01-08T21:17:51 INFO common.c: STM32F05x: 8 KiB SRAM, 64 KiB flash in at least 1 KiB pages.
2024-01-08T21:17:51 INFO gdb-server.c: flash_erase: block 08000000 -> 1000
2024-01-08T21:17:51 INFO gdb-server.c: flash_erase: page 08000000
2024-01-08T21:17:51 INFO gdb-server.c: flash_erase: page 08000400
2024-01-08T21:17:51 INFO gdb-server.c: flash_erase: page 08000800
2024-01-08T21:17:51 INFO gdb-server.c: flash_erase: page 08000c00
2024-01-08T21:17:51 INFO flash_loader.c: Starting Flash write for VL/F0/F3/F1_XL
2024-01-08T21:17:51 INFO flash_loader.c: Successfully loaded flash loader in sram
2024-01-08T21:17:51 INFO flash_loader.c: Clear DFSR
2024-01-08T21:17:51 INFO gdb-server.c: flash_do: block 08000000 -> 1000
2024-01-08T21:17:51 INFO gdb-server.c: flash_do: page 08000000
2024-01-08T21:17:51 INFO gdb-server.c: flash_do: page 08000400
2024-01-08T21:17:51 INFO gdb-server.c: flash_do: page 08000800
2024-01-08T21:17:51 INFO gdb-server.c: flash_do: page 08000c00
Так. Отладчик работает. Все хорошо. Идём дальше.
❯ Установка плагина отладки для VS Code
Теперь, когда отладчик работает, можно настроить его использование в IDE. Немного изучив вопрос, я нашел интересным для себя плагин для отладки (и он, как оказалось, единственный) Cortex-Debug. Прочитав его описание на сайте проекта, нашел его достаточно мощным инструментом для отладки.
Теперь попробуем сконфигурировать этот плагин в VS Code и проверим, какие возможности он предоставляет в решении реальных задач.
Для этого нужно перейти в меню Run And Debug в боковом меню и создать файл launch.json, выбрав пункт Cortex-Debug:
Туда запишем следующее содержимое. Обратите внимание, что должен быть обязательно указан путь до скачанного ранее SVD-файла:
{
"version": "0.2.0",
"configurations": [
{
"name": "Cortex Debug",
"cwd": "${workspaceFolder}",
"executable": "${workspaceRoot}/build/${workspaceFolderBasename}.elf",
"request": "launch",
"type": "cortex-debug",
"runToEntryPoint": "main",
"servertype": "stutil",
"preLaunchTask" : "Build",
"preRestartCommands" : [ "load", "enable breakpoint", "monitor reset" ],
"showDevDebugOutput" : "raw",
"svdFile" : "${workspaceRoot}/STM32F0x1.svd"
}
]
}
Вот! Теперь можно запустить отладку и мы увидим сразу все доступные нам функции отладчика. Пробежимся по возможностям.
Variables, в котором можно просмотреть все необходимые значения переменных, значения регистров процессора и прочее.
Watch, секция в которой можно выставить наблюдение за конкретно взятой переменной:
Breakpoints — все выставленные прерывания в коде программы (разумеется, с ограничением по количеству), Call Stack с очередью вызова, XPeripherials со значениями регистров периферии:
Дополнительно можно воспользоваться меню Memory и поставив на паузу дебагер или остановив его на точке останова, увидеть значения в указанном адресе:
Отлично. С VSCode разобрались. И кажется, тут все получилось очень даже удобно для работы с МК. Теперь можно перейти к рассмотрению процесса установки и настройки Eclipse IDE, чтобы сравнить насколько он юзабельнее.
❯ Настройка Eclipse IDE для работы с STM32
Перейдем к установке и настройке Eclipse IDE. Для этого необходимо перейти по ссылке и скачать версию IDE for C/C++ developers тут.
После распакуем архив и запускаем инсталлятор:
tar xfzv eclipse-inst-jre-linux64.tar.gz
cd eclipse-installer
./eclipse-inst
Тут я столкнулся с проблемой. Инсталлятор запустился и завершился с ошибкой:
megalloid@megalloid-pc:~/sources/eclipse-installer$ ./eclipse-inst
SLF4J: No SLF4J providers were found.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See https://www.slf4j.org/codes.html#noProviders for further details.
EGLDisplay Initialization failed: EGL_BAD_ACCESS
EGLDisplay Initialization failed: EGL_NOT_INITIALIZED
Cannot create EGL context: invalid display (last error: EGL_SUCCESS)
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007fc9f21b63ef, pid=266685, tid=266686
#
# JRE version: OpenJDK Runtime Environment Temurin-17.0.9+9 (17.0.9+9) (build 17.0.9+9)
# Java VM: OpenJDK 64-Bit Server VM Temurin-17.0.9+9 (17.0.9+9, mixed mode, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# C [libwebkit2gtk-4.0.so.37+0x29b63ef]
#
# Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport -p%p -s%s -c%c -d%d -P%P -u%u -g%g -- %E" (or dumping to /home/megalloid/sources/eclipse-installer/core.266685)
#
# An error report file with more information is saved as:
# /tmp/hs_err_pid266685.log
#
# If you would like to submit a bug report, please visit:
# https://github.com/adoptium/adoptium-support/issues
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
Вероятно, это связано с устаревшим драйвером видеокарты, который я использовал. Обновил его достаточно просто:
wget https://ru.download.nvidia.com/XFree86/Linux-x86_64/535.146.02/NVIDIA-Linux-x86_64-535.146.02.run
chmod +x NVIDIA-Linux-x86_64-535.146.02.run
После скачивания необходимо завершить сессию оконного менеджера X Window и произвести установку из окна терминала. Переключившись туда через сочетание клавиш Ctrl+Alt+F1. Но это оффтоп. Об этом можете потом спросить в комментариях.
После того, как я решил проблему с драйвером — таки запустился инсталлятор:
Выбираем Eclipse IDE for Embedded C/C++ Developers. И нажимаем кнопку установки Install. После установки выбираем Launch.
Выбираем удобное расположение каталога для Workspace Eclipse. Я оставил предложенное значение по умолчанию:
Откроется главное окно IDE. Теперь настроим проект. Закрываем Welcome-страницу и переходим в меню Window — Preferences, где мы настроим тулчейн.
Обычно первым шагом настраивается переменная окружения PATH, которая будет нужна при работе с Makefile-проектом. Это настройка производится в меню C/C++ — Build — Environment и тут добавляется путь до тулчейна. А раз мы это сделали выше, то отдельно добавлять тут ничего не нужно.
Создадим проект. Для этого перейдем в меню File — New — C/C++ Projects и выбираем C Managed Build:
Далее укажем имя проекта, в моем случае это будет STM32F0-Blink. Из предложенного списка выбираем пункт STM32F0xx C/C++ Project:
После нажимаем Next и выбираем семейство микроконтроллеров, которое используется на плате STM32F051x8:
Нажимаем Next, ничего не меняем и идем в следующее меню:
В следующем меню оставляем все как выставлено по умолчанию:
Далее будет предложен выбор тулчейна и пути к нему — оставляем предложенный вариант по умолчанию:
Нажимаем Finish. И будет создан шаблон проекта и запущен установщик различных плагинов и дополнений необходимых в работе. Дожидаемся окончания работы в данном окне:
После этого появится окно IDE и кажется все готово к работе с проектом, но когда я попробовал скомпилировать проект — вышло некоторое количество ошибок:
Не знаю почему так. Но надо найти в древе проекта файл cxx.cpp и добавить в него подключение библиотеки stdlib.h:
#include <stdlib.h>
Выглядит это следующим образом:
После можно запустить сборку проекта и она должна окончиться успешно. Полученный бинарный файл необходимо прошить в плату. При старте проекта мы создали две конфигурации для сборки: Debug и Release (отмотайте выше). Между этими конфигурациями можно переключаться кликнув правой кнопкой в Project Explorer на заголовке проекта:
Теперь разберемся с каждой из них. Сборка Debug подразумевает компиляцию проекта с отладочной информацией и отладочными функциями, с последующим запуском отладчика. А сборка Release компилируется без отладочного содержимого и сразу загружается в микроконтроллер. Но чтобы все эти операции реализовать, необходимо сконфигурировать проект и внешний отладчик. Поскольку Eclipse плотно интегрирован с отладчиком OpenOCD — необходимо его настроить. Процесс настройки OpenOCD я вынес в отдельную главу.
❯ Установка отладчика OpenOCD
Один из наиболее популярных средств отладки и работы с микроконтроллерами — это OpenOCD. Рассмотрим процесс установки и интеграции в среду разработки Eclipse данного отладчика.
Первым делом необходимо скачать последнюю версию с официального репозитория:
git clone https://github.com/openocd-org/openocd
cd openocd/
./bootstrap
./configure
make -j$(nproc)
sudo make install
Проверим, что отладчик работает:
megalloid@megalloid-pc:~/sources/openocd$ openocd --version
Open On-Chip Debugger 0.12.0+dev-01472-gadcc8ef87 (2024-01-11-22:57)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Отлично. Отладчик работает. Теперь можно его проверить в действии. Для этого необходимо ему указать путь до конфигурации ST-Link и файл конфигурации микроконтроллера. Т. к. я использую плату STM32F0-Discovery, команда должна выглядеть следующим образом:
openocd -f /usr/local/share/openocd/scripts/interface/stlink.cfg -f /usr/local/share/openocd/scripts/board/stm32f0discovery.cfg
Никакого специфического содержимого там нет и уверен, что вы сможете сделать аналогичный конфиг и для своей кастомной платы.
После запуска отладчика вы должны увидеть нечто похожее:
Open On-Chip Debugger 0.12.0+dev-01472-gadcc8ef87 (2024-01-11-22:57)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Warn : Interface already configured, ignoring
Error: already specified hl_layout stlink
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 1000 kHz
Info : STLINK V2J37S0 (API v2) VID:PID 0483:3748
Info : Target voltage: 2.869226
Info : [stm32f0x.cpu] Cortex-M0 r0p0 processor detected
Info : [stm32f0x.cpu] target has 4 breakpoints, 2 watchpoints
Info : [stm32f0x.cpu] Examination succeed
Info : starting gdb server for stm32f0x.cpu on 3333
Info : Listening on port 3333 for gdb connections
Хорошо. Видим, что GDB-сервер ожидает соединения по адресу localhost:3333. Идём дальше. Теперь вернемся в Eclipse IDE и подключим OpenOCD в качестве внешнего отладчика. Для это идем в меню Window — Preferences — MCU — Global OpenOCD Path и указываем следующие значения:
Далее перейдем к настройке Debug Configuration через меню Project Explorer — Debug As — Debug Configuration:
В открывшемся окне двойным кликом нажимаем на пункт GDB OpenOCD Debugging и откроется шаблон конфигурации:
Необходимо перейти на вкладку Debugger и настроить параметры запуска OpenOCD с которыми мы проверяли его работоспособность при установке. В поле Config options пишем:
-f /usr/local/share/openocd/scripts/interface/stlink.cfg -f /usr/local/share/openocd/scripts/board/stm32f0discovery.cfg
После этого можно нажать кнопку Debug и будет запущена отладка проекта. Необходимо чтобы плата была подключена к компьютеру. Будет выдано предупреждение о переходе в отладочный режим. Нажимае галочку помнить наше решение и не выдавать данное предупреждение:
Запустим проект и видно, как зеленый светодиод начал мигать и появился отладочный вывод:
Осмотримся, какие средства отладки представлены в Eclipse IDE. В первую очередь обратим внимание на Disassembly окно, которое включается кнопкой Instruction Stepping Mode:
После поищем, где находятся регистры ядра Cortex:
Долго ковыряясь в интерфейсе я не мог найти регистры периферии. В предназначенном для этого окне было пусто. Разберемся, как это настроить. Перейдем в настройки проекта, кликнув правой кнопкой по заголовку проекта в Project Manager — Preferences — C/C++ Build — Settings. Выберем конфигурацию Debug и перейдем в закладку Devices и увидим, что у нас не установлен ни один CMSIS-пак. Что ж, в любом случае, нам нужен полноценный дебаг.
После этого переходим в меню Window — Perspective — Open Perspective — Other… — CMSIS Packs. Необходимо нажать кнопку Refresh, загрузятся все необходимые описания. Это займет какое-то время, часть паков будет не доступна к загрузке.
После загрузки нужно будет выбрать необходимое семейство контроллеров, у меня это будет STM32F0. Необходимо его установить, нажав правой кнопкой и выбрать пункт Install.
Получится следующее:
Далее переключаемся в обычный режим и открываем настройки проекта по уже известному нам пути:
Открываем меню C/C++ Build — Settings — Devices и выбираем целевой микроконтроллер:
Все. Теперь вернемся к месту где мы остановились. После запуска отладки — в окне Peripherials появится вся необходимая периферия:
Если пробежаться по интерфейсу окна — судя по всему все опции отладки присутствуют. Супер. Теперь необходимо сконфигурировать Release-конфигурацию и на этом закончим рассмотрение вопроса в и так раздувшейся статье 🙂.
Откроем настройки проекта, переходим в меню C/C++ Build — Settings — GNU Arm Cross Create Flash Image — General и выбираем Configuration: Release:
После этого необходимо настроить прошивальщик для загрузки получаемого бинаря в микроконтроллер.
Переходим в меню Run — External Tools — External Tools Configuration. Двойным кликом выбираем Program и добавляем конфигурацию.
- Обзовем ее ST-Link Flash;
- В поле Location укажем путь до st-flash: /usr/local/bin/st-flash;
- В поле Arguments укажем write {project_loc}/Release/{project_name}.bin 0x08000000.
Получится следующее:
Нажимаем Run и прошивка будет загружена на МК и светодиоды замигают:
Теперь, чтобы прошить прошивку из Release — необходимо нажать эту кнопку из меню:
Кажется, на этом всё.
❯ Заключение
После того, как рассмотрели самые популярные IDE и необходимые средства разработки для STM32 — выбор за вами. Согласен, что настройка и подготовка заготовки проекта весьма объемная, но все же она не лишена гибкости в выборе параметров и опций. Наверняка я многие интересные и полезные опции и плагины пропустил — но если мне будет о чем вам рассказать, то обязательно это сделаю.
До встречи в следующих статьях! 🙂
Автор: Андрей
Здорово. Помаленьку изучал гайд. Получилось освоить VS Code для stm.