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 000000000..b6165e51f Binary files /dev/null and b/python/packages/jumpstarter-driver-renode/examples/stm32f407-rust-blink/stm32f407-rust-blink.elf differ