đĄïž Ada â Safety-Critical Avionics
Ada 83/95/2005/2012 : typage fort, packages, contrats, concurrence contrÎlée. Focus : temps réel, fiabilité, auditabilité, profils (Ravenscar), et Ada/SPARK pour preuves formelles.
Ada : le langage âengineered for correctnessâ.
Contrairement au C âprofilĂ©â, Ada embarque nativement des mĂ©canismes de sĂ»retĂ© : typage strict, modularitĂ©, contrĂŽle de concurrence, et un Ă©cosystĂšme orientĂ© temps rĂ©el / safety-critical.

Ăvolution : Ada 83 â 95 â 2005 â 2012
Pourquoi Ada a été conçu (DoD), comment Ada 95 a modernisé (OOP/real-time), Ada 2012 (contracts, expressions, safety).
Ada 83Ada 95Ada 2012Concepts fondamentaux
Packages, specs/bodies, types, subtypes & ranges, exceptions (encadrées), generics, visibilité contrÎlée.
PackagesSubtypesGenericsPourquoi Ada est âsafety-friendlyâ
PrĂ©vention dâerreurs : contraintes de plage, checks runtime, initialisation, interfaces explicites, compilation stricte.
Range checksInitVisibilityConcurrence & temps réel (tasks, protected)
ModÚle de concurrence intégré : tasks, rendezvous, protected objects. Approche robuste pour RTOS avionique.
TasksProtectedRTOSRavenscar Profile
Sous-ensemble temps rĂ©el dĂ©terministe : restrictions de concurrence pour rendre lâanalyse WCET/scheduling plus âprouvableâ.
RavenscarDeterminismSchedulabilitySPARK : preuves formelles
Annotations/contracts + analyses formelles : absence dâerreurs runtime, invariants, preuves de propriĂ©tĂ©s (selon contexte).
ContractsProofNo RTEDomaines avioniques
FCS, navigation, systĂšmes embarquĂ©s temps rĂ©el, calculateurs critiques. OĂč Ada est historiquement prĂ©sent et pertinent.
FCSNavEmbeddedAda vs Deterministic C
MĂȘme objectif (fiabilitĂ©) mais approche diffĂ©rente : Ada âsafe by designâ vs C âsafe by discipline + rĂšglesâ.
C vs AdaSafetyAuditGNAT / Toolchain & certification
Compilateurs, options, profilage, coverage, analyses. Intégration V&V et preuves (DO-178C / outillage).
GNATCoverageCIChecklist Ada safety-critical
RĂšgles de style/architecture, restrictions, patterns, maĂźtrise exceptions, bornage, tĂąches et protected objects.
ReviewBoundedRTMini-projet : capteur â normalisation â clamp
Exemple Ada complet (package spec/body) + subtypes, ranges, et version SPARK-like avec contrats.
ExamplePackageContractsRéférences & ressources
Ada standard/overview, GNAT, SPARK, profils temps rĂ©el, points dâentrĂ©e vers DO-178C / process safety-critical.
AdaSPARKReal-timeTimeline simplifiée
| Version | Apports | Pourquoi ça compte en safety-critical |
|---|---|---|
| Ada 83 | base structurĂ©e, packages, typage fort | interfaces claires, modularitĂ©, rĂ©duction dâerreurs |
| Ada 95 | OOP, tùches/RT enrichi, hiérarchies | concurrence plus robuste, systÚmes RT complexes |
| Ada 2005 | améliorations RT, containers, patterns | outillage et expressivité (avec discipline) |
| Ada 2012 | contracts (pre/post), expressions, safety | spécification plus précise, meilleure vérification |
Package spec/body (modularitĂ© âcontract-firstâ)
-- file: altitude.ads (spec)
package Altitude is
subtype Feet is Integer range 0 .. 60_000;
function Get return Feet;
procedure Set (Value : Feet);
end Altitude;
-- file: altitude.adb (body)
package body Altitude is
Current : Feet := 0;
function Get return Feet is
begin
return Current;
end Get;
procedure Set (Value : Feet) is
begin
Current := Value; -- range-checked by subtype
end Set;
end Altitude;
Ce que ça âachĂšteâ en safety
- Subtypes + ranges : lâerreur âout of rangeâ devient explicite.
- Interface claire : la spec est un contrat (lisible/auditable).
- Encapsulation : état interne caché, accÚs maßtrisé.
- LisibilitĂ© : moins de âpointeursâ et de surprises implicites.
Table : Ada vs classes dâerreurs frĂ©quentes en C
| Classe de problĂšme | Approche Ada | Impact safety |
|---|---|---|
| Plages invalides | subtypes + ranges + checks | réduction erreurs silencieuses |
| Interfaces floues | spec explicite (package) + types | auditabilité accrue |
| Conversions | conversions explicites, typage strict | moins de ânarrowingâ invisible |
| Concurrence | primitives langage (tasks/protected) | modĂšle plus contrĂŽlable |
| Undefined behavior | moins de zones UB âhistoriquesâ | exĂ©cution plus prĂ©dictible |
Protected object : partage de données maßtrisé
protected type Sensor_Buffer is
procedure Put (V : Integer);
function Get return Integer;
private
Last : Integer := 0;
end Sensor_Buffer;
protected body Sensor_Buffer is
procedure Put (V : Integer) is
begin
Last := V;
end Put;
function Get return Integer is
begin
return Last;
end Get;
end Sensor_Buffer;
Lecture safety / deterministic
- Encapsulation + exclusion mutuelle gérée par le langage.
- RĂ©duit le risque de races âaccidentellesâ.
- Facilite lâanalyse de contention / latence.
Diagramme (concept) : tasks périodiques
sequenceDiagram
participant T10 as Task@10ms
participant T50 as Task@50ms
participant Buf as Protected Buffer
T10->>Buf: Put(sensor_sample)
T10->>T10: Validate/Compute/Output
T50->>Buf: Get()
T50->>T50: Health monitoring / BIT
Ravenscar est un profil (ensemble de restrictions) visant à rendre la concurrence Ada prévisible et plus facile à analyser (schedulability / WCET / contention).
Pourquoi un profil ?
| But | Ce quâon restreint | BĂ©nĂ©fice |
|---|---|---|
| Scheduling prouvable | constructions de tĂąche trop dynamiques | analyse plus simple |
| Latence bornée | rendezvous complexes / comportements imprévisibles | jitter réduit |
| AuditabilitĂ© | patterns âmagiquesâ ou implicites | comportements plus lisibles |
Ce que SPARK apporte
- Contrats (pré/post-conditions, invariants) : spécification proche du code.
- Analyse formelle : prouver absence de certaines erreurs (selon niveau dâusage).
- Moins dâambiguĂŻtĂ© : le code devient âevidence-friendlyâ.
Exemple (style contrats Ada 2012 / SPARK-like)
subtype Feet is Integer range 0 .. 60_000;
function Clamp_Feet (V : Integer) return Feet
with
Pre => True,
Post => (Clamp_Feet'Result in Feet);
function Clamp_Feet (V : Integer) return Feet is
begin
if V < Feet'First then
return Feet'First;
elsif V > Feet'Last then
return Feet'Last;
else
return Feet(V); -- explicit conversion
end if;
end Clamp_Feet;
Comment SPARK sâintĂšgre au process (vue avionique)
flowchart LR
Req[Requirements] --> Spec[Ada spec + contracts]
Spec --> Impl[Ada/SPARK Implementation]
Impl --> Proof[Formal analysis / proofs]
Impl --> Tests[Unit + Integration tests]
Impl --> Cov[Coverage (if required)]
Proof --> Pkg[Evidence package]
Tests --> Pkg
Cov --> Pkg
Zones typiques safety-critical
| Domaine | Pourquoi Ada | Contraintes |
|---|---|---|
| Flight Control | typage + modularité + concurrence maßtrisée | latence, dégradations, modes |
| Navigation / Mission | maintenabilité long terme | interfaces strictes, intégration |
| Calculateurs RT | modĂšle de tĂąches robuste | schedulability, contention |
| Safety monitors | contrats + invariants (SPARK) | preuves, tests, audit |
Pattern (concept) : boucle de contrÎle + monitoring séparé
flowchart LR
CL[Control loop task] --> OUT[Actuators]
IN[Sensors] --> CL
CL --> DIAG[Diagnostics flags]
DIAG --> MON[Monitoring task]
MON --> LOG[Bounded logging]
Table comparatif (haut niveau)
| CritĂšre | Ada | Deterministic C |
|---|---|---|
| Safety by design | fort (typage, packages, checks) | faible â dĂ©pend des rĂšgles (MISRA/CERT) |
| Concurrence | primitives langage (tasks/protected) | via RTOS + discipline + patterns |
| UB / surprises | moins de zones âdangereusesâ | fort risque si non profilĂ© |
| Auditabilité | trÚs bonne (spec/bodies) | bonne si code strict + outillage |
| ĂcosystĂšme avionique | historique & niche | massif & dominant |
| Proof (SPARK) | excellent (selon pĂ©rimĂštre) | possible mais plus âartisanalâ |
Pipeline concept (Ada safety-critical)
1) Build (warnings strict)
2) Static checks (style + rules internes)
3) Unit tests + reports
4) Integration tests (target/HIL)
5) Coverage (selon criticité)
6) Traceability & evidence package (process DO-178C)
Table : livrables âaudit-friendlyâ
| Objet | Pourquoi |
|---|---|
| spec Ada | contrat dâinterface clair et stable |
| rapports tests | preuve de vérification |
| coverage | preuve structurelle (selon exigence) |
| analyses | dĂ©tection classes dâerreurs + justifications |
[Ada Safety-Critical Checklist]
A) Types & Ranges
- [ ] Use subtypes with ranges for domain values (Feet, Degrees, etc.)
- [ ] Avoid "raw Integer" in interfaces; prefer strong domain types
- [ ] Explicit conversions only; document rationale
B) Exceptions & Error Handling
- [ ] Define a strategy: avoid exceptions in control loop (or strictly bound them)
- [ ] Return status codes or use controlled error channels
- [ ] No hidden exception propagation across safety boundaries
C) Concurrency (RT)
- [ ] Prefer protected objects for shared data
- [ ] Keep critical sections short and bounded
- [ ] Consider Ravenscar restrictions (if applicable) for analyzability
D) Determinism / Timing
- [ ] Bounded loops; no unbounded waiting
- [ ] Separate control loop tasks from monitoring/logging
- [ ] Ensure any IO is bounded and budgeted
E) Verification
- [ ] Unit tests cover edge cases (ranges, conversions, boundary values)
- [ ] Traceability Req -> Spec -> Code -> Tests -> Reports
- [ ] Coverage evidence as required
Spec : types domaine + API
package Sensor_Norm is
subtype Raw is Integer range 0 .. 4095;
subtype Q15 is Integer range -32768 .. 32767;
type Diag is record
Invalid_Count : Natural := 0;
Invalid_Range : Boolean := False;
end record;
function Normalize_Q15 (R : Raw; Min : Raw; Max : Raw; D : in out Diag) return Q15;
end Sensor_Norm;
Body : normalisation bornĂ©e, âsafe defaultâ
package body Sensor_Norm is
function Clamp_Q15 (V : Integer) return Q15 is
begin
if V < Q15'First then
return Q15'First;
elsif V > Q15'Last then
return Q15'Last;
else
return Q15(V);
end if;
end Clamp_Q15;
function Normalize_Q15 (R : Raw; Min : Raw; Max : Raw; D : in out Diag) return Q15 is
Num : Integer;
Den : Integer;
V : Integer;
begin
if Min >= Max then
D.Invalid_Count := D.Invalid_Count + 1;
D.Invalid_Range := True;
return 0; -- safe default
end if;
if (R < Min) or else (R > Max) then
D.Invalid_Count := D.Invalid_Count + 1;
D.Invalid_Range := True;
return 0; -- safe default
end if;
Num := Integer(R - Min);
Den := Integer(Max - Min);
-- map to [0..65535] then shift to [-32768..32767]
V := (Num * 65535) / Den;
V := V - 32768;
return Clamp_Q15(V);
end Normalize_Q15;
end Sensor_Norm;
Version âcontractsâ (style Ada 2012 / SPARK-like)
-- Example contract idea:
-- Normalize_Q15 returns a value always in Q15 range (guaranteed by subtype)
-- and sets diagnostics deterministically.
-- In real SPARK usage, you would add precise contracts, invariants,
-- and forbid or control certain features for proof.
Points dâentrĂ©e (liens Ă ajuster selon ta politique de sources IDEO-Lab).
1) Model your domains with subtypes + ranges (Feet, Degrees, Q15...)
2) Put stable interfaces in package specs; keep bodies small & testable
3) Prefer explicit conversions; avoid "Integer everywhere"
4) Decide your exception strategy early (often: avoid in control loop)
5) Use protected objects for shared data; tasks for periodic work
6) Consider Ravenscar (or similar restrictions) for analyzability
7) Bound loops and waiting; keep real-time path deterministic
8) Separate control loop and monitoring/logging tasks
9) Add contracts (Ada 2012) where it clarifies intent
10) Evidence-driven: tests, coverage, traceability, reports
