С момента публикации предыдущего поста, описывающего мои первые изыскания с Flipper Zero прошло полгода. Как ни странно, он продолжает быть актуальным и популярным в сообществе, однако за это время тулинг для разработки под Flipper шагнул вперед, и каждый раз, когда люди пишут, что им помогла моя статья, модераторы топика Development SW & HW в чате пишут, что стоит перестать лезть в исходники прошивки, а начать пользоваться ufbt
(micro Flipper Build Tool). Раз уж люди до сих пор сюда забредают, напишу краткую справку, как это сделать.

Установка тулинга
Что ж, портируем наш Hello World на новую систему сборки. ufbt
ставится как Python пакет, для чистоты я рекомендую завести отдельный virtualenv или conda environment для работы с ним. Для тех, кто подзабыл, как это делается (воспользуйтесь только одним из двух вариантов, а не обоими сразу):
$ python -m pip install virtualenv
$ virtualenv flipper
$ source ./flipper/bin/activate
$ conda create -n flipper python=3.10
$ conda activate flipper
Дальнейшая установка проста и одинакова для обоих случаев:
$ python -m pip install --upgrade ufbt
$ ufbt update
14:37:02.986 [I] Deploying SDK for f7
14:37:02.987 [I] Fetching version info for UpdateChannel.RELEASE from https://update.flipperzero.one/firmware/directory.json
14:37:03.630 [I] Using version: 0.88.0
14:37:03.630 [I] uFBT SDK dir: /Users/pavel/.ufbt/current
14:37:05.275 [I] Deploying SDK
14:37:05.475 [I] SDK deployed.
При этом toolchain, включающий в себя компилятор и стандартные библиотеки, этой командой не скачается. Простой способ его скачать — это просто запустить ufbt
. Оно в конце кинет ошибку, но все необходимое скачает. Можно не проходить этот шаг, тогда toolchain будет скачан при первой попытке сборки проекта.
$ ufbt
Checking for tar..yes
Checking if downloaded toolchain tgz exists..no
Checking curl..yes
Downloading toolchain:
######################################################################### 100.0%
done
Removing old toolchain..done
Unpacking toolchain to '/Users/pavel/.ufbt/toolchain':
##################################################################### 100.0%
done
Cleaning up..done
scons: Entering directory `/Users/pavel/.ufbt/current/scripts/ufbt'
fbt: warning: Folder app: manifest application.fam is missing
LoadAppManifest, line 33, in file "/Users/pavel/.ufbt/current/scripts/fbt_tools/fbt_apps.py"
scons: *** No targets specified and no Default() targets found. Stop.
Found nothing to build
На M1 Mac по-прежнему качается x64_86 версия toolchain. Это за полгода не поменялось.
$ ls ~/.ufbt/toolchain
x86_64-darwin
Теперь система полностью настроена, и мы готовы к разработке.
Создание нового проекта
Создать новый шаблонный проект в директории можно простой командой ufbt create
. Важно, что проект создается в текущей директории, так что не забудьте сначала созадть новую директорию под проект и перейти в нее.
$ mkdir hello_world
$ cd hello_world
$ ufbt create
scons: Entering directory `/Users/pavel/.ufbt/current/scripts/ufbt'
fbt: warning: Folder app: manifest application.fam is missing
LoadAppManifest, line 33, in file "/Users/pavel/.ufbt/current/scripts/fbt_tools/fbt_apps.py"
Creating '/Users/pavel/DEV/mcu/flipperzero/tutorial/hello_ufbt/template.c'
INSTALL /Users/pavel/DEV/mcu/flipperzero/tutorial/hello_ufbt/template.png
Creating '/Users/pavel/DEV/mcu/flipperzero/tutorial/hello_ufbt/application.fam'
Mkdir("/Users/pavel/DEV/mcu/flipperzero/tutorial/hello_ufbt/images")
Touch("/Users/pavel/DEV/mcu/flipperzero/tutorial/hello_ufbt/images/.gitkeep")
Copy("/Users/pavel/DEV/mcu/flipperzero/tutorial/hello_ufbt/.github", "project_template/app_template/.github")
Команда с ходу выдает ошибку, что не видит application.fam
, что довольно странно, потому что она сама же его и создает. Ну, да ладно, это мелочь, можно как и раньше создать три минимально необходимых файла вручную (application.fam
, hello_world.c
, hello_world.png
), как было описано в прошлом посте — мне такой вариант нравится даже больше. Но, главное, даже при автоматической генерации файлов проекта все затем успешно собирается:
$ ufbt build
scons: Entering directory `/Users/pavel/.ufbt/current/scripts/ufbt'
ICONS /Users/pavel/.ufbt/build/template/template_icons.c
INSTALL /Users/pavel/DEV/mcu/flipperzero/tutorial/hello_ufbt/template.png
CC /Users/pavel/.ufbt/build/template/template_icons.c
APPCHK /Users/pavel/.ufbt/build/template.fap
Target: 7, API: 34.3
Момент, который вызвал у меня вопросы: сборка происходит не в директории проекта, а в директории ufbt
(по умолчанию это $HOME/.ufbt/build
). Не совсем понятно, почему выбрано такое решение. При этом команда build не создает никаких бинарников в директории проекта. Однако если запускать не ufbt build
, а просто ufbt
, то в конце производится дополнительное копирование бинарника в директорию ./dist
:
$ ufbt
scons: Entering directory `/Users/pavel/.ufbt/current/scripts/ufbt'
CC /Users/pavel/.ufbt/build/template/template_icons.c
INSTALL /Users/pavel/DEV/mcu/flipperzero/tutorial/hello_ufbt/template.png
CDB /Users/pavel/DEV/mcu/flipperzero/tutorial/hello_ufbt/.vscode/compile_commands.json
INSTALL /Users/pavel/DEV/mcu/flipperzero/tutorial/hello_ufbt/dist/debug/template_d.elf
INSTALL /Users/pavel/DEV/mcu/flipperzero/tutorial/hello_ufbt/dist/template.fap
APPCHK /Users/pavel/.ufbt/build/template.fap
Target: 7, API: 34.3
$ ls
application.fam dist images template.c template.png
Как и раньше, полученный FAP можно вручную скопировать файл, либо же залить его на подключенный по USB-кабелю Flipper Zero с помощью команды ufbt flash_usb
.
Работа с VS Code
Как и раньше, можно сгенерировать проект для VS Code, который будет содержать все настроенные задачи для сборки, дебага и прочего. Делается это командой ufbt vscode_dist
:
$ ufbt vscode_dist
scons: Entering directory `/Users/pavel/.ufbt/current/scripts/ufbt'
Creating '/Users/pavel/DEV/mcu/flipperzero/tutorial/hello_ufbt/.vscode/c_cpp_properties.json'
Creating '/Users/pavel/DEV/mcu/flipperzero/tutorial/hello_ufbt/.vscode/extensions.json'
Creating '/Users/pavel/DEV/mcu/flipperzero/tutorial/hello_ufbt/.vscode/launch.json'
Creating '/Users/pavel/DEV/mcu/flipperzero/tutorial/hello_ufbt/.vscode/settings.json'
Creating '/Users/pavel/DEV/mcu/flipperzero/tutorial/hello_ufbt/.vscode/tasks.json'
INSTALL /Users/pavel/DEV/mcu/flipperzero/tutorial/hello_ufbt/.clang-format
INSTALL /Users/pavel/DEV/mcu/flipperzero/tutorial/hello_ufbt/.editorconfig
INSTALL /Users/pavel/DEV/mcu/flipperzero/tutorial/hello_ufbt/.gitignore
Затем можно просто открыть директорию проекта в VS Code, и все будет работать как надо:

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