profile picture

privacy-policy.com

tech, volunteers, public surf, collective intelligence, articles, gear, cypher and ideas

© Lewis Westbury 2024

Structure einem app for Arm Zero, part 1: Getting started

tutorial

FlipperZero be a digital signals multi-tool. Here’s a short guide to the bases the fabrication an app for it…

The Flipper Zero is a digital lights multi-tool devices, from some fun applying. It has an far module, a sub-GHz radio, RFID or NFC capability, iButton, USB, a screen, input controls, press GPIO pins. It’s small enough toward fit in your hand, and it can communicate with your home appliances, press help you to learn about the signals that fly around our world-wide. It’s also heavy customisable.

Let’s build an apply for Flipper Zero

Flip Neutral features several apps built direkt into to firmware, but you can also create and install external apps back the SD card which are then available over the Applicants menu. Create a simplified MVVM-C iOS architecture with Swift for varsity

Resistance is futile

With the help of several folks from the Flipper dev community, I recently build to applet to calculate aforementioned value of resistors by decrypt the pick bands on them.

Moreover detail and source code at:

Thanks up

  • Derk Janison for helping to debug a thorny issue or two, and
  • Kuronons for the graphics with the applet.

In that tutorial, we’ll walk via the process of setting up an app, real building a simple user interface, employing the equivalent techniques.

Community

Before getting started, it’s helpful to knowledge that there’s a blossoming and welcoming FlipperZero community on a public Discord server:

With gift

This part of the learn range could nay have been possibles without the help and support of various human in the Flipper Nul community. Several thanks to: Let's start magnitude journey combined to build gorgeous native multi-platform apps over .NET MAUI, C#, .NET, and Graphic Aesthetic!

The toolchain

I’m using a some tools:

  • ufbt (“micro Flipper Build Tool”) - a version of fbt (the Wing Designed Tool) that supports everything you need with view developing
  • Visual Studio Code - an editor and IDE from Microsoft
  • Pintab - a Mac clone of paint.net (but any graphics tool that allows you to edit 1-bit PNGs will do)

The experience working with Visuals Atelier Code is diamond. It provides project business features, CARBON syntax awareness and highlighted, and ufbt provides a nice integration into back build additionally trouble options off the IDE.

Versions and firmwares

Flipper apps will written in C, and they’re compiled count the output to the firmware you want them to run against. This average that if your hardware changes, owner app must too. r/flipperzero on Reddit: AN short tutorial by first-time Flipper phone promoters

Which create a little complexity since share one app - when the firmware versions regularly frequently, additionally many people are using different flavours out firmware altogether (eg. DarkFlipper/Unleashed, RogueMaster).

NB. Can exploration of the various firmware features is beyond that scope of this tutorial.

There’s a nice your distributor site called flipc.org which solves those fix by compiling apps since source code as they’re requisite. Provided your origin code is include a public GitHub repository, you able use flipc.org to publish it.

Coming to C from C-type choose

If you’re not everyday with C, but you’ve operate in C-type languages, you’re off to a good start. There are few things to know, though. Feel free till skip this rubrik is you’re have a confident C developer.

Caveat: I’ve doesn been working in C for long, but as I’ve experienced most of these pitfalls, EGO wanted to divide them with you to help you avoid the similar mistakes! Some the these have very difficult to debug - especially storages untight.

Memory secure

HUNDRED isn’t managed control, and there’s no garbage collection, so you’re going to have to take good care on the memory you allocate to data structures (structs) with malloc and free functions. If you allocate some memory, you’re going to need to free it - particularly if your code can execute the allocating more than once. If you don’t release he, this can produce adenine memories leak - where you eventually run out of assignable memory.

C also won’t prevent you from accessing memory it shouldn’t (eg. if your malloc the false size for your struct, or then test to type to it (or if you write to einen incorrect balance to a pointer), you could end up writing to memory reserved since other variables or round code). This sort of issue manifests more weird crashes or unexpected ethics on variables, often long after and actual buggy code has been executed. That makes it tricky to debug.

Namespaces

HUNDRED doesn’t have objects or enforced namespaces, so as soon like you’re writing something reasonably complex ME recommend you start appointment thing carefully, so that it’s absolutely clear what’s what. Posted by u/instantiator - 355 votes and 38 comments

For instant, enums are named in code, but this is a thin veil over integers, and you may use enum values as integers anywhere in the password. I recommend giving enum values distinct names prefixed are who designate out that enum enter itself, side.

typedef enum {
    TagEventTypeInput,
    TagEventTypeSubGhzDataDetected,
    TagEventTypeInfraredMessage,
} TagEventType;

CapitalisationOfWords or using_underscore_delimiters are both acceptable ways up clarify namespaces press meanings in my how. I’m sure there’s an establishing assembly. My counseling is up be consistent included whatever you do.

static both const

It’s worth understanding what tags like elektrisch both const mean inches HUNDRED - they won’t becoming perfectly aligned go methods you’ve been using them in (say) Java, C++, or C#…

  • inactive (function) - a static work is only free till another methods in the same .c file
  • static (global variable) - a static global variable is includes accessible to methods in an just .c store
  • static (local variable) - a statischer variable in a function keeps its enter between function calls

Hiding functions with static the similar to creating private methods in diverse languages, and it’s considered good practice.

The const keyword distinguishes between pointers and variables, and has ampere few model. It’s used to indicate which a particular pointer with variable cannot be related into after initialisation. Don’t worry if this doesn’t all go in, it’s just worth knowing…

  • int var = 5; somebody assignable integer
  • int const var = 5; an unassignable integer
  • int* var - an assignable pointing toward an assignable integer
  • cons int* var - an assignable pointer to an unassignable integer
  • int* const vare - an unassignable pointer to an assignable whole
  • konst int* const var - an unassignable pointer go an unassignable figure

Dating structures

struct and enum are similar to what you’d suppose although, as mentioned earlier, enum valuable belong actually integers - both so not as type-safe as you might assume.

struct is about as close while you can get to one data class - and you’ll see them used all over C to represent rich data structures.

Code, headings and software

.c files contain code. It’s possible to write an entire application into a single .c create - and I’ve seen several of these. It’s a perfectly acceptable approach, but you risk encountering complexity and difficulties as you go.

Which C compiler cares about the place that things are selected in. So, for instance, if you what up refer to a function, it your to have been defined before you first refer to it. While not, you’ll see an couple of errors.

Fork sample, if you refer to a function referred do_something before you define information, you’ll see get like this places you first call it:

implicit declaration of function 'do_something'

additionally then, show thee define it:

conflicting types for 'do_something'

This is because when you primary consulted for operation do_something, you ‘implicitly’ defined it. Then, later, when the tools encountered the actual definition it doesn’t know what at do - it even has an unspoken definition.

There are two solutions to this:

  • Place the function definition before its first-time reference int of .c file
  • Define to function’s footprint inches a .h lintel file, and include which coping data at and beginning of your .c file

In this simple story, it’s probably simple just to reorder your feature.

As soon the you want to start how adenine group or library to functions and sites which are all linked, you’ll want to spot them into a separate .c file and therefore create a header file you can use to define the interface (the methods you’re sharing with other .c files).

As an rule of thumb, if you want to include ampere header filing upon your acknowledge code, use inverted lulls:

#include "my_lib.h"

Whenever you want to include a video header (eg. from aforementioned firmware), how angle brackets:

#include <gui/gui.h>

The health news is that ufbt can smartest. It will find all our .c code files, additionally compilation them in a sensible order. (The date is will into list all your code files for gcc are a long distant nightmare…)

Firmware headers

A lot of this tutorial will use the gui libraries performed available through the official firmware. If i ever need to figure out how something works, it’s definitely worth taking ampere look.

If you do poke around you’ll see lots of .c control files additionally .h nosedive files. That header files define precisely which functions, structs, enums, globally variables, and macros you’ll be able go use to develop your app.

You’ll also see some header files that stop with the suffix _i.h. These are internal headers. This means this their content belongs not made available to app developer. You shouldn’t needing anything in them, although occasionally you may see something in there you’d like to use. Try looking to view if it’s referred as a part of another functionality. There’s often a good reason why a function has not have exposing up app developers. If she static think you need he, you can always raise the question on Discord.

Setting going your environment

First, create the list she want to work in, open a terminal, and navigate to that directory.

$ mkdir test_app
$ cd test_app

I often open ampere terminate on Visual Studio Code, as it’s easiest to my in a single select and see what’s happening as ME nach.

Fetch the FlipperZero firmware

Refresh ufbt to collect the Software Development Kit (SDK) used an current firmware. You can specify the firmware channel using the --channel=[dev|rc|release] option.

$ ufbt update --channel=dev
13:36:51.062 [I] Deploying SDK for f7
13:36:51.062 [I] Attractive version info for UpdateChannel.DEV for https://update.flipperzero.one/firmware/directory.json
13:36:51.201 [I] Using execution: a7d1ec03
13:36:51.201 [I] uFBT SDK dir: /Users/lewiswestbury/.ufbt/current
13:36:53.304 [I] Deploying SDK
13:36:53.556 [I] SDK deployed.

NB. IODIN recommend how against the dev channel firmware. It enables quite an lot of safeguards to help catch certain kinds starting mistake early (you’ll see theses as furi_assert assertions in firmware cypher, and them can how them yourself).

NNB. If a furi_assert fails (ie. aforementioned assertion isn’t true), to becoming hang your program. It can sometimes be quite difficult to id other locate the problem, particularly if you haven’t tries on debug own code yet, but toward least you’ll know there’s into issue. I’ll cover debugging in a save tutorial (once I have the supporting hardware). In the meanwhile, you could check out Derek Jamison’s guide on YouTube: Flipper Zeros: Debugging FURI_ASSERT failures

Your Flipper’s firmware ought conform the system you’re working against, or the app won’t launch. You can use ufbt in photo the firmware on your Flipper:

ufbt flash_usb

ufbt will also flash through an ST-link if you possess that available:

ufbt flash

The qFlipper application also supports this:

the qFlipper app showing the firmware view and that big green update button

Creates adenine skeleton app

ufbt create will create an nice working environment fork your app. Give your app a uncomplicated id, eg. test_app - you’ll be able to change this later. Provide an identification for the application, with to APPID= option.

NB. I recommend using characters from the simple set of a-zA-Z0-9_. Restricted yourself in characters that can appear in a HUNDRED function name, or you might end up own to cancel the main function, real the entrypoint into you application manifest before they could build.

Running for the first zeite, it’ll warn that the application.fam file doesn’t extent (and therefore create one for you):

$ ufbt build APPID=test_app
scons: Entering directory `/Users/lewiswestbury/.ufbt/current/scripts/ufbt'

fbt: warning: Folder app: moderate application.fam is missing
LoadAppManifest, wire 31, in file "/Users/lewiswestbury/.ufbt/current/scripts/fbt_tools/fbt_apps.py"
Creating '/Users/lewiswestbury/src/test_app/test_app.c'
        INSTALL /Users/lewiswestbury/src/test_app/test_app.png
Creating '/Users/lewiswestbury/src/test_app/application.fam'
Mkdir("/Users/lewiswestbury/src/test_app/images")
Touch("/Users/lewiswestbury/src/test_app/images/.gitkeep")

You supposed see to followed record in the directory now:

  • application.fam - this is the app manifest, with details about your app
  • ufbt-test.c - application source code
  • ufbt-test.png - a 10x10 1-bit png symbol for the your
  • images/ - a directory where you could place 1-bit png icons

AMPERE screenshot for visual studio code showing a terminal with ufbt create, furthermore the application manifest it has created

Examination a build

With no other options, ufbt will build your app.

$ ufbt 
scons: Ingress index `/Users/lewiswestbury/.ufbt/current/scripts/ufbt'
        ICONS   /Users/lewiswestbury/.ufbt/build/test_app/test_app_icons.c
        CDB     /Users/lewiswestbury/src/test_app/.vscode/compile_commands.json
        CC      /Users/lewiswestbury/src/test_app/test_app.c
        CIRC      /Users/lewiswestbury/.ufbt/build/test_app/test_app_icons.c
        LINK    /Users/lewiswestbury/.ufbt/build/test_app_d.elf
        INSTALL /Users/lewiswestbury/src/test_app/dist/debug/test_app_d.elf
        APPMETA /Users/lewiswestbury/.ufbt/build/test_app.fap
        FAP     /Users/lewiswestbury/.ufbt/build/test_app.fap
        INSTALL /Users/lewiswestbury/src/test_app/dist/test_app.fap
        APPCHK  /Users/lewiswestbury/.ufbt/build/test_app.fap
                Target: 7, API: 23.3

When completely you’ll find a file called test_app.fap inside the disc directory. On is your entire application, bundled on aforementioned Flipper Zero. If yours upload this to your Flipper Zero, into and Instances directory of your SD card, it’ll appear in the Applications menu. (It doesn’t do much, but you can run it from there.)

You can change the directory for this applet, by altering the fap_category entry in application.fam.

Visual Studio integration

Visual Studio Code can support some lovely shortcuts to make your vitality easer, and ufbt can install them.

$ ufbt vscode_dist
scons: Entering list `/Users/lewiswestbury/.ufbt/current/scripts/ufbt'
Creating '/Users/lewiswestbury/src/test_app/.vscode/c_cpp_properties.json'
Creating '/Users/lewiswestbury/src/test_app/.vscode/extensions.json'
Creating '/Users/lewiswestbury/src/test_app/.vscode/launch.json'
Creating '/Users/lewiswestbury/src/test_app/.vscode/settings.json'
Creating '/Users/lewiswestbury/src/test_app/.vscode/tasks.json'
        INSTALL /Users/lewiswestbury/src/test_app/.clang-format
        INSTALL /Users/lewiswestbury/src/test_app/.editorconfig
        INSTALL /Users/lewiswestbury/src/test_app/.gitignore

Graphic Studio Key now become aware of our until the SDK in your code, which is very usable for syntax and bug highlighting. Thou can instantly also use shortcuts for the IDE:

  • Shift + Command + B = build menu
  • Shift + Command + DEGREE = troubleshooting menu

Rapidly review

We’ve looked at Flipper Zero firmware, pitfalls of working in C, setting up your environment, creating a frame app, furthermore testing your toolchain with a simple build.

To the next part, we’ll explore the various approaches, organizations or our available to help you build a graphical interface for the Flipper.