|
Safe API Framework
Layered API framework for safety-related applications (ERTMS RBC reference targeting CENELEC EN 50128 SIL 4)
|
Status: Draft Date: 2026-08-05 Applies to: safeAPIFreamwork, RBC core's dual-channel (2-channel) vital computation, and the new sapi_channel module.
The RBC core is planned to run as two vital channels, A and B, whose results are compared so a single-channel fault is detected rather than silently trusted (a 2-out-of-2, "2oo2", pattern). Both channels are currently planned to run on the same CPU architecture (x86).
That is a real common-cause-failure (CCF) concern, not a detail to leave implicit. If both channels run identical hardware and identical compiled code, a systematic fault - a CPU-family-specific errata, a compiler codegen bug, a timing-dependent race triggered by one specific instruction sequence - can hit both channels the same way at the same moment, which defeats the reason a second channel exists. EN 50129 expects an explicit CCF analysis for any redundant/voted architecture; this ADR states the same-architecture assumption plainly and defines what SAPI does to mitigate it, rather than letting "two channels" silently imply independence it doesn't actually have.
Only the SAPI-relevant slice of a full 2oo2 vital computer design is in scope here: giving channel-level code (1) a query for its own channel identity, (2) a bounds-checked way to compare its computed result against the peer channel's result, and (3) a defined fail-safe reaction on disagreement. The physical transport that carries the peer channel's result to the local channel (serial link, dual-port RAM, network) is expected to build on sapi_ipc (ADR-001 section 4, service 5) and is not designed by this ADR.
Both channels stay on x86 - that constraint is accepted here, not re-litigated by this ADR. CCF mitigation is via build diversity: channel A and channel B are compiled from identical SAPI/application source but with two independently-configured toolchains (different compiler, and/or different optimization level and code-generation flags).
This is weaker than the N-version programming / hardware diversity techniques described for SIL3/4 architecture (independently designed implementations, or a genuinely different CPU family) - it does not protect against a specification-level or algorithmic defect, since both binaries still implement the same algorithm and will compute the same wrong answer given the same wrong logic. It does reduce the chance that a single compiler-specific codegen fault, or a CPU-microarchitecture corner case triggered by one particular instruction sequence, hits both channels identically. It is the mitigation chosen here because it's affordable without qualifying a second hardware platform, given the project's same-architecture constraint - not because it's presented as equivalent to hardware diversity.
This is not a dead end if stronger mitigation is ever needed: the OAL's backend-registration design (ADR-001 section 3.5, ADR-005) already means channel-specific code never calls the OS/CPU directly, so moving channel B to a different CPU family later is a backend swap, not an application rewrite.
A new, OS-independent module (like buffer/cast/safestate/string - pure data/logic, no backend):
This is deliberately a comparator, not a voter: with exactly two channels there is no majority to take, so the only sound reaction to disagreement is "neither channel is trusted, enter SAFE." A 2oo2 architecture is a fault detector with a fail-safe reaction, not a fault masker with continued operation - achieving continued-operation fault tolerance would need a third channel (2oo3) or channel-level recovery logic, both out of this ADR's scope.
docs/safety/CCF_ANALYSIS.md records: the same-architecture assumption; what diverse compilation catches (compiler/codegen-specific systematic faults) and explicitly does not catch (CPU-silicon-family-wide errata, shared power/environment faults, and any specification-level bug common to both channels, since they still share one algorithm); and the compensating measures expected outside SAPI's scope (independent power supplies, independent clocking, physical separation) that a full safety case will still need to state.
include/safeapi/channel/sapi_channel.h + src/channel/sapi_channel.c (target safeapi::channel, links safeapi::buffer and safeapi::safestate), per the per-feature layout (ADR-007). Build-diversity toolchain skeletons at cmake/toolchain-channel-a.cmake / cmake/toolchain-channel-b.cmake. CCF analysis at docs/safety/CCF_ANALYSIS.md.