# What Is the F Prime Message Queue? Architecture and Implementation Guide

> Discover the F Prime message queue, an OS-agnostic abstraction facilitating inter-component communication. Learn how this portable solution enables seamless message exchange across diverse platforms for your flight software.

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

---

**The F Prime message queue is a portable, OS-agnostic abstraction implemented in the `Os::Queue` class that enables inter-component communication through a delegate-based architecture, allowing flight software components to exchange serialized messages across POSIX, Windows, and embedded platforms without modification.**

The message queue mechanism in the NASA F´ (fprime) repository provides the fundamental infrastructure for asynchronous data flow between components. Located in the `Os` (Operating System) abstraction layer and integrated through the `Fw` (Framework) component base classes, this system decouples application logic from platform-specific queue implementations while maintaining deterministic performance characteristics critical for flight software.

## Core Architecture of the F Prime Message Queue

The F Prime message queue architecture centers on a generic interface that abstracts OS-specific implementations, enabling the same flight code to run across development hosts and target hardware.

### The Os::Queue Interface

At the heart of the system lies **`Os::Queue`**, defined in **[[`Os/Queue.hpp`](https://github.com/nasa/fprime/blob/main/Os/Queue.hpp)](https://github.com/nasa/fprime/blob/devel/Os/Queue.hpp)**. This class exposes **`QueueInterface`**, which specifies the core lifecycle and messaging operations:

- **create** – Initialize queue resources
- **send** – Enqueue a message
- **receive** – Dequeue a message  
- **teardown** – Clean up resources
- **Status queries** – Check operational state

The interface design ensures that components interact with queues through standardized methods regardless of the underlying operating system.

### Platform Abstraction via Delegates

The concrete **`Os::Queue`** implementation employs a delegate pattern to achieve portability. Rather than containing OS-specific logic directly, the class forwards all operations to a platform-supplied delegate stored in fixed-size **`QueueHandleStorage`**.

This delegate is instantiated via **placement-new** during queue creation, allowing the same F Prime binary to utilize POSIX message queues on Linux, Windows APIs on desktop systems, or custom RTOS implementations on embedded targets. The platform-specific delegate logic resides in **[[`Os/Queue.cpp`](https://github.com/nasa/fprime/blob/main/Os/Queue.cpp)](https://github.com/nasa/fprime/blob/devel/Os/Queue.cpp)**, which handles the translation between generic F Prime calls and native OS primitives.

## Component Integration with QueuedComponentBase

Components that require message processing capabilities inherit from **`Fw::QueuedComponentBase`**, located in **[[`Fw/Comp/QueuedComponentBase.hpp`](https://github.com/nasa/fprime/blob/main/Fw/Comp/QueuedComponentBase.hpp)](https://github.com/nasa/fprime/blob/devel/Fw/Comp/QueuedComponentBase.hpp)** and implemented in **[[`Fw/Comp/QueuedComponentBase.cpp`](https://github.com/nasa/fprime/blob/main/Fw/Comp/QueuedComponentBase.cpp)](https://github.com/nasa/fprime/blob/devel/Fw/Comp/QueuedComponentBase.cpp)**.

### Queue Creation and Configuration

The base class contains an **`Os::Queue m_queue`** member and provides **`createQueue(U32 depth, U32 msgSize)`** to initialize the queue with a specific depth (number of messages) and maximum message size. This method allocates the underlying storage and prepares the delegate for the target platform.

### Message Dispatch Flow

Incoming messages are processed through the **`dispatchAvailableMessages()`** method, which implements a polling loop that repeatedly calls the pure-virtual **`doDispatch()`** method until the queue is empty or an error status is returned. This design allows components to drain their message queue during execution cycles, processing each message through the derived component's implementation of `doDispatch()`.

## Message Flow and Serialization

When a component sends a message, the F Prime framework serializes the data into a linear buffer and invokes **`Os::Queue::send()`**. The receiving component polls its queue through **`dispatchAvailableMessages()`**, which calls **`receive()`** on the underlying `Os::Queue`.

The **`doDispatch()`** implementation deserializes the buffer and invokes the appropriate message handler. This separation of concerns ensures that the queue mechanism handles only byte transport, while component logic manages message interpretation and business logic.

## Monitoring and Diagnostics

F Prime queues support observability through human-readable names and statistics tracking. The **`Os::QueueString`** class (defined in **[[`Os/QueueString.hpp`](https://github.com/nasa/fprime/blob/main/Os/QueueString.hpp)](https://github.com/nasa/fprime/blob/devel/Os/QueueString.hpp**) provides naming capabilities for queue identification during debugging.

Each queue maintains diagnostic counters including **`m_msgsDropped`**, which tracks messages dropped due to full queues, and **`getMessageHighWaterMark()`**, which reports the maximum queue depth reached during operation. These metrics enable flight software engineers to detect congestion and size queues appropriately for mission requirements.

## Practical Implementation Example

The following example demonstrates a component implementing the F Prime message queue pattern:

```cpp
// MyComponent.hpp
#include <Fw/Comp/QueuedComponentBase.hpp>

class MyComponent : public Fw::QueuedComponentBase {
public:
    MyComponent(const char* compName) : QueuedComponentBase(compName) {
        // Create a queue that can hold 10 messages, each up to 256 bytes
        this->createQueue(10, 256);
    }

protected:
    // Called by dispatchAvailableMessages()
    MsgDispatchStatus doDispatch() override {
        // Receive a message from the queue
        Fw::LinearBufferBase buf;
        Fw::QueuePriorityType prio;
        Os::Queue::Status stat = this->m_queue.receive(buf, Os::Queue::BLOCKING, prio);
        if (stat != Os::Queue::OP_OK) {
            return MSG_DISPATCH_ERROR;
        }

        // Deserialize and handle the message (example only)
        MyMessage msg;
        buf.deserialize(msg);
        handleMessage(msg);
        return MSG_DISPATCH_OK;
    }

private:
    void handleMessage(const MyMessage& msg) {
        // Component-specific processing
    }
};

```

Runtime processing occurs through the dispatch loop:

```cpp
// Somewhere in the runtime loop
MyComponent comp("MyComp");

// Process all pending messages
while (true) {
    Fw::QueuedComponentBase::MsgDispatchStatus stat = comp.dispatchAvailableMessages();
    if (stat == Fw::QueuedComponentBase::MSG_DISPATCH_EXIT) break;
    // Optional: sleep or perform other work
}

```

## Key Source Files

The F Prime message queue implementation spans the following critical files:

- **[[`Os/Queue.hpp`](https://github.com/nasa/fprime/blob/main/Os/Queue.hpp)](https://github.com/nasa/fprime/blob/devel/Os/Queue.hpp)** – Core queue interface and concrete implementation
- **[[`Os/Queue.cpp`](https://github.com/nasa/fprime/blob/main/Os/Queue.cpp)](https://github.com/nasa/fprime/blob/devel/Os/Queue.cpp)** – Platform-specific delegate logic for POSIX and other systems
- **[[`Os/QueueString.hpp`](https://github.com/nasa/fprime/blob/main/Os/QueueString.hpp)](https://github.com/nasa/fprime/blob/devel/Os/QueueString.hpp)** – Helper utilities for queue naming
- **[[`Fw/Comp/QueuedComponentBase.hpp`](https://github.com/nasa/fprime/blob/main/Fw/Comp/QueuedComponentBase.hpp)](https://github.com/nasa/fprime/blob/devel/Fw/Comp/QueuedComponentBase.hpp)** – Base class providing queue infrastructure to components
- **[[`Fw/Comp/QueuedComponentBase.cpp`](https://github.com/nasa/fprime/blob/main/Fw/Comp/QueuedComponentBase.cpp)](https://github.com/nasa/fprime/blob/devel/Fw/Comp/QueuedComponentBase.cpp)** – Implementation of dispatch loops and queue management
- **[[`Svc/ComQueue/ComQueue.hpp`](https://github.com/nasa/fprime/blob/main/Svc/ComQueue/ComQueue.hpp)](https://github.com/nasa/fprime/blob/devel/Svc/ComQueue/ComQueue.hpp)** – Production service example wrapping `Os::Queue` for command and telemetry traffic

## Summary

- **The F Prime message queue** is implemented in the `Os::Queue` class following a delegate pattern that abstracts OS-specific implementations for portable flight software.
- **Platform abstraction** occurs through placement-new instantiation of platform delegates into fixed-size `QueueHandleStorage`, enabling identical code to run on POSIX, Windows, and embedded targets.
- **Component integration** happens through `Fw::QueuedComponentBase`, which provides `createQueue()` for configuration and `dispatchAvailableMessages()` for message processing.
- **Message flow** involves serialization into linear buffers, `send()` operations by producers, and `receive()` calls within the component's `doDispatch()` implementation.
- **Observability features** include queue naming via `Os::QueueString` and statistics tracking for dropped messages and high-water marks.

## Frequently Asked Questions

### How does the F Prime message queue support multiple operating systems?

The F Prime message queue achieves cross-platform compatibility through a delegate pattern where the `Os::Queue` class forwards operations to a platform-specific implementation stored in `QueueHandleStorage`. This delegate is instantiated via placement-new during queue creation, allowing the same flight software to utilize POSIX message queues on Linux, native Windows APIs, or custom RTOS implementations without source code modification.

### What is the relationship between Os::Queue and QueuedComponentBase?

`Os::Queue` provides the low-level, OS-agnostic queue mechanism for byte transport, while `QueuedComponentBase` offers the component-level integration layer. The base class contains an `Os::Queue m_queue` member and manages the queue lifecycle through `createQueue()`, while providing the `dispatchAvailableMessages()` framework that calls the derived component's `doDispatch()` method to handle message deserialization and business logic.

### How does F Prime handle message queue overflows?

When a queue reaches capacity, the `m_msgsDropped` counter increments to track lost messages, and the `send()` operation returns an appropriate error status. Components can monitor queue health through `getMessageHighWaterMark()` to detect peak usage patterns and size their queues appropriately during the design phase to prevent data loss during high-traffic mission phases.

### What determines the message size and queue depth in F Prime?

Queue parameters are specified during instantiation via `createQueue(U32 depth, U32 msgSize)`, where `depth` defines the maximum number of messages that can be stored and `msgSize` sets the maximum byte length per message. These values are fixed at creation time and must accommodate the serialized size of the largest message type the component expects to receive, plus any F Prime framework overhead.