# What Is the F Prime (F') Software? NASA's Component-Driven Flight Framework

> Discover NASA's F Prime F flight software framework. This open-source, component-driven C++ system uses model-driven code generation for reliable flight implementations from FPP specifications.

- Repository: [NASA/fprime](https://github.com/nasa/fprime)
- Tags: getting-started
- Published: 2026-07-13

---

**F Prime (F') is NASA's open-source, component-driven flight software framework that combines a C++ core for low-level services with a model-driven code generator that turns FPP language specifications into flight-ready implementations.**

The F Prime software serves as the backbone for numerous NASA missions, providing a robust architecture for embedded systems and spacecraft applications. Developed in the `nasa/fprime` repository, this framework separates system design from implementation by using the **F Prime Prime (FPP)** modeling language to define components, which the framework then converts into compile-ready C++ code.

## Core Architecture and Design Philosophy

At its heart, F Prime employs a **model-driven development** approach that distinguishes between high-level system specifications and low-level implementations. The framework provides a C++ runtime handling threading, message queues, and memory management, while the FPP compiler generates type-safe boilerplate code from component specifications.

This architecture enables rapid development through reusability. Components written for one mission can be dropped into new topologies with minimal modification, as demonstrated by reusable service components like the watchdog timer found in `Svc/WatchDog/WatchDog.fpp`.

## The Three Fundamental Constructs

The framework organizes software into three interconnected abstractions, detailed in [`docs/user-manual/overview/03-port-comp-top.md`](https://github.com/nasa/fprime/blob/main/docs/user-manual/overview/03-port-comp-top.md).

### Ports: Typed Communication Interfaces

**Ports** define typed interfaces that connect components, specifying direction (input/output), synchronization behavior (synchronous/asynchronous), and optional guarding. They act as the contract between components, ensuring type-safe communication across the system.

### Components: Self-Contained Behavior Modules

**Components** encapsulate specific functionality and inherit from framework base classes categorized as passive, active, or queued. Each component implements logic to handle port invocations, commands, events, and telemetry. The component model requires that developers implement virtual handlers for input ports while the framework manages the underlying dispatch mechanism.

### Topologies: System Wiring Diagrams

**Topologies** are graphs that instantiate components and connect their ports at runtime. Defined in FPP files and generated into C++ code, topologies create the component objects and establish the wiring that defines how data flows through the system.

## Component Kinds and Threading Models

F Prime supports three distinct component types, each determining threading capabilities and port compatibility:

- **Passive components** execute without dedicated threads or message queues, making them suitable for simple, deterministic logic that runs in the caller's context.
- **Active components** possess both a thread and a message queue, enabling them to process asynchronous requests independently of their callers.
- **Queued components** maintain a message queue but borrow the thread of their caller, offering a middle ground for sequencing operations without dedicated thread resources.

Only active components can host asynchronous input ports, as the component kind dictates which port types are supported according to the core constructs documentation.

## Port Types and Communication Patterns

The framework implements four port kinds that determine how method invocations are dispatched:

1. **Output ports** – Allow components to call methods on other components
2. **Synchronous input ports** – Execute handlers immediately in the caller's thread
3. **Asynchronous input ports** – Queue requests for later processing by the component's thread
4. **Guarded input ports** – Protect handler execution with mutex locking for thread-safe access

Each port kind influences the dispatch mechanism, ranging from direct function calls to queued messages protected by synchronization primitives.

## The FPP Modeling Language

**F Prime Prime (FPP)** is a domain-specific language for defining component interfaces, behavior, and system topology. FPP files use a declarative syntax to specify ports, commands, events, telemetry, and parameters, which the `fpp` compiler then transforms into C++ source files.

The following example from `FppTestProject/FppTest/topology/components/Comp/Comp.fpp` demonstrates a complete active component definition:

```fpp
module FppTest {
  active component Comp {
    // Ports
    async input port PingIn:  Svc.Ping
    output       port PingOut: Svc.Ping

    // Commands
    async command Start(nRecords: U32)
    async command End()

    // Event
    event Event(a: U32, b: F32, c: string size 10)
      severity activity high format "a: {}, b: {}, c: {}"

    // Telemetry
    telemetry Telemetry: U32

    // Parameter
    param Param: U32 default 0
  }
}

```

This specification defines an active component with asynchronous communication capabilities, command handlers, event logging, telemetry channels, and configurable parameters.

## Code Generation Workflow

When the FPP compiler processes component definitions, it generates C++ header and implementation files that inherit from the appropriate framework base classes. The generated code handles boilerplate serialization, dispatch logic, and interface enforcement.

For the component defined above, the compiler generates a base class similar to this simplified version:

```cpp
// CompComponentAc.hpp – generated base class
class CompComponentAc : public Fw::ActiveComponentBase {
public:
    // Port handlers (generated)
    virtual void PingIn_handler(const Svc::Ping& ping) = 0;
    void PingOut_out(const Svc::Ping& ping);

    // Command handlers (generated)
    void Start_cmdHandler(Fw::CmdSlotType opCode,
                          U32 nRecords);
    void End_cmdHandler(Fw::CmdSlotType opCode);
    
    // Event and telemetry accessors (generated)
    void Event_out(U32 a, F32 b, const char* c);
    void Telemetry_out(U32 value);
};

```

Developers implement business logic by subclassing the generated base class and overriding the pure virtual handlers:

```cpp
// CompComponentImpl.cpp – user-provided implementation
void CompComponentImpl::PingIn_handler(const Svc::Ping& ping) {
    // Respond to incoming ping
    PingOut_out(ping);
}

```

This separation allows engineers to focus on application logic while the framework manages threading, queuing, and type safety.

## Serialization and Data Transport

F Prime supports **port call serialization**, which marshals arguments into buffers for transport across address-space boundaries. This capability enables communication between flight components and ground-system proxies, or between processes in distributed systems.

Serialization allows the framework to maintain type safety at the API level while supporting generic data transport mechanisms underneath. Arguments are automatically packed and unpacked according to the types defined in `Fw/Types/Types.fpp`, which provides core definitions for primitives like `U32` and `F32`.

## Project Structure and Key Files

The `nasa/fprime` repository organizes framework code, documentation, and reference implementations across several key locations:

- **[`README.md`](https://github.com/nasa/fprime/blob/main/README.md)** – High-level overview, system requirements, and getting-started instructions
- **[`docs/user-manual/overview/01-full-intro.md`](https://github.com/nasa/fprime/blob/main/docs/user-manual/overview/01-full-intro.md)** – Comprehensive introduction to framework purpose and scope
- **[`docs/user-manual/overview/03-port-comp-top.md`](https://github.com/nasa/fprime/blob/main/docs/user-manual/overview/03-port-comp-top.md)** – Detailed specification of ports, components, and topologies
- **`FppTestProject/FppTest/topology/components/Comp/Comp.fpp`** – Reference component showing FPP syntax for commands, events, and telemetry
- **`Fw/Types/Types.fpp`** – Core type definitions underlying the FPP language
- **`Svc/WatchDog/WatchDog.fpp`** – Example reusable service component for mission-critical watchdog functionality

These files provide the definitive reference for understanding how the F Prime software implements its component-driven architecture.

## Summary

F Prime (F') software provides a sophisticated framework for flight software development through these key characteristics:

- **Component-driven architecture** separating design (FPP models) from implementation (C++ code)
- **Three core abstractions**: Ports for interfaces, Components for behavior, and Topologies for system wiring
- **Flexible threading models** supporting passive, active, and queued component types
- **Automatic code generation** from FPP specifications, ensuring type safety and reducing boilerplate
- **Serialization support** enabling communication across address-space boundaries

The framework's model-driven approach enables rapid development, automated consistency checks, and component reuse across multiple NASA missions.

## Frequently Asked Questions

### What programming languages does F Prime use?

F Prime uses a combination of **FPP (F Prime Prime)** for high-level modeling and **C++** for implementation. Developers write component specifications in FPP, which the `fpp` compiler translates into C++ base classes. The framework core and generated code are written in C++, providing the performance and determinism required for flight software.

### How does F Prime handle communication between components?

Communication occurs through **ports**, which are typed interfaces defined in FPP and implemented in C++. Ports support synchronous, asynchronous, and guarded input types, allowing components to communicate via direct method calls, message queues, or mutex-protected handlers. The framework automatically handles serialization when data must cross address-space boundaries.

### What is the difference between active and passive components in F Prime?

**Active components** possess their own thread and message queue, enabling them to process asynchronous requests independently. **Passive components** execute entirely within the caller's thread without dedicated resources, making them suitable for deterministic, low-overhead operations. Only active components can host asynchronous input ports that require queuing capabilities.

### Where can I find examples of F Prime components?

Reference implementations are available throughout the `nasa/fprime` repository. The `FppTestProject/FppTest/topology/components/Comp/` directory contains a comprehensive example showing ports, commands, events, telemetry, and parameters. Additionally, the `Svc/` directory includes reusable service components like `WatchDog.fpp` that demonstrate production-ready patterns for spacecraft applications.