← Back
Home › Systems › Embedded and IoT

satellite-flight-software

Keeps a spacecraft alive and doing its job on its onboard computer, mostly without a human in the loop.

NASA cFS

Open the satellite-flight-software pagesatellite-flight-sof… Edac memory scrubbingembedded: ECC/EDAC memory with periodic scrubbing to correct radiation-induced bit flipsFault detection isolationrecoveryembedded: Monitor/response tables, fault isolation and safe-mode recovery hierarchies for autonomous systemsPreemptive priority schedulingembedded: Always run the highest-priority ready task, switching the instant a higher one becomes ready; selection is O(1) with one FIFO per priority and a bitmap.›Redundancy votingembedded: N-modular redundancy and MooN voting (2oo3, TMR) with discrepancy detectionWatchdog timerembedded: A hardware down-counter that resets the chip unless software proves, in time and in a plausible pattern, that it is still healthy.›CRC32C checksumshardware-os: The Castagnoli CRC-32 with dedicated instructions on x86 (SSE4.2) and ARMv8. It is the standard fast integrity check for storage blocks, logs and network frames.›Ccsds space packetsnetworking: CCSDS space packet and transfer frame protocols: APIDs, sync markers, virtual channelsOrbit propagationnumerics: Propagate satellite orbits (Kepler, SGP4, numerical with perturbations) and frame transformsRunge-Kutta 4numerics: The classic four-stage, fourth-order ODE step; error drops 16× when the step halves, with no derivatives or past steps needed.›Attitude determinationrobotics: Estimate orientation from vector observations (TRIAD, QUEST/Wahba) and gyrosExtended Kalman filterrobotics: Kalman filter for nonlinear motion and measurement models: linearize f and h with Jacobians at the current estimate each step. The default estimator in robot navigation.›PID controllerrobotics: Drive a measured value to a setpoint with three terms on the error: proportional, integral, derivative. The default feedback loop for motors, heaters, drones and gimbals.›Rigid-body transforms (SE(3)poses)robotics: Represent, compose, invert, integrate and interpolate 3D poses as unit quaternion plus translation, with exp/log maps for small motions and uncertainty.›Message authentication codes(HMAC, CMAC, Poly1305, KMAC)security: A keyed short tag proving a message is unmodified and came from a key holder; pick HMAC, CMAC, KMAC or a one-time polynomial MAC by what primitive you already have.›Convolutional codes and theViterbi decodersignal-processing: Streaming error-correcting code: each output bit is a parity of the last K input bits; the Viterbi decoder finds the most likely path through a 2^(K-1)-state trellis.›Ldpc codessignal-processing: Low-density parity-check codes with soft-decision min-sum decoding, used in NAND flashReed-Solomon codessignal-processing: Byte-oriented MDS code: n-k parity symbols correct (n-k)/2 unknown symbol errors or n-k known erasures; the workhorse for bursts, QR codes, discs and storage.›Hierarchical state machinesystems: Nest states so a substate inherits its parent's reactions and only overrides what differs, with ordered entry and exit actions along the path.›Hierarchical timing wheelsystems: Timers bucketed by expiry into wheels of slots, coarser wheels for far deadlines: O(1) insert and cancel for millions of timeouts.›Publish subscribe event bussystems: In-process or on-box topic bus decoupling producers and consumers with bounded queuesAdaptive Runge-Kutta(Dormand-Prince)numerics: An embedded 5(4) Runge-Kutta pair estimates each step's error for free and resizes the step to meet a tolerance; the default non-stiff solver.›Spherical harmonic transformnumerics: Fast spherical harmonic transforms via FFT in longitude and Legendre in latitudeCalendar date arithmeticsystems: Civil dates, time zones (tzdb), DST gaps, month-end anchoring and duration mathPCA and SVDmachine-learning: Find orthogonal directions of maximum variance by an SVD of the centred data; randomized SVD gets the top k components in a few passes.›SIMD programminghardware-os: Process 4-16 lanes per instruction with AVX2, AVX-512 or NEON via Rust std::arch, with runtime dispatch and a portable fallback.›Finite differencesnumerics: Replace derivatives with weighted differences of grid values; simple stencils plus a stability condition (CFL) turn PDEs like heat, advection and waves into array loops.›LU and Cholesky factorizationnumerics: Factor A = PLU (any square matrix, partial pivoting) or A = LLᵀ (SPD) once in O(n³), then solve each right-hand side in O(n²).›Kalman filterrobotics: Optimal recursive estimator for a linear system with Gaussian noise: fuses a motion model with noisy measurements into a state estimate plus its covariance.›Quaternion rotationsgeometry: Unit quaternions as 3D rotations: 4 floats, cheap composition, no gimbal lock, plus the conversions, interpolation choices and numerical care needed in practice.›Homogeneous transformsgeometry: 4x4 affine and projective matrices, homogeneous coordinates, view and projection, normal matricesSparse matrices (CSR)numerics: Compressed sparse row stores only nonzeros as row pointers, column indices and values; SpMV streams them once, so it is memory-bandwidth bound.›Qam soft demappingsignal-processing: PSK/QAM constellation mapping and max-log LLR soft demapping for decoders+ 1 moreFast Fourier transformnumerics: Computes the DFT in O(n log n) by recursively splitting into even and odd halves; the basis of fast convolution and spectral methods.›Gaussian quadraturenumerics: Approximate an integral by a weighted sum of n function values at roots of orthogonal polynomials; exact for polynomials up to degree 2n-1.›Spherical gridsnumerics: Lat-lon, cubed-sphere and icosahedral grids for global models; pole and area issuesExplicit Eulernumerics: Step an ODE forward by its current slope, y += h·f(t, y); first-order, one evaluation per step, the baseline every other integrator is measured against.›Thomas tridiagonal solvernumerics: O(n) tridiagonal linear solve used in implicit finite-difference and spline schemes

How it is built

Architecture overview

Satellite flight software (FSW) is the program on the spacecraft's computer that keeps it alive and doing its job without a human in the loop most of the time. The computer is slow by ground standards, the radio link is short and intermittent, radiation flips memory bits, and nobody can reboot it by hand, so the design is built around three ideas. First, isolation by layers: a thin operating-system and hardware abstraction below, a set of core services (messaging, time, events, tables, files) in the middle, and many small applications on top, each of which does one job and talks to the others only through messages. Second, everything is a command or a telemetry packet: the ground sends commands, the spacecraft returns packets, and applications inside use the same format, so ground tools and flight code share one vocabulary. Third, autonomy for faults: monitors compare telemetry with limits and trigger stored responses (safe mode) faster than the ground could. NASA's core Flight System (cFS) and JPL's F Prime (F´) are the open frameworks for this shape; cFS flew on flagship and human missions and runs on CubeSats and Raspberry Pi, F´ targets smaller systems (source: cFS README; F´ README).

Parts:

  ground ──uplink (packets, files)──► radio/decoder ──► command ingest ──┐
    ▲                                                                    ▼
    │                                        ┌──────────── software bus (pub/sub) ───────────┐
 downlink ◄── telemetry output ◄─────────────┤                                                │
 (packets, files)                            │  scheduler   GNC apps   health & safety   limit │
                                             │  (time)      (EKF, PID) (watchdog, apps) checker│
                                             │      stored commands   data storage   file xfer │
                                             └──── core services: events, tables, time, memory ┘
                                                          │
                                                OS abstraction + platform layer ──► RTOS ──► CPU, sensors, actuators

There are two products of the same design: the flight build (a fixed set of applications and tables for one mission, verified for that mission) and the ground and test builds (the same code on a workstation or a development board, used with a simulator). The cFS bundle on GitHub is explicitly a demo, not a flight distribution (source: cFS README).

How the parts fit together

OS abstraction and platform layer

Flight code that calls the operating system directly cannot move to the next mission. cFS therefore has two layers below the applications: the Operating System Abstraction Layer (OSAL, tasks, queues, semaphores, files behind one API) and the Platform Support Package (PSP, board and memory specifics) (source: cFS component READMEs). The cFE guide tells application authors to call only the cFE and OSAL APIs and never the hardware or the OS directly (source: cFE Application Developer's Guide). Under that layer sits a real-time kernel with fixed-priority preemption: Preemptive priority scheduling is the dominant choice because worst-case latency can be analysed. See also the system page on RTOS.

One contract is worth knowing: interrupt handling is not abstracted. The guide notes that the OSAL interrupt functions were deprecated for platform dependencies, and it describes the device-driver pattern instead: a three-function model in which a short ISR does the time-critical part, then wakes a task that may call the full API (source: cFE Application Developer's Guide). The same split exists in every RTOS: the ISR cannot use calls that may block.

Message bus

The software bus (SB) is how applications talk. An application creates a pipe, a queue with a fixed depth, and subscribes its pipe to the message IDs it wants; senders just publish a message with an ID and the bus routes it to every subscribed pipe. This is publish-subscribe-event-bus (no page yet) specialised for flight (source: cFE Application Developer's Guide, Software Bus). The contracts:

  • A pipe is read by exactly one application, though an application may read several pipes.
  • Bounded queues, explicit overflow. If a pipe reaches its depth, further messages to that pipe are rejected (an overflow) while other pipes continue normally, so a slow application cannot stall the bus. A per-subscription message limit adds a second bound per message ID.
  • Opaque IDs. The message ID is not to be interpreted by applications; by default it maps to a CCSDS stream ID, and the format is selectable (source: same guide). Commands and telemetry use the CCSDS packet shape (ccsds-space-packets, no page yet), which is why ground tools can read bus traffic directly.
  • No bus calls from interrupt handlers, since the bus uses OS calls that may block.
  • Routing table: a direct-indexed map by message ID, or a hashed map to save memory when IDs are sparse. That is a space/speed trade-off the guide documents with the memory impact "significant".

The alternative is direct function calls between modules, which is simpler and faster but ties every module to every other. The bus costs a copy and a queue per message; it buys replaceable, testable, individually restartable applications.

F´ makes the same decoupling with typed ports between components: a port is an interface of a fixed type and a component's ports are connected in a topology. A port can be synchronous (runs on the caller's thread), guarded (the same, under a component mutex) or asynchronous (the call is placed on a queue and handled on the component's own thread) (source: F´ User Manual). The difference from cFS is in when connections are made: F´ connects components at build time from a model and generates code, cFS connects applications at runtime by subscription.

Time and scheduling

Telemetry and control need a shared timebase. The cFE Time Service keeps Mission Elapsed Time (MET) in a hardware register, applies a Spacecraft Time Correlation Factor (STCF) to relate it to an epoch, and defines TAI = MET + STCF; the factor can compensate a known oscillator drift (source: cFE Application Developer's Guide, Time Service). That is Clock synchronization in the small: estimate the offset between the on-board clock and a reference, and steer it gradually. The feedback loops PID control and Phase-locked loop, are the standard tools for locking a local oscillator to a reference such as a one-pulse-per-second signal.

Activity is scheduled from a table. The scheduler application releases message IDs on a fixed one-second grid in the demo version (sch_lab), and applications wake when their message arrives (source: nasa/sch_lab README; the cFE guide names Scheduler and Stored Command as typical software-only applications). This is a coarse timing wheel: the table slot is the bucket; Hierarchical timing wheel is the general structure when timers are many and irregular.

Fault detection and recovery

The spacecraft must handle failures by itself, in time. fault-detection-isolation-recovery (no page yet) is realised in cFS by cooperating applications:

  • Health and Safety (HS) monitors applications and events, and services a hardware watchdog (source: nasa/HS README).
  • Limit Checker (LC) compares telemetry data points with thresholds; on a violation it issues an event and can start a Relative Time Sequence script as the response (source: nasa/LC README).
  • Stored Command (SC) holds command sequences with time tags or wake-up counts: absolute-time sequences (ATS) and relative-time sequences (RTS) (source: nasa/SC README). The response to a limit violation is an RTS; the ground-visible record is an event.

Together this is a monitor/response table pair: a monitor table (LC) says what is wrong, a response table (SC) says what to do, and escalation climbs from restarting one application to rebooting the processor to safe mode. The Watchdog timer is the last resort, and the contract is the usual one: it is serviced only by something that verifies health (HS here), not by an unconditional timer. A Hierarchical state machine is the natural model of the operating modes (nominal, safe, survival) with entry and exit actions; F´ documents state machine support in the framework. Redundant sensors or computers add redundancy-voting (no page yet): two-out-of-three voting masks one bad input, at the cost of triple the hardware.

Memory and storage

Memory is scarce and radiation-prone. The cFE memory pool provides pseudo-dynamic allocation from a block that the application gives it: fixed-size blocks, without the fragmentation of malloc (source: cFE Application Developer's Guide). That is the Slab allocator idea; buddy-allocator and arena-allocator (no pages yet) are the alternatives for mixed sizes or per-cycle memory. F´ offers a buffer pool for the same reason.

Data that must survive a processor reset goes to the Critical Data Store (CDS): an area not modified during a reset, which the application copies its working data into periodically; the cFE adds an integrity value and the application decides whether the contents are logically valid (source: same guide). The cFE offers a mission-wide CRC API; historically a single algorithm, CRC-16/ARC, and others by option. CRC32C checksums are the strong-integrity variant for storage, but the check chosen is a mission decision.

Radiation flips bits in RAM, so edac-memory-scrubbing (no page yet) uses error-correcting memory plus a background task that reads every word periodically, so single-bit errors are fixed before a second one accumulates into an uncorrectable error. The scrub period is chosen from the expected upset rate. The Data Storage application writes bus messages to files on a recorder, and the CFDP application transfers them to the ground, mapping CFDP PDUs onto the software bus (source: nasa/DS and nasa/CF READMEs).

Tables carry configuration (thresholds, schedule, routes). Each table has an active and an inactive image; ground loads and validates the inactive image, then commands the switch. A single-buffered table shares one inactive buffer (less memory, but the reader may be delayed), a double-buffered table has its own and switches without blocking, good for time-critical readers (source: cFE guide, Table Service). The result is that thresholds change by uplinking a file, not by reflashing code.

Commands arrive and telemetry leaves over a lossy link. Layers, from the radio up: modulation and demodulation (qam-soft-demapping, no page yet, converts received symbols to soft bits); forward error correction (Reed-Solomon codes, Convolutional codes and Viterbi, ldpc-codes (no page yet) as the modern high-gain choice); framing into CCSDS transfer frames; then packets on the bus. The FEC is usually in the radio hardware or a dedicated decoder, because LDPC decoding at high rates is heavy work (sparse matrices, Sparse matrices (CSR), and SIMD programming on the ground), and flight software handles frames and files above it. Which code to choose is a link-budget decision: LDPC and turbo codes (ldpc-codes ↔ polar-codes, turbo-codes, no pages yet) come closer to channel capacity than Reed-Solomon, at higher decoder cost.

Uplink authentication matters because a command can change the orbit. Message authentication codes give each command a keyed tag and a counter, so a recorded command cannot be replayed (see Replay protection window). The public cFS is limited to the framework and common applications; security measures for a full flight mission are part of the government version (source: cFS README).

Guidance, navigation and control

GNC is mission-specific application code on top of the framework. The pieces: attitude-determination (no page yet) turns star-tracker and sun-sensor vectors (TRIAD, QUEST for Wahba's problem) and gyro rates into a quaternion orientation; an Extended Kalman filter fuses gyro propagation with vector measurements, where the plain Kalman filter suffices if the model is linear; PCA/SVD appears in the SVD solution of Wahba's problem. The estimate feeds a PID control or similar loop driving reaction wheels or magnetorquers. The alternative to a Kalman filter is the complementary filter, simpler and cheaper but without covariance.

Orbit and frames

orbit-propagation (no page yet) predicts where the spacecraft is: analytic models (Kepler, SGP4) for low-cost use, numerical integration with perturbations (gravity harmonics via spherical-harmonic-transform, drag, solar radiation) when precision matters. The integrator is Adaptive Runge-Kutta when step size should follow the dynamics, or fixed-step Runge-Kutta 4 when run time must be constant; Explicit Euler is the baseline that is cheap but loses accuracy fast. Position in the Earth-fixed, inertial and body frames is converted with Rigid-body transforms and calendar-date-arithmetic (no page yet) for time scales.

Data and control flow

A ground command:

  1. The radio decodes the frame (FEC) and checks the integrity and authenticity tag.
  2. The command-ingest application publishes the packet on the bus under its message ID.
  3. The subscribing application reads it from its pipe, validates length and arguments, executes it, and emits an event and housekeeping telemetry with a command counter.
  4. Telemetry output applications collect those packets and queue them for the next downlink pass.

A fault response:

  1. A sensor value drifts; the limit checker compares the telemetry point against its table and finds a violation.
  2. It issues an event and starts a stored command sequence.
  3. The sequence disables a payload and commands safe mode through the bus.
  4. Health and Safety services the hardware watchdog; the design intent is that it does so only while monitored applications are healthy, so a hang ends in a processor reset, after which applications restore state from the Critical Data Store.
  5. The ground sees the event and the housekeeping telemetry on the next pass and decides how to recover.

Scaling

  1. Link capacity limits how much telemetry reaches the ground per pass. Levers: onboard storage with prioritised downlink, event filtering (cFE's binary filter masks a counter to suppress repeats), compression, a stronger code.
  2. Processor time limits control rate and onboard estimation. Levers: fixed-rate schedule, simple filters, offload orbit work to ground.
  3. Memory limits the number of applications and tables. Levers: pools, single-buffered tables, a small routing map.
  4. Application count grows the bus traffic and the test matrix. Levers: reuse unchanged, previously flown applications; keep interfaces in header files so a change recompiles only what it touches (a cFS guideline).
  5. Reliability is paid for in redundancy: voted sensors, cold or hot spares, and verification effort.

Failure modes

FailureSymptomCauseFix
Pipe overflowan application misses messagesqueue depth too small or the application too slowsize depth from rates; per-message limits; fix the slow path
Single-event upset in RAMbad data, odd behaviour that clears on rebootradiation flips a bitEDAC memory with scrubbing; checksums on tables
Latch-up or resetthe processor rebootsradiation or a software hangwatchdog, restore from the Critical Data Store, safe mode
Wrong tableunexpected thresholds or scheduleuploaded values not validatedload to the inactive image, validate, then activate
Estimator divergenceattitude error grows, wrong pointingbad sensor, wrong noise model, singularityoutlier rejection, covariance monitoring, fall back to a simple mode
Command replay or spoofan old command executes againno counter or tagauthenticated commands with a replay window
Fault cascadeone fault trips many monitorsthresholds overlap, no isolationisolate by subsystem, escalation levels, hold-off timers
Lost linkno contactwrong pointing or transmitter faultautonomous recovery that re-points and retries on a schedule

Real implementations

namewhat it isrepolicencenotes
cFS (core Flight System)framework: cFE core services, OSAL, PSP, and flight apps (HS, LC, SC, DS, CF, ...)nasa/cFSApache-2.0bundle repo; submodules nasa/cFE, nasa/osal, nasa/PSP
F Prime (F´)component framework: ports, components, topologies, modelling language, code generation, ground data systemnasa/fprimeApache-2.0aimed at CubeSats, SmallSats, instruments; project site fprime.jpl.nasa.gov

The alternative: F´ and cFS differ in how the system is wired. In cFS an application is a separate task that finds its peers at runtime through message subscription, so configuring a mission is a matter of tables and a startup script. In F´ the wiring is a topology written in a modelling language, from which code is generated, so a mismatch of interfaces is a build error. cFS has a longer flight history on larger spacecraft and a rich set of ready-made applications; F´ gives a typed, model-driven path that suits small teams.

Sources

Similar systems

Share the most building blocks with this one.