
Una plantilla moderna y lista para producción para desarrollar aplicaciones para Flipper Zero con el lenguaje de programación Zig. Este proyecto proporciona un sistema de compilación optimizado que integra Zig con el SDK de Flipper Zero, lo que permite a los desarrolladores escribir aplicaciones con seguridad de tipos y de memoria para la plataforma Flipper Zero.
Esta plantilla tiende un puente entre el potente sistema de compilación y las características del lenguaje Zig y el kit de desarrollo de firmware de Flipper Zero. Gestiona la compleja integración entre la compilación cruzada ARM Cortex-M4 de Zig y el SDK de Flipper, proporcionando un punto de partida limpio para aplicaciones personalizadas.
ufbt (herramienta de compilación no oficial) para empaquetar archivos FAPLa plantilla utiliza un proceso de compilación en dos etapas:
Etapa de compilación Zig: Compila el código fuente Zig a archivos objeto ARM Cortex-M4 (app.o)
thumb con modelo de CPU cortex-m4eabihf (Interfaz Binaria de Aplicaciones Embebidas, coma flotante hardware)ReleaseSmall para un tamaño de binario mínimoEtapa de empaquetado UFBT: Enlaza los archivos objeto con el SDK y los empaqueta en formato .fap
ufbtufbt (se instala en ~/.ufbt)La plantilla está preconfigurada para macOS ARM64 con la ruta de la cadena de herramientas ARM:
~/.ufbt/toolchain/arm64-darwin/arm-none-eabi/include
Si estás en otra plataforma, es posible que necesites ajustar la ruta arm_libc_include en build.zig:31 para que coincida con la ubicación de tu cadena de herramientas.
Instalar UFBT:
python3 -m pip install --upgrade ufbt
ufbt update
Clonar o descargar esta plantilla:
git clone https://github.com/yourusername/flipper-template.git
cd flipper-template
Inicializar tu proyecto:
zig build init
Este script interactivo te solicitará:
my_custom_app)Compila el código fuente Zig a un archivo objeto:
zig build
Esto crea zig-out/bin/app.o con todo el código de aplicación compilado.
Compila y empaqueta la aplicación completa:
zig build fap
Esto ejecuta el pipeline completo:
ufbt para enlazar con el SDK.fap en el directorio dist/Ejecuta la aplicación directamente en un Flipper Zero conectado:
zig build launch
Esto compila, empaqueta y transfiere la aplicación por USB y, a continuación, la inicia automáticamente.
flipper-template/
├── application.fam # Flipper app manifest (metadata, entry points)
├── build.zig # Zig build system configuration
├── build.zig.zon # Zig package manifest
├── icon.png # App icon (10x10px recommended)
├── setup.sh # Interactive project initialization script
├── src/
│ └── root.zig # Main application source code
└── zig-out/ # Build artifacts (generated)
└── bin/
└── app.o # Compiled object file
src/root.zig: Punto de entrada que contiene la función start() y la lógica de la aplicaciónapplication.fam: Configuración específica de Flipper (ID de la aplicación, categoría, dependencias, tamaño de pila)build.zig: Define los objetivos de compilación, las rutas del SDK y los comandos de compilaciónLa plantilla incluye un ejemplo "Hola mundo" que demuestra las API principales de Flipper:
// Import Flipper SDK functions
const flipper = @cImport({
@cInclude("furi.h");
@cInclude("gui/gui.h");
@cInclude("gui/canvas.h");
@cInclude("gui/view_port.h");
});
// Application entry point (must be named "start")
export fn start(_: ?*anyopaque) callconv(.{ .arm_aapcs = .{} }) i32 {
// Initialize GUI viewport
const gui = flipper.furi_record_open("gui");
const view_port = flipper.view_port_alloc();
// Set up callbacks and UI
// ... (see src/root.zig for complete implementation)
// Event loop
_ = flipper.furi_thread_flags_wait(1, flipper.FuriFlagWaitAny, flipper.FuriWaitForever);
return 0;
}
El sistema de compilación configura automáticamente las rutas de inclusión para:
Todos los encabezados están disponibles mediante @cImport() en tu código Zig.
El SDK de Flipper utiliza las convenciones de llamada ARM AAPCS:
start())Asegúrate de que las funciones exportadas coincidan con la convención de llamada esperada:
export fn start(_: ?*anyopaque) callconv(.{ .arm_aapcs = .{} }) i32
export fn draw_callback(canvas: ?*Canvas, ctx: ?*anyopaque) callconv(.{ .arm_aapcs_vfp = .{} }) void
Algunos encabezados del SDK contienen construcciones que el traductor de C de Zig no puede procesar (p. ej., uniones con tipos opacos en input/input.h). Para estos casos, declara manualmente las funciones externas:
extern fn view_port_input_callback_set(
view_port: ?*flipper.ViewPort,
callback: ?*const fn (?*anyopaque, ?*anyopaque) callconv(.{ .arm_aapcs_vfp = .{} }) void,
context: ?*anyopaque
) callconv(.{ .arm_aapcs = .{} }) void;
Problema: unable to find header 'furi.h'
~/.ufbt es incorrectaufbt update para instalar los encabezados del SDKProblema: undefined reference to 'view_port_alloc'
zig build fap en lugar de zig build para completar el enlazadoProblema: No Flipper device found
Problema: La aplicación falla al iniciarse
stack_size en application.fam o verifica las firmas de las funcionesModifica addFlipperDefines() en build.zig para ajustar las macros del preprocesador:
obj.root_module.addCMacro("FAP_VERSION", "\\\"1.0\\\"");
obj.root_module.addCMacro("CUSTOM_DEFINE", "value");
Cambia el nivel de optimización en build.zig:11:
const optimize = b.standardOptimizeOption(.{
.preferred_optimize_mode = .ReleaseFast, // or .ReleaseSmall, .Debug
});
La plantilla está orientada al STM32WB55 (ARM Cortex-M4F) del Flipper Zero. Para portarla a otros dispositivos ARM, ajusta build.zig:4-9:
const target = b.resolveTargetQuery(.{
.cpu_arch = .thumb,
.cpu_model = .{ .explicit = &std.Target.arm.cpu.cortex_m4 },
.os_tag = .freestanding,
.abi = .eabihf,
});
¡Las contribuciones son bienvenidas! Esta plantilla tiene como objetivo simplificar el desarrollo con Zig para Flipper Zero. Si encuentras problemas de compatibilidad con el SDK o tienes sugerencias para mejorar el proceso de compilación, abre un issue o una pull request.
Este proyecto está licenciado bajo la Licencia MIT; consulta el archivo LICENSE para más detalles.
Nota: Esta es una plantilla no oficial y no está afiliada a Flipper Devices Inc. Prueba siempre las aplicaciones a fondo antes de desplegarlas en dispositivos de producción.