Сборка Hello World под Flipper Zero в 2023

Сборка Hello World под Flipper Zero в 2023

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

Август 2023

Установка тулинга

Что ж, портируем наш Hello World на новую систему сборки. ufbt ставится как Python пакет, для чистоты я рекомендую завести отдельный virtualenv или conda environment для работы с ним. Для тех, кто подзабыл, как это делается (воспользуйтесь только одним из двух вариантов, а не обоими сразу):

$ python -m pip install virtualenv
$ virtualenv flipper
$ source ./flipper/bin/activate
Заводим virtualenv с именем flipper
$ conda create -n flipper python=3.10
$ conda activate flipper
Заводим conda environment

Дальнейшая установка проста и одинакова для обоих случаев:

$ 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.
Первая команда скачает uFBT, вторая скачает текущую версию SDK

При этом 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
Скачали toolchain

На 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, и все будет работать как надо:

Настроенный проект в VS Code

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