diff --git a/.cargo/config.toml b/.cargo/config.toml index 1d4a03d..691ccb6 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,6 +1,9 @@ [build] target = "thumbv6m-none-eabi" +[env] +DEFMT_LOG = "trace" + [target.thumbv6m-none-eabi] rustflags = [ "-C", @@ -8,11 +11,13 @@ rustflags = [ "-C", "link-arg=-Tlink.x", "-C", + "link-arg=-Tdefmt.x", + "-C", "no-vectorize-loops", ] -runner = "picotool load --update --verify --execute -t elf" +#runner = "picotool load --update --verify --execute -t elf" # This runner will find a supported SWD debug probe and flash your RP2040 over # SWD: -# runner = "probe-rs run --chip RP2040" +runner = "probe-rs run --chip RP2040 --protocol swd --speed 2000" diff --git a/Cargo.lock b/Cargo.lock index 15bef12..fb32a32 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -74,6 +74,12 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d7e60934ceec538daadb9d8432424ed043a904d8e0243f3c6446bce549a46ac" +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.13.0" @@ -189,6 +195,47 @@ version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80a4af69c60438a1a82af89d362f4729fd38db7b73f305a237636fad31ceb2bf" +[[package]] +name = "defmt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8" +dependencies = [ + "defmt-parser", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror", +] + +[[package]] +name = "defmt-rtt" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05144944c117db54127a8ac17a3c9a28d55e7047bfddb950bcd20b4a94c79b10" +dependencies = [ + "critical-section", + "defmt", +] + [[package]] name = "digest" version = "0.10.7" @@ -608,6 +655,16 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a513e167849a384b7f9b746e517604398518590a9142f4846a32e3c2a4de7b11" +[[package]] +name = "panic-probe" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd402d00b0fb94c5aee000029204a46884b1262e0c443f166d86d2c0747e1a1a" +dependencies = [ + "cortex-m", + "defmt", +] + [[package]] name = "parking_lot" version = "0.12.5" @@ -661,10 +718,13 @@ name = "pico" version = "0.1.0" dependencies = [ "cortex-m-rt", + "defmt", + "defmt-rtt", "embedded-graphics", "embedded-hal 1.0.0", "heapless 0.9.3", "panic-halt", + "panic-probe", "rp2040-boot2", "rp2040-hal", "ssd1306", @@ -797,7 +857,7 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "679341d22c78c6c649893cbd6c3278dcbe9fc4faa62fea3a9296ae2b50c14625" dependencies = [ - "bitflags", + "bitflags 2.13.0", "memchr", "unicase", ] @@ -823,7 +883,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags", + "bitflags 2.13.0", ] [[package]] @@ -1072,6 +1132,26 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + [[package]] name = "typenum" version = "1.20.1" diff --git a/Cargo.toml b/Cargo.toml index 6ce17ed..3484e12 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,10 +5,13 @@ edition = "2024" [dependencies] cortex-m-rt = "0.7.5" +defmt = "1.1.1" +defmt-rtt = "1.3.0" embedded-graphics = "0.8.2" embedded-hal = "1.0.0" heapless = "0.9.3" panic-halt = "1.0.0" +panic-probe = { version = "1.0.0", features = ["print-defmt"] } rp2040-boot2 = "0.3.0" rp2040-hal = { version = "0.12.0", features = ["critical-section-impl"] } ssd1306 = "0.10.0" diff --git a/LEARNINGS.md b/LEARNINGS.md new file mode 100644 index 0000000..df5a462 --- /dev/null +++ b/LEARNINGS.md @@ -0,0 +1,267 @@ +# Raspberry Pi Pico Debugging mit Rust + +## ST-Link V2 funktioniert nicht mit dem RP2040 + +### Problem + +Beim Verbinden über `probe-rs` erschien: + +```text +JtagGetIdcodeError +``` + +Mit OpenOCD: + +```text +Error: init mode failed (unable to connect to the target) +``` + +### Ursache + +Der verwendete günstige ST-Link-V2-Klon konnte zwar erkannt werden und sogar die Zielspannung messen, war aber nicht in der Lage, zuverlässig mit dem RP2040 über SWD zu kommunizieren. + +### Lösung + +Verwendung der offiziellen **Raspberry Pi Debug Probe** (CMSIS-DAP). + +--- + +## Raspberry Pi Debug Probe + +Die Raspberry Pi Debug Probe wird von `probe-rs` und OpenOCD nativ unterstützt. + +Verkabelung: + +``` +Debug Probe Pico + +SWCLK --------> SWCLK +SWDIO --------> SWDIO +GND --------> GND +``` + +Der Pico kann weiterhin separat per USB versorgt werden. + +--- + +## Firmware der Debug Probe aktualisieren + +`probe-rs` meldete: + +```text +The firmware on the probe is outdated. +The minimum supported firmware version is 2.2.0. +``` + +### Lösung + +Firmware der Debug Probe mittels UF2-Datei aktualisieren. + +Danach funktionierte `probe-rs` problemlos. + +--- + +## OpenOCD testen + +Zum Testen der SWD-Verbindung: + +```bash +openocd \ + -f interface/cmsis-dap.cfg \ + -f target/rp2040.cfg +``` + +Erfolgreiche Verbindung erkennt man an: + +```text +SWD DPIDR 0x0bc12477 +``` + +--- + +## probe-rs als Cargo Runner + +In `.cargo/config.toml`: + +```toml +[target.thumbv6m-none-eabi] +runner = "probe-rs run --chip RP2040 --protocol swd" +``` + +Dadurch führt `cargo run` automatisch aus: + +- Build +- Flash +- Reset +- Start +- RTT/defmt-Monitoring + +--- + +## cargo run beendet sich nicht + +### Beobachtung + +Nach dem Flashen blieb `cargo run` geöffnet. + +### Erklärung + +Das ist beabsichtigt. + +`probe-rs run` bleibt mit dem Mikrocontroller verbunden, damit: + +- RTT gelesen werden kann +- `defmt`-Logs angezeigt werden +- später Debugging möglich ist + +--- + +## defmt einrichten + +Benötigte Crates: + +```toml +defmt = "1" +defmt-rtt = "1" +panic-probe = { version = "...", features = ["print-defmt"] } +``` + +Initialisierung: + +```rust +use defmt_rtt as _; +use panic_probe as _; +``` + +Logs: + +```rust +defmt::info!("Hello!"); +defmt::warn!("Voltage low"); +defmt::debug!("Counter = {}", counter); +``` + +--- + +## duplicate lang item: panic_impl + +### Problem + +```text +duplicate lang item: panic_impl +``` + +### Ursache + +Es waren zwei Panic-Handler eingebunden. + +Beispielsweise: + +```rust +use panic_halt as _; +``` + +und zusätzlich + +```rust +use panic_probe as _; +``` + +### Lösung + +Es darf nur **ein** Panic-Handler vorhanden sein. + +Für `defmt` sollte ausschließlich `panic-probe` verwendet werden. + +--- + +## Failed to parse defmt data + +### Problem + +```text +Failed to parse defmt data + +defmt version found, but no .defmt section +``` + +### Ursache + +Das Linkerscript `defmt.x` wurde nicht eingebunden. + +### Lösung + +`.cargo/config.toml` erweitern: + +```toml +rustflags = [ + "-C", "link-arg=-Tlink.x", + "-C", "link-arg=-Tdefmt.x", +] +``` + +--- + +## Keine defmt-Ausgaben sichtbar + +### Ursache + +`DEFMT_LOG` war nicht gesetzt. + +### Lösung + +In `.cargo/config.toml`: + +```toml +[env] +DEFMT_LOG = "info" +``` + +oder + +```toml +DEFMT_LOG = "debug" +``` + +oder + +```toml +DEFMT_LOG = "trace" +``` + +Danach wurden die Log-Ausgaben sofort angezeigt. + +--- + +## Debugging-Geschwindigkeit + +Anfangs wurde mit + +```text +--speed 100 +``` + +gearbeitet. + +Das funktioniert zuverlässig, ist aber sehr langsam. + +Später kann die Geschwindigkeit auf mehrere MHz erhöht werden, z.B. + +```text +--speed 4000 +``` + +was Flash- und Debug-Zeiten deutlich reduziert. + +--- + +## Erkenntnisse + +- SWD benötigt lediglich: + - SWCLK + - SWDIO + - GND +- Der Pico kann gleichzeitig per USB versorgt werden. +- `probe-rs run` ersetzt den manuellen Flash-Vorgang. +- `defmt` ist der De-facto-Standard für Logging im Rust-Embedded-Ökosystem. +- Die Raspberry Pi Debug Probe funktioniert mit dem RP2040 deutlich zuverlässiger als günstige ST-Link-V2-Klone. \ No newline at end of file diff --git a/src/boilerplate.rs b/src/boilerplate.rs index c2f81e1..bd2d468 100644 --- a/src/boilerplate.rs +++ b/src/boilerplate.rs @@ -1,4 +1,6 @@ +use defmt_rtt as _; use panic_halt as _; +// use panic_probe as _; use rp2040_hal::{ Timer, clocks::ClocksManager, diff --git a/src/main.rs b/src/main.rs index e217e3f..0fb9c8a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,6 +16,8 @@ use crate::display::DisplayModule; #[rp2040_hal::entry] fn main() -> ! { + defmt::info!("Controller started."); + let PicoParts { timer, pins,