Embedded HandbookПриложения
Все разделы › XIII. Другие языки и их сборщики
STM32F103, STM32F407 · уровень средний · 6 мин чтения
Открыть в интерактивном справочнике

115. Менеджеры сборки для прошивки: PlatformIO, west (Zephyr), CMake-пресеты

Alire у Ada и Cargo у Rust делают одно и то же: ставят компилятор, тянут зависимости нужных версий и собирают проект одной командой. У C для микроконтроллеров такого единого инструмента нет, и роль берут на себя PlatformIO, west у Zephyr или CMake с файлом тулчейна и пресетами. Раздел собирает одну и ту же прошивку — CRC-32 и мигание из разделов 113 и 114 — через PlatformIO и через CMake-пресеты, для BluePill и STM32F4 Discovery, в образе stm-pio:1, и показывает, где у каждого закреплены версии.

Ada и Alire — раздел 113, Rust и Cargo — раздел 114, CI/CD — раздел 110.

Как это называется в документации

Оригинал Перевод
environment ([env:…]) окружение PlatformIO: плата, платформа, флаги
platform, framework набор для семейства камней, библиотека поверх регистров
package, tool пакет PlatformIO: тулчейн, фреймворк, инструмент
manifest, west.yml список репозиториев и их версий у Zephyr
workspace рабочее дерево west со всеми проектами
toolchain file файл тулчейна CMake: чем собирать для чужой машины
presets (CMakePresets.json) готовые наборы настроек CMake
generator (Ninja) чем CMake исполняет сборку
cross-compilation сборка на одной машине для другой
pinning закрепление версии

115.1 PlatformIO: одна прошивка — две платы

Три способа собрать одну прошивку: что каждый ставит сам и где закреплены версии

Проект PlatformIO — файл platformio.ini и каталог src. Каждое окружение — своя плата; платформа, фреймворк и флаги общие:

[env]
platform = ststm32@20.0.0             ; версия закреплена: иначе завтра приедет другая
framework = cmsis
build_flags = -Wall -Wextra -Os

[env:bluepill]
board = bluepill_f103c8

[env:disco407]
board = disco_f407vg

pio run сам поставил платформу ststm32 20.0.0, тулчейн toolchain-gccarmnoneeabi 1.70201.0 — это GCC 7.2.1, — CMSIS для F1 4.3.5 и для F4 2.6.11 со стартовыми файлами. Отчёт pio run называет для BluePill 388 байт флеш-памяти и 28 байт ОЗУ, для Discovery — 396 и 28. Но во флеш-память он засчитывает только .text, .rodata и .data, а таблицу векторов (.isr_vector, 268 и 392 байта) и восемь байт .init_array и .fini_array не считает: целиком образ — 664 и 796 байт. Камень код узнаёт по макросу, который задаёт плата:

#if defined(STM32F103xB)

115.2 Версии: что закреплять

Незакреплённая платформа PlatformIO завтра приедет новой — с другим компилятором и другим размером образа. Поэтому версию пишут прямо в platform = ststm32@20.0.0. Тулчейн по умолчанию у этой платформы — GCC 7.2.1, давно не новый: другой компилятор задают отдельным пакетом в platform_packages. У Alire то же делает строка gnat_arm_elf = "=16.1.0", у Cargo версии крейтов закрепляет Cargo.lock, а сам компилятор — файл rust-toolchain.toml с версией и целями: rustup ставит их сам при первой сборке.


115.3 west и Zephyr

Zephyr — ОС для микроконтроллеров, и её проекты собирает west. Файл west.yml перечисляет репозитории — само ядро, модули HAL, библиотеки — и ревизию каждого; west update приводит рабочее дерево к ним, а west build -b <плата> собирает CMake-проект с описанием платы из дерева устройств. Рабочее дерево Zephyr занимает гигабайты, поэтому здесь его не собирают; устроено оно так же, как всё в этом разделе: версии — в манифесте, сборка — одной командой.


115.4 CMake: файл тулчейна и пресеты

Без менеджера та же прошивка собирается CMake. Файл тулчейна говорит, что собираем не для этой машины и чем:

set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)   # пробная сборка без компоновки: у голого камня нет libc-заглушек
file(GLOB _pio_gcc "$ENV{HOME}/.platformio/packages/toolchain-gccarmnoneeabi*/bin")
find_program(CMAKE_C_COMPILER arm-none-eabi-gcc HINTS ${_pio_gcc} REQUIRED)
set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})

Главная строка — CMAKE_C_COMPILER: без неё CMake возьмёт компилятор этой машины — тот, что собирает программы для компьютера. Здесь arm-none-eabi-gcc ищут сначала в пакете PlatformIO, потом в PATH. Ключи ядра — -mcpu=cortex-m3 -mthumb для F103 и -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 для F407 — задаёт CMakeLists.txt по переменной MCU, а её передают пресеты.

Пресеты сводят длинные командные строки к имени:

    { "name": "f103", "inherits": "base", "cacheVariables": { "MCU": "f103" } },
    { "name": "f407", "inherits": "base", "cacheVariables": { "MCU": "f407" } }

cmake --preset f103 и cmake --build --preset f103 собрали прошивку тем же GCC 7.2.1 из пакета PlatformIO, со своим стартовым кодом из раздела 113: 232 байта для F103 и 252 для F407. Это весь образ, с таблицей векторов, и сравнивать его надо с образом PlatformIO — 664 и 796 байт. Разница — таблица векторов камня в стартовом файле CMSIS (268 и 392 байта против наших четырёх слов) и его более длинный стартовый код: один __libc_init_array — 72 байта. В опыте CMake 4.4.3, PlatformIO 6.2.0.

Размер одной прошивки у PlatformIO и у CMake на двух камнях


115.5 Что выбрать

Ставит тулчейн Версии закреплены в Одна команда
PlatformIO да platformio.ini pio run
west (Zephyr) нет, SDK отдельно west.yml west build
CMake-пресеты нет образ или SDK cmake --build --preset
Alire (Ada) да alire.toml alr build
Cargo (Rust) через rustup по rust-toolchain.toml Cargo.lock и rust-toolchain.toml cargo build

Для CI (раздел 110) удобнее всего то, что собирается в контейнере одной командой и с закреплёнными версиями, — любой из пяти, если версии действительно закреплены.


115.6 Грабли

Вчера собиралось, сегодня нет. Платформа PlatformIO не закреплена и обновилась. Писать ststm32@20.0.0.

Компилятор оказался старым. Тулчейн по умолчанию у ststm32 20.0.0 — GCC 7.2.1.

CMake падает на проверке компилятора. Пробная сборка пытается скомпоновать программу для голого камня; CMAKE_TRY_COMPILE_TARGET_TYPE = STATIC_LIBRARY.

Скрипт компоновки не находит common.ld. INCLUDE ищет в путях -L.

Сборка на ноутбуке и в CI даёт разные образы. Тулчейн не из образа и не закреплён.


115.7 Итоги

Дальше: раздел 115а «CMake-проект прошивки: от .ioc до VS Code» — проект CubeMX для CMake.

Открыть в интерактивном справочнике