Udgivelsen af Rust 1.96. Vurdering af Rusts anvendelighed til at skabe firmware til mikrokontrollere

Udgivelsen af programmingssproget Rust 1.96 er blevet offentliggjort, oprindeligt baseret på projektet Mozilla, men nu udviklet under beskyttelse af den uafhængige, non-profit organisation Rust Foundation. Sproget fokuserer på sikker håndtering af hukommelse og tilbyder midler til at opnå høj parallellisme i udførelsen af opgaver, uden brug af garbage collector og runtime (runtime er begrænset til grundlæggende initialisering og vedligeholdelse af standardbiblioteket).

Metoderne til hukommelseshåndtering i Rust har til formål at eliminere fejl i forbindelse med manipulation af pegepunkter og beskytte mod problemer der opstår ved lavniveau hukommelseshåndtering, såsom adgang til hukommelse efter den er frigivet, de-referering af nulpegepunkter, overskridelse af buffergrænser osv. For distribution af biblioteker, sikring af bygning og håndtering af projektafhængigheder, udvikles pakkehåndteringssystemet Cargo. For placering af biblioteker understøttes et repository på crates.io.

Sikker håndtering af hukommelse sikres i Rust under kompilering ved referencekontrol, sporing af ejerskab af objekter, hensyntagen til livstid af objekter (synlighed) og vurdering af korrekt adgang til hukommelse under kodeudførelse. Rust tilbyder også midler til beskyttelse mod heltals-overløb, kræver obligatorisk initialisering af variabelværdier før brug, håndterer fejl bedre i standardbiblioteket, anvender konceptet med uforanderlige (immutable) referencer og variabler som standard og tilbyder stærk statisk typisering for at minimere logiske fejl.

Hovednyhederne:

  • Der er tilføjet en range-modul med implementering af nye typer, der udvikles som erstatning for de forældede typer Range, RangeInclusive, RangeToInclusive og RangeFrom, og som muliggør opbevaring af intervaller i Copy-strukturer. Typen Range definerer intervaller, som er begrænset af et minimums- og maksimumsværdi (men ikke inklusiv dem), typen RangeFrom definerer tal, der starter fra en angivet værdi, mens typen RangeInclusive — værdierne i det angivne interval med begge deres grænser. I fremtidige udgivelser vil typerne RangeFull og RangeTo blive tilføjet, den gamle implementering vil blive flyttet til core::range::legacy::*, og syntaksen "N..M" vil blive oversat til den nye version af typerne.

    De nye typer er kendetegnet ved, at de i stedet for trait Iterator implementerer trait IntoIterator, dvs. at de definerer, hvordan man konverterer typen til en iterator i stedet for at bruge den indbyggede iterator. Denne tilgang muliggør brugen af kopieringsoperationen (trait Copy, der viser, at værdier af typen kan kopieres ved simpel kopiering), som tidligere var utilgængelig på grund af inkompatibilitet med typer med indbyggede iteratorer.
    For eksempel giver de nye typer mulighed for at gemme skivernes grænser i en struktur, der fuldt ud kopieres uden separat gemme af start- og slutværdier:

    use core::range::Range;

    #[derive(Clone, Copy)]
    pub struct Span(Range);

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

  • Makroerne "assert_matches!" og "debug_assert_matches!" er blevet tilføjet, som kontrollerer, om værdien matcher den specificerede skabelon og krakelerer, hvis der er uoverensstemmelse. De adskiller sig fra udtrykkene "assert!(matches!(..))" og "debug_assert!(matches!(..))" ved at give debug-information med værdierne, der medførte fejlen. For at undgå konflikter med tredjeparts-makroer, der leveres med lignende navne, kræver de nye makroer en eksplicit import af biblioteket "core::assert_matches".

    use core::assert_matches;

    fn get_random_number() -> u32 {
    4
    }

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

  • Ved opbygning til målplatformen WebAssembly er overførslen af linker-argumentet «—allow-undefined» stoppet, hvilket gjorde det muligt at linke med udefinerede symboler, der blev konverteret til import fra modulet «env». Ved opbygning til WebAssembly skal alle linker-relaterede symboler nu som standard være defineret. For at genskabe den gamle adfærd kan miljøvariablen «RUSTFLAGS=-Clink-arg=—allow-undefined» eller udtrykket ‘#[link(wasm_import_module = «env»)]’ anvendes i koden.
  • En ny batch af API'er er blevet klassificeret som stabile, herunder stabilisering af metoder og implementeringer af traits:
    • assert_matches!
    • debug_assert_matches!
    • From for AssertUnwindSafe
    • From for LazyCell
    • From for LazyLock
    • core::range::RangeToInclusive
    • core::range::RangeToInclusiveIter
    • core::range::RangeFrom
    • core::range::RangeFromIter
    • core::range::Range
    • core::range::RangeIter
  • I pakkehåndteringssystemet Cargo er sårbarheden CVE-2026-5223 blevet elimineret, som kan bruges til at overskrive kildekoden for et andet crate-pakke i den lokale cache af pakker fra samme repository gennem manipulation med symbolske links inde i crate-pakkerne. Sårbarheden optræder kun ved brug af tredjeparts pakke-repositories og berører ikke brugerne af crates.io, da upload af pakker med symbolske links er forbudt i crates.io.

Det kan også nævnes, at resultaterne af analysen af programmeringssproget Rusts egnethed til udvikling af firmware til mikrocontrollere og indlejrede systemer med begrænsede ressourcer er blevet offentliggjort (PDF).
Undersøgelsen blev udført af STMicroelectronics med deltagelse af flere europæiske universiteter. To isolerede udviklingsteams fik til opgave at implementere den samme firmware til STM32U585AI mikrocontrollere med Arm Cortex-M33 kerner. Det første team skabte firmwaren i C, mens det andet gjorde det i Rust.

Testning af det udførte arbejde viste ingen væsentlige fordele ved at bruge C i stedet for Rust ved udvikling af firmware til mikrocontrollere, når man sammenlignede hukommelsesforbrug og ydeevne. Desuden gjorde brugen af det system-runtime skrevet i Rust fra det åbne projekt Ariel OS det muligt at opnå et lavere hukommelsesforbrug i Rust-projektet end i C-implementeringen, der brugte en traditionel stack til firmwareudvikling baseret på newlib-biblioteket.

Den endelige firmware-størrelse var 84100 bytes i projektet på Rust og 76744 bytes i projektet på C (10% mindre), men forbruget af RAM i firmwaren på Rust var markant lavere – 24640 bytes mod 42608 bytes. Hvad angår ydeevnen, viste test af de første prototyper, der blev udviklet på 6 uger, at implementeringen på Rust var to gange hurtigere end implementeringen på C, men begge implementeringer lå betydeligt under den beregnede maksimale ydeevne. Efter 4 uger afsat til optimering, opnåede begge implementeringer omtrent samme resultat, tæt på den beregnede maksimum.



Kilde: opennet.ru
Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster