- Rust nudi sigurnost memorije i konkurentnosti na razini kompajlera, dok se C oslanja na disciplinu programera i vanjske alate.
- C održava jasnu prednost u ugrađenim ekosustavima, podršci proizvođača i kompatibilnosti s ogromnim naslijeđenim kodnim bazama.
- U novim projektima ključnim za sigurnost i održavanje, Rust se pojavljuje kao vrlo solidna alternativa bez žrtvovanja performansi.
- Koegzistencija C i Rust modula putem FFI-ja omogućuje postupno usvajanje, minimizirajući rizike u sustavima koji su već u produkciji.
Ako radite u ugrađeni firmware i raspravljaš između Rusta i C-aNiste sami. Sve više timova se pita isplati li se nastaviti oslanjati na tradicionalni C ili početi migrirati neke od svojih projekata na Rust, posebno kada do izražaja dođu sigurnost, održavanje i povezani sustavi.
U ovom članku ćemo, smireno, ali izravno, analizirati Kakav je doprinos Rusta i C-a u kontekstu ugrađenih sustava?Sigurnost memorije, performanse, konkurentnost, alati, ekosustav, krivulja učenja i uklapanje u stvarne projekte s puno naslijeđenog koda. Ideja je da na kraju dobijete jasne kriterije za odlučivanje kada je smislenije držati se C-a, a kada se isplati odlučiti za Rust u svom firmwareu.
Kontekst: Zašto je bitka između Rusta i C-a ključna kod ugrađenog firmvera

U svijetu sustavi vrlo niske razine, mikrokontroleri i IoT uređajiC ostaje neosporni kralj. Desetljećima je bio izvorni jezik gotovo svega što se spaja na računalo: upravljačkih programa, proizvođačkih HAL-ova, RTOS-ova, TCP/IP stogova, bootloadera i još mnogo toga. To se prevodi u milijune linija koda koje se izvode u proizvodnji u sektorima kao što su automobilska industrija, industrija, energetika i potrošačka elektronika.
Hrđa, sa svoje strane, Rođen je mnogo kasnije s vrlo jasnom opsesijomPružiti sigurnost memorije i konkurentnosti bez potrebe za sakupljanjem smeća i bez žrtvovanja performansi niske razine. Iako je u početku stekao popularnost u većim sistemskim okruženjima (preglednici, backendovi, WebAssembly), zajednica je postigla značajan napredak u embedded prostoru zahvaljujući projektima, paketima i filozofiji "sigurnost na prvom mjestu".
Pitanje koje si mnogi timovi danas postavljaju je jednostavno, ali neugodno: Ima li smisla nastaviti pisati novi firmware u C-u?Sa svim rizicima pokazivača i prelijevanja, ili je vrijeme za prelazak na Rust, barem u najkritičnijim dijelovima sustava?
Nadalje, ova odluka se ne donosi u vakuumu. Mora se uzeti u obzir da dobar dio sigurnosnih propusta koje se pojavljuju na povezanim uređajima dolaze od memorijskih pogrešaka u C/C++, nešto što su različite organizacije i vlade počele eksplicitno isticati, promovirajući korištenje sigurnijih jezika za kritični softver.
Korijeni, zrelost i ekosustav: C kao veteran i Rust kao novajlija
Domena C-a u ugrađenom okruženju oslanja se na nekoliko povijesni korijeni koje je teško zanemaritiOd 70-ih, mikrokontroleri se koriste za pisanje operativnih sustava, firmwarea svih vrsta i aplikacija gdje je svaki bajt i svaki ciklus CPU-a važan. Na temelju toga izgrađen je golemi ekosustav kompajlera, biblioteka, RTOS-ova i alata za otklanjanje pogrešaka posebno dizajniranih za mikrokontrolere.
Ova inercija ima izravnu posljedicu: Proizvođači silicija dizajniraju svoje SDK-ove i primjere imajući na umu CKada preuzmete paket podrške za novi MCU, obično ćete pronaći testirani C kompajler, C upravljačke programe, referentne primjere i vrlo uglađenu integraciju s vlasničkim ili GCC-baziranim IDE-ima. To omogućuje trenutno pokretanje C projekta na gotovo bilo kojoj platformi.
Hrđa, usporedno, Stiže kao novak, pun entuzijazma i s radikalno drugačijim pristupom.U samo nekoliko godina, zajednica je izgradila sve robusniji ekosustav za ugrađene sustave, podržan paketima poput ugrađeni-halHAL obitelji specifične za desetke ARM Cortex-M i RISC-V mikrokontrolera, te projekte poput operativnih sustava u stvarnom vremenu ili ugrađenih aplikacijskih okvira u potpunosti napisanih u Rustu.
Međutim, čak i danas postoje područja gdje Podrška za Rust nije tako neposredna ili službena kao što se čini.U vrlo specifičnim arhitekturama, neuobičajenim čipovima ili vrlo zatvorenim vlasničkim SDK-ovima, uobičajeno je da "gotova" podrška za Rust još nije dostupna te da je potrebno koristiti C omotače ili ručno raditi s blokovima. nesiguran za pristup određenim značajkama.
Ukratko, iako C ima koristi od Desetljeća zrelosti, industrijski alati i službena podrška Na gotovo svakoj ugrađenoj platformi, Rust djelomično kompenzira ovaj nedostatak tradicije modernim dizajnom, vrlo aktivnom zajednicom i jasnim fokusom na sigurnost, ali je još uvijek u fazi ekspanzije u određenim vrlo specifičnim nišama.
Sigurnost memorije: C manual model u odnosu na vlasništvo u Rustu
U C-u je upravljanje memorijom jednako moćno koliko i opasno. Jezik vam omogućuje detaljno kontrolirati svaki dodijeljeni i oslobođeni bajtMeđutim, praktički ne nameće nikakva ograničenja: vi odlučujete kada koristiti malloc, kada osloboditi memoriju, kako rukovati pokazivačima i kako pristupiti nizovima. To pruža mnogo slobode, ali također otvara vrata klasičnim pogreškama poput prelijevanja međuspremnika, visećih pokazivača, ponovne upotrebe već oslobođene memorije i curenja koja je teško pratiti.
Ova stvarnost nije teoretska: Procjenjuje se da je veliki dio sigurnosnih ranjivosti u softveru napisanom u C/C++ Ovi problemi nastaju zbog problema s memorijom. Kod ugrađenog firmvera to je posebno kritično jer ne samo da može uzrokovati pad sustava, već i nepravilno ponašanje u stvarnom vremenu ili sigurnosne ranjivosti u povezanim uređajima.
Rust rješava ovaj problem vrlo drugačijim pristupom temeljenim na svom sustav vlasništva i kreditaSvaka vrijednost u Rustu ima jednog vlasnika, s životnim vijekom koji je jasno definiran od strane kompajlera. Kada nešto izađe izvan dosega, njegova memorija se deterministički oslobađa, bez sakupljanja smeća. Istovremeno, reference se moraju pridržavati strogih pravila: ne možete imati nevažeće reference, niti možete miješati istodobna čitanja i pisanja bez sigurnih mehanizama.
To podrazumijeva da Mnoge memorijske pogreške jednostavno sprječavaju kompilacijuAko pokušate koristiti podatke nakon što ste ih premjestili, kompajler će vas upozoriti. Ako želite imati dvije promjenjive reference na isti resurs, Rust to neće dopustiti osim ako ne unesete odgovarajući odjeljak. nesiguran i prihvatiti posljedice. Nadalje, pristup nizovima i dinamičkim kolekcijama provodi provjere granica prema zadanim postavkama, sprječavajući tipična prelijevanja, posebno u razvojnim verzijama.
Praktični rezultat je da, dok se u C-u oslanjate na svoje iskustvo, preglede koda i vanjske alate kako biste spriječili pogreške u memoriji, u Rustu sam jezik djeluje kao čuvar sigurnog upravljanja memorijom čak i prije nego što se firmware pokrene na mikrokontroleru.
Performanse i determinizam u sustavima s ograničenim resursima
Jedan od razloga zašto je C desetljećima ostao na tronu firmwarea je taj što Nudi iznimno predvidljive performanseZnate koje će se instrukcije izvršiti, možete fino podesiti korištenje memorije po bajtovima i eliminirati nepotrebno opterećenje. U sustavima s ograničenom RAM-om i vrlo strogim zahtjevima u stvarnom vremenu, ova sposobnost pomicanja hardvera do njegovih granica ostaje snažna prednost.
Međutim, Rust je od temelja dizajniran kako bi pružio apstrakcije s nultom cijenomTo znači da su mnoge visokorazinske konstrukcije koje jezik nudi (itatori, generici, tipovi pogrešaka itd.) optimizirane prilikom kompajliranja kako bi se proizveo strojni kod jednako učinkovit kao onaj koji biste ručno napisali u C-u. Ne postoji sakupljač smeća koji bi uvodio nepredvidive pauze, a kompajler može ukloniti većinu sigurnosnih provjera u produkcijskim verzijama kada može pokazati da nisu potrebne.
Mjerna ispitivanja sustava iz stvarnog svijeta pokazala su da Rust se obično podudara ili je vrlo blizu performansama C-a.pa čak i nadmašiti ga u nekim slučajevima zahvaljujući modernim optimizacijama kompajlera i mogućnosti pisanja koda visoke razine koji optimizator može učinkovitije analizirati. Međutim, u vrlo uskim ugrađenim okruženjima, konačna binarna veličina i korištenje memorije ostaju važni čimbenici koje treba uzeti u obzir.
S gledišta programera firmvera, relevantno je to što Rust ne nameće automatski porez na performanseMožete nastaviti raditi blizu metala, kontrolirati strukture podataka niske razine i, kada je potrebno, pribjeći blokovima. nesiguran vrlo ograničeno na interakciju s registrima ili specifičnim hardverom, držeći ostatak koda pod sigurnosnim jamstvima jezika.
Posljedično, za većinu ugrađenih projekata gdje je C performansa bila ključni zahtjev, Hrđa je savršeno konkurentna, s dodatnom prednošću drastičnog smanjenja površine memorijskih pogrešaka i nedefiniranog ponašanja.
Konkurencija i stvarno vrijeme: ručna disciplina u C-u naspram sigurnosti tipova u Rustu
Kada počnete uvoditi istovremene zadatke, prekide i dijeljeni pristup resursima u firmware, C pruža sve dijelove: RTOS, niti, redovi čekanja, semafori, muteksi, atomske varijableProblem je u tome što, još jednom, jezik pretpostavlja da znate što radite. Ništa vas ne sprječava da čitate i pišete istu varijablu iz više nezaštićenih zadataka ili da dizajnirate shemu zaključavanja koja rezultira zastojem koji je teško reproducirati.
U tim scenarijima, sigurnost ovisi o disciplina tima, pregledi koda i testiranjeS pravim alatima, robusni konkurentni sustavi mogu se izgraditi u C-u, ali vjerojatnost uvođenja suptilnog uvjeta utrke je stvarna, posebno kako firmware raste i postaje složeniji.
Hrđa uključuje sigurnost konkurentnosti izravno u vašem sustavu tipovaKroz osobine Pošalji y SyncKompajler odlučuje koji se tipovi mogu sigurno premještati ili dijeliti između niti. Ovdje se također primjenjuju pravila posuđivanja: istovremeni promjenjivi pristup iz više konteksta nije dopušten bez korištenja sigurnih struktura kao što su mutexi, RwLock ili atomski prebrojani referentni tipovi.
Posljedica je ta Uvjeti memorijske utrke su uglavnom zabranjeni dizajnomAko pokušate proslijediti nesigurne podatke drugom zadatku bez odgovarajuće zaštite, kompajler će izbaciti grešku. Naravno, i dalje možete griješiti u logici visoke razine, ali cijela kategorija grešaka konkurentnosti je izostavljena jer se neće kompajlirati.
Za firmver koji počinje uključivati multitasking, intenzivna komunikacija ili paralelna obradaOvaj model pruža dodatni mir. Mnogi timovi cijene Rustovu "neustrašivu konkurentnost" upravo zato što smanjuje vrijeme provedeno u potrazi za neuhvatljivim bugovima povezanim s uvjetima utrke.
Produktivnost, krivulja učenja i dostupnost talenata
Jedan od najčešće ponavljanih argumenata u korist C-a u svijetu ugrađenih programskih jezika je... ogromna baza iskusnih programera koji već vladaju jezikom i njegovim alatima. Pronalaženje inženjera koji se s lakoćom mogu snalaziti u C kodu za mikrokontrolere relativno je jednostavno, posebno u sektorima koji desetljećima ulažu u ovu tehnologiju.
Hrđa, s druge strane, Još uvijek ima manju zajednicu u ugrađenom prostoruMnogi programeri su u procesu učenja i prelaska s C/C++, što znači da bi kratkoročno moglo biti skuplje regrutirati profile s dubokim iskustvom u Rustu, posebno za firmware niske razine.
Tome se dodaje i činjenica da Rustova krivulja učenja je, doduše, strmaPogotovo na početku. Model vlasništva, pravila posuđivanja, životni vijek i ograničenja promjenjivosti prisiljavaju vas da promijenite način na koji razmišljate i strukturirate svoj kod. Uobičajeno je da kompajler odbije mnoge pokušaje u prvih nekoliko mjeseci dok ne "usvojite" što očekuje od vas.
Druga strana medalje je da, kada ta početna faza završi, Produktivnost se može znatno povećati u srednjoročnom i dugoročnom razdobljuČinjenica da se mnoge pogreške uhvate tijekom kompilacije smanjuje sate otklanjanja pogrešaka, ponovljenog testiranja i suptilnih regresija, nešto što je posebno uočljivo kod proizvoda koji se moraju održavati godinama i razvijati s novim značajkama.
Što se tiče dokumentacije i resursa za obuku, Rust ima Visokokvalitetni službeni materijali i vrlo edukativna zajednicaKnjige, tečajevi, online dokumentacija i repozitoriji primjera olakšavaju cijelim timovima strukturiranu obuku, iako to zahtijeva izdvajanje vremena i proračuna za to, nešto što si ne mogu svi projekti odmah priuštiti.
Razvojni alati i iskustvo na projektima
U C projektima za ugrađene sustave uobičajeno je susresti se s heterogena mješavina alataTo uključuje razne kompajlere, vlasničke IDE-e, Makefile-ove ili CMake, prilagođene skripte i, u mnogim slučajevima, ručno upravljanje ovisnostima. Iako upravitelji ovisnosti poput vcpkg-a ili Conana postoje, nije neuobičajeno da svaka tvrtka ima vlastiti "koktel" alata i internih konvencija.
Za statičku analizu, otkrivanje curenja ili probleme konkurentnosti u C-u, obično se pribjegava vanjski uslužni programi poput Valgrinda, AddressSanitizera, ThreadSanitizera ili određenih linteraTo su moćni i dobro uspostavljeni alati, ali ih je potrebno ispravno integrirati i konfigurirati, a često nisu dio standardnog tijeka rada za sve razvojne programere u timu.
Rust pruža puno ujedinjenije iskustvo zahvaljujući Cargo, njegov sustav izgradnje i upravitelj paketaPomoću jednog alata možete stvarati projekte, dodavati ovisnosti, kompajlirati, pokretati testove, generirati dokumentaciju i upravljati verzijama. Nadalje, ekosustav uključuje alate kao što je [popis alata]. hrđanje formatirati kod i Clippy otkriti upitne obrasce kvalitete i predložiti poboljšanja.
U ugrađenom sustavu, ova homogenost je dobrodošla, jer Pojednostavljuje postavljanje novih repozitorija i suradnju između timova.Dodavanje HAL-a novom mikrokontroleru obično se svodi na uključivanje crate-a u konfiguracijsku datoteku i početak njegovog korištenja, umjesto da se morate boriti s uključenim putanjama i raspršenim skriptama za izgradnju.
To ne negira činjenicu da u nekim vrlo zatvorenim industrijskim tokovima, C alati i dalje nude dotjeraniju integraciju s hardverskim programerima, JTAG debuggerima ili certificiranim okruženjima. U tim slučajevima, Rust može zahtijevati dodatni rad kako bi se uklopio u postojeći alatni lanac, posebno ako dobavljač još ne nudi službenu podršku.
Integracija s postojećim kodom i postupno usvajanje
Malo je uređaja koji imaju luksuz pokretanja ažuriranja firmvera od nule. Češće je imati značajna baza C koda već je u produkciji Rust je prošao revizije, certifikate i godine održavanja. Potpuno prepisivanje u Rustu ne bi bilo samo izuzetno skupo već i rizično: svaki prepisani redak potencijalni je novi izvor pogrešaka.
U ovom kontekstu, C i dalje ima jasnu prednost Proširivanje sustava C s više C je trivijalnoMožete refaktorirati module, modernizirati dijelove kodne baze ili dodati značajke bez potrebe za uvođenjem nove tehnologije odjednom, što pojednostavljuje upravljanje rizicima.
Sada je Rust dizajniran da koegzistiraju relativno dobro s C-om putem FFI-ja (Foreign Function Interface - sučelja stranih funkcija)Moguće je izložiti C funkcije kao API-je koje Rust može pozivati i obrnuto, izgraditi Rust module koji izvoze sučelja s C ABI-jima za korištenje iz postojećeg firmvera. Ovaj pristup omogućuje postupno usvajanje: najosjetljivije komponente (npr. sigurnosni moduli ili složeni parseri) mogu se prepisati u Rustu dok ostatak sustava ostaje u C-u.
Međutim, granice između C-a i Rusta zahtijevaju Posebna se pozornost posvećuje definiciji struktura podataka, poravnanju, upravljanju memorijom i konvencijama pozivanja.Ta se područja obično proglašavaju nesiguran U Rustu to uključuje uspostavljanje vrlo jasnog ugovora s C svijetom kako bi se izbjegla iznenađenja. Uz pravilnu disciplinu, ova hibridna strategija pokazala se održivom čak i u velikim projektima.
Za mnoge timove, ovaj pristup koegzistenciji je razuman način da Počnite koristiti Rustu bez bacanja godina ulaganja u CIstovremeno, omogućuje vam stjecanje stvarnog iskustva s novim jezikom u kontroliranom okruženju prije nego što ga primijenite u više dijelova firmvera.
Tipični slučajevi upotrebe C-a i Rusta u ugrađenom firmveru
U području tradicionalnijih ugrađenih sustava, s jednostavni mikrokontroleri, vrlo strogi zahtjevi u stvarnom vremenu i ekosustavi uvelike usmjereni na jednog dobavljačaC ostaje prirodan izbor. Dostupnost primjera, biblioteka dobavljača, certificiranih upravljačkih programa i iskusnog osoblja uvelike smanjuje početne probleme i rizike projekta.
Također u sektorima s okviri za certifikaciju uvelike usmjereni na CNa primjer, u određenim automobilskim ili zrakoplovnim propisima, održavanje C-a kao primarnog jezika bolje je prikladno za ustaljene procese, postojeće alate za statičku analizu i revizije koje se godinama oslanjaju na ovaj tehnološki paket.
S druge strane, hrđa savršeno pristaje novi projekti gdje su sigurnost i dugoročna robusnost prioritetiIoT uređaji izloženi internetu, sustavi gdje ranjivost može imati ozbiljan utjecaj ili firmver koji će se godinama ažurirati na daljinu mogu imati velike koristi od jezika koji drastično smanjuje memorijske pogreške i prisiljava eksplicitno rukovanje pogreškama i stanjima.
Nadalje, u okruženjima gdje oprema nema veliki namjenski odjeli za kontrolu kvalitete ili sigurnostRust djeluje kao svojevrsna ugrađena sigurnosna mreža. Mnoge prakse koje se "preporučuju" u C-u (provjeravanje svakog pokazivača, neignoriranje kodova pogrešaka, izbjegavanje nekonzistentnih međustanja) postaju obvezni zahtjevi za kompajliranje koda.
Konačno, Rustov modularni pristup i njegov ekosustav sanduka čine ga posebno privlačnim za projekti koji žele dijeliti logiku u različitim okruženjima (na primjer, dijeljenje poslovne logike između backenda i firmwarea ili ponovna upotreba parsera i kriptografskih biblioteka na više platformi), pod uvjetom da se vodi računa o specifičnom niskorazinskom dijelu za svaki cilj.
Uz sve to, slika koja se pojavljuje je jasna: C ostaje nepobjediv kao jezik kontinuiteta i kompatibilnosti u većem dijelu današnjeg ugrađenog firmvera, dok se Rust pozicionira kao vrlo jak kandidat za nove razvoje gdje su sigurnost i dugoročno održavanje jednako važni kao i same performanse.
Kako odlučiti: praktični kriteriji za odabir jezika u vašem sljedećem firmveru
Izbor između Rusta i C-a za određeni embedded projekt rijetko je isključivo tehničko pitanje; Stvarnost vašeg tima, vaši rokovi i vaši poslovni zahtjevi također dolaze do izražaja.Neki kriteriji koji često čine razliku su količina naslijeđenog koda, potrebe za certifikacijom, sigurnosna kritičnost i vrijeme dostupno za obuku tima.
Ako vaša organizacija odugovlači Godine stabilnog, dobro testiranog C koda s utvrđenim procesimaA ako su vaše trenutne potrebe više vezane uz proširenje funkcionalnosti nego uz redizajn arhitekture, savršeno je logično držati se C-a. Promjena jezika bez uvjerljivog razloga može donijeti više problema nego rješenja, posebno u sustavima koji već ispunjavaju svoje ciljeve performansi i pouzdanosti.
S druge strane, ako započinjete novi proizvod bez jake ovisnosti o naslijeđenom koduPogotovo ako planirate živjeti povezani, ažurirati na daljinu i rukovati osjetljivim podacima, ulaganje vremena u usvajanje Rusta može biti vrlo vrijedan pothvat. Početna krivulja učenja kompenzirana je robusnijom i lakšom za održavanje kodnom bazom tijekom godina.
Također ima smisla razmotriti međupristupe, kao što je Započnite s uvođenjem Rusta u izoliranim i dobro definiranim modulima iz postojećih projekata: na primjer, komunikacijski slojevi gdje želite jamčiti da nema prelijevanja ili komponente koje upravljaju ključevima i kriptografijom. To vam omogućuje praktičnu procjenu utjecaja Rusta u vašem specifičnom kontekstu prije donošenja širih odluka.
Na kraju, umjesto traženja "ukupnog pobjednika", korisno je vidjeti Rust i C kao komplementarni alati unutar istog arsenalaSvaki ima vrlo jasne prednosti i očita ograničenja; ključno je iskoristiti najbolje od oba tamo gdje dodaju najveću vrijednost u životnom ciklusu vašeg firmvera.
Gledajući širu sliku, jasno je da C održava vodeću ulogu u ugrađenom firmveru zahvaljujući svojim dubokim korijenima, podršci proizvođača i apsolutnoj kontroli hardvera.No Rust je također prerastao iz noviteta u vrlo ozbiljnu alternativu u novim razvojima, posebno tamo gdje su sigurnost, sigurna konkurentnost i održavanje ključni. Za mnoge timove, najrazumniji pristup je kombinirati kontinuiranu upotrebu C-a s postupnim usvajanjem Rusta u kritičnim područjima, čime se grade robusniji ugrađeni sustavi bez napuštanja svega što je naučeno tijekom posljednjih nekoliko desetljeća.
Strastveni pisac o svijetu bajtova i tehnologije općenito. Volim dijeliti svoje znanje pisanjem, a to je ono što ću učiniti na ovom blogu, pokazati vam sve najzanimljivije stvari o gadgetima, softveru, hardveru, tehnološkim trendovima i još mnogo toga. Moj cilj je pomoći vam da se snađete u digitalnom svijetu na jednostavan i zabavan način.

