Kedvem szottyant a Rust-hoz, megnézni hogy amit pár éve implementáltam Rust-ban "Hello World"-öt (értsd: LED villogtatást), szóval azon túllépve mennyire nehéz boldogulni vele.
C után furcsa, viszont némi guglizás után gyorsan összetákoltam a feladatot. Picit olyan érzésem van, mint a natív C-beli mikrovezérlő programozásból az Arduino LIB-re váltás esetén, amikor a sok-sok általános funkció (pl. ADC kezelés, I2C kezelés, ...) mind ott van készen a keretrendszerben, csak felparaméterezve meg kell hívni és működik.
Feladat egyébként nem bonyolult, ezért is gondoltam hogy itt az ideje kipróbálnom a Rust-ot mikrovezérlőn is:
- UART
- 2 ADC
- GPIO lábak kezelése
- időzítés
- némi logika
Viszont tényleg szépen összepattintható a stable fordítóval és unsafe nélkül.
- hg2ecz blogja
- A hozzászóláshoz be kell jelentkezni
Hozzászólások
Na, erdekes a dolog! C-n (meg asm-en) kivul meg nem tettem ilyesmi MCU-kra programot. Irhatnal kicsit reszletesebben is, ilyesmikrol, hogy:
- Mi maga a toolchain? A szokasos C-s valtozatbol kiindulva a *.rs => *.o => *.elf => *.hex, majd...ooo... profit?
- Ezen belul hol mondjuk meg hogy mi az architektura? Pl. a rustc honnan tudja hogy (mondjuk) armv6-m-re kell forditatni?
- Szinten ezen belul, hol mondjuk meg hogy mi a linker script, hogy osszuk fel a memoriat, ilyesmi?
- Mi ez a ``keretrendszer'', amiben mar minden (is) keszen van? Ez egy HAL (hardware abstraction layer)-re epulo rust library?
- A hozzászóláshoz be kell jelentkezni
Felrakod userként a $HOME-ba a Rust fordítót: https://www.rust-lang.org/tools/install
... kiszáll-beszáll ... a .profile-ban a PATH módosul (de ezt kézzel is bedobhatod)
Ez eddig a normál Rust fordító (stable), amivel a host rendszerre fordítanál.
Adjuk hozzá az ARM Cortex M3-hoz szükséges kiegészítést:
$ rustup target add thumbv7m-none-eabi
Létrehozod az alábbi példa projektet:
$ cargo new projekted
Ebben a "projekted" mappában (ahol a Cargo.toml is van) alá létrehozol egy .cargo mappát, abba egy config fájlt. Itt mondod meg hogy nem a host rendszerre fogsz fordítani:
[build]
target = "thumbv7m-none-eabi"
rustflags = [
"-C", "link-arg=-Tlink.x",
]
Egyúttal az utóbbi link-arg részben írt link.x fogja a linkelésnél követelni a projekt gyökerében a memory.x állományt, amit kérdeztél. Ez minimum ennyi:
MEMORY
{
FLASH : ORIGIN = 0x08000000, LENGTH = 64K
RAM : ORIGIN = 0x20000000, LENGTH = 20K
}
Cargo.toml [dependencies] részébe pár csomag (alább) és forráskód innentől
$ cargo build --release # és lefordul
$ sudo apt install binutils-arm-none-eabi # bin előállításához
$ arm-none-eabi-objcopy -O binary target/thumbv7m-none-eabi/release/projekted projekted.bin # csak erre kell
$ sudo apt install stm32flash # USB-TTL átalakítón vagy Raspberry UART-ján keresztül áttölti a "projekted.bin" kódot.
$ stm32flash -w projekted.bin /dev/ttyUSB0 # tartalmaznak az STM32 mikrovezérlők egy kinyírhatatlan UART-os bootloadert, ehhez a BOOT0 lábat kell felhúzni + reset és ekkor ez a bootloader rész fut.
A stm32f1xx-hal csomagban van az igazi varázslat.
use stm32f1xx_hal::{adc, pac, prelude::*, serial, timer};
Ami még fontos: minimál forráskód (main.rs), amely bár még nem csinál semmit, de az a minimum ami már lefordul.
Látszik, hogy a no_std és no_main miatt erősen eltér attól, amit például Linux alatt lazán "fn main() { ... }" -ként megszoktunk.
#![no_std]
#![no_main]
extern crate panic_halt; // ez kell!
use cortex_m_rt::entry;
use stm32f1xx_hal;
#[entry]
fn main() -> ! {
// ...
loop {
// ...
}
}
A Cargo.toml-ben is van furcsaság. Itt adod meg azt is, hogy melyik mikrovezérlő legyen.
[dependencies]
panic-halt = "0.2"
cortex-m-rt = "0.6"
stm32f1xx-hal = {version = "0.7", features = ["stm32f103", "rt"]}
- A hozzászóláshoz be kell jelentkezni
Köszi!
- A hozzászóláshoz be kell jelentkezni
Hm... a rustc-nek kozvetlenul is megadhatom a thumbv6m-none-eabi argumentumot? Eselyes, mert a `rustc --print target-list` kiirja.
- A hozzászóláshoz be kell jelentkezni
Először én is rustc + Makefile módon kezdtem az ismerkedést. Aztán rá kellett jönnöm, hogy rustc -t közvetlenül ritkán fogsz használni. Kb. akkor, amikor csak
use std::akármi;
van használatban és semmi fordításkor importált külső csomagod nincs.
A probléma vele, hogy ekkor a külső csomag menedzsmentet neked kell végigszkriptelned, amit a cargo automatikusan megcsinál. Miért nehezítenéd meg az életedet?
A cargo és a Cargo.toml txt fájl ugyanis sokkal több a make és "Makefile" képességénél.
Lásd még $ cargo --help
- A hozzászóláshoz be kell jelentkezni
Tetszik! Visszatalálós hsz. :-)
- A hozzászóláshoz be kell jelentkezni