Skip to content
Snippets Groups Projects
Commit 9418030e authored by Per Lindgren's avatar Per Lindgren
Browse files

polishing

parent dc83de16
No related branches found
No related tags found
No related merge requests found
......@@ -12,11 +12,11 @@ cortex-m-rtic = "0.5.5"
# tracing
cortex-m-semihosting = "0.3.5"
rtt-target = { version = "0.2.2", features = ["cortex-m"] }
rtt-target = { version = "0.3.0", features = ["cortex-m"] }
# panic handlers
panic-halt = "0.2.0"
panic-semihosting = "0.5.4"
panic-semihosting = "0.5.6"
panic-rtt-target = { version = "0.1.1", features = ["cortex-m"] }
[dependencies.stm32f4]
......
......@@ -29,5 +29,26 @@ Linux tooling:
You may use any editor of choice. `vscode` supports Rust using the `rust-analyzer` plugin.
---
## Exercises
- `src/main.rs`
Developing embedded applications in Rust is made simle by the RTIC framework. In this exercise you will familiarize yourself with the basics `init` and `idle`, and see how you can trace the output to a terminal using `cargo-run`.
You will also learn about `panic`s and how they can be traced.
- `examples/rtt_timing.rs`
Here you will learn about cycle accurate timing measurements.
- Using instrumentation code (which introduces bloat and overhead).
- Non intrusive measurements using the on-chip debug unit and `gdb`.
- Code generation optimization
- Code inspection, `objdump`, debugging and interactive `disassemble`.
- Code trimming, RTIC is "A Zero-Cost Abstraction for Memory Safe Concurrency".
//! examples/rtt_simple.rs
#![deny(unsafe_code)]
#![deny(warnings)]
#![no_main]
#![no_std]
use panic_rtt_target as _;
use rtt_target::{rprintln, rtt_init_print};
use stm32f4;
#[rtic::app(device = stm32f4)]
const APP: () = {
#[init]
fn init(_cx: init::Context) {
rtt_init_print!();
rprintln!("init");
}
#[idle]
fn idle(_cx: idle::Context) -> ! {
rprintln!("idle");
loop {
continue;
}
}
};
// > cargo run rtt_simple
// Compiling app v0.1.0 (/home/pln/courses/e7020e/app)
// Finished dev [unoptimized + debuginfo] target(s) in 0.15s
// Running `probe-run --chip STM32F411RETx target/thumbv7em-none-eabi/debug/examples/rtt_simple`
// flashing program ..
// DONE
// resetting device
// init
// idle
//
// > [Ctrl-C]
// stack backtrace:
// 0: 0x0800031a - rtt_simple::idle
// 1: 0x0800036c - main
// 2: 0x080001da - Reset
......@@ -69,6 +69,10 @@ fn timed_loop() -> (u32, u32) {
//
// [Your answer here]
//
// A.3) Why do we need a wrapping subtraction?
//
// [Your answer here]
//
// ------------------------------------------------------------------------
// Now try a release (optimized build, see `Cargo.toml` for build options).
// B.1) What is the cycle count for the loop?
......@@ -106,7 +110,7 @@ fn timed_loop() -> (u32, u32) {
//
// Now try a release (optimized build, see `Cargo.toml` for build options).
// C.1) What is the cycle count for the loop?
// > cargo run --example rtt_timing --release
// > cargo run --example rtt_timing --release --features nightly
//
// [Your answer here]
//
......@@ -121,7 +125,7 @@ fn timed_loop() -> (u32, u32) {
// ------------------------------------------------------------------------
// D) Now lets have a closer look at the generated assembly.
//
// > cargo objdump --example rtt_timing --release --features nightly -- --disassemble > rtt_timing.objdump
// > cargo objdump --example rtt_timing --release --features nightly -- --disassemble --no-show-raw-insn > rtt_timing.objdump
//
// Open the file in you editor and search for the `timed_loop`.
//
......
//! examples/init.rs
//! main.rs
#![deny(unsafe_code)]
// #![deny(warnings)]
#![deny(warnings)]
#![no_main]
#![no_std]
use cortex_m;
// use panic_halt as _;
use panic_rtt_target as _;
use rtt_target::{rprintln, rtt_init_print};
use stm32f4;
// #[rtic::app(device = lm3s6965, peripherals = true)]
#[rtic::app(device = stm32f4)]
const APP: () = {
#[init]
fn init(_cx: init::Context) {
rtt_init_print!();
rprintln!("init");
}
#[idle]
fn idle(_cx: idle::Context) -> ! {
rprintln!("idle");
panic!("panic");
// panic!("panic");
loop {
continue;
}
}
};
// A) A Simple Trace
// > cargo run
// cargo run
// Compiling app v0.1.0 (/home/pln/courses/d7020e/rtic_f4xx_nucleo)
// Finished dev [unoptimized + debuginfo] target(s) in 0.18s
// Running `probe-run --chip STM32F411RETx target/thumbv7em-none-eabi/debug/app`
// (HOST) INFO flashing program (15.06 KiB)
// (HOST) INFO success!
// ────────────────────────────────────────────────────────────────────────────────
// init
// idle
//
// B) Breaking
// Now press Ctrl-C
// ^Cstack backtrace:
// 0: app::idle
// at src/main.rs:25
// 1: main
// at src/main.rs:13
// 2: Reset
// at /home/pln/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-rt-0.6.13/src/lib.rs:526
//
// Make sure you got the expected output
//
// C) Panic tracing
// Rust is designed for reliability, with the aim to deliver memory safety
// and defined behavior at all times.
// Recoverable errors (in libraries and user code) should use the `Result<T,E>` type,
// while unrecoverable errors should `panic`.
//
// Let's introduce a `panic` (uncomment line 24).
// > cargo run
//
// What is the output?
//
// [Your answer here]
//
// D) Panic halt
// Tracing is nice during development, but requires a debugger attached
// and a host listening. For a deployed product, other `panic` behavior
// should be adopted (e.g. storing to flash, for later post-mortem debugging)
// or just reset:ing the device. In this example we chose just to `halt`
//
// Enable `panic_halt` (line 8).
// > cargo run
//
// What is the output?
//
// [Your answer here]
//
// Now press Ctrl-C
//
// What is the output?
//
// [Your answer here]
//
// E) Find the source
// Figure out how to find the source of `panic_halt`, and look at the implementation.
//
// - `cargo doc --open` (you need to disable the rtt-panic handler in `Cargo.toml`).
// - `crates.io`
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment