Lansarea Rust 1.96: Evaluarea compatibilității Rust cu dezvoltarea firmware-ului pentru microcontrolere

Limbajul de programare Rust 1.96, fondat de proiectul Mozilla, dar dezvoltat acum sub auspiciile organizației non-profit independente Rust Foundation, a fost lansat. Limbajul se concentrează pe siguranța memoriei și oferă instrumente pentru obținerea unui paralelism ridicat în execuția sarcinilor, renunțând în același timp la utilizarea unui colector de gunoi și a runtime-ului (runtime-ul este redus la inițializarea și întreținerea de bază a bibliotecii standard).

Metodele de gestionare a memoriei din Rust sunt concepute pentru a elimina erorile în manipularea pointerilor și pentru a proteja împotriva problemelor care apar din gestionarea memoriei de nivel scăzut, cum ar fi accesarea memoriei după ce aceasta a fost eliberată, dereferențierea pointerilor nuli, depășirea buffer-ului și așa mai departe. Proiectul dezvoltă managerul de pachete Cargo pentru a distribui biblioteci, a facilita compilările și a gestiona dependențele. Depozitul crates.io este întreținut pentru găzduirea bibliotecilor.

Siguranța memoriei este furnizată în Rust în timpul compilării prin verificarea referințelor, urmărirea proprietății obiectului, urmărirea duratelor de viață a obiectelor (sfere de aplicare) și evaluarea corectitudinii accesului la memorie în timpul execuției codului. Rust oferă, de asemenea, protecție împotriva depășirilor de numere întregi, necesită inițializarea obligatorie a valorilor variabilelor înainte de utilizare, gestionează mai bine erorile în biblioteca standard, aplică implicit conceptul de referințe imuabile și variabile, oferă tastare statică puternică pentru a minimiza erorile logice.

Principalele inovații:

  • Modulul range a fost adăugat, implementând noi tipuri concepute pentru a înlocui tipurile depreciate Range, RangeInclusive, RangeToInclusive și RangeFrom, permițând stocarea intervalelor în structuri Copy. Tipul Range definește intervale delimitate de o valoare minimă și maximă admisă (dar neconținute în aceasta), tipul RangeFrom definește numere începând de la o valoare specificată, iar tipul RangeInclusive definește valori dintr-un interval specificat și ambele limite ale acestuia. Versiunile viitoare vor introduce, de asemenea, tipurile RangeFull și RangeTo, vechea implementare va fi migrată la core::range::legacy::*, iar sintaxa „N..M” va fi migrată la noua variantă de tip.

    Noile tipuri diferă prin faptul că, în loc de trăsătura Iterator, implementează trăsătura IntoIterator, ceea ce înseamnă că, în loc de un iterator încorporat, definesc modul de conversie a tipului într-un iterator. Această abordare permite noilor tipuri să utilizeze operația de copiere (trăsătura Copy, care indică faptul că valorile tipului pot fi duplicate prin copiere simplă), care anterior nu era disponibilă din cauza incompatibilității cu tipurile cu iteratori încorporați.
    De exemplu, noile tipuri permit stocarea limitelor unei secțiuni într-o structură copiată complet, fără a stoca separat valorile de început și de sfârșit:

    utilizați core::range::Range;

    #[derive(Clonează, Copiază)]
    pub struct Span(Interval );

    simpl Span {
    pub fn of(self, s: &str) -> &str {
    &s[self.0]
    }
    }

  • Au fost adăugate macrocomenzile „assert_matches!” și „debug_assert_matches!”, care verifică dacă o valoare se potrivește cu un model specificat și anulează execuția dacă există o discrepanță. Aceste noi macrocomenzi diferă de expresiile „assert!(matches!(..))” și „debug_assert!(matches!(..))” prin afișarea informațiilor de depanare cu valorile care au cauzat eroarea. Pentru a evita coliziunile cu macrocomenzi terțe livrate cu nume similare, noile macrocomenzi necesită importul explicit al bibliotecii „core::assert_matches”.

    folosește core::assert_matches;

    fn obține_număr_aleator() -> u32 {
    4
    }

    fn principal() {
    assert_matches!(get_random_number(), 1..=6);
    }

  • La construirea pentru ținta WebAssembly, opțiunea „--allow-undefined” pentru linker a fost întreruptă. Această opțiune permitea linkarea în prezența simbolurilor nedefinite care erau convertite în importuri din modulul „env”. La construirea pentru WebAssembly, toate simbolurile legate de link trebuie acum definite în mod implicit. Pentru a reveni la vechiul comportament, puteți utiliza variabila de mediu „RUSTFLAGS=-Clink-arg=--allow-undefined” sau expresia „#[link(wasm_import_module = "env")]” în cod.
  • O nouă porțiune a API-ului a fost mutată în categoria de stabil, inclusiv metodele și implementările de trăsături au fost stabilizate:
    • assert_matches!
    • debug_assert_matches!
    • Din pentru AssertUnwindSafe
    • Din pentru LazyCell
    • Din pentru LazyLock
    • core::range::RangeToInclusive
    • core::range::RangeToInclusiveIter
    • core::range::RangeFrom
    • core::range::RangeFromIter
    • core::range::Range
    • core::range::RangeIter
  • Managerul de pachete Cargo a remediat vulnerabilitatea CVE-2026-5223, care putea fi utilizată pentru a suprascrie codul sursă al unui alt pachet crate în memoria cache locală a pachetelor din același depozit, prin manipularea linkurilor simbolice din cadrul crate-ului. Vulnerabilitatea se manifestă doar atunci când se lucrează cu depozite de pachete terțe și nu afectează utilizatorii depozitului crates.io, deoarece crates.io interzice descărcarea pachetelor cu linkuri simbolice.

În plus, merită menționată publicarea (PDF) a rezultatelor unei analize privind adecvarea limbajului Rust pentru dezvoltarea de firmware pentru microcontrolere și sisteme integrate cu resurse limitate.
Studiul a fost realizat de STMicroelectronics cu participarea mai multor universități europene. Două echipe de dezvoltare separate au fost însărcinate cu implementarea aceluiași firmware pentru microcontrolerele STM32U585AI cu nucleu Arm Cortex-M33. Prima echipă a dezvoltat firmware-ul în C, iar a doua în Rust.

Testarea lucrării finalizate nu a relevat avantaje semnificative în utilizarea limbajului C față de Rust pentru dezvoltarea firmware-ului microcontrolerelor, comparând consumul de memorie și performanța. În plus, utilizarea runtime-ului de sistem bazat pe Rust din proiectul open-source Ariel OS a dus la un consum de memorie mai mic pentru proiectul Rust decât pentru implementarea C, care utilizează o stivă tradițională de dezvoltare firmware bazată pe biblioteca newlib.

Dimensiunea firmware-ului rezultat a fost de 84100 de octeți pentru proiectul Rust și de 76744 de octeți pentru proiectul C (cu 10% mai mică), dar consumul de RAM al firmware-ului Rust a fost semnificativ mai mic - 24640 de octeți față de 42608 octeți. În ceea ce privește performanța, la testarea prototipurilor inițiale dezvoltate pe parcursul a șase săptămâni, implementarea Rust a avut performanțe de două ori mai bune decât implementarea C, dar ambele implementări au rămas semnificativ în urma performanței maxime estimate. După patru săptămâni de optimizare, ambele implementări au obținut aproximativ același rezultat, aproape de maximul estimat.



Sursa: opennet.ru
Cumpărați găzduire de încredere pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără găzduire web fiabilă cu protecție DDoS, servere VPS VDS | ProHoster