SYS: FANTASI WIKI PAGE: ARCHITECTURE_
← HOME

Architecture

Fantasi is a FreeRTOS-based system. The kernel provides preemptive multitasking, heap management, and synchronization primitives. A thin HAL layer abstracts hardware differences between targets so that core logic - the CLI, storage, and application loader - is written once and compiled for all platforms.

  ┌──────────────────────────────────┐
  │         Applications             │  ← loaded into RAM from host
  ├──────────────────────────────────┤
  │    core/       CLI, commands     │
  │    hal/        serial, storage   │
  ├──────────────────────────────────┤
  │   platform HAL implementations   │
  ├──────────────────────────────────┤
  │          FreeRTOS kernel         │
  ├──────────────────────────────────┤
  │          MCU hardware            │
  └──────────────────────────────────┘

Tasks

TaskPriorityRole
USBtskIDLE + 2Drives TinyUSB (tud_task), services CDC and MSC class drivers
CLItskIDLE + 1Line-editing, command dispatch, serial I/O
IdletskIDLEFreeRTOS idle hook (unused)

Code Structure

core/           Shared across all targets
  main.c          Task creation, scheduler start
  cli.c           Line editor, command dispatch loop
  commands/       Built-in commands, one file per command (help, free, scan, msc, ...)
  elf_loader.c    Load + run apps; ramfs.c / vfs.c storage

hal/            Hardware abstraction
  hal.h           HAL contract - every platform implements these
  storage/        LittleFS mount/unmount, MSC block-device callbacks
  tinyusb/        Shared USB descriptors, CDC serial transport

platforms/      One directory per target
  flipper/        STM32WB55 - hal.c, display, BLE, flash driver, linker
  kiisu/          STM32WB55 - Flipper-compatible; reuses flipper/ sources, SH1106-via-companion display
  chameleon/      nRF52840  - hal.c, BLE, flash driver, linker
  proxmark3/      AT91SAM7S - hal.c, flash driver, USB mode-switch, linker

third_party/    tinyusb + littlefs are auto-cloned on first build; the rest are vendored in-tree
  tinyusb/        USB device stack (pinned tag, fetched)
  littlefs/       On-flash filesystem (pinned tag, fetched)
  FreeRTOS-Kernel/
  nanopb/         protobuf (WebUSB vendor pipe)
  cmsis_core/
  stm32wb_cmsis/
  nrf52_mdk/

HAL Contract

Every platform implements the functions declared in hal/hal.h:

  • hal_init - clock, GPIO, peripheral setup
  • hal_serial_read/write/connected - USB CDC transport
  • hal_reboot, hal_reboot_dfu - warm reset, bootloader entry
  • hal_battery_percent - fuel gauge or ADC reading (-1 if unavailable)
  • hal_ble_scan - passive BLE scan with per-device callback (-1 if no radio)
  • hal_flash_free_bytes - free flash between firmware end and reserved regions
  • hal_enter_msc_mode - USB mode switch to MSC (PM3), or -1 if MSC is concurrent (FZ/CU)

Platforms that lack a feature return a sentinel value rather than requiring compile-time exclusion. The CLI adapts at runtime.

USB

All four targets use TinyUSB as the USB device stack. The Flipper Zero, Kiisu, and Chameleon Ultra run CDC and MSC as a composite device (both interfaces active simultaneously). The Proxmark3 has only 4 hardware endpoints, so it mode-switches between CDC and MSC on demand - the msc CLI command re-enumerates as MSC-only, and host-side eject returns to CDC.

Storage

Each device reserves 256 KB of internal flash for a LittleFS filesystem, placed at the top of available flash so firmware updates (which write from the bottom) never touch stored files.

TargetStorage RegionPlacement Logic
Flipper ZeroJust below BLE secure flash (SFSA)Runtime-detected from FLASH->SFR
KiisuJust below BLE secure flash (SFSA)Runtime-detected from FLASH->SFR
Chameleon UltraJust below DFU bootloaderRuntime-detected from UICR.NRFFW[0]
Proxmark3Flash plane 1 (0x140000)Fixed; S512 only

The storage is exposed to the host as a USB mass storage block device (512-byte sectors). Host tools that understand LittleFS can read/write files directly. The on-device firmware mounts LittleFS at boot and can read/write files via the lfs_* API.

Application Model

Fantasi's long-term role is a runtime and loader, not a monolithic firmware:

  1. Host deploys an application via the web flasher or CLI tool. The binary is transferred over USB into device RAM.
  2. The loader executes the application from RAM. The application has access to a defined API surface (serial I/O, storage, radio, display where available).
  3. Persistence is handled through LittleFS. Configuration, calibration data, captured samples - anything that should survive a power cycle lives here, including a limited number of apps.
  4. Applications are portable across targets. The HAL and loader API abstract hardware differences. An application compiled for the Fantasi API runs on any supported device, with runtime capability queries for target-specific features.
★ DREAM // HACK ★