DO-178C is the standard that airborne software is certified against. It does not prescribe a programming language. It asks for evidence: requirements, traceability from requirements to code and tests, and verification that the code does what the requirements say. The language changes how hard that evidence is to produce, and which errors are left for verification to find.
Design assurance levels
DO-178C sets the amount of evidence by the software's Design Assurance Level (DAL), which follows from the worst effect a failure can have on the aircraft:
| Level | Failure condition | Objectives |
|---|---|---|
| A | Catastrophic | 71 |
| B | Hazardous | 69 |
| C | Major | 62 |
| D | Minor | 26 |
| E | No safety effect | None |
Level D needs high-level requirements and requirements-based testing, but no structural code coverage analysis. Most of the effort goes into the requirements and the tests against them, so every defect class the language removes is one fewer thing those tests have to catch.
What Rust removes
In C, a large share of embedded defects are memory errors, and every one of them has to be caught by review or test. Safe Rust makes them compile errors:
- Buffer overruns. Slices carry their length, and every index is checked.
- Use-after-free and dangling pointers. The borrow checker proves that every reference outlives its use.
- Data races. Data shared with an interrupt handler must go through a type that makes the sharing safe.
- Uninitialised memory. Every variable is initialised before it is read.
Two settings make this a property of the whole program instead of a habit. #![forbid(unsafe_code)] on the application crates means no code in them can opt out of the checks; only a small board support layer touches hardware registers. no_std with no heap allocator means all memory is fixed at build time, so the memory map is known and the program cannot run out of memory at run time.
What Rust does not remove
- Wrong requirements and logic errors. The compiler checks that the code is memory-safe, not that it does the right thing. Requirements-based testing is still the core of the evidence.
- Panics. A failed bounds check stops the program instead of corrupting memory. That is safer, but the design still needs a defined response, and the code should avoid paths that can panic.
- Process. Plans, standards, reviews, configuration management and quality assurance are the same in any language.
The toolchain
DO-178C treats the compiler as a tool whose output is verified by testing the executable, so a qualified compiler is not normally required. Some programs still ask for one. Ferrocene is a qualified distribution of the Rust compiler, qualified for ISO 26262 and IEC 61508, and gives those programs a toolchain with qualification evidence behind it.
In practice
Our VITA 46.11 IPMC is written this way: no C, no heap, no RTOS, forbid(unsafe_code) in all IPMI logic, and designed to meet DO-178C Level D with a Level D plan, gap analysis and tool assessment. It builds with Ferrocene, and the same IPMI code runs on a PC as an emulator, where 1,253 tests run on every build.