Rust - mikrovezérlőre

 ( hg2ecz | 2019. június 1., szombat - 13:34 )

Rust nyelven a mikrovezérlős "hello world" nehezebben adta magát a linuxos konzolalkalmazásnál. A konzolalkalmazásnál egy alap hello world mindössze cargo new akarmi, amit már csak le kell fordítani cargo build módon.
De végre összeállt egy működő, Rust nyelven írt "hello world" (ledvillogtató) mikrovezérlőre is.

A kód itt látható.

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

Mi a toolchain? :) openocd+stmdiscovery-szeruseg vagy cel-hardver?

1,6 dollárért rendeltem blue pill lapkákat meg hasonló árban USB-TTL átalakítót.

Simán stm32flash + USB-TTL átalakító. Az STM32-ben kinyírhatatlan bootloader van.
stm32flash -w $BINFILE /dev/ttyUSB0

Debugolás terén C-ben az UART-ra való részeredmény kiírásra szoktam rá a hardveres debuggerek helyett. Ezért is fontos, hogy mostantól már van GPIO-s debug pont. Következő az UART-ra írás lesz és van Rust esetén is megszokott debug lehetőségem.

Írnál az eddigi tapasztalataidról Rust-al kapcsolatban? Mi tetszik és mennyire áll kézre, illetve érdekelne hogy mennyire elégséges az std lib-je?

Belekóstoltam a Rust-ba kb. 2 éve egy benchmarking kapcsán. Megküzdöttem az alapjaival és megfogott. Mondjuk nekem főleg apróbb konzolos feldolgozók és apróbb hálózati démonok kellenek. Ezekre C és Python volt eddig a fő irány, a C++ alapjait megismertem valamikor, de valahogy azóta sem fogott meg. Legutóbb azt kerestem, hogy a g++ illetve clang C++ fordítása esetén van-e lehetőség warningolni az unsafe C-s kifejezésekre. Egyelőre nem találtam ilyen kapcsolót.
Kerestem újabb nyelvet. Érdekes módon a Go sem fogott meg, D-t is megnéztem. A Rust viszont annyira máshogy közelít meg sok dolgot, hogy felcsigázott, meg akartam ismerni és közel 2 év alatt megkedveltem.

Ma már könnyebb a nyelvvel ismerkedni, van jó oktatóanyag a Youtube-on. Továbbá a Rust könyv és a példákon kersztül könyv annó is sokat segítettek, érdemes a példákat kipróbálni, szokni.

Ami tapasztalat:

- nyelv nagyon tetszik. Alapból nem enged buffer túlcsordulást és sok más huncutságot sem. De ha mégis "huncutkodni" akarsz, akkor unsafe { ...... } és a benne levő lehet bármi. Aztán már csak az unsafe szóra kell grep-elni és ha van a kódban, azt jobban megvizsgálni. Több dolgot annyira máshogy közelít meg, hogy első körben nagy pofonokat ad a nyelv. Mondhatni a tanulási görbéje nem az erőssége. Kellett szoknom.
A lifetime a kezdőket nagyon tudja szivatni, ahogy az ownership-téma is sok bosszúságot okozott kezdőként. És még sorolhatnám. De hozzá lehet szokni. :)
A könnyen implementálható iterátor viszont elegáns. Pythonban írt feldolgozókban szoktam rá az iterátorra.
Tetszetős, hogy a String alapból UTF8-only.

- unit testing: szerves része. A "cargo test" parancs kiadása után unit testtel fordul és fut le a kód.

- dokumentáció: NAGYON JÓ

- std lib: praktikus, bár lehetne tágabb (Python elkényeztetett). Sokkal összetettebb adatszerkezetei vannak C-hez képest, inkább a Python adatszerkezeteire emlékeztet. Mindegyiknél a biztonságos használat a "normál út", de ha nagyon kikivánkozik, az unsafe { .... } rendelkezésedre áll. Alap TCP vagy UDP szerver/kliens std-ben van. Szerintem kiforrott. Lásd: https://doc.rust-lang.org/std/#primitives és https://doc.rust-lang.org/std/collections/ illetve https://doc.rust-lang.org/std/net/
Ez lassan de bővül, például néhány a crates.io -ról stabilizálódó dolgok közül mászik bele.

- crates.io : rengeteg csomag (cargo search bármi) ... viszont erre a kiforrottság már sok esetben nem annyira igaz. És itt nem arra gondolok, hogy Rust szokás szerint 0.xx.xx verziószámozás a "divat", hanem hogy valakinek kellett és ha már megírta saját szája íze szerint, az került bármiféle közösségi javítás nélkül megosztásra. De idővel ez is remélhetőleg csak jobb lesz.

- tempó: sok tesztet csináltam C <--> Rust között. Mire minden ellenőrzést berakok a C-ben megírt alternatívába, rádöbbenek hogy nem vagy elenyészően lesz gyorsabb a Rust-ban írt átláthatóbb kódhoz képest. Kivéve jelfeldolgozás. Ott C-ben a fix puffereken hogy ellenőrzés nélkül szaladhatok végig, jobban tudom AVX2-baráttá / ARM NEON baráttá tenni C-ből. Ez talán a kivétel. Viszont szépen lehet Rust alá integrálni a C-ben írt modult is.

A Rust a célkitűzése szerint C-szerű tempóra képes, de alapból biztonságos nyelvnek szánják az alábbi területekre:

- parancssoros alkalmazások
- hálózati alkalmazások, démonok.
- beágyazott rendszerek - szépen fejlődik
- webassembly

Mint minden nyelvnek, a Rustnak is megvan az, amikor praktikus választás és van, amikor kevésbé. Amire nekem kell, arra sok esetben az elején jön a döntés: C vagy Python vagy Rust melyike legyen? Feladattól függ, melyik mellett döntök. Raspberry-n is volt GPIO-t használó projektem, aminél Rust mellett döntöttem.

A nyelv szépen fejlődik, 6 hetente jön ki új verzió, új lehetőségekkel. Viszont a régi kódod lefordíthatóságára is ügyelnek.

Köszi. Vonzó.

Ami kimaradt, van user fórumuk, ahol gyakran kisegítettek engem is: https://users.rust-lang.org/

és pl. kapcsolt lista helyett mire szoktál rá rustban? :-)

Mit értesz kapcsolt lista alatt?

A legegyszerűbb, C-ben talán leggyakrabban használt adatszerkezetet.

Magyar neve láncolt lista.
Itt nem kell töltögetned az előző struktúra next pointerét, amit ha elrontanál (bár faék egyszerű), akkor segfault vagy ami még rosszabb, hogy nincs segfault, hanem valami más memóriát felülírsz.

Rust esetén: https://doc.rust-lang.org/std/collections/struct.LinkedList.html

    let mut person_ll = LinkedList::new();

    let p = Person{name: "Laci".into(), age: 21};
    person_ll.push_back(p);

A vágásra, beillesztésre és a két résztömb gyors összerakásra is a fenti linken ott a metódus.
Viszont elgondolkoztató a fenti leírás egyik első mondata: Almost always it is better to use Vec or VecDeque instead of LinkedList. In general, array-based containers are faster, more memory efficient and make better use of CPU cache.

Mekkora kod lesz? Ez csak jatszani van ugye?
------------------------
uint8_t *data; // tipussal megszorozzuk az adatot. wtf?

Linux felett már nem csak játék, viszont mikrovezérlő esetén ahogy írtad, még csak játék részemről.
Egyébként 528 byte lett ez az alapkód, amiből 300 a fullosan kitöltött interrupt vektor táblázata.
A valódi pazarlás aránya csak nagyobb kód esetén fog látszani.