Project Oxygen & Ideo-LabIDEO LAB Dashboard 2026

đŸ›Ąïž 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.

Packages & modularité Strong typing Real-time Ravenscar / Scheduling
IdĂ©e clĂ© : Ada rĂ©duit drastiquement les classes d’erreurs (casts implicites, dĂ©bordements non maĂźtrisĂ©s, aliasing sauvage, interfaces floues) en les rendant illĂ©gales ou trĂšs visibles.
Ada safety-critical hero
1.1 Fondations

É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 2012
1.2 Core

Concepts fondamentaux

Packages, specs/bodies, types, subtypes & ranges, exceptions (encadrées), generics, visibilité contrÎlée.

PackagesSubtypesGenerics
1.3 Safety

Pourquoi Ada est “safety-friendly”

PrĂ©vention d’erreurs : contraintes de plage, checks runtime, initialisation, interfaces explicites, compilation stricte.

Range checksInitVisibility
2.1 Real-Time

Concurrence & temps réel (tasks, protected)

ModÚle de concurrence intégré : tasks, rendezvous, protected objects. Approche robuste pour RTOS avionique.

TasksProtectedRTOS
2.2 Critique

Ravenscar Profile

Sous-ensemble temps rĂ©el dĂ©terministe : restrictions de concurrence pour rendre l’analyse WCET/scheduling plus “prouvable”.

RavenscarDeterminismSchedulability
2.3 Preuves

SPARK : preuves formelles

Annotations/contracts + analyses formelles : absence d’erreurs runtime, invariants, preuves de propriĂ©tĂ©s (selon contexte).

ContractsProofNo RTE
3.1 Contexte

Domaines avioniques

FCS, navigation, systĂšmes embarquĂ©s temps rĂ©el, calculateurs critiques. OĂč Ada est historiquement prĂ©sent et pertinent.

FCSNavEmbedded
3.2 Comparatif

Ada vs Deterministic C

MĂȘme objectif (fiabilitĂ©) mais approche diffĂ©rente : Ada “safe by design” vs C “safe by discipline + rĂšgles”.

C vs AdaSafetyAudit
3.3 Tooling

GNAT / Toolchain & certification

Compilateurs, options, profilage, coverage, analyses. Intégration V&V et preuves (DO-178C / outillage).

GNATCoverageCI
4.1 Pratique

Checklist Ada safety-critical

RĂšgles de style/architecture, restrictions, patterns, maĂźtrise exceptions, bornage, tĂąches et protected objects.

ReviewBoundedRT
4.2 Atelier

Mini-projet : capteur → normalisation → clamp

Exemple Ada complet (package spec/body) + subtypes, ranges, et version SPARK-like avec contrats.

ExamplePackageContracts
4.3 Réfs

Références & ressources

Ada standard/overview, GNAT, SPARK, profils temps rĂ©el, points d’entrĂ©e vers DO-178C / process safety-critical.

AdaSPARKReal-time
1.1 Évolution : Ada 83 / 95 / 2005 / 2012 (vue avionique)
Timeline simplifiée
VersionApportsPourquoi ça compte en safety-critical
Ada 83base structurĂ©e, packages, typage fortinterfaces claires, modularitĂ©, rĂ©duction d’erreurs
Ada 95OOP, tùches/RT enrichi, hiérarchiesconcurrence plus robuste, systÚmes RT complexes
Ada 2005améliorations RT, containers, patternsoutillage et expressivité (avec discipline)
Ada 2012contracts (pre/post), expressions, safetyspécification plus précise, meilleure vérification
Lecture avionique : Ada a Ă©tĂ© conçu pour des projets longs, multi-Ă©quipes, oĂč la maintenabilitĂ© et la preuve de sĂ»retĂ© sont aussi importantes que la performance.
1.2 Concepts fondamentaux Ada (packages, types, visibilité)
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.
L’idĂ©e n’est pas d’éviter tous les bugs “par magie”, mais de rendre les classes d’erreurs rares, visibles, et testables.
1.3 Pourquoi Ada est “safety-friendly” (safe by design)
Table : Ada vs classes d’erreurs frĂ©quentes en C
Classe de problĂšmeApproche AdaImpact safety
Plages invalidessubtypes + ranges + checksréduction erreurs silencieuses
Interfaces flouesspec explicite (package) + typesauditabilité accrue
Conversionsconversions explicites, typage strictmoins de “narrowing” invisible
Concurrenceprimitives langage (tasks/protected)modĂšle plus contrĂŽlable
Undefined behaviormoins de zones UB “historiques”exĂ©cution plus prĂ©dictible
Important : en safety-critical, on choisit souvent des sous-ensembles/profils (et des rĂšgles internes) mĂȘme en Ada, pour renforcer le dĂ©terminisme et la vĂ©rifiabilitĂ©.
2.1 Concurrence Ada : tasks & protected objects (temps réel)
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.
Dans les profils “stricts”, on limite encore certaines constructions de concurrence pour rendre le scheduling prouvable.
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
      
2.2 Ravenscar Profile : Ada temps réel déterministe (sous-ensemble)

Ravenscar est un profil (ensemble de restrictions) visant à rendre la concurrence Ada prévisible et plus facile à analyser (schedulability / WCET / contention).

Pourquoi un profil ?
ButCe qu’on restreintBĂ©nĂ©fice
Scheduling prouvableconstructions de tĂąche trop dynamiquesanalyse plus simple
Latence bornéerendezvous complexes / comportements imprévisiblesjitter réduit
AuditabilitĂ©patterns “magiques” ou implicitescomportements plus lisibles
En avionique, la question n’est pas “peut-on le coder ?” mais “peut-on le prouver et le maintenir sur 20 ans ?”.
2.3 SPARK : Ada + preuves formelles (contrats, absence d’erreurs runtime)
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”.
SPARK n’est pas “magique” : on choisit des sous-ensembles, on structure, on prouve ce qui est critique, et on garde des tests/coverage en complĂ©ment.
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;
        
Lecture deterministic : bornage explicite + types/ranges + conversion contrÎlée = comportement stable et auditable.
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
        
En pratique : proofs + tests + coverage + traceability. On cumule les preuves, on ne remplace pas tout par du “formel”.
3.1 Domaines avioniques : oĂč Ada est pertinent
Zones typiques safety-critical
DomainePourquoi AdaContraintes
Flight Controltypage + modularité + concurrence maßtriséelatence, dégradations, modes
Navigation / Missionmaintenabilité long termeinterfaces strictes, intégration
Calculateurs RTmodĂšle de tĂąches robusteschedulability, contention
Safety monitorscontrats + 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]
      
3.2 Ada vs Deterministic C (lecture engineering)
Table comparatif (haut niveau)
CritĂšreAdaDeterministic C
Safety by designfort (typage, packages, checks)faible → dĂ©pend des rĂšgles (MISRA/CERT)
Concurrenceprimitives langage (tasks/protected)via RTOS + discipline + patterns
UB / surprisesmoins de zones “dangereuses”fort risque si non profilĂ©
AuditabilitétrÚs bonne (spec/bodies)bonne si code strict + outillage
Écosystùme avioniquehistorique & nichemassif & dominant
Proof (SPARK)excellent (selon pĂ©rimĂštre)possible mais plus “artisanal”
Conclusion pratique : Ada peut rĂ©duire le coĂ»t de sĂ»retĂ© via le design du langage, tandis que le C impose une discipline stricte (rĂšgles + tooling + V&V). Les deux peuvent ĂȘtre certifiĂ©s, l’optimisation dĂ©pend du contexte.
3.3 Tooling : GNAT, build, analyses, coverage, CI
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”
ObjetPourquoi
spec Adacontrat d’interface clair et stable
rapports testspreuve de vérification
coveragepreuve structurelle (selon exigence)
analysesdĂ©tection classes d’erreurs + justifications
MĂȘme avec Ada, en certification : ce qui compte est le process + preuves. Ada rend souvent les preuves plus “propres”.
4.1 Checklist Ada safety-critical (revue de code & conception)
[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
      
4.2 Mini-projet : capteur → normalisation → clamp (Ada package complet)
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.
        
En safety-critical, l’intĂ©rĂȘt : la spec est dĂ©jĂ  “proche requirement”, et les types imposent des invariants.
⚙ Quickstart Ada (style avionique)
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