- Rust ponuja varnost pomnilnika in sočasnosti na ravni prevajalnika, medtem ko se C zanaša na disciplino razvijalcev in zunanja orodja.
- C ohranja jasno prednost na področju vgrajenih ekosistemov, podpore proizvajalcev in združljivosti z ogromnimi starejšimi kodnimi bazami.
- V novih projektih, ki so ključni za varnost in vzdrževanje, se Rust pojavlja kot zelo solidna alternativa brez žrtvovanja zmogljivosti.
- Soobstoj modulov C in Rust prek FFI omogoča postopno uvajanje in zmanjšuje tveganja v sistemih, ki so že v produkciji.
Če delaš v vgrajeno programsko opremo in razpravljaš med Rustom in C-jemNiste sami. Vedno več ekip se sprašuje, ali se splača še naprej zanašati na tradicionalni C ali začeti nekatere svoje projekte seliti na Rust, še posebej, ko pridejo v poštev varnost, vzdrževanje in povezani sistemi.
V tem članku bomo mirno, a neposredno razčlenili, Kakšen prispevek Rust in C imata v kontekstu vgrajenih sistemov?Varnost pomnilnika, zmogljivost, sočasnost, orodja, ekosistem, krivulja učenja in ustreznost za resnične projekte z veliko starejše kode. Ideja je, da na koncu dobite jasna merila za odločitev, kdaj je bolj smiselno ostati pri C-ju in kdaj se je splačalo izbrati Rust v svoji vdelani programski opremi.
Kontekst: Zakaj je boj med Rustom in C-jem ključen pri vgrajeni programski opremi

V svetu zelo nizkonivojski sistemi, mikrokrmilniki in naprave interneta stvariC ostaja nesporni kralj. Že desetletja je materni jezik skoraj vsega, kar se priključi na računalnik: gonilnikov, proizvajalčevih HAL-ov, RTOS-ov, skladov TCP/IP, zagonskih nalagalnikov in še veliko več. To se prevede v milijone vrstic kode, ki se izvajajo v proizvodnji v sektorjih, kot so avtomobilska industrija, industrija, energetika in potrošniška elektronika.
Rust pa je s svoje strani Rodil se je veliko kasneje z zelo jasno obsesijoZagotavljanje varnosti pomnilnika in sočasnosti brez potrebe po zbiranju smeti in brez žrtvovanja nizkonivojske zmogljivosti. Čeprav je sprva pridobil na veljavi v večjih sistemskih okoljih (brskalniki, zaledni sistemi, WebAssembly), je skupnost dosegla pomemben napredek na področju vgrajenih sistemov zahvaljujoč projektom, paketom in filozofiji »varnost na prvem mestu«.
Vprašanje, ki si ga danes zastavljajo številne ekipe, je preprosto, a neprijetno: Ali je smiselno še naprej pisati novo vdelano programsko opremo v jeziku C?Z vsemi tveganji kazalcev in prelivanj, ali je že čas za preskok na Rust, vsaj v najbolj kritičnih delih sistema?
Poleg tega ta odločitev ni sprejeta v vakuumu. Upoštevati je treba, da dober del varnostnih napak ki se pojavljajo na povezanih napravah, izvirajo iz napak pomnilnika v C/C++, na kar so začele izrecno opozarjati različne organizacije in vlade ter spodbujati uporabo varnejših jezikov za kritično programsko opremo.
Korenine, zrelost in ekosistem: C kot veteran in Rust kot novinec
Domena jezika C v vgrajenem okolju je odvisna od nekaj zgodovinske korenine, ki jih je težko prezretiOd sedemdesetih let prejšnjega stoletja se mikrokrmilniki uporabljajo za pisanje operacijskih sistemov, vdelane programske opreme vseh vrst in aplikacij, kjer šteje vsak bajt in vsak cikel procesorja. Na tej osnovi je bil zgrajen obsežen ekosistem prevajalnikov, knjižnic, RTOS-ov in orodij za odpravljanje napak, posebej zasnovanih za mikrokrmilnike.
Ta inercija ima neposredno posledico: Proizvajalci silicija oblikujejo svoje SDK-je in primere z mislijo na CKo prenesete paket podpore za nov mikrokontroler, boste običajno našli preizkušen prevajalnik C, gonilnike C, referenčne primere in zelo dodelano integracijo z lastniškimi ali na GCC temelječimi IDE. Zaradi tega je začetek projekta C na praktično kateri koli platformi takojšen.
Rja, primerjalno, Prihaja kot novinec, poln navdušenja in z radikalno drugačnim pristopom.V samo nekaj letih je skupnost zgradila vse bolj robusten ekosistem za vgrajene sisteme, ki ga podpirajo paketi, kot je vgrajeni-halDružine HAL, specifične za številne mikrokontrolerje ARM Cortex-M in RISC-V, ter projekte, kot so operacijski sistemi v realnem času ali ogrodja vgrajenih aplikacij, v celoti napisani v Rustu.
Vendar pa tudi danes še vedno obstajajo območja, kjer Podpora za Rust ni tako neposredna ali uradna, kot se zdi.V zelo specifičnih arhitekturah, nenavadnih čipih ali zelo zaprtih lastniških SDK-jih je pogosto, da podpora za Rust "iz škatle" še ni na voljo in da je treba uporabljati ovojnice C ali ročno delati z bloki. nevaren za dostop do določenih funkcij.
Skratka, čeprav ima C koristi od Desetletja zrelosti, industrijska orodja in uradna podpora Na skoraj vsaki vgrajeni platformi Rust to pomanjkanje tradicije delno nadomesti s sodobnim dizajnom, zelo aktivno skupnostjo in jasnim poudarkom na varnosti, vendar je v nekaterih zelo specifičnih nišah še vedno v fazi širitve.
Varnost pomnilnika: ročni model v jeziku C v primerjavi z lastništvom v Rustu
V jeziku C je upravljanje pomnilnika prav tako močno kot nevarno. Jezik vam omogoča podroben nadzor nad vsakim dodeljenim in sproščenim bajtomVendar pa praktično ne nalaga nobenih omejitev: vi se odločite, kdaj boste uporabili malloc, kdaj boste sprostili pomnilnik, kako boste obravnavali kazalce in kako boste dostopali do polj. To vam zagotavlja veliko svobode, a hkrati odpira vrata klasičnim napakam, kot so prelivanje medpomnilnika, viseči kazalci, ponovna uporaba že sproščenega pomnilnika in puščanja, ki jih je težko izslediti.
Ta resničnost ni teoretična: Ocenjuje se, da je velik del varnostnih ranljivosti v programski opremi, napisani v jeziku C/C++ Te težave izvirajo iz težav s pomnilnikom. Pri vgrajeni programski opremi je to še posebej kritično, saj lahko povzroči ne le zrušitve, temveč tudi nepravilno delovanje v realnem času ali varnostne ranljivosti v povezanih napravah.
Rust se tega problema loteva z zelo drugačnim pristopom, ki temelji na njegovih sistem lastništva in posojilVsaka vrednost v Rustu ima enega samega lastnika, katerega življenjsko dobo jasno določi prevajalnik. Ko nekaj zaide izven obsega, se njegov pomnilnik sprosti deterministično, brez pobiranja smeti. Hkrati se morajo reference držati strogih pravil: ne smete imeti neveljavnih referenc niti ne smete mešati sočasnega branja in pisanja brez vzpostavljenih varnih mehanizmov.
To pomeni, da Številne napake v pomnilniku preprosto preprečujejo prevajanjeČe poskušate uporabiti podatke po tem, ko ste jih premaknili, vas bo prevajalnik opozoril. Če želite imeti dve spremenljivi referenci na isti vir, Rust tega ne bo dovolil, razen če vnesete ustrezen razdelek. nevaren in sprejeti posledice. Poleg tega dostop do polj in dinamičnih zbirk privzeto izvaja preverjanja meja, kar preprečuje tipične prelivanja, zlasti v razvojnih gradnjah.
Praktični rezultat je, da medtem ko ste v jeziku C odvisni od svojih izkušenj, pregledov kode in zunanjih orodij, da preprečite napake v pomnilniku, v Rustu sam jezik deluje kot varuh varnega upravljanja pomnilnika še preden se vdelana programska oprema zažene na mikrokrmilniku.
Zmogljivost in determinizem v sistemih z omejenimi viri
Eden od razlogov, zakaj je C že desetletja na prestolu vdelane programske opreme, je ta, da Ponuja izjemno predvidljivo delovanjeVeste, katera navodila se bodo izvedla, lahko natančno prilagodite porabo pomnilnika za vsak bajt in odpravite nepotrebne stroške. V sistemih z omejenim RAM-om in zelo strogimi zahtevami v realnem času ta sposobnost pritiskanja strojne opreme na njene meje ostaja velika prednost.
Vendar pa je bila Rust zasnovana od začetka do konca, da bi zagotovila abstrakcije z ničelnimi stroškiTo pomeni, da so številne visokonivojske konstrukcije, ki jih ponuja jezik (itatorji, generiki, tipi napak itd.), optimizirane med prevajanjem, da ustvarijo strojno kodo, ki je enako učinkovita kot tista, ki bi jo ročno napisali v jeziku C. Ni zbiralnika smeti, ki bi uvedel nepredvidljive premore, in prevajalnik lahko odstrani večino varnostnih preverjanj v produkcijskih gradnjah, ko lahko dokaže, da niso potrebna.
Primerjalni testi sistemov v resničnem svetu so pokazali, da Rust se običajno ujema ali zelo približa zmogljivosti C-ja.in ga v nekaterih primerih celo presežejo zaradi sodobnih optimizacij prevajalnikov in zmožnosti pisanja visokonivojske kode, ki jo lahko optimizator učinkoviteje analizira. Vendar pa v zelo tesnih vgrajenih okoljih ostajata končna binarna velikost in poraba pomnilnika pomembna dejavnika, ki ju je treba upoštevati.
Z vidika razvijalca vdelane programske opreme je pomembno, da Rust ne nalaga samodejnega bremena zmogljivostiLahko nadaljujete z delom blizu kovine, nadzorujete nizkonivojske podatkovne strukture in se po potrebi zatečete k blokom. nevaren zelo omejeno na interakcijo z registri ali specifično strojno opremo, preostanek kode pa je pod varnostnimi jamstvi jezika.
Posledično je bila za večino vgrajenih projektov, kjer je bila zmogljivost C ključna zahteva, Rust je popolnoma konkurenčen, z dodatno prednostjo drastičnega zmanjšanja površine pomnilniških napak in nedefiniranega vedenja.
Sočasnost in realni čas: ročna disciplina v jeziku C v primerjavi z varnostjo tipov v jeziku Rust
Ko v vdelano programsko opremo začnete uvajati sočasna opravila, prekinitve in dostop do skupnih virov, C zagotovi vse dele: RTOS, niti, čakalne vrste, semaforji, muteksi, atomske spremenljivkeTežava je v tem, da jezik spet predpostavlja, da veste, kaj počnete. Nič vam ne preprečuje, da bi brali in pisali isto spremenljivko iz več nezaščitenih nalog ali oblikovali shemo zaklepanja, ki bi povzročila zastoj, ki ga je težko reproducirati.
V teh primerih je varnost odvisna od disciplina ekipe, pregledi kode in testiranjeZ ustreznimi orodji je mogoče v jeziku C zgraditi robustne sočasne sisteme, vendar je verjetnost uvedbe subtilnega tekmovalnega pogoja resnična, še posebej, ko vdelana programska oprema raste in postaja bolj zapletena.
Rust vključuje varnost sočasnosti neposredno v vašem sistemu tipovSkozi lastnosti Pošlji y SinhronizacijaPrevajalnik odloči, katere tipe je mogoče varno premikati ali deliti med nitmi. Tukaj veljajo tudi pravila izposoje: sočasen dostop do spremenljivih tipov iz več kontekstov ni dovoljen brez uporabe varnih struktur, kot so mutex-i, RwLock ali atomsko prešteti referenčni tipi.
Posledica je, da Pogoji tekme pomnilnika so v veliki meri prepovedani z zasnovoČe poskušate nevarne podatke posredovati drugi nalogi brez ustrezne zaščite, bo prevajalnik vrgel napako. Seveda lahko še vedno delate napake v logiki na visoki ravni, vendar je cela kategorija napak sočasnosti izpuščena, ker se ne bo prevedla.
Za vdelano programsko opremo, ki začne vključevati večopravilnost, intenzivna komunikacija ali vzporedna obdelavaTa model zagotavlja dodaten mir. Številne ekipe cenijo Rustovo "neustrašno sočasnost" prav zato, ker skrajša čas, porabljen za lovljenje izmuzljivih hroščev, povezanih z dirkaškimi pogoji.
Produktivnost, krivulja učenja in razpoložljivost talentov
Eden najpogosteje ponavljajočih se argumentov v prid programskemu jeziku C v svetu vgrajenih komponent je ... ogromna baza izkušenih razvijalcev ki že obvladajo jezik in njegova orodja. Najti inženirje, ki znajo z lahkoto krmariti po kodi C za mikrokrmilnike, je relativno enostavno, zlasti v sektorjih, ki v to tehnologijo vlagajo že desetletja.
Rja pa na drugi strani, V vgrajenem prostoru ima še vedno manjšo skupnost.Mnogi razvijalci se učijo in prehajajo s C/C++, kar pomeni, da bo kratkoročno morda dražje zaposliti razvijalce z bogatimi izkušnjami v Rustu, posebej za nizkonivojsko vdelano programsko opremo.
K temu se doda še dejstvo, da Rustova krivulja učenja je priznano strmaŠe posebej na začetku. Model lastništva, pravila izposoje, življenjske dobe in omejitve spremenljivosti vas silijo, da spremenite način razmišljanja in strukturiranja kode. Pogosto prevajalnik v prvih nekaj mesecih zavrne veliko poskusov, dokler ne "ponotranjite", kaj pričakuje od vas.
Druga plat medalje pa je, da ko je ta začetna faza končana, Produktivnost se lahko srednjeročno in dolgoročno očitno povečaDejstvo, da se med prevajanjem odkrije veliko napak, skrajša ure odpravljanja napak, ponavljajočega se testiranja in subtilnih regresij, kar je še posebej opazno pri izdelkih, ki jih je treba vzdrževati leta in se razvijati z novimi funkcijami.
Kar zadeva dokumentacijo in vire za usposabljanje, ima Rust Visokokakovostno izdelani uradni materiali in zelo izobraževalna skupnostKnjige, tečaji, spletna dokumentacija in vzorčni repozitoriji olajšajo strukturirano usposabljanje celotnih ekip, čeprav to zahteva namenitev časa in proračuna, kar si vsi projekti ne morejo takoj privoščiti.
Razvojna orodja in izkušnje s projekti
V projektih C za vgrajene sisteme je pogosto srečati heterogena mešanica orodijSem spadajo različni prevajalniki, lastniška integrirana razvojna okolja (IDE), datoteke Makefile ali CMake, skripti po meri in v mnogih primerih ročno upravljanje odvisnosti. Čeprav obstajajo upravljalniki odvisnosti, kot sta vcpkg ali Conan, ni neobičajno, da ima vsako podjetje svoj "koktajl" orodij in internih konvencij.
Za statično analizo, odkrivanje puščanj ali probleme sočasnosti v jeziku C se običajno zatečemo k zunanji pripomočki, kot so Valgrind, AddressSanitizer, ThreadSanitizer ali specifični linterjiSo zmogljiva in dobro uveljavljena orodja, vendar jih je treba pravilno integrirati in konfigurirati, pogosto pa niso del standardnega delovnega toka za vse razvijalce v ekipi.
Rust ponuja veliko bolj enotno izkušnjo zaradi Cargo, njegov gradbeni sistem in upravljavec paketovZ enim samim orodjem lahko ustvarjate projekte, dodajate odvisnosti, prevajate, izvajate teste, ustvarjate dokumentacijo in upravljate različice. Poleg tega ekosistem vključuje orodja, kot je [seznam orodij]. rustfmt formatirati kodo in Clippy za odkrivanje vprašljivih vzorcev kakovosti in predlaganje izboljšav.
V vgrajenem sistemu je ta homogenost dobrodošla, ker Poenostavlja nastavitev novih repozitorijev in sodelovanje med ekipami.Dodajanje HAL-a novemu mikrokrmilniku se običajno skrči na vključitev paketa v konfiguracijsko datoteko in začetek njegove uporabe, namesto da bi se bilo treba ukvarjati z vključenimi potmi in razpršenimi skripti za gradnjo.
To ne zanika dejstva, da v nekaterih zelo zaprtih industrijskih tokovih Orodja C še naprej ponujajo bolj dodelano integracijo s programerji strojne opreme, odpravljalniki napak JTAG ali certificiranimi okolji. V teh primerih bo Rust morda potreboval dodatno delo, da se bo prilagodil obstoječemu orodju, še posebej, če prodajalec še ne ponuja uradne podpore.
Integracija z obstoječo kodo in postopno sprejemanje
Le malo naprav si lahko privošči posodobitev vdelane programske opreme iz nič. Pogosteje pa imajo znatna baza kode C je že v produkciji Rust je prestal revizije, certifikate in leta vzdrževanja. Popolna prepisovanje v Rustu ne bi bilo le izjemno drago, ampak tudi tvegano: vsaka prepisana vrstica je potencialno nov vir napak.
V tem kontekstu ima C še vedno jasno prednost, da Razširitev sistema C z več C je trivialnaModule lahko preoblikujete, dele kodne baze posodobite ali dodate funkcije, ne da bi morali hkrati uvesti novo tehnologijo, kar poenostavi upravljanje tveganj.
Zdaj je Rust zasnovan tako, da dokaj dobro sobivajo s C-jem prek FFI (vmesnika tujih funkcij)Funkcije C je mogoče predstaviti kot API-je, ki jih lahko Rust pokliče, in obratno, zgraditi module Rust, ki izvažajo vmesnike z ABI-ji C za uporabo iz obstoječe vdelane programske opreme. Ta pristop omogoča postopno uvajanje: najbolj občutljive komponente (npr. varnostne module ali kompleksne razčlenjevalnike) je mogoče prepisati v Rustu, medtem ko preostali del sistema ostane v C-ju.
Vendar pa meje med C in Rustom zahtevajo Posebna pozornost je namenjena definiciji podatkovnih struktur, poravnavi, upravljanju pomnilnika in konvencijam klicanja.Ta območja so običajno razglašena za nevaren V Rustu to vključuje vzpostavitev zelo jasne pogodbe s svetom C, da se izognemo presenečenjem. Z ustrezno disciplino se je ta hibridna strategija izkazala za izvedljivo tudi pri velikih projektih.
Za številne ekipe je ta pristop k sobivanju razumen način Začnite izkoriščati prednosti Rusta, ne da bi pri tem zavrgli leta naložb v CHkrati vam omogoča, da pridobite praktične izkušnje z novim jezikom v nadzorovanem okolju, preden se ga lotite v več delih vdelane programske opreme.
Tipični primeri uporabe C in Rust v vgrajeni programski opremi
Na področju bolj tradicionalnih vgrajenih sistemov, z preprosti mikrokrmilniki, zelo stroge zahteve v realnem času in ekosistemi, močno osredotočeni na enega samega prodajalcaC ostaja naravna izbira. Razpoložljivost primerov, knjižnic ponudnikov, certificiranih gonilnikov in izkušenega osebja močno zmanjša začetne težave in tveganja projekta.
Tudi v sektorjih z certifikacijski okviri, ki so močno osredotočeni na CNa primer, v nekaterih avtomobilskih ali letalskih predpisih je ohranitev jezika C kot primarnega jezika boljša izbira za uveljavljene procese, obstoječa orodja za statično analizo in revizije, ki se že leta zanašajo na ta tehnološki paket.
Rja pa se po drugi strani paše kot rokavica novi projekti, kjer sta varnost in dolgoročna robustnost prednostni nalogiNaprave interneta stvari, ki so izpostavljene internetu, sistemi, kjer ima lahko ranljivost resen vpliv, ali vdelana programska oprema, ki se bo leta posodabljala na daljavo, lahko močno izkoristijo jezik, ki drastično zmanjša napake pomnilnika in vsili eksplicitno obravnavo napak in stanj.
Poleg tega v okoljih, kjer oprema nima veliki namenski oddelki za zagotavljanje kakovosti ali varnostRust deluje kot nekakšna vgrajena varnostna mreža. Številne prakse, ki so v jeziku C "priporočene" (preverjanje vsakega kazalca, neignoriranje kod napak, izogibanje nedoslednim vmesnim stanjem), postanejo obvezne zahteve za prevajanje kode.
Končno, Rustov modularni pristop in njegov ekosistem zabojev ga delata še posebej privlačnega za projekti, ki želijo deliti logiko v različnih okoljih (na primer deljenje poslovne logike med zalednim sistemom in vdelano programsko opremo ali ponovna uporaba razčlenjevalnikov in kriptografskih knjižnic na več platformah), pod pogojem, da je poskrbljeno za specifični nizkonivojski del za vsak cilj.
Ob vsem tem se izkaže jasna slika: C ostaja nepremagljiv jezik kontinuitete in združljivosti v večini današnje vgrajene programske opreme, medtem ko se Rust pozicionira kot zelo močan kandidat za nove razvojne projekte, kjer sta varnost in dolgoročna vzdrževalna zmogljivost prav tako pomembni kot zgolj zmogljivost.
Kako se odločiti: praktična merila za izbiro jezika v naslednji vdelani programski opremi
Izbira med Rustom in C-jem za določen vgrajeni projekt je le redko zgolj tehnična zadeva; V poštev pridejo tudi realnost vaše ekipe, vaši roki in vaše poslovne zahteve.Nekatera merila, ki pogosto vplivajo, so količina starejše kode, potrebe po certificiranju, varnostna kritičnost in čas, ki je na voljo za usposabljanje ekipe.
Če se vaša organizacija vleče Leta stabilne, dobro preizkušene kode C z uveljavljenimi procesiIn če so vaše trenutne potrebe bolj povezane z razširitvijo funkcionalnosti kot s prenovo arhitekture, je povsem smiselno, da ostanete pri jeziku C. Spreminjanje jezikov brez tehtnega razloga lahko povzroči več težav kot rešitev, zlasti v sistemih, ki že izpolnjujejo svoje cilje glede zmogljivosti in zanesljivosti.
Po drugi strani pa, če začenjate nov izdelek brez močne odvisnosti od starejše kodeŠe posebej, če nameravate živeti povezani, posodabljati na daljavo in upravljati občutljive podatke, je lahko vlaganje časa v uvajanje Rusta zelo koristno. Začetno krivuljo učenja z leti izravna robustnejša in lažje vzdrževalna kodna baza.
Smiselno je razmisliti tudi o vmesnih pristopih, kot je npr. Začnite uvajati Rust v izoliranih in dobro definiranih modulih iz obstoječih projektov: na primer komunikacijskih plasti, kjer želite zagotoviti, da ne bo preobremenitev, ali komponent, ki upravljajo ključe in kriptografijo. To vam omogoča, da praktično ocenite vpliv Rusta v vašem specifičnem kontekstu, preden sprejmete širše odločitve.
Na koncu je namesto iskanja "skupnega zmagovalca" koristno videti Rust in C kot dopolnilna orodja znotraj istega arzenalaVsak ima zelo jasne prednosti in očitne omejitve; ključno je, da izkoristite najboljše od obeh, kjer dodajo največ vrednosti v življenjskem ciklu vaše vdelane programske opreme.
Če pogledamo širšo sliko, je jasno, da C ohranja vodilno vlogo na področju vgrajene programske opreme zaradi svojih globokih korenin, podpore proizvajalcev in absolutnega nadzora nad strojno opremo.Vendar pa je Rust presegel meje novosti in postal zelo resna alternativa pri novih razvojnih projektih, zlasti tam, kjer so varnost, varna sočasnost in vzdrževanje ključnega pomena. Za številne ekipe je najbolj smiseln pristop združiti nadaljnjo uporabo jezika C s postopnim uvajanjem Rusta na kritičnih področjih, s čimer se zgradijo robustnejši vgrajeni sistemi, ne da bi se pri tem opustilo vse, kar se je naučilo v zadnjih nekaj desetletjih.
Strasten pisec o svetu bajtov in tehnologije nasploh. Rad delim svoje znanje s pisanjem in to je tisto, kar bom počel v tem blogu, saj vam bom pokazal vse najbolj zanimive stvari o pripomočkih, programski opremi, strojni opremi, tehnoloških trendih in še več. Moj cilj je, da vam pomagam krmariti po digitalnem svetu na preprost in zabaven način.

