Le modèle devient le firmware. En Rust.
Simuler un système, c’est la moitié du travail ; le livrer en est l’autre moitié. DjiniousLab génère le code d’un contrôleur que vous avez conçu sous forme de schéma-bloc en une crate Rust autonome et sûre en mémoire — prouvée équivalente au modèle, compilée de manière croisée pour un microcontrôleur, et attestée cryptographiquement. C’est ce que fait Embedded Coder de Simulink, sauf que l’artefact généré est du Rust, pas du C — la différence qui compte quand le code va quelque part de critique pour la sécurité.
Une seule commande du schéma-bloc à la crate.
Une boucle de commande écrite comme un schéma-bloc .djl s’abaisse en une représentation intermédiaire plate, et `djinious codegen` la transforme en crate Cargo : une struct State, un constructeur de conditions initiales, et une fonction `pub fn step(state, inputs, t, dt) -> Outputs` qui fait avancer le contrôleur d’un tick. Ajoutez `--no-std` et elle émet un firmware embarquable utilisant libm pour le calcul au lieu de la bibliothèque standard. Les trois mêmes boucles de pilote automatique Djinborn T4 — altitude, attitude, position — que le programme quadricoptère fait voler en simulation se génèrent directement en Rust.
Des boucles fermées, pas seulement des chaînes en anticipation.
Un contrôleur est une boucle de rétroaction — la sortie de l’intégrateur reboucle sur l’erreur. La génération de code émettait auparavant les blocs dans l’ordre de déclaration, si bien que la sortie d’un intégrateur rebouclé pouvait être référencée avant d’être liée : du Rust qui ne compile pas. La correction émet les liaisons de sortie dans l’ordre topologique, en traitant les sorties d’intégrateurs et de retards comme des sources sans dépendance (leur sortie lit un état stocké), ce qui brise le cycle ; les mises à jour d’état sont différées à la fin du pas. Une boucle de rétroaction sans élément d’état pour la briser est une véritable boucle algébrique, et génère désormais honnêtement une erreur au lieu de produire du code cassé. La suite complète de tests de génération de code — 765 tests unitaires plus 523 allers-retours compilation-exécution — reste au vert.
Le code généré fait la différence.
Sûr en mémoire par construction
Pas de débordement de tampon, pas d’utilisation après libération, pas de comportement indéfini — les classes de bugs que les normes de sécurité passent des pages entières à essayer d’exclure du C généré sont absentes de Rust grâce aux garanties propres du langage.
Embarquable, no_std
Les crates sont `#![no_std]` avec libm pour le calcul transcendant — pas d’allocateur, pas de système d’exploitation. Elles se compilent de manière croisée pour une cible bare-metal Cortex-M4F (STM32F4) comme vérifié ici, prêtes pour un HAL de carte et un ISR de minuteur.
Provenance attestée
`djinious attest` lie le modèle au SHA-256 du firmware dans une Statement in-toto ; `djinious sign` la signe avec cosign. Le lien de chaîne d’approvisionnement de « ce modèle » à « ce binaire » que la certification exige.
Équivalence prouvée
Un banc logiciel-dans-la-boucle exécute le modèle et le firmware côte à côte et les différencie — le code généré est conditionné à correspondre à la référence, pas simplement supposé le faire.
Chaque affirmation est une commande que vous pouvez réexécuter.
L’ensemble du pipeline est fait d’artefacts réels — abaissement, génération de code, compilation, exécution, comparaison, compilation croisée, attestation — pas une démonstration de diapositives.
Étape
- Boucles générées et compilées : 3 / 3
- Écart SIL (firmware vs modèle) : < 1,2 %
- Compilation croisée embarquée : thumbv7em
- Provenance : in-toto v1
- Suite de tests de génération de code : au vert
Résultat
- Boucles générées et compilées : altitude · attitude · position
- Écart SIL (firmware vs modèle) : de la plage, les trois
- Compilation croisée embarquée : rlib Cortex-M4F
- Provenance : empreinte modèle → firmware
- Suite de tests de génération de code : 765 + 523 allers-retours
Génération de code par flux de signaux, de qualité embarquée.
Le code généré est en Euler explicite à pas fixe — la norme embarquée — sur la palette de blocs de signaux du catalogue (constante, somme, gain, intégrateur, saturation, oscilloscope et consorts), qui est exactement ce dont un contrôleur est constitué. Les composants DJL non linéaires personnalisés ne se génèrent pas encore en code ; ils s’exécutent dans le worker Julia. Flasher sur une carte spécifique nécessite une crate HAL et un point d’entrée `cortex-m-rt`, et `sign` / `verify` nécessitent un cosign local — l’intégration de carte et la signature CI dépassent le cadre de ce programme. Ce qu’il livre, c’est l’épine dorsale de la conception orientée modèle faite en Rust : concevoir, simuler, générer, prouver l’équivalence et tracer — de bout en bout, sur un seul outil.