Compile-Probleme Rust für ESP32

Alles, was nicht direkt mit Python-Problemen zu tun hat. Dies ist auch der perfekte Platz für Jobangebote.
Antworten
Benutzeravatar
Dennis89
User
Beiträge: 1156
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo zusammen,

trotz folgendem Hinweis oder vielleicht auch gerade deswegen, wurde ich sehr neugierig:
__deets__ hat geschrieben: Freitag 27. Oktober 2023, 22:23 Rust in embedded ist schon ne Herausforderung, aber wenn es dir mehr zusagt als C++, go for it.
Ich habe zum großen Teil das offizielle Rust-Tutorial durchgearbeitet und habe auch sehr kleine lauffähige Programme erfolgreich erstellt.
Das habe ich aber nur gemacht, weil ich ja gerne den ESP mit Rust steuern möchte. Ich wollte einfach starten und nur eine LED blinken lassen. Irgendwie fand ich mich nicht so ganz zu recht und das ist wahrscheinlich auch der Grund, wieso ich nicht erfolgreich war. Ich arbeite mit Fedora und habe folgendes gemacht:

ESP-IDF installiert wie hier:

Code: Alles auswählen

mkdir -p ~/esp
cd ~/esp
git clone --recursive https://github.com/espressif/esp-idf.git

cd ~/esp/esp-idf
./install.sh all

. $HOME/esp/esp-idf/export.sh
Lief alles problemlos durch.

Dann habe ich folgende 'cargo'-Befehle ausgeführt, wie hier beschrieben:

Code: Alles auswählen

cargo install cargo-generate
cargo install ldproxy
cargo install espup
cargo install espflash
cargo install cargo-espflash
Lief auch problemlos durch.
Dann bin ich in dieses Tutorial eingestiegen.

Mit

Code: Alles auswählen

cargo generate esp-rs/esp-idf-template cargo
habe ich ein neues Projekt erstellt, die 'main.rs' gelöscht, die gezeigte aus dem Tutorial etwas abgeändert:

Code: Alles auswählen

use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported
use log::*;

use esp_idf_hal::delay::FreeRtos;
use esp_idf_hal::gpio::*;
use esp_idf_hal::peripherals::Peripherals;

fn main(){
    
    esp_idf_sys::link_patches();
    esp_idf_svc::log::EspLogger::initialize_default();

    info!("Author: Zacchaeus Oluwole!");
    let peripherals = Peripherals::take().unwrap();
    let mut r_pin = PinDriver::output(peripherals.pins.gpio16).expect("Error: Unable to set pin(r) gpio2 Output");
    loop{
        r_pin.set_high().expect("Error: Unable to set pin r high");
        FreeRtos::delay_ms(1000);
        r_pin.set_low().expect("Error: Unable to set pin r low");
        FreeRtos::delay_ms(1000);
    }
}
Eigentlich ist alles gleich, ich habe nur die Pin-Nummer geändert und die Schleife gekürzt. Den vollständigen original Code gibt es hier

In meinem Projekt-Ordner habe ich dann folgendes gemacht:

Code: Alles auswählen

espup install
. ~/export-esp.sh
Das lief noch problemlos durch und dann kam wieder ein bekannter Befehl für mich

Code: Alles auswählen

cargo build
Und der warf folgende Fehler:

Code: Alles auswählen

[dennis@dennis test]$ cargo build
    Updating crates.io index
   Compiling compiler_builtins v0.1.101
   Compiling core v0.0.0 (/home/dennis/.rustup/toolchains/esp/lib/rustlib/src/rust/library/core)
   Compiling proc-macro2 v1.0.70
   Compiling unicode-ident v1.0.12
   Compiling libc v0.2.148
   Compiling cc v1.0.79
   Compiling memchr v2.5.0
   Compiling quote v1.0.33
   Compiling syn v2.0.39
   Compiling std v0.0.0 (/home/dennis/.rustup/toolchains/esp/lib/rustlib/src/rust/library/std)
   Compiling serde v1.0.193
   Compiling autocfg v1.1.0
   Compiling unwind v0.0.0 (/home/dennis/.rustup/toolchains/esp/lib/rustlib/src/rust/library/unwind)
   Compiling cfg-if v1.0.0
   Compiling memchr v2.6.4
   Compiling libc v0.2.150
   Compiling aho-corasick v1.1.2
   Compiling memoffset v0.9.0
   Compiling semver v1.0.20
   Compiling regex-syntax v0.8.2
   Compiling crossbeam-utils v0.8.16
   Compiling regex-automata v0.4.3
   Compiling rustc-std-workspace-core v1.99.0 (/home/dennis/.rustup/toolchains/esp/lib/rustlib/src/rust/library/rustc-std-workspace-core)
   Compiling serde_derive v1.0.193
   Compiling alloc v0.0.0 (/home/dennis/.rustup/toolchains/esp/lib/rustlib/src/rust/library/alloc)
   Compiling rustc-std-workspace-alloc v1.99.0 (/home/dennis/.rustup/toolchains/esp/lib/rustlib/src/rust/library/rustc-std-workspace-alloc)
   Compiling gimli v0.28.0
   Compiling adler v1.0.2
   Compiling miniz_oxide v0.7.1
   Compiling object v0.32.0
   Compiling panic_unwind v0.0.0 (/home/dennis/.rustup/toolchains/esp/lib/rustlib/src/rust/library/panic_unwind)
   Compiling std_detect v0.1.5 (/home/dennis/.rustup/toolchains/esp/lib/rustlib/src/rust/library/stdarch/crates/std_detect)
   Compiling panic_abort v0.0.0 (/home/dennis/.rustup/toolchains/esp/lib/rustlib/src/rust/library/panic_abort)
   Compiling hashbrown v0.14.0
   Compiling addr2line v0.21.0
   Compiling rustc-demangle v0.1.23
   Compiling crossbeam-epoch v0.9.15
   Compiling syn v1.0.109
   Compiling rustix v0.38.28
   Compiling bitflags v1.3.2
   Compiling glob v0.3.1
   Compiling clang-sys v1.6.1
   Compiling linux-raw-sys v0.4.12
   Compiling scopeguard v1.2.0
   Compiling rustversion v1.0.14
   Compiling log v0.4.20
   Compiling bitflags v2.4.1
   Compiling bstr v1.8.0
   Compiling minimal-lexical v0.2.1
   Compiling thiserror v1.0.50
   Compiling serde_json v1.0.108
   Compiling proc_macro v0.0.0 (/home/dennis/.rustup/toolchains/esp/lib/rustlib/src/rust/library/proc_macro)
   Compiling same-file v1.0.6
   Compiling walkdir v2.4.0
   Compiling nom v7.1.3
   Compiling globset v0.4.14
   Compiling crossbeam-deque v0.8.3
   Compiling nix v0.26.4
   Compiling thiserror-impl v1.0.50
   Compiling cvt v0.1.2
   Compiling libloading v0.7.4
   Compiling itoa v1.0.10
   Compiling ryu v1.0.16
   Compiling heck v0.4.1
   Compiling home v0.5.5
   Compiling anyhow v1.0.75
   Compiling bindgen v0.63.0
   Compiling either v1.9.0
   Compiling lazy_static v1.4.0
   Compiling strum_macros v0.24.3
   Compiling which v4.4.2
   Compiling fs_at v0.1.10
   Compiling ignore v0.4.21
   Compiling cexpr v0.6.0
   Compiling regex v1.10.2
   Compiling cc v1.0.83
   Compiling fastrand v2.0.1
   Compiling peeking_take_while v0.1.2
   Compiling shlex v1.2.0
   Compiling lazycell v1.3.0
   Compiling rustc-hash v1.1.0
   Compiling normpath v1.1.1
   Compiling remove_dir_all v0.8.2
   Compiling cmake v0.1.50
   Compiling tempfile v3.8.1
   Compiling strum v0.24.1
   Compiling globwalk v0.8.1
   Compiling filetime v0.2.23
   Compiling camino v1.1.6
   Compiling embuild v0.31.4
   Compiling cargo-platform v0.1.5
   Compiling cargo_metadata v0.15.4
   Compiling rustc_version v0.4.0
   Compiling envy v0.4.2
   Compiling fnv v1.0.7
   Compiling ident_case v1.0.1
   Compiling darling_core v0.20.3
   Compiling heapless v0.7.17
   Compiling byteorder v1.5.0
   Compiling nb v1.1.0
   Compiling num-traits v0.2.17
   Compiling futures-core v0.3.29
   Compiling futures-task v0.3.29
   Compiling hash32 v0.2.1
   Compiling stable_deref_trait v1.2.0
   Compiling futures-util v0.3.29
   Compiling pin-utils v0.1.0
   Compiling pin-project-lite v0.2.13
   Compiling iana-time-zone v0.1.58
   Compiling embassy-time v0.1.5
   Compiling unicode-xid v0.2.4
   Compiling const_format_proc_macros v0.2.32
   Compiling darling_macro v0.20.3
   Compiling chrono v0.4.31
   Compiling darling v0.20.3
   Compiling enumset_derive v0.8.1
   Compiling esp-idf-sys v0.33.7
   Compiling esp-idf-hal v0.42.5
   Compiling nb v0.1.3
   Compiling critical-section v1.1.2
   Compiling void v1.0.2
   Compiling embassy-sync v0.3.0
   Compiling once_cell v1.19.0
   Compiling version_check v0.9.4
   Compiling build-time v0.1.3
   Compiling embedded-hal v0.2.7
   Compiling uncased v0.9.9
   Compiling enumset v1.1.3
   Compiling const_format v0.2.32
   Compiling esp-idf-svc v0.47.3
   Compiling atomic-waker v1.1.2
   Compiling embedded-hal v1.0.0-rc.1
   Compiling embedded-io v0.6.1
   Compiling num_enum_derive v0.7.1
   Compiling embedded-hal-nb v1.0.0-rc.1
   Compiling embedded-can v0.4.1
   Compiling no-std-net v0.5.0
   Compiling num_enum v0.7.1
   Compiling test v0.1.0 (/home/dennis/Rust/test)
   Compiling embassy-futures v0.1.1
   Compiling embedded-svc v0.26.4
error[E0433]: failed to resolve: use of undeclared crate or module `esp_idf_hal`
 --> src/main.rs:5:5
  |
5 | use esp_idf_hal::gpio::*;
  |     ^^^^^^^^^^^ use of undeclared crate or module `esp_idf_hal`
  |
help: there is a crate or module with a similar name
  |
5 | use esp_idf_svc::gpio::*;
  |     ~~~~~~~~~~~

error[E0433]: failed to resolve: use of undeclared crate or module `esp_idf_hal`
 --> src/main.rs:4:5
  |
4 | use esp_idf_hal::delay::FreeRtos;
  |     ^^^^^^^^^^^ use of undeclared crate or module `esp_idf_hal`
  |
help: there is a crate or module with a similar name
  |
4 | use esp_idf_svc::delay::FreeRtos;
  |     ~~~~~~~~~~~

error[E0433]: failed to resolve: use of undeclared crate or module `esp_idf_hal`
 --> src/main.rs:6:5
  |
6 | use esp_idf_hal::peripherals::Peripherals;
  |     ^^^^^^^^^^^ use of undeclared crate or module `esp_idf_hal`
  |
help: there is a crate or module with a similar name
  |
6 | use esp_idf_svc::peripherals::Peripherals;
  |     ~~~~~~~~~~~

error[E0432]: unresolved import `esp_idf_sys`
 --> src/main.rs:1:5
  |
1 | use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always k...
  |     ^^^^^^^^^^^^^^^^ no external crate `esp_idf_sys`

error[E0433]: failed to resolve: use of undeclared type `PinDriver`
  --> src/main.rs:15:21
   |
15 |     let mut r_pin = PinDriver::output(peripherals.pins.gpio16).expect("Error: Unab...
   |                     ^^^^^^^^^ use of undeclared type `PinDriver`
   |
help: consider importing this struct
   |
1  + use esp_idf_svc::hal::gpio::PinDriver;
   |

error[E0433]: failed to resolve: use of undeclared crate or module `esp_idf_sys`
  --> src/main.rs:10:5
   |
10 |     esp_idf_sys::link_patches();
   |     ^^^^^^^^^^^ use of undeclared crate or module `esp_idf_sys`
   |
help: there is a crate or module with a similar name
   |
10 |     esp_idf_svc::link_patches();
   |     ~~~~~~~~~~~

Some errors have detailed explanations: E0432, E0433.
For more information about an error, try `rustc --explain E0432`.
error: could not compile `test` (bin "test") due to 6 previous errors
Jetzt bin ich absolut planlos, was ich falsch gemacht habe bzw. was ich vergessen habe zu installieren, damit dem Compailer nicht klar ist, was 'esp_idf_hal' ist.
Ist die Vorgehensweise zum aufsetzen des Projekts richtig so? Das mit den 'generate' aus dem Tutorial, dass dann auf ein GitHub-Repository zurückgreift, kommt mir irgendwie komisch vor.

Habe mir schon gedacht, es wäre vielleicht sinnvoller gewesen, das erst mal in einer virtuellen Maschine aufzusetzen, nicht das ich jetzt schon so viel Mist auf meinem System installiert habe, das ich gar nicht brauche.

Ich wäre sehr dankbar, wenn mir jemand hier weiterhelfen könnte. Habe schon sehr große Lust darauf, so ein Rust-ESP-Projekt zu machen.
Hätte auch schon sehr coole Ideen, besonders sowas würde ich genial finden. Aber da bin ich eher realistisch gestimmt und werde erst mal die grundlegenden Dinge (LED, Taster und Co) lernen und verstehen (und natürlich die Sprache an sich).

Viele Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
__deets__
User
Beiträge: 14544
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wie sieht denn die Cargo.toml aus? Mein laufendes Projekt fuer den TTGO ESP32S2 sieht so aus (nur dependencies):

Code: Alles auswählen

[dependencies]
anyhow = {version = "1", features = ["backtrace"]}
log = "0.4"
url = "2"
esp-idf-sys = { version = "0.31", features = ["binstart"] }
esp-idf-svc = "0.42.1"
esp-idf-hal = "0.38"
embedded-svc = "0.22"
embedded-hal = "0.2"
embedded-graphics = "0.7"
display-interface = "0.4"
display-interface-spi = "0.4"
st7789 = "0.6"
epd-waveshare = "0.5.0"
smol = "1.2"
num_enum = { version = "0.5" }
num = "0.4.0"
biquad = "0.4.2"
byteorder = "1.4.3"

[build-dependencies]
embuild = "0.29"
anyhow = "1"
Benutzeravatar
Dennis89
User
Beiträge: 1156
Registriert: Freitag 11. Dezember 2020, 15:13

Hi,

danke für die schnelle Antwort.
Bei mir sind die zwei "dependencies" wesentlich kürzer:

Code: Alles auswählen

[dependencies]
log = { version = "0.4", default-features = false }
esp-idf-svc = { version = "0.47.3", default-features = false }

[build-dependencies]
embuild = "0.31.3"
Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
__deets__
User
Beiträge: 14544
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dir fehlt da ja auch esp-idf-hal, was du benutzen willst. Ich bin gerade selber darüber gestolpert, dass ohne eine solche Deklaration kein use möglich ist. Auch wenn das crate im dependency tree ist. Was es denke ich sein sollte. Schau mal mit cargo tree, was da alles drin steckt. Wenns drin ist, pack es mit der Version in die toml. Sonst eine passende raussuchen.
Benutzeravatar
Dennis89
User
Beiträge: 1156
Registriert: Freitag 11. Dezember 2020, 15:13

Ja es ist drin, die Cargo.toml habe ich so abgeändert:

Code: Alles auswählen

[dependencies]
log = { version = "0.4", default-features = false }
esp-idf-svc = { version = "0.47.3", default-features = false }
esp-idf-hal = { version = "0.42.5", default-features = false }
esp-idf-sys = { version = "0.33.7", default-features = false }

und 'build' lief erfolgreich durch 🙂

Ob die LED, blinkt, teste ich nachher.

Vielen Dank für die schnelle Hilfe!

Muss man das jedes mal so machen? Gehst du gleich vor, wenn du ein neues Projekt aufsetzt oder wie erstellst du dir oder würdest du dir die Umgebung erstellen?

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
__deets__
User
Beiträge: 14544
Registriert: Mittwoch 14. Oktober 2015, 14:29

Schön, dass es klappt. Die Frage verstehe ich nicht. Was muss man so machen? Dependencies erklären? Das ja.
Benutzeravatar
Dennis89
User
Beiträge: 1156
Registriert: Freitag 11. Dezember 2020, 15:13

Kurz gefragt, wenn du ein neues Projekt mit einem ESP startest, legst du das auch so an:

Code: Alles auswählen

cargo generate esp-rs/esp-idf-template cargo
Wenn nein, wieso nicht und wie dann?

Danke und Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
__deets__
User
Beiträge: 14544
Registriert: Mittwoch 14. Oktober 2015, 14:29

Es ist schon etwas her (momentan Rust ja fuer den Pico + gerade aktuell Pi 4, weil ich eine dicke GUI brauche), aber wenn ich mich recht erinnere, habe ich das Beispielprojekt genommen und angepasst. Kann aber gut sein, dass das auf das gleiche rauslaeuft. Was ich in jedem Fall empfehlen kann ist der esp-rs Matrix-Kanal, da haben sie mir auch gut geholfen.
Benutzeravatar
Dennis89
User
Beiträge: 1156
Registriert: Freitag 11. Dezember 2020, 15:13

Super, vielen Dank, habe mir den Link gleich mal gespeichert.

Die LED blinkt 🥳

Viele Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
Dennis89
User
Beiträge: 1156
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

falls jemand auch an einem Einstieg in Rust mit ESP interessiert ist, über den esp-rs Matrix-Kanal habe ich folgendes gefunden:
https://esp-rs.github.io/std-training/01_intro.html

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
Dennis89
User
Beiträge: 1156
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

ich habe mal wieder eine Frage. Ich schaue mir immer wieder Tutorials und habe das hier gefunden. Der Code daraus ist folgender:

Code: Alles auswählen

use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported

use esp_idf_hal::delay::FreeRtos;
use esp_idf_hal::gpio::*;
use esp_idf_hal::peripherals::Peripherals;

fn main() {
    // It is necessary to call this function once. Otherwise some patches to the runtime
    // implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71
    esp_idf_sys::link_patches();

    // Take Peripherals
    let dp = Peripherals::take().unwrap();

    let mut leds = [
        PinDriver::output(dp.pins.gpio1.downgrade_output()).unwrap(),
        PinDriver::output(dp.pins.gpio10.downgrade_output()).unwrap(),
        PinDriver::output(dp.pins.gpio19.downgrade_output()).unwrap(),
        PinDriver::output(dp.pins.gpio18.downgrade_output()).unwrap(),
        PinDriver::output(dp.pins.gpio4.downgrade_output()).unwrap(),
        PinDriver::output(dp.pins.gpio5.downgrade_output()).unwrap(),
        PinDriver::output(dp.pins.gpio6.downgrade_output()).unwrap(),
        PinDriver::output(dp.pins.gpio7.downgrade_output()).unwrap(),
        PinDriver::output(dp.pins.gpio8.downgrade_output()).unwrap(),
        PinDriver::output(dp.pins.gpio9.downgrade_output()).unwrap(),
    ];

    // Configure Button pin to input with Pull Up
    let mut button = PinDriver::input(dp.pins.gpio3).unwrap();
    button.set_pull(Pull::Up).unwrap();

    // Initialize variable with starting delay
    let mut blinkdelay = 200_u32;

    loop {
        for mut led in &mut leds {
            led.set_high().unwrap();
            blinkdelay = button_pressed(&button, &blinkdelay);
            FreeRtos::delay_ms(blinkdelay);
            led.set_low().unwrap();
            FreeRtos::delay_ms(100_u32);
        }
    }
}

fn button_pressed(but: &PinDriver<'_, Gpio3, Input>, del: &u32) -> u32 {
    // Check if Button has been pressed
    // If not pressed, return the delay value unchanged
    if but.is_low() {
        // if the value of the delay passed is less of equal to 50 then reset it to initial value
        // else subtract 50 from the passed delay
        println!("Button Pressed!");
        if del <= &50_u32 {
            return 200_u32;
        } else {
            return del - 50_u32;
        }
    } else {
        return *del;
    }
}
Mir geht es um die Funktion 'button_pressed' und zwar um die Angabe der Argumente. Der Name 'but' wird angegeben und ist eine Referenz von 'PinDriver'. Ich verstehe nicht was die spitzen Klammern bedeuten. Ich kann mir zusammen reimen, dass damit angegeben wird, welcher 'PinDriver' gemeint ist. Aber so ganz klar ist mir das nicht. Ich habe mir die Dokue zu PinDriver angeschaut. Dort findet man

Code: Alles auswählen

pub struct PinDriver<'d, T: Pin, MODE> { /* private fields */ }
Sieht ja ähnlich aus. Nur das in dem Code 'd' ignoriert wird, aber beides mal wir davor ein Hochkomma angeben, wieso und was ist 'd'? Dann ist 'T' der Pin, das leuchtet mir ein. Gibts eigentlich eine Übersetzung für 'T'? Es gibt ja immer in den 'Results' 'T' und 'E''. 'E' ist der Fehler und 'T' der Wert.
'Mode' ist auch selbsterklärend.
Wieso wird bei ''d' und 'MODE' nicht angeben um welchen Datentyp es sich handelt und bei 'T' schon?

Könnt ihr mir das bitte erklären? Ich kann mit der Doku irgendwie nicht ganz so viel anfangen und das mit der spitzen Klammer habe ich in Rust - The book nicht finden können. Vielleicht würde es auch schon helfen, wenn ich wüsste wie man die Angabe der spitzen Klammern nennt. Dann könnte ich besser danach suchen und ich würde nicht immer beim Größer-Vergleich landen.

Vielen Dank für eure Hilfe vorab.

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
narpfel
User
Beiträge: 645
Registriert: Freitag 20. Oktober 2017, 16:10

Die spitzen Klammern sind für Generics. In Python-Typannotationen wären das eckige Klammern, z. B. `list[int]` wäre in Rust in etwa `Vec<u64>`.

`T: Pin` heißt, dass der Typ, der für den Typparameter `T` angegeben wird, den Trait `Pin` implementieren muss. In Python wäre das in etwa `T = TypeVar("T", bound=Pin)`. Der Name vom Typparameter ist dabei (wie bei normalen Funktionsparametern und Variablen) einfach nur ein Name. `T` ist als Abkürzung für „type“ relativ üblich in Generics, wo man nichts genaues über den Typ weiß. `list[T]` bzw. `Vec<T>` ist ein klassisches Beispiel, `T` kann alles sein und man weiß nichts über den Typen, also `T`.

Wenn der Typparameter nicht mit `: Trait` oder in einer `where`-Clause eingeschränkt wird (wie bei `Vec<T>`), dann kann man da alle Typen angeben. `MODE` kann also jeder beliebige Typ sein.

Generische Parameter, die mit einem ' anfangen, sind keine Typparameter, sondern Lifetime-Parameter. Das Thema kann man nicht mal eben in einem Forenbeitrag erklären (und es gibt in Python kein analoges Konzept), da solltest du mindestens die entsprechenden Kapitel im Buch lesen. Das schon verlinkte zu Generics und Lifetime-Parametern, und davor das Kapitel über Ownership. (Und am besten das ganze Buch von vorne bis hinten durcharbeiten. :mrgreen: Das ist zwar doof, wenn man schnell Erfolge sehen will, aber Rust ist schon relativ anders als Python, und mittelfristig ist es einfacher, wenn man eine gewisse Grundlage hat. Insbesondere auch, weil so spezielle Themen wie Rust auf ESP32 die im Buch beschriebenen Grundlagen wahrscheinlich einfach voraussetzen.)

Die Kurzversion ist, dass eine Referenz auf einen Wert in Rust den Wert nicht automatisch am Leben erhält wie in Python, sondern dass man selbst dafür sorgen muss, dass der Wert, auf den die Referenz zeigt, mindestens so lange lebt wie die Referenz. Und damit das alles (anders als in Sprachen wie C oder C++) nicht sofort kaputt geht, wenn man einen Fehler macht, muss man dem Compiler genug Informationen geben, dass der beweisen kann, dass es keine Referenzen auf tote Werte gibt. Und das macht man über Lifetime-Parameter (kleines Beispiel), mit denen man z. B. kennzeichnen kann, dass die Lebenszeit des Rückgabewerts einer Funktion höchstens so lang sein darf wie die Lebenszeit der Argumente (weil man sonst auf tote Werte zugreifen könnte).

In dem gezeigten `PinDriver`-Fall scheint die Lifetime benutzt zu werden, um sicherzustellen, dass man nicht zwei verschiedene `PinDriver` für den gleichen Pin erstellen kann. Sowas sieht man in Rust relativ oft, und aus Python-Sicht ist das immer ein wenig ungewohnt: Das Typsystem wird benutzt, um bestimmte Programmierfehler zu einem Fehler zur Compilezeit zu machen, wo man in Python einen Laufzeitfehler (oder komisches Verhalten) bekommen würde. Das führt dazu, dass die Typen in Rust manchmal ein bisschen unhandlich werden; da muss man dann einfach durch.
Benutzeravatar
Dennis89
User
Beiträge: 1156
Registriert: Freitag 11. Dezember 2020, 15:13

Vielen Dank für die ausführliche Erklärungen und auch für die Links zu den richtigen Kapiteln.🙂
Ich werde die Kapitel (noch ein mal) durcharbeiten und auch versuchen dein Beispiel zu verstehen. Wollte nur mit der Antwort nicht so lange warten, bis ich damit durch bin.

Ich habe das Buch von Anfang an bis Kapitel 7 gelesen. An dem Punkt dachte ich mir, das ich jetzt mal irgendwas machen/programmieren muss um das gelesene irgendwie zu verarbeiten. Aber ich muss auch ehrlicherweise sagen, dass gelesen nicht bedeutet das ich auch alles verstanden habe. Gerade weil das ganz anders wie Python ist und Python die einzige Sprache ist, mit der ich mich beschäftigt habe, ist hier seeeehr viel neues für mich dabei. Da bin ich schon etwas verwöhnt geworden. Es ist echt faszinierend an was man alles so denken muss.

Eine gute Voraussetzung zum lernen von Rust habe ich: Seit dem ich es mir überlegt habe, habe ich nicht ein mal an einen schnellen Erfolg gedacht 😅

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
__deets__
User
Beiträge: 14544
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich kämpfe da auch durchaus immer noch. Gerade auch im embedded Bereich ist die Typ-annotiererei extrem, eben wie die HAL-Autoren schon zur compile-zeit gewisse Fehler ausschließen wollen. Aber es wird langsam besser.
Benutzeravatar
Dennis89
User
Beiträge: 1156
Registriert: Freitag 11. Dezember 2020, 15:13

Guten Morgen,

ohje, der Weg wird also noch steiniger als gedacht. 🦧
"When I got the music, I got a place to go" [Rancid, 1993]
narpfel
User
Beiträge: 645
Registriert: Freitag 20. Oktober 2017, 16:10

Dennis89 hat geschrieben: Samstag 16. Dezember 2023, 23:38 Aber ich muss auch ehrlicherweise sagen, dass gelesen nicht bedeutet das ich auch alles verstanden habe.
Alles verstehen muss man nicht, aber es ist IMHO wichtig, alle Grundlagen zumindest mal gesehen zu haben. Damit man weiß, was möglich ist (auch wenn man es ohne erneutes Nachlesen nicht umsetzen kann) oder (und das war der Grund, warum ich das Buch in diesem Fall nochmal speziell erwähnt habe) damit man weiß, wonach man suchen muss, wann man was sieht, was man nicht versteht.

Aber wenn du das Buch liest und parallel dazu ein Projekt (oder ein paar kleine Beispielprogramme) umsetzt, bist du schonmal auf einem guten Weg. :) Wenn man am Ball bleibt, ist das alles gar nicht soo schwer.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Gerade weil das ganz anders wie Python ist und Python die einzige Sprache ist, mit der ich mich beschäftigt habe, ist hier seeeehr viel neues für mich dabei. Da bin ich schon etwas verwöhnt geworden.
Ja, es ist sehr anders. Ich habe mich auch mal angefangen, mit Rust zu beschäftigen, bin dann aber ziemlich zügig zu dem Entschluss gekommen, das abzubrechen. Weil mir für mich klar war, das ich das auf absehbare Zeit nie brauchen werden. Bei dir ist es ja anders, weil die konkrete Projekte hast.

Rust lernen halte ich per se schon für gut, weil das IMHO auf absehbare Zeit weiter wichtiger / populärer für "low level" Programmierung anstelle von C oder C++ wird.

Gruß, noisefloor
Benutzeravatar
snafu
User
Beiträge: 6742
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

noisefloor hat geschrieben: Sonntag 17. Dezember 2023, 15:37 Rust lernen halte ich per se schon für gut, weil das IMHO auf absehbare Zeit weiter wichtiger / populärer für "low level" Programmierung anstelle von C oder C++ wird.
Wobei es da mit Go einen nicht zu unterschätzenden Mitstreiter gibt. Ich persönlich finde Go sogar besser, auch aufgrund der externen Bibliotheken, die hierfür im Umlauf sind. Als Beispiel sei hier Bubble Tea (https://github.com/charmbracelet/bubbletea) genannt, was man in der Python-Welt wohl am ehesten mit rich (https://github.com/Textualize/rich) vergleichen kann. Für Bubble Tea gibt es auch noch jede Menge Erweiterungen (z. B. Lipgloss). Bin darauf gestoßen, weil Savannah Ostrowski damit ein Tool gebastelt hat, was eigentlich nicht viel tut, aber dafür total schick aussieht (https://github.com/savannahostrowski/gruyere). :mrgreen:
Benutzeravatar
Dennis89
User
Beiträge: 1156
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,
Wenn man am Ball bleibt, ist das alles gar nicht soo schwer.
Ich werde berichten :mrgreen:
weil die konkrete Projekte hast.
Ohne Ziel finde ich das fast unmöglich, weil man kann ja "alles" programmieren und zu Beginn sollte man ja mal in eine Richtung abbiegen und sich auf einen Bruchteil konzentrieren. Mir hilft das auf jeden Fall sehr. Aber da ist ja auch jeder anders.

Auf jeden Fall werde ich ich natürlich weiter machen und mich hier bestimmt noch öfters melden. :oops:

Schönen Sonntagabend euch noch,
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Antworten