STM32. Подготавливаем среду разработки в Linux

в 8:01, , рубрики: compile, debug, eclipse, flash, gdb, IDE, linux, openocd, st-link, st-utility, stm32, timeweb_статьи, Ubuntu, vscode
В недавнем времени получилось так, что у меня появилась пара интересных проектов, где одна из составных частей — микроконтроллер STM32. И каждый раз при смене ноутбука или ОС на домашнем компе приходится настраивать окружение для разработки как в первый раз. Плюсом, последние проекты, которые я делал для STM32 — выполнял в Windows, в демо-версии Keil uVision. Но поскольку я давно переехал в Linux — возникла необходимость основательно разобраться и изложить процесс настройки окружения для будущих применений.

Всем, кому интересно — добро пожаловать под кат.

STM32. Подготавливаем среду разработки в Linux - 1

Дисклеймер. Во избежание срача, который может возникнуть на фоне различных воззрений на лучший вариант реализации среды разработки в 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

В итоге вы увидите:

STM32. Подготавливаем среду разработки в Linux - 2

Что ж. Этот этап выполнен. Идём далее.

Установка 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 

Теперь настроим генерацию проекта:

STM32. Подготавливаем среду разработки в Linux - 3

Выбираем нужный контроллер:

STM32. Подготавливаем среду разработки в Linux - 4

Настроим проект. Сначала настроим тактирование в секции RCC:

STM32. Подготавливаем среду разработки в Linux - 5

Устанавливаем галочку для настройки порта отладочной шины, так как по умолчанию выводы переводятся на вход:

STM32. Подготавливаем среду разработки в Linux - 6

Настроим GPIO-пины к которым подключены светодиоды:

STM32. Подготавливаем среду разработки в Linux - 7

Отметим их на схеме настройки выводов:

STM32. Подготавливаем среду разработки в Linux - 8

И настраиваем тактирование:

STM32. Подготавливаем среду разработки в Linux - 9

После завершаем настройку кодогенераратора и установим IDE в значение Makefile:

STM32. Подготавливаем среду разработки в Linux - 10

После этого придется ввести логин и пароль от учетной записи 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:

STM32. Подготавливаем среду разработки в Linux - 11

В архиве есть файл 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:

STM32. Подготавливаем среду разработки в Linux - 12

Теперь перейдем к самому проекту. После запуска 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 — мы получим бинарный файл, который можно прошить:

STM32. Подготавливаем среду разработки в Linux - 13

Можно прошить отладку в этом же терминале:

st-flash --connect-under-reset write ./Blink.hex 0x08000000
st-flash reset

Произойдет прошивка и светодиоды заморгают:

STM32. Подготавливаем среду разработки в Linux - 14

После того, как мы проверили, что цель билдится, надо автоматизировать этот процесс. Для этого необходимо настроить проект.

Необходимо нажать сочетание клавиш 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:

STM32. Подготавливаем среду разработки в Linux - 15

Попробуем выполнить эти команды. У меня они сработали как нужно и светодиоды радостно заморгали. Значит, все сделано верно.

Но это еще не всё. Необходимо, чтобы отладка запускалась из 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. Прочитав его описание на сайте проекта, нашел его достаточно мощным инструментом для отладки.

STM32. Подготавливаем среду разработки в Linux - 16

Теперь попробуем сконфигурировать этот плагин в VS Code и проверим, какие возможности он предоставляет в решении реальных задач.

Для этого нужно перейти в меню Run And Debug в боковом меню и создать файл launch.json, выбрав пункт Cortex-Debug:

STM32. Подготавливаем среду разработки в Linux - 17

Туда запишем следующее содержимое. Обратите внимание, что должен быть обязательно указан путь до скачанного ранее 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, в котором можно просмотреть все необходимые значения переменных, значения регистров процессора и прочее.

STM32. Подготавливаем среду разработки в Linux - 18

Watch, секция в которой можно выставить наблюдение за конкретно взятой переменной:

STM32. Подготавливаем среду разработки в Linux - 19

Breakpoints — все выставленные прерывания в коде программы (разумеется, с ограничением по количеству), Call Stack с очередью вызова, XPeripherials со значениями регистров периферии:

STM32. Подготавливаем среду разработки в Linux - 20

Дополнительно можно воспользоваться меню Memory и поставив на паузу дебагер или остановив его на точке останова, увидеть значения в указанном адресе:

STM32. Подготавливаем среду разработки в Linux - 21

Отлично. С 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. Но это оффтоп. Об этом можете потом спросить в комментариях.

После того, как я решил проблему с драйвером — таки запустился инсталлятор:

STM32. Подготавливаем среду разработки в Linux - 22

Выбираем Eclipse IDE for Embedded C/C++ Developers. И нажимаем кнопку установки Install. После установки выбираем Launch.

Выбираем удобное расположение каталога для Workspace Eclipse. Я оставил предложенное значение по умолчанию:

STM32. Подготавливаем среду разработки в Linux - 23

Откроется главное окно IDE. Теперь настроим проект. Закрываем Welcome-страницу и переходим в меню Window — Preferences, где мы настроим тулчейн.

Обычно первым шагом настраивается переменная окружения PATH, которая будет нужна при работе с Makefile-проектом. Это настройка производится в меню C/C++ — Build — Environment и тут добавляется путь до тулчейна. А раз мы это сделали выше, то отдельно добавлять тут ничего не нужно.

Создадим проект. Для этого перейдем в меню File — New — C/C++ Projects и выбираем C Managed Build:

STM32. Подготавливаем среду разработки в Linux - 24

Далее укажем имя проекта, в моем случае это будет STM32F0-Blink. Из предложенного списка выбираем пункт STM32F0xx C/C++ Project:

STM32. Подготавливаем среду разработки в Linux - 25

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

STM32. Подготавливаем среду разработки в Linux - 26

Нажимаем Next, ничего не меняем и идем в следующее меню:

STM32. Подготавливаем среду разработки в Linux - 27

В следующем меню оставляем все как выставлено по умолчанию:

STM32. Подготавливаем среду разработки в Linux - 28

Далее будет предложен выбор тулчейна и пути к нему — оставляем предложенный вариант по умолчанию:

STM32. Подготавливаем среду разработки в Linux - 29

Нажимаем Finish. И будет создан шаблон проекта и запущен установщик различных плагинов и дополнений необходимых в работе. Дожидаемся окончания работы в данном окне:

STM32. Подготавливаем среду разработки в Linux - 30

После этого появится окно IDE и кажется все готово к работе с проектом, но когда я попробовал скомпилировать проект — вышло некоторое количество ошибок:

STM32. Подготавливаем среду разработки в Linux - 31

Не знаю почему так. Но надо найти в древе проекта файл cxx.cpp и добавить в него подключение библиотеки stdlib.h:

#include <stdlib.h>

Выглядит это следующим образом:

STM32. Подготавливаем среду разработки в Linux - 32

После можно запустить сборку проекта и она должна окончиться успешно. Полученный бинарный файл необходимо прошить в плату. При старте проекта мы создали две конфигурации для сборки: Debug и Release (отмотайте выше). Между этими конфигурациями можно переключаться кликнув правой кнопкой в Project Explorer на заголовке проекта:

STM32. Подготавливаем среду разработки в Linux - 33

Теперь разберемся с каждой из них. Сборка 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 и указываем следующие значения:

STM32. Подготавливаем среду разработки в Linux - 34

Далее перейдем к настройке Debug Configuration через меню Project Explorer — Debug As — Debug Configuration:

STM32. Подготавливаем среду разработки в Linux - 35

В открывшемся окне двойным кликом нажимаем на пункт GDB OpenOCD Debugging и откроется шаблон конфигурации:

STM32. Подготавливаем среду разработки в Linux - 36

Необходимо перейти на вкладку Debugger и настроить параметры запуска OpenOCD с которыми мы проверяли его работоспособность при установке. В поле Config options пишем:

-f /usr/local/share/openocd/scripts/interface/stlink.cfg -f /usr/local/share/openocd/scripts/board/stm32f0discovery.cfg

После этого можно нажать кнопку Debug и будет запущена отладка проекта. Необходимо чтобы плата была подключена к компьютеру. Будет выдано предупреждение о переходе в отладочный режим. Нажимае галочку помнить наше решение и не выдавать данное предупреждение:

STM32. Подготавливаем среду разработки в Linux - 37

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

STM32. Подготавливаем среду разработки в Linux - 38

Осмотримся, какие средства отладки представлены в Eclipse IDE. В первую очередь обратим внимание на Disassembly окно, которое включается кнопкой Instruction Stepping Mode:

STM32. Подготавливаем среду разработки в Linux - 39

После поищем, где находятся регистры ядра Cortex:

STM32. Подготавливаем среду разработки в Linux - 40

Долго ковыряясь в интерфейсе я не мог найти регистры периферии. В предназначенном для этого окне было пусто. Разберемся, как это настроить. Перейдем в настройки проекта, кликнув правой кнопкой по заголовку проекта в Project Manager — Preferences — C/C++ Build — Settings. Выберем конфигурацию Debug и перейдем в закладку Devices и увидим, что у нас не установлен ни один CMSIS-пак. Что ж, в любом случае, нам нужен полноценный дебаг.

После этого переходим в меню Window — Perspective — Open Perspective — Other… — CMSIS Packs. Необходимо нажать кнопку Refresh, загрузятся все необходимые описания. Это займет какое-то время, часть паков будет не доступна к загрузке.

После загрузки нужно будет выбрать необходимое семейство контроллеров, у меня это будет STM32F0. Необходимо его установить, нажав правой кнопкой и выбрать пункт Install.

Получится следующее:

STM32. Подготавливаем среду разработки в Linux - 41

Далее переключаемся в обычный режим и открываем настройки проекта по уже известному нам пути:

STM32. Подготавливаем среду разработки в Linux - 42

Открываем меню C/C++ Build — Settings — Devices и выбираем целевой микроконтроллер:

STM32. Подготавливаем среду разработки в Linux - 43

Все. Теперь вернемся к месту где мы остановились. После запуска отладки — в окне Peripherials появится вся необходимая периферия:

STM32. Подготавливаем среду разработки в Linux - 44

Если пробежаться по интерфейсу окна — судя по всему все опции отладки присутствуют. Супер. Теперь необходимо сконфигурировать Release-конфигурацию и на этом закончим рассмотрение вопроса в и так раздувшейся статье 🙂.

Откроем настройки проекта, переходим в меню C/C++ Build — Settings — GNU Arm Cross Create Flash Image — General и выбираем Configuration: Release:

STM32. Подготавливаем среду разработки в Linux - 45

После этого необходимо настроить прошивальщик для загрузки получаемого бинаря в микроконтроллер.

Переходим в меню 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.

Получится следующее:

STM32. Подготавливаем среду разработки в Linux - 46

Нажимаем Run и прошивка будет загружена на МК и светодиоды замигают:

STM32. Подготавливаем среду разработки в Linux - 47

Теперь, чтобы прошить прошивку из Release — необходимо нажать эту кнопку из меню:

STM32. Подготавливаем среду разработки в Linux - 48

Кажется, на этом всё.

Заключение

После того, как рассмотрели самые популярные IDE и необходимые средства разработки для STM32 — выбор за вами. Согласен, что настройка и подготовка заготовки проекта весьма объемная, но все же она не лишена гибкости в выборе параметров и опций. Наверняка я многие интересные и полезные опции и плагины пропустил — но если мне будет о чем вам рассказать, то обязательно это сделаю.

До встречи в следующих статьях! 🙂


Автор: Андрей

Источник

  1. Slavian:

    Здорово. Помаленьку изучал гайд. Получилось освоить VS Code для stm.

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js