za/ch

Making a Flipper App, Part 1: General Advice

Table of Contents

How to unbrick your Flipper

DON'T PANIC
1

It’s very likely your Flipper will freeze or look like it’s totally bricked at some point. Keep this guide handy. It was a little hard to find when I needed it.

The main way to force a restart is Left+Back, but eventually if you hit something that that doesn’t fix, consult the guide.

(Also, if it looks frozen and debug mode is enabled, it may have just hit a breakpoint. Try attaching to the debugger and use that to tell it to continue.)

Choosing a Build Tool

There are two options: Micro Flipper build tool (uFBT) and Flipper Build Tool (FBT). FBT came first, and the readme for uFBT explains the difference: uFBT is a smaller download and a simpler interface for basic app development.

Apps are also built with uFBT in a Github action to deploy them to the app catalog, so to get an app into the catalog, eventually it’ll need to compile with that.

Personally, I found it easier to use the regular FBT while I was developing the app. When things went wrong, I liked its error messages more. When I ran into trouble with uFBT I couldn’t find a lot of information on how to fix it, and there was more out there for FBT.

It’s possible to switch tools after starting with one of them, it just requires moving some files around and setting VSCode up again.

WiFi Devboard

You should get one

If you want to make an app, it will make the process much easier to get a Wifi devboard. It’s listed as optional in the documentation, but really do get one. You can also use some other SWD (Serial Wire Debug) probe or other hardware debugging tools if they’re on hand already. If you’re buying something though, get the Flipper wifi devboard.

Technically it is possible to compile an app and upload it to the Flipper without a debug probe or wifi dev board, but it will be a Much More Difficult Time writing the app if you don’t have a way to interactively debug it. Using the Flipper CLI to view logs does not provide the same information and control as an SWD or other interactive hardware debugging connection. Also, if your app uses the Flipper’s USB connection, connecting to it via the devboard will keep that free and still show the logs.

A handy tip: the latest dev version of the firmware (which can be flashed to the devboard with ./fbt devboard_flash ARGS="-c dev") sends the Flipper’s logs to the wifi portal. If you don’t have many USB ports on your computer, or just don’t want a pile of cables in the way, this is really helpful.

There’s a bit of information later about using the board, and a lot more in the actual documentation.

How to reset the wifi devboard settings

If the devboard is in a state where you can’t connect to it, hold down its boot button for a while (like 10 seconds) to reset the settings. Apparently the official board has a light that will turn red. Release the boot button, then press reset. It should be back to the blackmagic iamwitcher defaults.

DIY

Having DIYed a wifi devboard, if you want to get work done efficiently or quickly, I don’t suggest it. Technically some other ESP32-S2 boards will run the firmware (for a lot less than $40), but the real one is worth the 40 bucks just so you know it will work.

There are some notes at the end about my (partially successful) attempts to make one, which will either convince you not to DIY, or potentially help if you do it anyway.

I also don’t recommend using a 4-in-1 wifi nrf rf wtf board from aliexpress to debug because those are unreliable, barely documented, and to the extent that they were tested it was probably with Marauder firmware, not blackmagic. I tried one2 and it was acting like the SWD wasn’t totally hooked up. YMMV.

ESP32 Marauder

An alternate use of the devboard is messing around with wifi. For debugging, the devboard uses a fork of the Black Magic Debug Probe firmware. For wifi faffing about it uses ESP32 Marauder firmware. Marauder seems to be the more common use overall, or at least more commonly discussed online, so I frequently looked for something about the devboard and had to sift through a lot of stuff about Marauder.

Where to look for information

Google was a little tough to use for this project. Lots of reddit threads came up, with responses telling OP that they’re lazy and they need to google their question, then responses to those responses saying “I got here from a Google search”.

The official documentation also seems to have moved around a few times, and it’s really low in the results, if it’s indexed at all. And there’s a lot of discussion in Discord, which doesn’t show up on Google.

Despite that, the information does exist!

The Truth Is Out There screenshot from the X Files credits

General Development Homepage

https://docs.flipper.net/development/

This has links to all relevant documentation on flipper.net about developing apps and hardware for the Flipper.

Developer Docs

The Developer Docs cover most things app development, and they are generated with doxygen from files here. They have a lot of useful information, but the search bar only looks at page titles, and they didn’t really show up in Google results. I actually had the best luck searching the firmware github repo since it has the source markdown files in it.

CLI docs

The built in CLI was almost enough to do what I needed without writing a whole app. If you just need to do something the built in apps do but programmatically, check here first. I ended up adding my own command to the CLI, which still saved me a ton of work related to actually interfacing directly with the USB connection. Details on how to do this are in the other post about the app itself.

Source Code

It was extremely helpful to look at the firmware’s source code.

I wasn’t actually changing anything in the firmware code, but I called functions from it, and it also includes a variety of example apps. Even when what I was looking for was documented somewhere else, this was still the most reliable entry point to finding that other documentation. Github search works really well, and I knew it had to be in there somewhere if the Flipper was doing it.

Also, every app in the Flipper App Catalog is open source, so if there’s an app out there that does something similar to what you want to do, go check out how they did it.

Past issues and pull requests in the firmware Github Repo

https://github.com/flipperdevices/flipperzero-firmware/issues

Discord

https://flipperzero.one/discord

There’s a lot of information in past messages in the Discord that isn’t written down anywhere else. It’s also possible to get answers from experienced developers and people who helped design the Flipper if you’re really stuck, or trying to do something that’s not documented.

Reddit

There’s some useful information on the Flipper subreddit. The mods mostly seem to work for Flipper or be otherwise heavily involved, and sometimes they share things that aren’t really written down anywhere else. It’s still Reddit, so there’s a lot of noise to sort through, but there’s useful stuff there.

Flipper Forums

The forums aren’t particularly active, but I’ve found good information there. The posts show up in Google searches, sometimes, but it could be worth searching separately.

Miro boards

I found a couple of these, and they seem to be essentially slide decks left over from presentations. I think they’re old information, but they had some high level context that wasn’t anywhere else, so maybe you’ll find it useful too. Take with a grain of salt because it is likely not 100% accurate anymore.

https://miro.com/app/board/o9J_l1XZfbw=/?invite_link_id=945998406939

Community-made tutorials and examples

A helpful tutorial mostly focused on getting started and making a user interface, with links to lots of other resources:

https://instantiator.dev/post/flipper-zero-app-tutorial-01/

Several detailed tutorials including videos (I didn’t actually follow these but I read through one and they look like a great resource):

https://github.com/jamisonderek/flipper-zero-tutorials

Outside knowledge3

There’s a lot of information not directly related to the Flipper that is necessary to understand the documentation and other writing about it. It mostly falls under the umbrella of “embedded devices”. Below, in the yak shaving section, there’s a list of a few other types of background information to look for if someone is using a lot of unfamiliar acronyms.

If you don’t already know most of it, that’s okay! I learned what I needed as I ran into new concepts, but do be prepared to take a multi-day break from one project to go learn about some new thing you’ve never heard of, and then take a break from that to go learn about another new thing, and then…

LLMs

I didn’t use these, since I enjoyed the process of figuring it out myself. Maybe this would help if you just want to make something as quickly as possible and don’t care how it works.

Running and debugging an app

“Debugging” has multiple meanings and I need to use two different ones here. In this section:

“Debugging” = “understanding and fixing a bug in a program via whatever means necessary”

“Interactive debugging” = “using some tool to inspect registers and memory while a program is running, set breakpoints, and step through code”

Interactive Debugging

Some useful tools for this are GDB (GNU Debugger) and/or OpenOCD (Open On Chip Debugger), or VSCode (which uses those under the hood).

They allow you to set breakpoints, pause the program, check registers and memory while it’s running, and more.

There’s an incredibly deep well to tap here, and it’s out of scope for this guide. I’m also not the best person to talk about it, since I used a very small fraction of the features offered. GDB is widely used in and out of embedded development, so it’s worth investing time to learn about it.

Logs

Logs can also help with debugging a program. They provide different information than the interactive debugging tools, and there are options in the Flipper settings to adjust how detailed they are.

The Flipper sends logs out over two interfaces:

I needed to use the Flipper’s USB serial connection in my app, so I had to get the logs through the debugger. If you app uses the UART GPIO pins, you might need to get your logs over USB. Or some other interface.

Connections

It took me a while to get a mental model of what was happening when the Flipper and devboard were plugged into the computer. Reading this and all the sub-pages is a good starting point: https://developer.flipper.net/flipperzero/doxygen/dev_board.html

But, that felt hard to integrate with some of the other explanations I found. To supplement, here’s a basic overview of how everything is talking to each other.

How everything shows up on the computer:

Each serial device can only be connected to one thing at a time. For example, if the Flipper CLI is open, it has exclusive access to the Flipper’s USB serial device. If you leave the Flipper CLI open and try to use VSCode to launch an app on the Flipper, it will not work.

How the Flipper and the devboard fit together:

Examples:

Program/Command/Action Required Connections
qFlipper or lab.flipper.net Flipper’s USB serial port
VSCode, Launch App On Flipper command Flipper’s USB serial port
View logs in Flipper CLI with the “log” command Flipper’s USB serial port
View Flipper logs on devboard Logging serial port for the devboard, or wifi connection to the devboard
gdb Interactive debugging serial port for the devboard, or wifi connection to the devboard. The Flipper must have “Debug” turned on in the system settings.
VSCode, Attach FW (in debug sidebar, blackmagic mode) Same as gdb
Build App No connection needed
Flash firmware to the Flipper Depends which interface you select

VSCode

I used VSCode for interactive debugging (it’s basically just a GUI for GDB), but I didn’t use it for the logging. If you want it all in one place, there’s a serial monitor in VSCode that might be useful.

The vscode_dist command

The docs say this should only be run once per project, but there were times I had to remove some files and then run it again. If you move a project into a different location on the computer computer, for example, it will stop working because it uses some absolute paths that need to be updated when the project is moved. I removed the .vscode and toolchain directories and ran vscode_dist again, and it worked.

Hardware bugs

Usually when writing software, the hardware is pretty well abstracted away by the language and the OS. The abstractions here are…less abstract since the hardware in the Flipper needs to interact closely with the physical world at a low level.

This is just a reminder that the physical object might be the problem. A wire might be loose or disconnected, something might be plugged in backwards, or the overhead light might be interfering with the infrared signal. If you’re hitting your head against a wall looking for a bug and it reallllly looks like the code is correct, check the hardware too.

This is also true to a lesser extent for firmware and build tools. Some of them have bugs or unexpected behavior! (see: UFBT trying to link the virtual environment I made). It is not always your code causing problems.

You’re going to shave some yaks 4

Ganesh Mohan T, CC BY-SA 4.0, via Wikimedia Commons

Ganesh Mohan T, CC BY-SA 4.0, via Wikimedia Commons

I also call these “side quests” sometimes. These are some yak shaves/side quests from this project.

Embedded systems development and debugging

The Flipper is an embedded device, even thought it acts more like a computer or a cell phone than many embedded devices do. It’s not the most approachable one for a First Embedded Devices Project because it has so much going on.

The corner I found to start getting my fingernails under was reading a few chapters of an embedded systems book, then working through the getting started with pico guide using C. There’s a lot I still don’t know, but this was a good start. Other people swear by Arduino, but the pico documentation and forum posts I found when googling stuff felt friendlier.

Many forum posts about embedded development (especially Arduino) imply that information about embedded devices is somehow both obvious and arcane, and if you don’t know it already, you’re doomed never to know. The explanations there are often rude, incorrect, incomplete, and/or unhelpful.5

There are good posts out there, but I found it demoralizing to look for them. Consulting a book or a class is a shortcut to good information without as much attitude, but it is usually a less direct path to the specific information.

Installing and compiling the build tools

I don’t have a ton to offer about this, because it will depend on the specific OS, and a complete Linux tutorial is way out of scope. Being comfortable with whichever operating system you’re using will pay dividends when compiling and installing anything from source code, or accessing/troubleshooting why you can’t access serial ports.

Being comfortable with git and Github is also useful, since that’s where all the source code is.

Serial ports and protocols

I still don’t really understand serial ports and TTYs but did need to use them for this project. Watching a bunch of Ben Eater videos could be fun here if you have the time. These are the main serial concepts I encountered:

UART (Universal Asynchronous Receiver/Transmitter): Basic serial connection that just needs two wires. Common in microcontrollers and embedded devices. The Flipper can send logs out over USART (Universal Synchronous Asynchronous Receiver/Transmitter) and LPUART (Low Power UART), which are types of UART.

USB (Universal Serial Bus): Also a type of serial connection, although a familiar one

COM (Communication) port: Serial devices are called this on Windows, for historical reasons

TTY (teletypewriter): Serial devices are called this on Linux, for historical reasons

ACM (Abstract Control Model): Serial devices may also be called this on Linux, for bizarre historical reasons

Python

The only Python necessary to write for a Flipper app is the manifest file, which barely counts, but a lot of the build tools use Python. The build tools can break, and the resulting errors are sometimes Python errors. When I used the regular Flipper Build Tool instead of the micro one, these errors were less common.

Unfortunately, most of the errors are related to virtual environments and pip, which are notoriously kind of unruly. For example, at some point, a VSCode task said that the command ufbt was not found. I think the tasks didn’t have the virtual environment I made in their path. I kind of gave up on this one since I switched to regular FBT for most of my development work. This is more of a VSCode issue than a python issue (and possibly a me-doing-something-wrong issue), but I would have been really confused if I hadn’t experienced similar errors using Python in the past.

C

The Flipper firmware is written in C, and most apps to use as examples are written in C. I decided it was most straightforward to also write my app in C.

There are alternatives–there is a new javascript API, or you can try to use any language that can compile and run on a Flipper. I want to try this someday, but for a first attempt, I am glad I just used C.

This tutorial covers the C aspect well, and it would be a good Flipper-focused starting point.

A cautionary tale and long digression about a DIY wifi devboard

I offer the advice to get a regular, normal, legit Flipper wifi devboard because I did not do that. Instead, I happened to have6 one of these with a ESP32-S2FN4R2 on it, and I used that.

The devboard has several functions that require different connections. The ones I wanted to use were:

The ESP32-S2 mini with ESP32-S2F-N4R2

a janky (if you want to be negative) or mad-max-looking (if you want to be positive) ESP32-S2 mini board with wires soldered to it and running through a cracked off piece of perf board to act as header pins for the Flipper

Not very pretty, but effective!

This mini ESP board runs the firmware, but doesn’t have GPIO43 or GPIO44 pins exposed on the board to solder to.7 That’s where the logs are supposed to go in, so at first I didn’t get any logs.

But! The Flipper has a setting to send its logs out over different pins. The default “USART” setting goes out of Flipper GPIO13 and GPIO14 and into devboard GPIO43 and GPIO44 (missing). “LPUART” sends the logs out of Flipper GPIO15 and GPIO16, into the devboard’s GPIO17 and GPIO18 (not missing!). There is not a corresponding setting in the devboard firmware to change where it listens for logs, but there is a repository with the complete source code that you can change the numbers in and recompile.

If you want to do this for some reason, I just searched 43 and 44 in the github repo for the Flipper fork of blackmagic, to see where pin 43 and 44 were used. As of the time of writing it’s only in main/usb-uart.c. I changed 43 to 17, and 44 to 18.

I also did not connect a pull up resistor to the devboard’s GPIO 18 (LPUART_TX), even though there is one in the wiring diagram. This might make a difference.

Note: If you compile modified blackmagic firmware and flash it to the devboard using the instructions in the blackmagic-esp32-s2 repo, this means you shouldn’t use the fbt or ufbt devboard flashing commands anymore. Those will pull the latest release or dev version from online and overwrite any adjustments.

In the end, this actually worked well enough to make an app, so yay.

The Saola-1 board with S2-WROVER

A nicer looking project board with a Saola-1 dev board and real header pins instead of wires. Shame it doesn't work right.

This one looks nicer but it doesn’t work correctly :(

I also bought a Saola-1 devboard that has the S2-WROVER chip on it (the same chip on the Flipper devboard). I hooked up almost everything from the wiring diagram, and the USB connection works for logging, but it does not work for interactive debugging.

My current theory is that this is because it has micro USB instead of USB-C. I believe the Flipper devboard does something to make itself show up as 2 serial devices that the Saola board can’t handle. It can debug wirelessly so I don’t think it’s on the Flipper side, it’s got to be something about the USB connection.

So, don’t get this particular board, and probably make sure anything you get has USB C.

Other ESP32s

I don’t know enough to predict if any given ESP32 will work, but if you’ve got an ESP32-S2 laying around, and it’s got USB-C and the right pins, might as well try. If you don’t care about logs and just want the SWD functionality, there’s a lot more flexibility.

Schematics

There is a schematic showing which pins go where in the devboard firmware repo.

There’s also a reddit post from /u/MidniteFluff with a diagram that fits on one page, and it’s easier to read. There are claims circulating on reddit that it only needs the SWD wires hooked up. That’s true if you only want to interactive debug with SWD, but I ended up wanted logs and power too, so I suggest hooking up the UART pins as well as the power pins.

Here’s the Reddit diagram for posterity because it’s just on a random screenshot sharing website (click the image for a larger version):

wiring diagram for how to make A DIY wifi devboard using a LILYGO ESP32_S2_WOOR board

from this Reddit post on June 9th 2024

Aside: The naming of ESP32s

ESP32s are named in hell with the aid of a random number generator. This table helps make some sense of it, sort of. Moreso than googling variations of “ESP32-S2-WROVER vs ESP32-WROVER-I”, at least, which got me absolutely nowhere.

Aside #2: Pinout diagrams

The first several times I tried to read a diagram like this it was pretty daunting (click the image for a larger version).

Pinout diagram for Adafruit Feather ESP32-S2

image source

Basically, if you’re using existing firmware where someone has already decided what each pin is used for, you can kind of ignore everything but the GPIO numbers.

Everything written in this post is in terms of the “GPIO” numbers. I think of them as a sort of lowest common denominator. That’s what the numbers printed on the board usually mean, and they’re also how the pins are defined in the blackmagic firmware. This probably doesn’t hold up to scrutiny, but it’s gotten me through this project and a couple of others.

Part 2: How to make a CLI App

Check out Part 2, making a CLI app to use with the Tamagometer


  1. https://en.wikipedia.org/wiki/Phrases_from_The_Hitchhiker%27s_Guide_to_the_Galaxy#Don't_Panic ↩︎

  2. I did approximately everything except the thing I’m recommending, but that’s why I’m recommending it so strongly. I tried to make two of these and tried a knockoff because I was impatient and cheap. Yes, I spent more time on troubleshooting my broken debugging tools than actually writing an app. Yes, this was a foolish decision. I did learn some things along the way that I think will come in handy, though. That’s my excuse, anyway. ↩︎

  3. I didn’t know a lot of the necessary information prior to starting this project, and maybe seeing that will encourage anyone else with an idea and limited experience to go forth and try to make an app. It’s totally possible to learn as you go, it just takes longer. ↩︎

  4. If you are not familiar with the term “yak shaving” ↩︎

  5. I am aware that this is a stone cold take about discussions on the Internet ↩︎

  6. Actually, my partner happened to have one and very kindly gave it to me… ↩︎

  7. I did consider using this as an excuse to get into micro soldering, but fortunately I was able to fix it in software before it got to that point. ↩︎

Tags: