diff --git a/Cargo.toml b/Cargo.toml
index 5566427d541becf7805eb85b9fee5795675370b6..80141736d21cfdb6d8cbf6fafca12f3b25029317 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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]
diff --git a/README.md b/README.md
index bc0b0e712cbe7673aac8b76a0cdca9bb7b936522..cc1de83be63db0f07d1b16e72506e1ce45eec16d 100644
--- a/README.md
+++ b/README.md
@@ -23,11 +23,32 @@ Linux tooling:
 
 - `openocd`
 - `arm-none-eabi-gdb`, or
-- `gdb-multiarch` 
+- `gdb-multiarch`
 
 ## Editor
 
 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".
diff --git a/examples/rtt_simple.rs b/examples/rtt_simple.rs
deleted file mode 100644
index c9005a436f1a189eb86647fa8a53f8e3e6b07ba0..0000000000000000000000000000000000000000
--- a/examples/rtt_simple.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-//! 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
diff --git a/examples/rtt_timing.rs b/examples/rtt_timing.rs
index e589698619d1c4730bfd78a73a59f5219fba96dd..4ee67756ac0d8fceb17692d8701abfa5df55fba9 100644
--- a/examples/rtt_timing.rs
+++ b/examples/rtt_timing.rs
@@ -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?
@@ -99,14 +103,14 @@ fn timed_loop() -> (u32, u32) {
 // info: using existing install for 'nightly-x86_64-unknown-linux-gnu'
 // info: override toolchain for '/home/pln/courses/e7020e/app' set to 'nightly-x86_64-unknown-linux-gnu'
 //
-//  nightly-x86_64-unknown-linux-gnu unchanged - rustc 1.49.0-nightly (cf9cf7c92 2020-11-10)
+// nightly-x86_64-unknown-linux-gnu unchanged - rustc 1.49.0-nightly (cf9cf7c92 2020-11-10)
 //
 // > rustup target add thumbv7em-none-eabi
 // (only needed first time)
 //
 // 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`.
 //
diff --git a/src/main.rs b/src/main.rs
index bc85ce18358c7480181753a839d9eb6a9d7862d5..885c4d75da0780a0baec617f7860895b39d2965b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,33 +1,91 @@
-//! 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`