Apps
Fantasi can load and run small apps - an app is a compiled program the firmware relocates into RAM, runs on its own task, and frees completely when it exits. Apps work on every supported target. They are architecture-specific, so use the build that matches your device: .cm4 for the Flipper Zero, Kiisu, and Chameleon Ultra, .arm7 for the Proxmark3.
Where apps live
| Path | Storage | Survives reboot |
|---|---|---|
/ramfs/<name> | RAM | No - gone on power-off, no flash wear |
/apps/<name> | Internal flash (LittleFS) | Yes - /apps is created automatically at boot |
launch runs an app from either location.
Running an app
launch is a device command (works over USB serial and BLE):
fantasi> launch /ramfs/hello
hello
exit 0
The app runs on a dedicated task, so the CLI stays responsive. Press Ctrl-C to stop a running app - its task is killed and all its memory freed. Run free before and after to confirm the heap returns to its pre-launch value.
Getting an app onto the device
Web launcher (easiest)
The launcher lists the apps on your device and gives each a Launch button; you can also upload a new app straight from the browser. No tools to install.
USB drive
The device presents a small FAT drive with RAMFS/ and APPS/ folders. Copy the variant for your target in and it's ready to launch:
cp hello.cm4.elf /media/<you>/Fantasi/RAMFS/hello # RAM (no flash wear)
cp hello.cm4.elf /media/<you>/Fantasi/APPS/hello # flash (persistent)
sync
(The mountpoint varies by OS; lsblk shows the Fantasi FAT volume.)
Host CLI
fantasi> upload hello.arm7.elf /ramfs/hello # .arm7 for a Proxmark3
fantasi> ls /ramfs
Memory
The app image, its stack, and anything it allocates all come from the firmware heap and are reclaimed when the app exits or is killed - even if the app leaks. free reflects the result.
Host-fetched modules
An app can pull extra code from the paired host on demand: it requests a module over the protobuf link, the host streams it in, the app runs it, then it is deleted so only one is resident at a time. This keeps a large feature set inside the tight flash and heap of the smallest targets - the RFID app is built this way, with a separate module for each reader, sniffer, and emulation stage. launch can also run a Berry script (.be) instead of a compiled .elf.
Writing your own app
An app is a freestanding C file with a single app_main(const fantasi_api_t *api) entry point; the API gives it console, heap, storage, and hardware access, and it returns an exit code. Building needs the firmware toolchain - make app APP=<name> produces a .cm4 and an .arm7 variant, and make launch APP=<name> builds, uploads, and runs it in one step. See docs/apps.md in the firmware repo for the full API and build details.