From c12d55ca3ba550df05768fc421c259cb25204af9 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Pelayo Date: Thu, 16 Apr 2026 15:49:05 +0200 Subject: [PATCH] Add STM32F407 Renode blink Rust firmware and Jumpstarter example Create the embedded Rust project (USART2 ON/OFF lines, PD12 LED) with stm32f4xx-hal, plus README, linker script, and rust-toolchain for thumbv7em-none-eabihf. Include Cargo.lock and a prebuilt ELF for flashing. Made-with: Cursor --- .../stm32f407-rust-blink/.cargo/config.toml | 5 + .../examples/stm32f407-rust-blink/.gitignore | 1 + .../examples/stm32f407-rust-blink/Cargo.lock | 384 ++++++++++++++++++ .../examples/stm32f407-rust-blink/Cargo.toml | 17 + .../examples/stm32f407-rust-blink/README.md | 75 ++++ .../examples/stm32f407-rust-blink/build.rs | 14 + .../exporter-stm32f4.yaml | 21 + .../examples/stm32f407-rust-blink/memory.x | 5 + .../stm32f407-rust-blink/rust-toolchain.toml | 3 + .../examples/stm32f407-rust-blink/src/main.rs | 46 +++ .../stm32f407-rust-blink.elf | Bin 0 -> 139864 bytes 11 files changed, 571 insertions(+) create mode 100644 python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/.cargo/config.toml create mode 100644 python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/.gitignore create mode 100644 python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/Cargo.lock create mode 100644 python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/Cargo.toml create mode 100644 python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/README.md create mode 100644 python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/build.rs create mode 100644 python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/exporter-stm32f4.yaml create mode 100644 python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/memory.x create mode 100644 python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/rust-toolchain.toml create mode 100644 python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/src/main.rs create mode 100644 python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/stm32f407-rust-blink.elf diff --git a/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/.cargo/config.toml b/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/.cargo/config.toml new file mode 100644 index 000000000..ff32d1319 --- /dev/null +++ b/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/.cargo/config.toml @@ -0,0 +1,5 @@ +[build] +target = "thumbv7em-none-eabihf" + +[target.thumbv7em-none-eabihf] +rustflags = ["-C", "link-arg=-Tlink.x"] diff --git a/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/.gitignore b/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/Cargo.lock b/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/Cargo.lock new file mode 100644 index 000000000..d191e66e6 --- /dev/null +++ b/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/Cargo.lock @@ -0,0 +1,384 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version", +] + +[[package]] +name = "bare-metal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" + +[[package]] +name = "bitfield" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" + +[[package]] +name = "cortex-m" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9" +dependencies = [ + "bare-metal 0.2.5", + "bitfield", + "critical-section", + "embedded-hal 0.2.7", + "volatile-register", +] + +[[package]] +name = "cortex-m-rt" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d4dec46b34c299ccf6b036717ae0fce602faa4f4fe816d9013b9a7c9f5ba6" +dependencies = [ + "cortex-m-rt-macros", +] + +[[package]] +name = "cortex-m-rt-macros" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e37549a379a9e0e6e576fd208ee60394ccb8be963889eebba3ffe0980364f472" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[package]] +name = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "document-features" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", +] + +[[package]] +name = "embedded-dma" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "994f7e5b5cb23521c22304927195f236813053eb9c065dd2226a32ba64695446" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "embedded-hal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" + +[[package]] +name = "embedded-hal-nb" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba4268c14288c828995299e59b12babdbe170f6c6d73731af1b4648142e8605" +dependencies = [ + "embedded-hal 1.0.0", + "nb 1.1.0", +] + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + +[[package]] +name = "embedded-storage" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" + +[[package]] +name = "enumflags2" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" +dependencies = [ + "enumflags2_derive", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "fugit" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e639847d312d9a82d2e75b0edcc1e934efcc64e6cb7aa94f0b1fbec0bc231d6" +dependencies = [ + "gcd", +] + +[[package]] +name = "fugit-timer" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9607bfc4c388f9d629704f56ede4a007546cad417b3bcd6fc7c87dc7edce04a" +dependencies = [ + "fugit", + "nb 1.1.0", +] + +[[package]] +name = "gcd" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" + +[[package]] +name = "litrs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" + +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "nb" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" + +[[package]] +name = "num-conv" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" + +[[package]] +name = "panic-halt" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a513e167849a384b7f9b746e517604398518590a9142f4846a32e3c2a4de7b11" + +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "stm32f4" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41bd8922df364cb7054cae71a95dcbb32cffd25b5c0f9c00272ef8c82279a65" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "critical-section", + "portable-atomic", + "vcell", +] + +[[package]] +name = "stm32f407-rust-blink" +version = "0.1.0" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "panic-halt", + "stm32f4xx-hal", +] + +[[package]] +name = "stm32f4xx-hal" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b5b520616b1ebd18b3ac2d809b8ae47851b14efc63aea7c85d8a45c1daa6fbb" +dependencies = [ + "bare-metal 1.0.0", + "cortex-m", + "cortex-m-rt", + "document-features", + "embedded-dma", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-nb", + "embedded-io", + "embedded-storage", + "enumflags2", + "fugit", + "fugit-timer", + "nb 1.1.0", + "rand_core 0.6.4", + "rand_core 0.9.5", + "stm32f4", + "time", + "void", +] + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "time" +version = "0.3.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "vcell" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "volatile-register" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc" +dependencies = [ + "vcell", +] diff --git a/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/Cargo.toml b/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/Cargo.toml new file mode 100644 index 000000000..2054e084c --- /dev/null +++ b/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "stm32f407-rust-blink" +version = "0.1.0" +edition = "2021" +description = "STM32F407 Discovery blink + USART2 (Renode / Jumpstarter example firmware)" +license = "Apache-2.0" + +[[bin]] +name = "stm32f407-rust-blink" +test = false +bench = false + +[dependencies] +cortex-m = "0.7.7" +cortex-m-rt = "0.7.5" +panic-halt = "1.0.0" +stm32f4xx-hal = { version = "0.23.0", features = ["stm32f407"] } diff --git a/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/README.md b/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/README.md new file mode 100644 index 000000000..d9b81f304 --- /dev/null +++ b/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/README.md @@ -0,0 +1,75 @@ +# STM32F407 Rust blink (Renode) + +This folder holds a **Jumpstarter exporter** plus a **prebuilt firmware** so you can run an STM32F407 blink demo inside **Renode** and drive it from the shell. + +## Files + +| File | Role | +|------|------| +| `exporter-stm32f4.yaml` | Exporter config: Renode platform (`stm32f4_discovery-kit.repl`), UART on `sysbus.usart2`, and the composite device label `ecu`. | +| `.cargo/config.toml` | Rust embedded target (`thumbv7em-none-eabihf`) and link script flags when you build firmware for this board. | +| `Cargo.toml`, `src/main.rs` | Firmware: toggles the Discovery user LED on **PD12**, prints **`ON` / `OFF`** on **USART2** (PA2 @ 115200 8N1), matching Renode’s `UserLED` and `usart2`. | +| `memory.x`, `build.rs` | Linker memory map for the STM32F407 and `cortex-m-rt` (`link.x`). | +| `rust-toolchain.toml` | Pins **stable** and the **`thumbv7em-none-eabihf`** target via rustup. | +| `stm32f407-rust-blink.elf` | Optional copy of the release ELF for flashing; the canonical build artifact is under `target/…/release/`. | +| `target/` | Rust build output (if you build here). | + +## Build the firmware + +Install the [rustup](https://rustup.rs/) toolchain and the embedded target (`rust-toolchain.toml` requests it). From this directory: + +```bash +PATH="$HOME/.cargo/bin:$PATH" cargo build --release +``` + +The ELF is `target/thumbv7em-none-eabihf/release/stm32f407-rust-blink`. Copy it if you want a stable name for Jumpstarter: + +```bash +cp target/thumbv7em-none-eabihf/release/stm32f407-rust-blink stm32f407-rust-blink.elf +``` + +## Workflow + +1. **Start a Jumpstarter shell** wired to this exporter (from this directory): + + ```bash + jmp shell --exporter-config exporter-stm32f4.yaml + ``` + +2. Inside that shell, `j` is the client for the exported **composite device**. The Renode stack is grouped under **`j ecu`** (not a top-level `j serial`). + +3. **Flash** the firmware: + + ```bash + j ecu flasher flash stm32f407-rust-blink.elf + ``` + +4. **Turn simulation on** and **open the serial console** (USART2 in this config): + + ```bash + j ecu power on && j ecu console start-console + ``` + + To reset the simulation and attach the console again: + + ```bash + j ecu power cycle && j ecu console start-console + ``` + +5. **Leave the console**: press **Ctrl+B three times** (as printed when the console starts). + +## `j ecu` commands (reference) + +Under `j ecu` you typically use: + +- **`flasher`** — load an ELF into the target. +- **`power`** — `on`, `off`, `cycle`, etc. (starts/controls the Renode simulation for this exporter). +- **`console`** — serial client (e.g. `start-console`) to the UART defined in the YAML. +- **`monitor`** — send commands to the Renode monitor. + +Run `j ecu --help` for the full list. + +## Requirements + +- **Renode** installed and on `PATH` (the driver spawns it for power/simulation). +- Jumpstarter CLI (`jmp`) and the **Renode driver** available to the exporter. diff --git a/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/build.rs b/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/build.rs new file mode 100644 index 000000000..0fe75885c --- /dev/null +++ b/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/build.rs @@ -0,0 +1,14 @@ +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; + +fn main() { + let out = PathBuf::from(env::var_os("OUT_DIR").expect("OUT_DIR")); + File::create(out.join("memory.x")) + .expect("memory.x in OUT_DIR") + .write_all(include_bytes!("memory.x")) + .expect("write memory.x"); + println!("cargo:rustc-link-search={}", out.display()); + println!("cargo:rerun-if-changed=memory.x"); +} diff --git a/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/exporter-stm32f4.yaml b/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/exporter-stm32f4.yaml new file mode 100644 index 000000000..967351077 --- /dev/null +++ b/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/exporter-stm32f4.yaml @@ -0,0 +1,21 @@ +# Renode driver exporter configuration examples +# +# Each example shows a different Renode target. The driver accepts any +# .repl platform description (built-in or custom) and any UART peripheral +# path -- new targets require only YAML configuration, no code changes. + +# --- STM32F407 Discovery (opensomeip FreeRTOS/ThreadX) --- +# Uses Renode's built-in platform, USART2 for console output. +# +apiVersion: jumpstarter.dev/v1alpha1 +kind: ExporterConfig +metadata: + name: renode-stm32f407 + namespace: test +export: + ecu: + type: jumpstarter_driver_renode.driver.Renode + config: + platform: "platforms/boards/stm32f4_discovery-kit.repl" + uart: "sysbus.usart2" + diff --git a/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/memory.x b/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/memory.x new file mode 100644 index 000000000..6888dcb2d --- /dev/null +++ b/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/memory.x @@ -0,0 +1,5 @@ +MEMORY +{ + FLASH : ORIGIN = 0x08000000, LENGTH = 1024K + RAM : ORIGIN = 0x20000000, LENGTH = 128K +} diff --git a/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/rust-toolchain.toml b/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/rust-toolchain.toml new file mode 100644 index 000000000..8de39d414 --- /dev/null +++ b/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/rust-toolchain.toml @@ -0,0 +1,3 @@ +[toolchain] +channel = "stable" +targets = ["thumbv7em-none-eabihf"] diff --git a/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/src/main.rs b/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/src/main.rs new file mode 100644 index 000000000..101baad80 --- /dev/null +++ b/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/src/main.rs @@ -0,0 +1,46 @@ +//! Blinks the STM32F407 Discovery user LED (PD12) and prints `ON` / `OFF` on USART2. +//! +//! Matches Renode `platforms/boards/stm32f4_discovery-kit.repl`: USART2 (`sysbus.usart2`), +//! green LED on `gpioPortD` pin 12. Console is typically wired to PA2 (TX) at 115200 8N1. + +#![no_std] +#![no_main] + +use core::fmt::Write; + +use cortex_m_rt::entry; +use panic_halt as _; +use stm32f4xx_hal::rcc::Config; +use stm32f4xx_hal::{pac, prelude::*}; + +#[entry] +fn main() -> ! { + let dp = pac::Peripherals::take().unwrap(); + + // STM32F407G-DISC1: 8 MHz HSE + let mut rcc = dp.RCC.freeze(Config::hse(8.MHz()).sysclk(168.MHz())); + + let gpioa = dp.GPIOA.split(&mut rcc); + let gpiod = dp.GPIOD.split(&mut rcc); + + let mut tx = dp + .USART2 + .tx(gpioa.pa2, 115200.bps(), &mut rcc) + .expect("USART2"); + + let mut led = gpiod.pd12.into_push_pull_output(); + + let mut delay = dp.TIM5.delay_ms(&mut rcc); + + loop { + led.set_high(); + writeln!(tx, "ON").ok(); + + delay.delay(200.millis()); + + led.set_low(); + writeln!(tx, "OFF").ok(); + + delay.delay(200.millis()); + } +} diff --git a/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/stm32f407-rust-blink.elf b/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/stm32f407-rust-blink.elf new file mode 100644 index 0000000000000000000000000000000000000000..b6165e51ff73409d01be4124782d454e24ca23f2 GIT binary patch literal 139864 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