Flight Software

Flight Software V&V Before a Satellite Launch

Every satellite programme reaches the same afternoon: the flight software is feature-complete, the schedule has a launch date on it, and someone has to answer whether the code is actually ready to fly. There is no single test that answers this. Readiness is the sum of a traceability chain, a testing ladder, and a fault-injection campaign, each of which catches a different class of mistake.

Verification and validation are not the same question

Verification asks whether the software was built correctly against its specification. Validation asks whether that specification was the right one to begin with. A team can verify flawlessly against a requirement that describes the wrong behaviour, and every test will pass while the vehicle does the wrong thing in orbit.

Keeping the two separate matters because they are checked by different people, at different times, against different documents. Verification is a software review. Validation is a systems review, and it has to happen early enough that a wrong requirement is still cheap to fix.

Requirements traceability is the backbone

Every requirement needs at least one test that exercises it, and every test needs to point back to the requirement it exists to satisfy. Without that link in both directions, two failure modes creep in unnoticed: requirements with no test coverage, and tests that exist but no longer map to anything current because the requirement changed underneath them.

A traceability matrix is tedious to maintain and it is the document a review board will ask for first. Build it from day one, not retroactively before a milestone review. Retroactive traceability tends to produce a matrix that matches the tests that happen to exist rather than the requirements that actually matter, which defeats the purpose of having one.

Unit and integration testing build the floor

Unit tests establish that a function behaves correctly in isolation, with every input boundary and error path exercised deliberately rather than by whatever values happen to occur during normal operation. For flight code this includes the paths nobody expects to take: a sensor returning a stale value, a command arriving with a malformed argument, a buffer at exactly its limit.

Integration testing is where the interesting defects show up, because the individual units were correct and the composition was not. Timing assumptions one module made about another, a shared resource neither module thought it owned exclusively, an error code one side checks and the other never sets. None of this is visible from reading either module alone.

Coverage numbers are a floor, not a target. A high percentage of lines executed says nothing about whether the right values were asserted at each one. Treat coverage as evidence that testing has not obviously stopped early, not as evidence that it is complete.

Model-in-the-loop, software-in-the-loop, hardware-in-the-loop

These three environments trade fidelity for speed, and a mature test programme uses all three rather than treating one as a substitute for the others.

Model-in-the-loop

MIL runs the control algorithms against a simulated plant before any embedded code exists. It is fast, cheap to iterate, and it is where algorithmic and control-law mistakes are caught while a fix still costs an afternoon rather than a firmware rebuild.

Software-in-the-loop

SIL moves to the actual flight code, compiled for the target instruction set or run on representative hardware, still against a simulated environment. This is where timing behaviour, fixed-point arithmetic, and integer overflow start to matter, because they do not exist in the MIL model at all.

Hardware-in-the-loop

HIL closes the loop with real flight hardware or a faithful electrical stand-in, real buses, and real timing, driven by a simulation fast enough to keep up with it in real time. HIL is expensive to set up and slow to iterate on, which is exactly why it belongs late in the sequence, after MIL and SIL have already removed the cheap defects. What HIL finds tends to be the failures that only exist at the hardware-software boundary: bus contention, interrupt latency, a driver that behaves differently against silicon than it did against a mock.

Fault injection: testing what you hope never happens

Nominal testing proves the software does the right thing when everything works. Fault injection proves it does something survivable when a piece of the system does not. A single-event upset flips a bit in memory. A sensor returns a value inside its valid range but physically wrong. A communication link drops mid-command. None of these are exotic; over a mission of years, most of them are expected to happen at least once.

The discipline is to inject faults the software is not expecting, not just the ones its exception handling was written around. A watchdog reset recovers cleanly because someone tested watchdog resets. The scenario worth testing is the one nobody wrote a handler for on purpose, because that is the one a real fault will resemble.

Fault injection at the SIL and HIL stages, not only at the unit level, matters because system-level response is what determines outcome. A unit test can confirm a function returns an error code. Only an integrated test can confirm the vehicle goes to a safe attitude when that error code appears during a burn.

What a launch-readiness bar actually looks like

There is no universal threshold that makes software launch-ready; every programme sets its own bar based on mission risk and consequence of failure. What the bar tends to share across programmes is structure rather than a specific number: every requirement traced to a passing test, every open anomaly dispositioned with a documented rationale rather than left open by default, every autonomous fault response exercised at least once under realistic timing, and a frozen build that is bit-for-bit the one that was tested, not a later revision that has drifted from what the review approved.

That last point catches more programmes than it should. A software baseline is only as trustworthy as the build's traceability to it. If the version running on the launch vehicle cannot be shown to be exactly the version that passed HIL testing, the testing that came before does not count for much.

None of this replaces engineering judgement, and none of it is a substitute for a team that has flown hardware before and knows where its own blind spots are. It is the scaffolding that makes that judgement defensible when someone asks how you know the software is ready.

Staring down a V&V campaign with a launch date already fixed?

We would rather have the technical conversation than the sales one.

See our flight software work