m1ch3al / flipper-zero-dev-tutorial

A set of small code examples to get in touch with the FreeRTOS, Flipper Zero and its ecosystem

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Flipper Zero dev tutorial with examples.

A fun journey to discover Flipper Zero and how a FAP (Flipper-zero APplication) is developed. title

VERY IMPORTANT: Most likely I will write some bullshit: feel free to clone my repository, try, change and why not, improve my code.

As a developer I am used to working with Linux, and this tutorial was written using ubuntu 20.04.5 LTS. I have not tried this on Microsoft Windows.

FlipperZero uses a particular structure to build its application called SCons (more information can be found here: https://scons.org): this ambitious project is a substitute of the classic MAKE, and the configurations files are Python scripts that use the power of a real programming language to solve build problems.

NOTE: for those that are interested learning more about SCons, I advise you to NOT continue. This tutorial helps you create applications for your FlipperZero, but does not provide you with information about compilation and/or internal FreeRTOS.

Simple FAP structure.

A The Flipperzero APplication FAP has a particular filesystem structure like this:

[FAP-name]
    ├── application.fam (type: text file, compulsory)
    ├── icon.png (type: image, optional)
    ├── README.md (type: text file, optional)
    │
    ├── [images] (type: folder, optional)
    │      └── {all the images required by the FAP}
    │
    ├── main.c (type: text file, optional)
    └── {others .c/.h files used by the FAP}

Let's analyze the parts of a FAP:

application.fam

If you want to create a FAP, this file is mandatory. For example, if you are familiar with Java/Kotlin (especially for Android OS) you will probably remember AndroidManifest.xml. The concept is the same. If you do not know what a manifest is, don't worry: this is a simple text (ascii) file with a list of "declarations" required to run the FAP correctly. Within application.fam, you will find all the information regarding the behavior of the FAP. You can specify the resources that the FAP will use (like images), which kind of application it will be (a plugin or external), the entry point of the FAP (the appid), the category, and so on. Most of them will be analyzed individually, allowing you to implement the functionality of all of the statements.

icon.png

When you turn your Flip.x0 on, you see many FAP in the various menus you navigate. Every FAP has a name and an icon, that means you can personalize your apps as you want.

flipper_icons

For convenience, in this tutorial I will use the name icon.png for the small FAP icons we will create together. But feel free to change the name of the file and its declaration inside the application.fam (we will see this later). Remember that the declaration of an icon for a FAP is not necessary. When you compile your application, the icon will be not shown in the list and you will only see the name with a blank space on the left.

README (.md)

I don't want to dwell too much on this part. Everyone knows (if you're a developer) the importance of a README file, Especially if you want to distribute your FAP using the most common channels like GitHub or something like it.

images (folder)

if your FAP needs to display some images, it's a good reason for keep all the resources organized inside a folder. In the same way, feel free to change the name of this folder as you prefer, but remember; change the name in the application.fam.

main.c

Somewhere the main function will be defined, right? During the compilation phase, the SCons system will check the contents of all .c files inside your FAP folder and it will recognize the name of the main function (declared inside the application.fam). So...it's better to keep the code organized. It doesn't matter what the names of the .c files inside you FAP application are. The important thing, for your convenience, is to have a .c file with an easily recognizable name. One that allow you to understand where the main entry of your application is. If you know the C language, you probably well understand what am I referring to:

int main(int argc,  char  *argv[])  {
    // Do something here...
    return 0;  
}

For a Flipper Zero Application, we need the same thing. Keep calm, we will return to it later in detail.

Content of application.fam

This is an example of the contents of the manifest for your Flip.x0 application.
Let's use my_first_app as an example (inside the 01_my_very_first_fap/my_first_app/ folder of this repository)

You will only find two files: - my_first_app.c - application.fam

The content of the application.fam is the following:

    App(
        appid="my_first_app",
        name="My First App",
        apptype=FlipperAppType.EXTERNAL,
        entry_point="my_first_app_main",
        stack_size=1 * 1024,
        fap_category="Examples",
        
        # Added for explanation
        fap_icon="icon.png",
        fap_icon_assets="images",
    )    

Let's analyze now all the declaration of the fam.

appid

This instruction helps your Flip.x0 identify your FAP inside its ecosystem. The appid has to be unique. Otherwise, the compiler (fbt) will throw an error. My suggestion is to choose a name that can be understood easily.

name

This field represents the string that will be displayed on your Flip.x0 when you use the browser, as shown below.

flipper_icons

apptype

This directive specifies which kind of FAP you want to create. Currently, the documentation is very poor and I only found four types of apptype:

  • FlipperAppType.PLUGIN
  • FlipperAppType.EXTERNAL
  • FlipperAppType.SETTINGS
  • FlipperAppType.METAPACKAGE

PLUGIN is used if you want to create a FAP to interact with of Flip.x0. The plugins are compiled into the kernel and will be flashed as part of the firmware on the main SoC. Furthermore, writing plugins requires the developer to edit/maintain /applications/meta/applications.fam

EXTERNAL is used (as in this case) for delopy FAP The compiled FAP are separated programs and you can store the build version (.fap file) inside your Flip.x0 microSD.

SETTINGS I'm not an expert, but I suppose that if you want to develop a FAP using the Settings app-type, you probably want to have integration with the FreeRTOS inside your Flip.x0

METAPACKAGE Unfortunately, I do not understand what this option represents. I will satisfy my curiosity when the the documentation becomes available.

FOUND Something new !! METAPACKAGE : Does not define any code to be run, it is used for declaring dependencies and application bundles.

All appplication type can be found here: https://github.com/flipperdevices/flipperzero-firmware/blob/dev/documentation/AppManifests.md#application-definition

entry_point

Is the main function of your FAP, like C with the main function. Here you have different naming options, but the concept is the same. As an example,I have a portion of code:

int32_t my_first_app_main(void* p) {
    UNUSED(p);
}

As you can see above, this kind of function is equivalent to this one when you write in pure C (forUnix/Linux).

int main(int argc,  char  *argv[])  {
    // Do something here...
    return 0;  
}

stack_size

I don't think there is much need to explain this statement. You can specify the size of the stack inside your FAP :P

fap_icon

Use this declaration if you want to give to your FAP a bit of elegance. In this case, we have an "icon.png" as a FAP icon. The important information you need to know are:

  • the size of the icon: 10 pixel x 10 pixel
  • the colors palette: only white and black are allowed

fap_icon_assets

This directive specifies a folder name and basically tells your Flip.x0 where to load the images to draw into the GUI. If you use this declaration, make sure to have the folder created before compiling the FAB. Otherwise the compilation phase will fail.

How to build a FAP.

Let's use the first application in this tutorial as an example. First, open a terminal and move yourself into your favorite folder for development. Use git to clone the official repository of Flip.x0 firmware. Or use a custom firmware like RogueMaster, as I did. If you want to use the official firmware repository you need launch this command:

git clone https://github.com/flipperdevices/flipperzero-firmware.git

Otherwise (like me) this is the RogueMaster firmware:

git clone https://github.com/RogueMaster/flipperzero-firmware-wPlugins.git

Once the repository is cloned, enter the firmware folder and explore what is inside:

drwxrwxr-x 19 user user    4096 dic 22 13:35 .
drwxrwxr-x 14 user user    4096 dic 23 12:49 ..
drwxrwxr-x  9 user user    4096 dic 18 14:09 applications
drwxrwxr-x  5 user user    4096 dic 21 21:09 applications_user
drwxrwxr-x  8 user user    4096 dic 18 14:09 assets
drwxrwxr-x  2 user user    4096 dic 18 14:09 brew-cask
-rw-rw-r--  1 user user     134 dic 18 14:09 Brewfile
drwxrwxr-x  4 user user    4096 dic 21 21:56 build
-rwxrwxr-x  1 user user     643 dic 20 09:48 buildRelease.sh
-rw-rw-r--  1 user user    3419 dic 20 09:48 CHANGELOG.md
-rw-rw-r--  1 user user    5358 dic 18 14:09 .clang-format
-rw-rw-r--  1 user user    5226 dic 18 14:09 CODE_OF_CONDUCT.md
-rw-rw-r--  1 user user    2874 dic 18 14:09 CODING_STYLE.md
-rwxrwxr-x  1 user user      92 dic 21 21:55 compile.sh
-rw-rw-r--  1 user user    4764 dic 18 14:09 CONTRIBUTING.md
drwxrwxr-x  4 user user    4096 dic 18 14:09 debug
drwxrwxr-x  3 user user    4096 dic 21 21:56 dist
drwxrwxr-x  3 user user    4096 dic 20 09:48 documentation
-rw-rw-r--  1 user user    9486 dic 18 14:09 .drone.yml
-rw-rw-r--  1 user user     173 dic 18 14:09 .editorconfig
-rwxrwxr-x  1 user user     727 dic 18 14:09 fbt
-rw-rw-r--  1 user user     388 dic 18 14:09 fbt.cmd
-rw-rw-r--  1 user user    2271 dic 18 14:09 fbt_options.py
drwxrwxr-x  3 user user    4096 dic 18 14:09 firmware
-rw-rw-r--  1 user user    8047 dic 18 14:09 firmware.scons
drwxrwxr-x  3 user user    4096 dic 18 14:09 furi
-rw-rw-r--  1 user user     605 dic 18 14:09 GAMES_ONLY.md
drwxrwxr-x  9 user user    4096 dic 22 13:35 .git
-rw-rw-r--  1 user user      64 dic 18 14:09 .gitattributes
drwxrwxr-x  3 user user    4096 dic 18 14:09 .github
-rw-rw-r--  1 user user     624 dic 22 13:35 .gitignore
-rw-rw-r--  1 user user    1198 dic 18 14:09 .gitmodules
drwxrwxr-x 34 user user    4096 dic 18 14:09 lib
-rw-rw-r--  1 user user   35149 dic 18 14:09 LICENSE
-rw-rw-r--  1 user user    3393 dic 18 14:09 MACOS_GUIDE.md
-rw-rw-r--  1 user user    1259 dic 18 14:09 Makefile
-rw-rw-r--  1 user user   54919 dic 20 09:48 patreon.png
-rw-rw-r--  1 user user     575 dic 18 14:09 .pvsconfig
-rw-rw-r--  1 user user     279 dic 18 14:09 .pvsoptions
-rw-rw-r--  1 user user   31567 dic 22 13:35 ReadMe.md
-rw-rw-r--  1 user user    3986 dic 18 14:09 RoadMap.md
-rw-rw-r--  1 user user 9881732 dic 22 09:50 .sconsign.dblite
-rw-rw-r--  1 user user    8326 dic 18 14:09 SConstruct
drwxrwxr-x  9 user user    4096 dic 18 14:55 scripts
drwxrwxr-x  3 user user    4096 dic 18 14:09 site_scons
-rw-rw-r--  1 user user    1080 dic 20 09:48 SUPPORT.md
-rw-rw-r--  1 user user   10760 dic 18 14:09 test_iso7816_helpers.c
-rw-rw-r--  1 user user   20665 dic 18 14:09 test_mrtd_helpers.c
drwxrwxr-x  3 user user    4096 dic 18 14:11 toolchain
drwxrwxr-x  3 user user    4096 dic 18 14:13 .vscode

it will be possible to notice an executable file inside the firmware folder called fbt that is the core of our entertainment. For more information about fbt please use the following link: https://github.com/flipperdevices/flipperzero-firmware/blob/dev/documentation/fbt.md As you can read from the documentation, fbt stands for Flipper Build Tool and it's the entry point for firmware-related commands and utilities. It is invoked by ./fbt in the firmware project root directory. Internally, it is a wrapper around the SCons build system.

Visual Studio Code integration (optional)

Personally, for the development of IoT firmware I am very happy with Visual Studio Code, but you can use what you prefer. fbt includes basic development environment configuration for VSCode. To deploy it, run ./fbt vscode_dist from the Flip.x0 firmware folder. That will copy the initial environment configuration to a .vscode folder. After that, you can use that configuration by starting VSCode and choosing the firmware root folder in "File > Open Folder" menu.

  • On first start, you'll be prompted to install recommended plug-ins. Install them for the best development experience. You can find a list of them in .vscode/extensions.json.
  • Basic build tasks are invoked in Ctrl+Shift+B menu.
  • Debugging requires a supported probe. That includes:
    • Wi-Fi devboard with stock firmware (blackmagic),
    • ST-Link and compatible devices,
    • J-Link for flashing and debugging (in VSCode only). Note that J-Link tools are not included with our toolchain and you have to download them yourself and put on your system's PATH.
  • Without a supported probe, you can install firmware on Flipper using USB installation method.

Prepare the environment and compile our first FAP :)

Finally it's time to fill out our first application. For this part of the tutorial, I will use my_first_app as an example. Navigate into the folder tree of the Flip.x0 firmware and enter the application_user folder. Copy the folder my_first_app into the application_user folder.

The content should be something like this:

user@yourpc:flipperzero-firmware-wPlugins/applications_user$ tree 
.
├── my_first_app
│   ├── application.fam
│   └── my_first_app.c
└── README.md

1 directory, 3 files
user@yourpc:flipperzero-firmware-wPlugins/applications_user$ 

Now return to the root of Flip.x0 firmware with a cd .. command and prepare yourself for the compilation phase. On the terminal type:

./fbt fap_my_first_app

and wait for the magic.

When you create a FAP and want to compile that application, you need to run the compiler with the './fbt' command before the name of your app. In this case, the name of the FAP is *my_first_app (that is also the name of the folder...) the word fap_ before the name tells SCons to compile THAT application. Every kind of application must be compiled with a fap_ as prefix before its name.

A small example. Suppose you have an amazing FAP to compile and its name is awesome_program (as the name of the folder in which it is contained). The command for compilation will be the following:

./fbt fap_awesome_program

Now let's go back to the previous stage, and see what happened to the FAP compilation.

2022-12-24 16:44:41,216 [INFO] Packing
	LINK	build/f7-firmware-C/.extapps/my_first_app_d.elf
2022-12-24 16:44:41,291 [INFO] Complete
2022-12-24 16:44:41,305 [INFO] Complete
	PBVER	build/f7-firmware-C/assets/compiled/protobuf_version.h
	PREGEN	build/f7-firmware-C/sdk_origin.i
	SDKSRC	build/f7-firmware-C/sdk_origin.i
	SDKCHK	firmware/targets/f7/api_symbols.csv
API version 11.3 is up to date
	APPMETA	build/f7-firmware-C/.extapps/my_first_app.fap
	FAP	build/f7-firmware-C/.extapps/my_first_app.fap
	APPCHK	build/f7-firmware-C/.extapps/my_first_app.fap

Near the end of our compilation output, we can clearly see that we successfully created our FAP binary. Your first FAP is waiting for you in this folder!

build/f7-firmware-C/.extapps/my_first_app.fap

At this point we can deploy our application in two different ways. Let's see how we can proceed.

Deploy FAP inside your Flip.x0

For deploy our FAP into our Flip.x0, we can proceed in two ways:

  1. Launch the application using the ./fbt command
  2. Copy the compiled FAP inside our Flip.x0

1) Using the Flipper Build Tool

Connect your Flip.x0 to your computer using the USB-Type C cable (the device will be powered on automatically). Make sure that the serial device associated to your Flip.x0 is not used by any program. Close any instance of the qFlipper application or any other kind of software that can perform serial communication with your Flip.x0 like minicom or miniterm.

When you're ready, type the following command:

./fbt launch_app APPSRC=my_first_app

After some time the Flipper Build Tool (fbt) will call the script runfap.py and as if by magic, your first FAP will appear on your Flip.x0!

flipper_icons

You can exit from the application by pressing the back button. my_first_fap_in_action

2) Copy the .fap file inside your Flip.x0 and run the application manually Locate your .fap binary reading the output of the compilation phase. In my case the file was created into this folder, and the full path is:

[your_working_folder]/flipperzero-firmware/build/f7-firmware-C/.extapps/my_first_app.fap

Launch the qFlipper application, select the file-manager, then drag 'n' drop the file into the folder Examples (just for keep all the stuff organized) like in the image below. my_first_fap_in_action

Once you complete the drag n' drop operation, you can find your FAP in the list of applications and it will be accessible by pressing the center button (OK) and navigate through Applications → Examples → My First App

my_first_fap_in_action

And now, what can I do?

Learning, for sure :) Now you know how to compile and deploy FAP inside your Flip.x0: all you have to do is learn to develop with the examples that I will add into this repository.

The code will be strong commented to allow you to better understand all the API calls to FreeRTOS and Furi

And here, a small gift for you: https://ilin.pt/stuff/fui-editor/

It's a web-base application for build Flip.x0 GUI very easily.

Index of code examples

N. Example name Small description
0x01 My First App The simplest possible FAP, using GUI
0x02 Keypad and GUI timer This FAP showing you how to interact with the Flip.x0 buttons and timer
0x03 Notification Learn how to use the notification system
0x04 More notifications Let's see how to generate sounds, using the integrated LED and Vibration
0x05 File I/O Basic filesystem operations (create, read, write, rename and delete) a file on microSD
0x06 Logging Learn how to integrate the serial logging through FlipperCLI
0x07 Threading Simple usage of the FuriThread and how to implements them
0x08 Advanced GUI (pt.1) Learn how to use advanced GUI component like dialogs, view, view_dispatcher, etc...
0x09 Advanced GUI (pt.2) Learn how to use advanced GUI component like Submenu, TextInput, TextBox and personalized buttons
0x10 UART (code in preparation) Basic use of the GPIO with the UART system (Serial interface)

About

A set of small code examples to get in touch with the FreeRTOS, Flipper Zero and its ecosystem

License:GNU General Public License v3.0


Languages

Language:C 92.2%Language:Python 7.8%