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.
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.
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.