Djinious
Generazione di codice embeddedMetodi di ingegneria

Modello → firmware Rust

Dal design basato su modello al codice distribuibile, alla maniera Rust-first — un autopilota progettato come schemi a blocchi, generato in codice Rust #![no_std], dimostrato equivalente al modello, cross-compilato per un target Cortex-M, e attestato per la provenienza.

DjiniousLab
Tre grafici software-in-the-loop — altitudine, assetto e posizione — dove il firmware Rust generato da codice (tratteggiato) segue il modello DjiniousLab (continuo) entro una frazione di punto percentuale
cascata dell’autopilota → Rust
3 anellicascata dell’autopilota → Rust
deviazione firmware-modello
< 1.2%deviazione firmware-modello
embeddable, matematica libm
#![no_std]embeddable, matematica libm
cross-compilazione verificata
Cortex-M4Fcross-compilazione verificata
attestazione di provenienza
in-totoattestazione di provenienza
Rust, non C
memory-safeRust, non C

Il modello diventa il firmware. In Rust.

Simulare un sistema è metà del lavoro; distribuirlo è l’altra metà. DjiniousLab genera il codice di un controllore che hai progettato come schema a blocchi in un crate Rust autonomo e memory-safe — dimostrato equivalente al modello, cross-compilato per un microcontrollore, e attestato crittograficamente. È ciò che fa l’Embedded Coder di Simulink, tranne che l’artefatto generato è Rust, non C — la differenza che conta quando il codice è destinato a qualcosa di safety-critical.

Un solo comando dallo schema a blocchi al crate.

Un anello di controllo scritto come schema a blocchi .djl si abbassa a una rappresentazione intermedia piatta, e `djinious codegen` lo trasforma in un crate Cargo: una struct State, un costruttore per le condizioni iniziali, e una `pub fn step(state, inputs, t, dt) -> Outputs` che fa avanzare il controllore di un tick. Aggiungi `--no-std` e genera firmware embeddable con libm per la matematica al posto della libreria standard. Gli stessi tre anelli dell’autopilota Djinborn T4 — altitudine, assetto, posizione — che il programma del quadricottero fa volare in simulazione vengono generati direttamente in Rust.

DjiniousLab
Il sorgente Rust no_std generato per il controllore di assetto: una struct State, un costruttore initial(), e una funzione step() che legge lo stato e poi calcola la legge di controllo a cascata
Non pseudocodice — il vero controllore di assetto generato `#![no_std]`. Ogni stato dell’integratore viene letto in cima (come sorgente senza dipendenze), la legge a cascata assetto-esterno / velocità-interna calcola nel mezzo, e gli aggiornamenti di stato sono rimandati in fondo. Leggibile, deterministico e privo della libreria standard.

Anelli chiusi, non solo catene feedforward.

Un controllore è un anello di retroazione — l’uscita dell’integratore si richiude sull’errore. Il codegen emetteva i blocchi nell’ordine di dichiarazione, così l’uscita di un integratore retroazionato poteva essere referenziata prima di essere assegnata: Rust che non compila. La correzione emette i binding di uscita in ordine topologico, trattando le uscite di integratori e ritardi come sorgenti senza dipendenze (la loro uscita legge lo stato memorizzato), il che spezza il ciclo; gli aggiornamenti di stato sono rimandati alla fine dello step. Un anello di retroazione senza alcun elemento di stato che lo spezzi è un vero anello algebrico e ora genera un errore onesto invece di produrre codice rotto. L’intera suite di codegen — 765 unit test più 523 round trip di compilazione ed esecuzione — resta verde.

DjiniousLab
Tre grafici software-in-the-loop dove la traiettoria del firmware Rust generato si sovrappone alla traiettoria del modello per gli anelli di altitudine, assetto e posizione
Prova software-in-the-loop: ogni anello eseguito attraverso il solver del modello accurato (continuo) e attraverso il firmware generato a passo fisso (tratteggiato), allineati e differenziati. Il firmware riproduce ogni sovraelongazione, tempo di assestamento e regime permanente — deviazione massima 0,09% / 1,18% / 0,24% del range. Il codegen è esatto; il residuo è solo discretizzazione a passo fisso.

Il codice generato è l’elemento distintivo.

Memory-safe per costruzione

Nessun buffer overrun, nessun use-after-free, nessun comportamento indefinito — le classi di bug che gli standard di sicurezza dedicano pagine intere a cercare di escludere dal C generato sono assenti da Rust per le garanzie stesse del linguaggio.

Embeddable, no_std

I crate sono `#![no_std]` con libm per la matematica trascendente — nessun allocatore, nessun sistema operativo. Vengono cross-compilati per un target bare-metal Cortex-M4F (STM32F4) come verificato qui, pronti per una HAL di scheda e un ISR timer.

Provenienza attestata

`djinious attest` vincola il modello allo SHA-256 del firmware in una Statement in-toto; `djinious sign` la firma con cosign. Il collegamento di supply chain da “questo modello” a “questo binario” che la certificazione richiede.

Equivalenza dimostrata

Un harness software-in-the-loop esegue il modello e il firmware fianco a fianco e ne calcola la differenza — il codice generato è sottoposto a gate sulla corrispondenza con il riferimento, non semplicemente presunto tale.

Ogni affermazione è un comando che puoi rieseguire.

L’intera pipeline è fatta di artefatti reali — abbassamento, codegen, compilazione, esecuzione, diff, cross-compilazione, attestazione — non una demo da slide.

Fase

  • Anelli generati e compilati: 3 / 3
  • Deviazione SIL (firmware vs modello): < 1,2%
  • Cross-compilazione embedded: thumbv7em
  • Provenienza: in-toto v1
  • Suite di test codegen: verde

Risultato

  • Anelli generati e compilati: altitudine · assetto · posizione
  • Deviazione SIL (firmware vs modello): del range, tutti e tre
  • Cross-compilazione embedded: rlib Cortex-M4F
  • Provenienza: digest modello → firmware
  • Suite di test codegen: 765 + 523 round trip

Codegen a flusso di segnale, di livello embedded.

Il codice generato è forward-Euler a passo fisso — la norma dell’embedded — sulla tavolozza di blocchi di segnale del catalogo (costante, somma, guadagno, integratore, saturazione, scope e affini), che è esattamente ciò da cui è costruito un controllore. I componenti DJL non lineari personalizzati non generano ancora codice; vengono eseguiti nel worker Julia. Flashare su una scheda specifica richiede un crate HAL e un entry point `cortex-m-rt`, e `sign` / `verify` richiedono un cosign locale — l’integrazione con la scheda e la firma in CI esulano da questo programma. Ciò che offre è la spina dorsale del design basato su modello fatto in Rust: progettare, simulare, generare, dimostrare l’equivalenza e tracciare — end to end, su un unico strumento.