From d2d86753ad17672def15b186fc6f21a8c346ab20 Mon Sep 17 00:00:00 2001
From: Per <Per Lindgren>
Date: Mon, 13 Jan 2020 22:53:32 +0100
Subject: [PATCH] runner examples

---
 Cargo.lock                | 154 ++++----
 Cargo.toml                |   6 +-
 README.md                 |  19 +-
 examples/f401_minimal.rs  |  85 +++-
 examples/f401_minimal2.rs | 229 +++++++++++
 examples/f401_probe.rs    |  99 +++++
 ktest/gdb.py              | 812 --------------------------------------
 openocd.gdb               |   6 +-
 runner/Cargo.lock         |  76 ++++
 9 files changed, 586 insertions(+), 900 deletions(-)
 create mode 100644 examples/f401_minimal2.rs
 create mode 100644 examples/f401_probe.rs
 delete mode 100644 ktest/gdb.py

diff --git a/Cargo.lock b/Cargo.lock
index 7a17f6b..2aed0e1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4,37 +4,40 @@
 name = "aligned"
 version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eb1ce8b3382016136ab1d31a1b5ce807144f8b7eb2d5f16b2108f0f07edceb94"
 dependencies = [
- "as-slice 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "as-slice",
 ]
 
 [[package]]
 name = "as-slice"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be6b7e95ac49d753f19cab5a825dea99a1149a04e4e3230b33ae16e120954c04"
 dependencies = [
- "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "generic-array 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "generic-array 0.12.3",
+ "generic-array 0.13.2",
+ "stable_deref_trait",
 ]
 
 [[package]]
 name = "bare-metal"
 version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3"
 dependencies = [
- "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version",
 ]
 
 [[package]]
 name = "cortex-m"
 version = "0.6.1"
-source = "git+https://github.com/perlindgren/cortex-m.git?branch=trustit#b2fa26f1044509a34006d4ad6303abc52ea09bce"
+source = "git+https://github.com/perlindgren/cortex-m.git?branch=trustit#d8f28518c429febf488baf0dd8d3488779edaa0e"
 dependencies = [
- "aligned 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "bare-metal 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "klee-sys 0.1.0 (git+https://gitlab.henriktjader.com/pln/klee-sys.git)",
- "volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "aligned",
+ "bare-metal",
+ "klee-sys",
+ "volatile-register",
 ]
 
 [[package]]
@@ -42,10 +45,10 @@ name = "cortex-m-rt"
 version = "0.6.11"
 source = "git+https://github.com/perlindgren/cortex-m-rt.git?branch=trustit#8d2686097e168e8b82d51ae1ea17d9ebe6d567e0"
 dependencies = [
- "cortex-m 0.6.1 (git+https://github.com/perlindgren/cortex-m.git?branch=trustit)",
- "cortex-m-rt-macros 0.1.7 (git+https://github.com/perlindgren/cortex-m-rt.git?branch=trustit)",
- "klee-sys 0.1.0 (git+https://gitlab.henriktjader.com/pln/klee-sys.git)",
- "r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cortex-m",
+ "cortex-m-rt-macros",
+ "klee-sys",
+ "r0",
 ]
 
 [[package]]
@@ -53,91 +56,99 @@ name = "cortex-m-rt-macros"
 version = "0.1.7"
 source = "git+https://github.com/perlindgren/cortex-m-rt.git?branch=trustit#8d2686097e168e8b82d51ae1ea17d9ebe6d567e0"
 dependencies = [
- "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
 name = "cortex-m-semihosting"
 version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "113ef0ecffee2b62b58f9380f4469099b30e9f9cbee2804771b4203ba1762cfa"
 dependencies = [
- "cortex-m 0.6.1 (git+https://github.com/perlindgren/cortex-m.git?branch=trustit)",
+ "cortex-m",
 ]
 
 [[package]]
 name = "cstr_core"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ebe7158ee57e848621d24d0ed87910edb97639cb94ad9977edf440e31226035"
 dependencies = [
- "cty 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cty",
+ "memchr",
 ]
 
 [[package]]
 name = "cty"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4e1d41c471573612df00397113557693b5bf5909666a8acb253930612b93312"
 
 [[package]]
 name = "generic-array"
 version = "0.12.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
 dependencies = [
- "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "typenum",
 ]
 
 [[package]]
 name = "generic-array"
 version = "0.13.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd"
 dependencies = [
- "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "typenum",
 ]
 
 [[package]]
 name = "klee-examples"
 version = "0.1.0"
 dependencies = [
- "cortex-m 0.6.1 (git+https://github.com/perlindgren/cortex-m.git?branch=trustit)",
- "cortex-m-rt 0.6.11 (git+https://github.com/perlindgren/cortex-m-rt.git?branch=trustit)",
- "cortex-m-semihosting 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "klee-sys 0.1.0 (git+https://gitlab.henriktjader.com/pln/klee-sys.git)",
- "lm3s6965 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "panic-halt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "panic-klee 0.1.0 (git+https://gitlab.henriktjader.com/pln/panic-klee.git)",
- "stm32f4 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "vcell 0.1.2 (git+https://github.com/perlindgren/vcell.git?branch=trustit)",
- "volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cortex-m",
+ "cortex-m-rt",
+ "cortex-m-semihosting",
+ "klee-sys",
+ "lm3s6965",
+ "panic-halt",
+ "panic-klee",
+ "stm32f4",
+ "vcell",
+ "volatile-register",
 ]
 
 [[package]]
 name = "klee-sys"
 version = "0.1.0"
-source = "git+https://gitlab.henriktjader.com/pln/klee-sys.git#c8275a34cffb895984d6bdea80e9c6ff9079f769"
+source = "git+https://gitlab.henriktjader.com/pln/klee-sys.git#3e49ed21f5514e7a3244a21c3cbebfcc4042929c"
 dependencies = [
- "cstr_core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cstr_core",
 ]
 
 [[package]]
 name = "lm3s6965"
 version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8698042a7495160eac9f7298a32cd1ddbb6ad2780f766f5a99b4f0a6b915e0ad"
 dependencies = [
- "bare-metal 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "cortex-m-rt 0.6.11 (git+https://github.com/perlindgren/cortex-m-rt.git?branch=trustit)",
+ "bare-metal",
+ "cortex-m-rt",
 ]
 
 [[package]]
 name = "memchr"
-version = "2.2.1"
+version = "2.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3197e20c7edb283f87c071ddfc7a2cca8f8e0b888c242959846a6fce03c72223"
 
 [[package]]
 name = "panic-halt"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812"
 
 [[package]]
 name = "panic-klee"
@@ -148,123 +159,104 @@ source = "git+https://gitlab.henriktjader.com/pln/panic-klee.git#3b0c897f49d7fff
 name = "proc-macro2"
 version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0319972dcae462681daf4da1adeeaa066e3ebd29c69be96c6abb1259d2ee2bcc"
 dependencies = [
- "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid",
 ]
 
 [[package]]
 name = "quote"
 version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
 dependencies = [
- "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2",
 ]
 
 [[package]]
 name = "r0"
 version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"
 
 [[package]]
 name = "rustc_version"
 version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
 dependencies = [
- "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "semver",
 ]
 
 [[package]]
 name = "semver"
 version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
 dependencies = [
- "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "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.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
 
 [[package]]
 name = "stm32f4"
 version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88640ad08c62e0651a1320187f38c3655d025ed580a10f0e4d85a2cc4829069f"
 dependencies = [
- "bare-metal 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "cortex-m 0.6.1 (git+https://github.com/perlindgren/cortex-m.git?branch=trustit)",
- "cortex-m-rt 0.6.11 (git+https://github.com/perlindgren/cortex-m-rt.git?branch=trustit)",
- "vcell 0.1.2 (git+https://github.com/perlindgren/vcell.git?branch=trustit)",
+ "bare-metal",
+ "cortex-m",
+ "cortex-m-rt",
+ "vcell",
 ]
 
 [[package]]
 name = "syn"
 version = "1.0.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e4ff033220a41d1a57d8125eab57bf5263783dfdcc18688b1dacc6ce9651ef8"
 dependencies = [
- "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2",
+ "quote",
+ "unicode-xid",
 ]
 
 [[package]]
 name = "typenum"
 version = "1.11.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
 
 [[package]]
 name = "unicode-xid"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
 
 [[package]]
 name = "vcell"
 version = "0.1.2"
 source = "git+https://github.com/perlindgren/vcell.git?branch=trustit#4eb44a012d65860c596556d6a63af9e0fa31853a"
 dependencies = [
- "klee-sys 0.1.0 (git+https://gitlab.henriktjader.com/pln/klee-sys.git)",
+ "klee-sys",
 ]
 
 [[package]]
 name = "volatile-register"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286"
 dependencies = [
- "vcell 0.1.2 (git+https://github.com/perlindgren/vcell.git?branch=trustit)",
+ "vcell",
 ]
-
-[metadata]
-"checksum aligned 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eb1ce8b3382016136ab1d31a1b5ce807144f8b7eb2d5f16b2108f0f07edceb94"
-"checksum as-slice 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "be6b7e95ac49d753f19cab5a825dea99a1149a04e4e3230b33ae16e120954c04"
-"checksum bare-metal 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3"
-"checksum cortex-m 0.6.1 (git+https://github.com/perlindgren/cortex-m.git?branch=trustit)" = "<none>"
-"checksum cortex-m-rt 0.6.11 (git+https://github.com/perlindgren/cortex-m-rt.git?branch=trustit)" = "<none>"
-"checksum cortex-m-rt-macros 0.1.7 (git+https://github.com/perlindgren/cortex-m-rt.git?branch=trustit)" = "<none>"
-"checksum cortex-m-semihosting 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "113ef0ecffee2b62b58f9380f4469099b30e9f9cbee2804771b4203ba1762cfa"
-"checksum cstr_core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6ebe7158ee57e848621d24d0ed87910edb97639cb94ad9977edf440e31226035"
-"checksum cty 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c4e1d41c471573612df00397113557693b5bf5909666a8acb253930612b93312"
-"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
-"checksum generic-array 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd"
-"checksum klee-sys 0.1.0 (git+https://gitlab.henriktjader.com/pln/klee-sys.git)" = "<none>"
-"checksum lm3s6965 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8698042a7495160eac9f7298a32cd1ddbb6ad2780f766f5a99b4f0a6b915e0ad"
-"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
-"checksum panic-halt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812"
-"checksum panic-klee 0.1.0 (git+https://gitlab.henriktjader.com/pln/panic-klee.git)" = "<none>"
-"checksum proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0319972dcae462681daf4da1adeeaa066e3ebd29c69be96c6abb1259d2ee2bcc"
-"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
-"checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"
-"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
-"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
-"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
-"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
-"checksum stm32f4 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "88640ad08c62e0651a1320187f38c3655d025ed580a10f0e4d85a2cc4829069f"
-"checksum syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4ff033220a41d1a57d8125eab57bf5263783dfdcc18688b1dacc6ce9651ef8"
-"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
-"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
-"checksum vcell 0.1.2 (git+https://github.com/perlindgren/vcell.git?branch=trustit)" = "<none>"
-"checksum volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286"
diff --git a/Cargo.toml b/Cargo.toml
index 0bf009d..62c5fe3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -33,7 +33,9 @@ version = "0.1.0"
 
 [dependencies.klee-sys]
 git = "https://gitlab.henriktjader.com/pln/klee-sys.git"
+# path = "../klee-sys"
 version = "0.1.0"
+features = ["inline-asm"]
 
 # [dependencies.cortex-m-rtfm]
 # path = "../cortex-m-rtpro"
@@ -48,13 +50,15 @@ vcell = { git = "https://github.com/perlindgren/vcell.git", branch = "trustit" }
 #vcell = { path = "../vcell" }
 
 cortex-m = { git = "https://github.com/perlindgren/cortex-m.git", branch = "trustit" }
-# cortex-m = { path = "../cortex-m" }
+#cortex-m = { path = "../cortex-m" }
 
 cortex-m-rt = { git = "https://github.com/perlindgren/cortex-m-rt.git", branch = "trustit" }
 # cortex-m-rt = { path = "../cortex-m-rt" }
 
 [features] 
+# default = ["f4"] # uncomment to enable as default feature
 klee-analysis = [ 
+     "klee-sys/klee-analysis",
      "vcell/klee-analysis",
      "cortex-m/klee-analysis", 
      "cortex-m-rt/klee-analysis" 
diff --git a/README.md b/README.md
index 978fc99..078e9ea 100644
--- a/README.md
+++ b/README.md
@@ -73,14 +73,29 @@ See section `Cargo.toml` for detaled information on features introduced.
 - llvm target `thumbv7em-none-eabihf` 
   - `> rustup show`, to show current Rust tool-chain and installed targets.
   - `> rustup target add <target>`, to add target, e.g., `thumbv7em-none-eab¡hf`.
+- [cargo bin-utils](https://github.com/rust-embedded/cargo-binutils) (tested with version 0.1.7)
   
 ### Examples
 
 - `f401_minimal.rs`
 
-This example showcase the execution of code on the stm32f401 (and similar targets from the f4).
+This example showcase the execution of a minimal "Hello World!" application on the stm32f401 (and similar targets from the f4).
 
---
+- `f401_minimal2.rs`
+
+This example showcase cycle accurate and non-intrusive execution time measurements. It also covers, debug vs. release mode optimization and the effect of the `inline-asm` feauture.
+
+- `f401_probe.rs`
+
+A continuation of `f401_minimal2.rs`, showcasing the ultimate degree of automation possible, in an all Rust profiling setting. Further information is found in the `runner` crate.
+
+---
+
+### Disclaimer
+
+This project is in early development, thus expect bugs and shortcomings, no API stability offered or guaranteed. It is however well suited for experimentation and all implemented features have been successfully tested.
+
+---
 
 ## Licencse
 
diff --git a/examples/f401_minimal.rs b/examples/f401_minimal.rs
index ca716ee..679771a 100644
--- a/examples/f401_minimal.rs
+++ b/examples/f401_minimal.rs
@@ -8,6 +8,7 @@ extern crate panic_halt;
 
 use stm32f4::stm32f401 as stm32;
 
+use cortex_m::asm;
 use cortex_m_rt::entry;
 use cortex_m_semihosting::hprintln;
 
@@ -15,7 +16,9 @@ use cortex_m_semihosting::hprintln;
 fn main() -> ! {
     hprintln!("Hello, world!").unwrap();
 
-    loop {}
+    loop {
+        asm::nop();
+    }
 }
 
 // See RM0368 Reference Manual for details
@@ -29,4 +32,84 @@ fn main() -> ! {
 // openocd -f openocd.cfg
 //
 // cargo run --example f401_minimal --features f4 --target thumbv7em-none-eabihf
+//
+// ...
+// DefaultPreInit () at /home/pln/.cargo/git/checkouts/cortex-m-rt-073d0396a6df513c/8d26860/src/lib_thumb_rt.rs:571
+// 571     pub unsafe extern "C" fn DefaultPreInit() {}
+// (gdb)
+//
+// At this point, the progrom has been flashed onto the target (stm32f401/f411).
+//
+// (gdb) c
+// Continuing.
+//
+// Breakpoint 1, main () at examples/f401_minimal.rs:14
+// 14      #[entry]
+//
+// `main` is our "entry" point for the user applicaiton.
+// It can be named anything by needs to annoted by #[entry].
+// At this point global variables have been initiated.
+//
+// The `openocd.gdb` script defines the startup procedure, where we have set
+// a breakpoint at the `main` symbol.
+//
+// Let's continue.
+//
+// (gdb) c
+// Continuing.
+// halted: PC: 0x08001206
+//
+// In the `openocd` terminal the `Hello world!` text should appear.
+// The program is stuck in the infinite `loop {}`.
+//
+// If you press Ctrl-C, you will force the target (stm32fxx) to break.
+//
+// (gdb) c
+// Continuing.
+// halted: PC: 0x08001206
+// ^C
+// Program received signal SIGINT, Interrupt.
+// f401_minimal::__cortex_m_rt_main () at examples/f401_minimal.rs:19
+// 19          loop {
+//
+// (gdb) disassemble
+// Dump of assembler code for function f401_minimal::__cortex_m_rt_main:
+// 0x0800019a <+0>:     movw    r0, #5104       ; 0x13f0
+// 0x0800019e <+4>:     movt    r0, #2048       ; 0x800
+// 0x080001a2 <+8>:     movs    r1, #14
+// 0x080001a4 <+10>:    bl      0x8000f86 <cortex_m_semihosting::export::hstdout_str>
+// 0x080001a8 <+14>:    movw    r1, #5144       ; 0x1418
+// 0x080001ac <+18>:    movt    r1, #2048       ; 0x800
+// 0x080001b0 <+22>:    bl      0x80011fa <core::result::Result<T,E>::unwrap>
+// 0x080001b4 <+26>:    b.n     0x80001b6 <f401_minimal::__cortex_m_rt_main+28>
+// 0x080001b6 <+28>:    bl      0x80012b4 <__nop>
+// => 0x080001ba <+32>:    b.n     0x80001b6 <f401_minimal::__cortex_m_rt_main+28>
+//
+// (In gdb you may use tab, for command completion, up arrow for previous command and
+// shortcuts for just about anything, `c` for `continue` e.g.)
+//
+// 0x080001b6 <+28>:    bl      0x80012b4 <__nop>
+// is a "branch and link call" to a function `__nop`, that simply does nothing (no operation).
+// 0x080001ba <+32>:    b.n     0x80001b6 <f401_minimal::__cortex_m_rt_main+28>
+// in a branch to the previous instruction, indeed an infinite loop right.
+//
+// Some basic Rust.
+// Use https://www.rust-lang.org/learn and in particular https://doc.rust-lang.org/book/.
+// There is even a book on embeddded Rust available:
+// https://rust-embedded.github.io/book/, it covers much more than we need here.
+//
+// Figure out a way to print the numbers 0..10 using a for loop.
+//
+// Figure out a way to store the numbers in 0..10 in a stacic (global) array using a loop.
+//
+// Print the resulting array (using a single println invocation, not a loop).
+//
+// (You may prototype the code directly on https://play.rust-lang.org/, and when it works
+// backport that into the minimal example, and chack that it works the same)
+//
+// These two small excersises should get you warmed up.
+//
+// Some reflections:
+// Why is does dealing with static variables require `unsafe`?
+//
 // This is the way!
diff --git a/examples/f401_minimal2.rs b/examples/f401_minimal2.rs
new file mode 100644
index 0000000..e23945d
--- /dev/null
+++ b/examples/f401_minimal2.rs
@@ -0,0 +1,229 @@
+// minimal example for the stm32-f401 (and the f4 series)
+//! Prints "Hello, world!" on the host console using semihosting
+
+#![no_main]
+#![no_std]
+
+extern crate panic_halt;
+
+use stm32f4::stm32f401 as stm32;
+
+use cortex_m::asm;
+use cortex_m_rt::entry;
+
+#[entry]
+#[inline(never)] // to keep the symbol
+fn main() -> ! {
+    asm::nop();
+    asm::nop();
+    asm::bkpt();
+    do_some_work();
+    asm::bkpt();
+    loop {
+        asm::nop();
+    }
+}
+
+fn do_some_work() {
+    for _ in 0..100 {
+        asm::nop();
+    }
+}
+// cargo run --example f401_minimal2 --features f4 --target thumbv7em-none-eabihf
+// ...
+// halted: PC: 0x08000322
+// DefaultPreInit () at /home/pln/.cargo/git/checkouts/cortex-m-rt-073d0396a6df513c/8d26860/src/lib_thumb_rt.rs:571
+// 571     pub unsafe extern "C" fn DefaultPreInit() {}
+// (gdb) disassemble
+// Dump of assembler code for function DefaultPreInit:
+// => 0x08000322 <+0>:     bx      lr
+// End of assembler dump.
+// (gdb) c
+// Continuing.
+
+// Breakpoint 1, main () at examples/f401_minimal2.rs:14
+// 14      #[entry]
+// (gdb) c
+// Continuing.
+// halted: PC: 0x0800019a
+
+// Program received signal SIGTRAP, Trace/breakpoint trap.
+// 0x08000420 in __bkpt ()
+// (gdb) backtrace
+// #0  0x08000420 in __bkpt ()
+// #1  0x080001a6 in cortex_m::asm::bkpt () at /home/pln/.cargo/git/checkouts/cortex-m-514878a7410beb63/d8f2851/src/asm.rs:19
+// #2  f401_minimal2::__cortex_m_rt_main () at examples/f401_minimal2.rs:18
+// inline-frame.c:156: internal-error: void inline_frame_this_id(frame_info*, void**, frame_id*): Assertion `frame_id_p (*this_id)' failed.
+// A problem internal to GDB has been detected,
+// further debugging may prove unreliable.
+// Quit this debugging session? (y or n) n
+//
+// This is a bug, please report it.  For instructions, see:
+// <http://www.gnu.org/software/gdb/bugs/>.
+//
+// inline-frame.c:156: internal-error: void inline_frame_this_id(frame_info*, void**, frame_id*): Assertion `frame_id_p (*this_id)' failed.
+// A problem internal to GDB has been detected,
+// further debugging may prove unreliable.
+// Create a core file of GDB? (y or n) n
+// Command aborted.
+// .... eeeehhh no worries, GDB is written in C and still kind of works
+// (gdb) frame 2
+// #2  f401_minimal2::__cortex_m_rt_main () at examples/f401_minimal2.rs:18
+// 18          asm::bkpt();
+// So we can get back to the "caller" (that called the `__bkpt()` function).
+// At this point we can disassassemble the program.
+//
+// (gdb) disassemble
+// Dump of assembler code for function f401_minimal2::__cortex_m_rt_main:
+// 0x08000584 <+0>:     bl      0x800077c <__nop>
+// 0x08000588 <+4>:     bl      0x800077c <__nop>
+// 0x0800058c <+8>:     bl      0x8000778 <__bkpt>
+// => 0x08000590 <+12>:    bl      0x800059c <f401_minimal2::do_some_work>
+// 0x08000594 <+16>:    b.n     0x8000596 <f401_minimal2::__cortex_m_rt_main+18>
+// 0x08000596 <+18>:    bl      0x800077c <__nop>
+// 0x0800059a <+22>:    b.n     0x8000596 <f401_minimal2::__cortex_m_rt_main+18>
+//
+// We see the two calls to the nop function, the bkpt call, the call to do_some_work_
+// followed by the infinite loop.
+// Great!
+//
+// Now lets try to find out how long it takes to `do_some_work`.
+//
+// One way would be by stepping the code and counting the number of steps.
+// That is tedious and boring, and prone to errors.
+//
+// The ARM M4 core has some nice features allowing making our life easier.
+//
+// The DWT (Debug and Watchpoint and Trace Unit)
+// http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.100166_0001_00_en/ric1417175910926.html
+// And in particular, the DWT programmers model.
+// What we want to do is
+// (gdb) mon mww 0xe0001000 1
+// (gdb) mon mww 0xe0001004 0
+// (gdb) mon mdw 0xe0001004
+// Which
+//  - enables the DWT
+//  - sets the cyclecounter to 0
+//  - reads the cyclcounter
+//
+// Now let the program run (from the first bkpt to the next bkpt.
+// (gdb) c
+// Continuing.
+// Program received signal SIGTRAP, Trace/breakpoint trap.
+// 0x0800077c in __bkpt ()
+//
+// (gdb) mon mdw 0xe0001004
+// 0xe0001004: 0000b92f
+//
+// Alternativle you may use the `x` (examine memory command)
+// (gdb) x 0xe0001004
+// 0xe0001004:     0x0000b92f
+//
+// Or in decimal
+// (gdb) x/d 0xe0001004
+// 0xe0001004:     47407
+//
+// So some 47k clock cycles... Hmm quite a lot for a loop 0..100 doing ... nothing
+//
+// Let's repeat the experiment in --release (optimized mode)
+//
+// cargo run --example f401_minimal2 --features f4 --target thumbv7em-none-eabihf --release
+// ...
+// run to first breakpoint, setup the DWT cyclecounter, run to breakpoint
+// I got 505, cycles. Good but not great... still 5 cycles per nop, right?
+//
+// Well let's look at the code.
+// (gdb) disassemble
+// Dump of assembler code for function f401_minimal2::__cortex_m_rt_main:
+// => 0x0800019a <+0>:     bl      0x80003f4 <__nop>
+// 0x0800019e <+4>:     bl      0x80003f4 <__nop>
+// 0x080001a2 <+8>:     bl      0x80003f0 <__bkpt>
+// 0x080001a6 <+12>:    bl      0x80003f4 <__nop>
+// 0x080001aa <+16>:    bl      0x80003f4 <__nop>
+// 0x080001ae <+20>:    bl      0x80003f4 <__nop>
+// 0x080001b2 <+24>:    bl      0x80003f4 <__nop>
+// 0x080001b6 <+28>:    bl      0x80003f4 <__nop>
+// 0x080001ba <+32>:    bl      0x80003f4 <__nop>
+// 0x080001be <+36>:    bl      0x80003f4 <__nop>
+// 0x080001c2 <+40>:    bl      0x80003f4 <__nop>
+// 0x080001c6 <+44>:    bl      0x80003f4 <__nop>
+// 0x080001ca <+48>:    bl      0x80003f4 <__nop>
+// 0x080001ce <+52>:    bl      0x80003f4 <__nop>
+// 0x080001d2 <+56>:    bl      0x80003f4 <__nop>
+// ... a 100 in a row, that's some heavy inlining right!
+//
+// Well at this point, Rust + LLVM is not ALLOWED to do better.
+// The assembly (nop) instruction is marked "volatile", meaning it implies
+// a side effect, so Rust + LLVM is not allowed to optimize it out.
+// That is indeed excellent, as we will discuss later.
+//
+// But why is the `__nop` a function call and not a native assebly nop?
+// Well, Rust has yet to decide on a "stable" format for inline assembly.
+// It's merely a syntactical thing, and the RFC has not yet been accepted
+// (in due time we will have it.)
+//
+// In the meantime we can use inline assembly as an "unstable" feature
+// by enabled in the nightly toolchain.
+//
+// > rustup override set nightly
+//
+// Now we have enabled the nightly toolchain for the current directory (a bit Nix like)
+//
+// cargo run --example f401_minimal2 --features f4 --target thumbv7em-none-eabihf --release --features inline-asm
+//
+// run until the first bkpt instruction...
+//
+// Program received signal SIGTRAP, Trace/breakpoint trap.
+// f401_minimal2::__cortex_m_rt_main () at examples/f401_minimal2.rs:19
+// 19          asm::bkpt();
+// (gdb) disassemble
+// Dump of assembler code for function f401_minimal2::__cortex_m_rt_main:
+//    0x0800019a <+0>:     nop
+//    0x0800019c <+2>:     nop
+// => 0x0800019e <+4>:     bkpt    0x0000
+//    0x080001a0 <+6>:     nop
+//    0x080001a2 <+8>:     nop
+//    0x080001a4 <+10>:    nop
+//    0x080001a6 <+12>:    nop
+//    0x080001a8 <+14>:    nop
+//    0x080001aa <+16>:    nop
+//    0x080001ac <+18>:    nop
+//    0x080001ae <+20>:    nop
+//    0x080001b0 <+22>:    nop
+//    0x080001b2 <+24>:    nop
+//    0x080001b4 <+26>:    nop
+//
+// (gdb) mon mww 0xe0001000 1
+// (gdb) mon mww 0xe0001004 0
+// (gdb) c
+// Continuing.
+//
+// Program received signal SIGTRAP, Trace/breakpoint trap.
+// f401_minimal2::__cortex_m_rt_main () at examples/f401_minimal2.rs:21
+// 21          asm::bkpt();
+// (gdb) mon mdw 0xe0001004
+// 0xe0001004: 00000064
+//
+// (gdb) x/d 0xe0001004
+// 0xe0001004:     100
+//
+// So what have we learned?
+// - how we can do NON INTRUSIVE cycle accurate execution time measuremnts
+// - how we can speed up a program 470 times without altering its semantics
+//
+// So back to the question on "volatile" (assembly) instructions.
+// "volatile" in this context implies a number of things.
+// - it may note be optimized out
+// - the order of volatile instructions along an execution path must be preserved
+//
+// This allows us to
+// - write inline assembler for parts of our code that is extremely timing critical
+// - introduce precise delays
+// - fiddle with CPU registers
+//   - stack pointer
+//   - link register
+//   - special purpose core registers (interrupt enable/disable etc.)
+// Essentially using inline assembly we can ALL in Rust. We do not NEED to link
+// to external assembly code or external C code (still we can if we want)...
+//
+// All in Rust, That is the Way!
diff --git a/examples/f401_probe.rs b/examples/f401_probe.rs
new file mode 100644
index 0000000..ed267fb
--- /dev/null
+++ b/examples/f401_probe.rs
@@ -0,0 +1,99 @@
+// minimal example for the stm32-f401 (and the f4 series)
+//! Prints "Hello, world!" on the host console using semihosting
+
+#![no_main]
+#![no_std]
+
+extern crate panic_halt;
+
+use stm32f4::stm32f401 as stm32;
+
+use cortex_m::asm;
+use cortex_m_rt::entry;
+
+#[entry]
+#[inline(never)] // to keep the symbol
+fn main() -> ! {
+    asm::nop();
+    asm::nop();
+    asm::bkpt();
+    do_some_work();
+    asm::bkpt();
+    loop {
+        asm::nop();
+    }
+}
+
+fn do_some_work() {
+    for _ in 0..100 {
+        asm::nop();
+    }
+}
+// cargo run --example f401_probe --features f4 --target thumbv7em-none-eabihf
+// ...
+//
+// The ARM M4 core provides the DWT register for cycle accurate measurements (CYCCNT).
+// There is a lot more possibilities to tracing etc. that we will not cover in this course
+//
+// The real power however comes from automation.
+// gdb (designed in the mid 80s) offers automation through python (natively)
+// and bindings to sereverals high level languages have been developed.
+//
+// However, internally gdb has a lot of technical dept, and high internal complexity
+// partly due to C and the ad-hoc threading model (threading was introduced along the way
+// and not part of the "design".)
+//
+// More recently the llvm project has released debugger with largely compatible
+// interface and automation capabalities. lldb is however not yet supporting
+// embedded systems (so we stick to gdb atm)
+//
+// In both cases their code base is huge, and they are vary capable as designed for
+// general purpose debugging.
+//
+// What we need in order to profile embedded code is however just a small but very
+// precise subset of the functionality, defined by the ARM coresight API (for core access)
+// and probing functionality (providid by e.g. stlink or DAP link).
+//
+// Using the latter you can e.g.:
+// - read and write bytes/words and blocks thereof
+// - read and write flash (writing is section based, first eraze then program)
+//
+// This type of low-level debug access is sufficent to automate profiling,
+// tracing, etc.
+//
+// The recent Rust `probe-rs` team aims at supporting probing and coresight APIs.
+// While the code base is young and immature, it already provides what we need to:
+// - program (flash code), this was implemented for the M4 this weekend
+// - stepping to and from breakpoint instructions
+// - managing the DWT
+// The latter two I implemented yesterday, so be aware there might be bugs out there...
+//
+// So here we go:
+// 1. confirm that the above program compiles and runs as expected.
+// 2. go to the `runner` folder and run `cargo run --bin f401_probe`
+//
+// You should get something like:
+// device STLink V2-1 (VID: 1155, PID: 14155, STLink)
+// probe connected
+// strategy ChipInfo(ChipInfo { manufacturer: JEP106Code({ cc: 0x00, id: 0x20 } => Some("STMicroelectronics")), part: 1041 })
+// target Target { identifier: TargetIdentifier { chip_name: "STM32F411VETx", ...
+// Continue running
+// Hit breakpoint :Core stopped at address 0x0800019e
+// Continue from breakpoint.
+// running
+// Hit breakpoint :Core stopped at address 0x08000268
+// cycles 100
+//
+// Have a close look at the small program, and the `runner` library.
+//
+// Hints:
+// cargo doc --open
+// Documenst the API, and lets you browse the documentation and source code behind.
+//
+// cargo objdump --example f401_probe --release --features f4,inline-asm --target thumbv7em-none-eabihf -- -d
+// Part of the `cargo bin-utils` package that lets you inspect the generated binary.
+//
+// Later you will build a small analysis framework combining symbolic execution
+// with the measurement based testing, to derive WCET estimates for embedded applications.
+//
+// This is the Way!
diff --git a/ktest/gdb.py b/ktest/gdb.py
deleted file mode 100644
index fa25058..0000000
--- a/ktest/gdb.py
+++ /dev/null
@@ -1,812 +0,0 @@
-#!/usr/bin/env python
-import gdb
-import os
-import sys
-import struct
-from subprocess import call
-import subprocess
-import glob
-
-""" ktest file version """
-version_no = 3
-
-# debug = False
-debug = True
-autobuild = True
-
-debug_file = "resource"
-
-# klee_out_folder = 'target/x86_64-unknown-linux-gnu/debug/examples/'
-klee_out_folder = 'target/x86_64-unknown-linux-gnu/release/examples/'
-stm_out_folder = 'target/thumbv7em-none-eabihf/release/examples/'
-
-file_list = []
-file_index_current = -1
-object_index_current = 0
-
-tasks = []
-priorities = []
-interarrival = []
-
-task_name = ""
-file_name = ""
-
-priority = 0
-first = True
-
-# [[ Test, Task, Cyccnt, priority/ceiling]]
-outputdata = []
-
-""" Max number of events guard """
-object_index_max = 100
-
-""" Define the original working directory """
-original_pwd = os.getcwd()
-
-
-""" taken from KLEE """
-
-
-class KTestError(Exception):
-    pass
-
-
-class KTest:
-
-    @staticmethod
-    def fromfile(path):
-        if not os.path.exists(path):
-            print("ERROR: file %s not found" % (path))
-            sys.exit(1)
-
-        f = open(path, 'rb')
-        hdr = f.read(5)
-        if len(hdr) != 5 or (hdr != b'KTEST' and hdr != b"BOUT\n"):
-            raise KTestError('unrecognized file')
-        version, = struct.unpack('>i', f.read(4))
-        if version > version_no:
-            raise KTestError('unrecognized version')
-        numArgs, = struct.unpack('>i', f.read(4))
-        args = []
-        for i in range(numArgs):
-            size, = struct.unpack('>i', f.read(4))
-            args.append(str(f.read(size).decode(encoding='ascii')))
-
-        if version >= 2:
-            symArgvs, = struct.unpack('>i', f.read(4))
-            symArgvLen, = struct.unpack('>i', f.read(4))
-        else:
-            symArgvs = 0
-            symArgvLen = 0
-
-        numObjects, = struct.unpack('>i', f.read(4))
-        objects = []
-        for i in range(numObjects):
-            size, = struct.unpack('>i', f.read(4))
-            name = f.read(size)
-            size, = struct.unpack('>i', f.read(4))
-            bytes = f.read(size)
-            objects.append((name, bytes))
-
-        # Create an instance
-        b = KTest(version, args, symArgvs, symArgvLen, objects)
-        # Augment with extra filename field
-        b.filename = path
-        return b
-
-    def __init__(self, version, args, symArgvs, symArgvLen, objects):
-        self.version = version
-        self.symArgvs = symArgvs
-        self.symArgvLen = symArgvLen
-        self.args = args
-        self.objects = objects
-
-        # add a field that represents the name of the program used to
-        # generate this .ktest file:
-        program_full_path = self.args[0]
-        program_name = os.path.basename(program_full_path)
-        # sometimes program names end in .bc, so strip them
-        if program_name.endswith('.bc'):
-            program_name = program_name[:-3]
-        self.programName = program_name
-
-# Event handling
-
-# Ugly hack to avoid race condtitons in the python gdb API
-
-
-class Executor:
-    def __init__(self, cmd):
-        self.__cmd = cmd
-
-    def __call__(self):
-        gdb.execute(self.__cmd)
-
-
-"""
-Every time a breakpoint is hit this function is executed
-"""
-
-
-def stop_event(evt):
-    global outputdata
-    global task_name
-    global priority
-    global file_name
-
-    imm = gdb_bkpt_read()
-    if debug:
-        print("Debug: stop event in file {}".format(file_name))
-        print("Debug: evt %r" % evt)
-        print("Debug: imm = {}".format(imm))
-
-    if imm == 0:
-        print("Ordinary breakpoint, exiting!")
-        sys.exit(1)
-
-    elif imm == 1 or imm == 2:
-        try:
-            ceiling = int(gdb.parse_and_eval(
-                "ceiling").cast(gdb.lookup_type('u8')))
-        except gdb.error:
-            print("No ceiling found, exciting!")
-            sys.exit(1)
-
-        if imm == 1:
-            action = "Enter"
-        elif imm == 2:
-            action = "Exit"
-
-        if debug:
-            print("Debug: Append action {} at cycle {}".format(
-                action, gdb_cyccnt_read()))
-
-        outputdata.append(
-            [file_name, task_name, gdb_cyccnt_read(), ceiling, action])
-
-        gdb.post_event(Executor("continue"))
-
-    elif imm == 3:
-        if debug:
-            print("Debug: found finish bkpt_3 at cycle {}"
-                  .format(gdb_cyccnt_read()))
-
-        gdb.post_event(Executor("si"))
-
-    elif imm == 4:
-        if debug:
-            print("Debug: found finish bkpt_4 at cycle {}"
-                  .format(gdb_cyccnt_read()))
-
-        gdb.post_event(posted_event_init)
-
-    else:
-        print("Unexpected stop event, exiting")
-        sys.exit(1)
-
-
-""" Loads each defined task """
-
-
-def posted_event_init():
-    if debug:
-        print("\nDebug: Entering posted_event_init")
-
-    global tasks
-    global task_name
-    global file_name
-    global file_index_current
-    global file_list
-    global outputdata
-    global priority
-    global priorities
-
-    if file_index_current < 0:
-        if debug:
-            print("Debug: Skipped first measurement")
-
-    else:
-        if debug:
-            print("Debug: Append Finish action at cycle {}"
-                  .format(gdb_cyccnt_read()))
-
-        outputdata.append(
-            [file_name, task_name, gdb_cyccnt_read(), priority, "Finish"])
-
-    """ loop to skip to next task *omitting the dummy* """
-    while True:
-        file_index_current += 1
-        if file_index_current == len(file_list):
-            """ finished """
-            break
-
-        task_to_test = ktest_setdata(file_index_current)
-        if 0 <= task_to_test < len(tasks):
-            """ next """
-            break
-
-    if file_index_current < len(file_list):
-        """ Load the variable data """
-
-        if debug:
-            print("Debug: Task number to test {}".format(task_to_test))
-
-        """
-        Before the call to the next task, reset the cycle counter
-        """
-        gdb_cyccnt_reset()
-
-        file_name = file_list[file_index_current].split('/')[-1]
-        task_name = tasks[task_to_test]
-        priority = priorities[task_to_test]
-
-        outputdata.append([file_name, task_name,
-                           gdb_cyccnt_read(), priority, "Start"])
-
-        print('Task to call: %s \n' % (
-            tasks[task_to_test] + "()"))
-        gdb.execute('call %s' % "stub_" +
-                    tasks[task_to_test] + "()")
-
-    else:
-        """ here we are done, call your analysis here """
-        offset = 1
-        print("\nFinished all ktest files!\n")
-        print("Claims:")
-        for index, obj in enumerate(outputdata):
-            if obj[4] == "Exit":
-                claim_time = (obj[2] -
-                              outputdata[index - (offset)][2])
-                print("%s Claim time: %s" % (obj, claim_time))
-                offset += 2
-            elif obj[4] == "Finish" and not obj[2] == 0:
-                offset = 1
-                tot_time = obj[2]
-                print("%s Total time: %s" % (obj, tot_time))
-            else:
-                print("%s" % (obj))
-        # comment out to prevent gdb from quit on finish, useful to debugging
-        gdb.execute("quit")
-
-
-def trimZeros(str):
-    for i in range(len(str))[::-1]:
-        if str[i] != '\x00':
-            return str[:i + 1]
-
-    return ''
-
-
-def ktest_setdata(file_index):
-    """
-    Substitute every variable found in ktest-file
-    """
-    global file_list
-    global debug
-
-    if debug:
-        print("Debug: ktest_setdata on index{}".format(file_index))
-
-    b = KTest.fromfile(file_list[file_index])
-
-    if debug:
-        # print('ktest filename : %r' % filename)
-        print('Debug: ktest file: %r \n' % file_list[file_index])
-        # print('args       : %r' % b.args)
-        # print('num objects: %r' % len(b.objects))
-    for i, (name, data) in enumerate(b.objects):
-        str = trimZeros(data)
-
-        """ If Name is "task", skip it """
-        if name.decode('UTF-8') == "task":
-            if debug:
-                print('Debug: object %4d: name: %r' % (i, name))
-                print('Debug: object %4d: size: %r' % (i, len(data)))
-            # print(struct.unpack('i', str).repr())
-            # task_to_test = struct.unpack('i', str)[0]
-            # print("str: ", str)
-            # print("str: ", str[0])
-            task_to_test = struct.unpack('i', str)[0]
-            # task_to_test = int(str[0])
-            if debug:
-                print("Debug: Task to test:", task_to_test)
-        else:
-            if debug:
-                print('Debug: object %4d: name: %r' % (i, name))
-                print('Degug: object %4d: size: %r' % (i, len(data)))
-                print(str)
-            # if opts.writeInts and len(data) == 4:
-            obj_data = struct.unpack('i', str)[0]
-            if debug:
-                print('Dubug: object %4d: data: %r' %
-                      (i, obj_data))
-            # gdb.execute('whatis %r' % name.decode('UTF-8'))
-            # gdb.execute('whatis %r' % obj_data)
-            gdb.execute('set variable %s = %r' %
-                        (name.decode('UTF-8'), obj_data))
-            # gdb.write('Variable %s is:' % name.decode('UTF-8'))
-            # gdb.execute('print %s' % name.decode('UTF-8'))
-            # else:
-            # print('object %4d: data: %r' % (i, str))
-
-    if debug:
-        print("Dubug: Done with setdata")
-    return task_to_test
-
-
-def ktest_iterate():
-    """ Get the list of folders in current directory, sort and then grab the
-        last one.
-    """
-    global debug
-    global autobuild
-
-    curdir = os.getcwd()
-    if debug:
-        print("Debug: Current directory {}".format(curdir))
-
-    rustoutputfolder = curdir + "/" + klee_out_folder
-    try:
-        os.chdir(rustoutputfolder)
-    except IOError:
-        print(rustoutputfolder + "not found. Need to run\n")
-        print("xargo build --example " + example_name + " --features" +
-              " klee_mode --target x86_64-unknown-linux-gnu ")
-        if autobuild:
-            xargo_run("klee")
-            klee_run()
-        else:
-            print("Run the above commands before proceeding")
-            sys.exit(1)
-
-    if os.listdir(rustoutputfolder) == []:
-        """
-        The folder is empty, generate some files
-        """
-        xargo_run("klee")
-        klee_run()
-
-    dirlist = next(os.walk("."))[1]
-    dirlist.sort()
-    if debug:
-        print(dirlist)
-
-    if not dirlist:
-        print("No KLEE output, need to run KLEE")
-        print("Running klee...")
-        klee_run()
-
-    """ Ran KLEE, need to update the dirlist """
-    dirlist = next(os.walk("."))[1]
-    dirlist.sort()
-    try:
-        directory = dirlist[-1]
-    except IOError:
-        print("No KLEE output, need to run KLEE")
-        print("Running klee...")
-        klee_run()
-
-    print("Using ktest-files from directory:\n" + rustoutputfolder + directory)
-
-    """ Iterate over all files ending with ktest in the "klee-last" folder """
-    for filename in os.listdir(directory):
-        if filename.endswith(".ktest"):
-            file_list.append(os.path.join(rustoutputfolder + directory,
-                                          filename))
-        else:
-            continue
-
-    file_list.sort()
-    """ Return to the old path """
-    os.chdir(curdir)
-    return file_list
-
-
-def tasklist_get():
-    """ Parse the automatically generated tasklist
-    """
-
-    if debug:
-        print(os.getcwd())
-    with open('klee/tasks.txt') as fin:
-        for line in fin:
-                # print(line)
-            if not line == "// autogenerated file\n":
-                return [x.strip().strip("[]\"").split(' ')
-                        for x in line.split(',')]
-
-
-""" Run xargo for building """
-
-
-def xargo_run(mode):
-
-    if "klee" in mode:
-        xargo_cmd = ("xargo build --release --example " + example_name
-                     + " --features "
-                     + "klee_mode --target x86_64-unknown-linux-gnu ")
-    elif "stm" in mode:
-        xargo_cmd = ("xargo build --release --example " + example_name +
-                     " --features " +
-                     "wcet_bkpt --target thumbv7em-none-eabihf")
-    else:
-        print("Provide either 'klee' or 'stm' as mode")
-        sys.exit(1)
-
-    call(xargo_cmd, shell=True)
-
-
-""" Stub for running KLEE on the LLVM IR """
-
-
-def klee_run():
-    global debug
-    global original_pwd
-
-    PWD = original_pwd
-
-    user_id = subprocess.check_output(['id', '-u']).decode()
-    group_id = subprocess.check_output(['id', '-g']).decode()
-
-    bc_file = (glob.glob(PWD + "/" +
-                         klee_out_folder +
-                         '*.bc', recursive=False))[-1].split('/')[-1].strip(
-                             '\'')
-    if debug:
-        print(PWD + "/" + klee_out_folder)
-        print(bc_file)
-
-    klee_cmd = ("klee %s" % bc_file)
-    if debug:
-        print(klee_cmd)
-    call(klee_cmd, shell=True)
-
-
-def gdb_cyccnt_enable():
-    # Enable cyccnt
-    gdb.execute("mon mww 0xe0001000 1")
-
-
-def gdb_cyccnt_disable():
-    # Disble cyccnt
-    gdb.execute("mon mww 0xe0001000 0")
-
-
-def gdb_cyccnt_reset():
-    # Reset cycle counter to 0
-    gdb.execute("mon mww 0xe0001004 0")
-
-
-def gdb_cyccnt_read():
-    # Read cycle counter
-    return int(gdb.execute("mon mdw 0xe0001004", False, True).strip(
-        '\n').strip('0xe000012004:').strip(',').strip(), 16)
-
-
-def gdb_cyccnt_write(num):
-    # Write to cycle counter
-    gdb.execute('mon mww 0xe0001004 %r' % num)
-
-
-def gdb_bkpt_read():
-    # Read imm field of the current bkpt
-    try:
-        return int(gdb.execute("x/i $pc", False, True).
-                   split("bkpt")[1].strip("\t").strip("\n"), 0)
-    except:
-        if debug:
-            print("Debug: It is not a bkpt so return 4")
-        return 4
-
-
-print("\n\n\nStarting script")
-
-"""Used for making GDB scriptable"""
-gdb.execute("set confirm off")
-gdb.execute("set pagination off")
-gdb.execute("set verbose off")
-gdb.execute("set height 0")
-
-"""
-Setup GDB for remote debugging
-"""
-gdb.execute("target remote :3333")
-gdb.execute("monitor arm semihosting enable")
-
-"""
-Check if the user passed a file to use as the source.
-
-If a file is given, use this as the example_name
-"""
-if gdb.progspaces()[0].filename:
-    """ A filename was given on the gdb command line """
-    example_name = gdb.progspaces()[0].filename.split('/')[-1]
-    print("The resource used for debugging: %s" % example_name)
-    try:
-        os.path.exists(gdb.progspaces()[0].filename)
-    except IOError:
-        """ Compiles the given example """
-        xargo_run("stm")
-        xargo_run("klee")
-else:
-    example_name = debug_file
-    print("Defaulting to example '%s' for debugging." % example_name)
-    try:
-        if example_name not in os.listdir(stm_out_folder):
-            """ Compiles the default example """
-            xargo_run("stm")
-            xargo_run("klee")
-    except IOError:
-        """ Compiles the default example """
-        xargo_run("stm")
-        xargo_run("klee")
-
-""" Tell GDB to load the file """
-gdb.execute("file %s" % (stm_out_folder + example_name))
-gdb.execute("load %s" % (stm_out_folder + example_name))
-
-""" Tell gdb-dashboard to hide """
-# gdb.execute("dashboard -enabled off")
-# gdb.execute("dashboard -output /dev/null")
-
-""" Enable the cycle counter """
-gdb_cyccnt_enable()
-gdb_cyccnt_reset()
-
-""" Save all ktest files into an array """
-file_list = ktest_iterate()
-
-""" Get all the tasks to jump to """
-task_list = tasklist_get()
-
-if debug:
-    print("Debug: file_list {}".format(file_list))
-    print("Debug: task_list {}".format(task_list))
-
-""" Split into tasks and priorities """
-for x in task_list:
-    interarrival.append(x.pop())
-    priorities.append(x.pop())
-    tasks.append(x.pop())
-
-print("Available tasks:")
-for t in tasks:
-    print(t)
-
-print("At priorities:")
-for t in priorities:
-    print(t)
-
-print("At interarrivals:")
-for t in interarrival:
-    print(t)
-
-""" Subscribe stop_event_ignore to Breakpoint notifications """
-gdb.events.stop.connect(stop_event)
-
-"""
-    continue until bkpt 3,
-    this will pick the next task (through a posted_event_init event)
-"""
-gdb.execute("continue")
-
-
-# Home exam, response time analysis
-#
-# Assignment 1.
-# Run the example and study the output.
-# you may need to run xargo clean first
-#
-# It generates `output data`, a list of list, something like:
-# Finished all ktest files!
-# Claims:
-# ['test000002.ktest', 'EXTI1', 0, '1', 'Start']
-# ['test000002.ktest', 'EXTI1', 15, 2, 'Enter']
-# ['test000002.ktest', 'EXTI1', 19, 3, 'Enter']
-# ['test000002.ktest', 'EXTI1', 28, 3, 'Exit'] Claim time: 9
-# ['test000002.ktest', 'EXTI1', 29, 2, 'Exit'] Claim time: 14
-# ['test000002.ktest', 'EXTI1', 36, '1', 'Finish'] Total time: 36
-# ['test000003.ktest', 'EXTI3', 0, '2', 'Start']
-# ['test000003.ktest', 'EXTI3', 8, '2', 'Finish'] Total time: 8
-# ['test000004.ktest', 'EXTI2', 0, '3', 'Start']
-# ['test000004.ktest', 'EXTI2', 11, '3', 'Finish'] Total time: 11
-# ['test000005.ktest', 'EXTI1', 0, '1', 'Start']
-# ['test000005.ktest', 'EXTI1', 15, 2, 'Enter']
-# ['test000005.ktest', 'EXTI1', 19, 3, 'Enter']
-# ['test000005.ktest', 'EXTI1', 29, 3, 'Exit'] Claim time: 10
-# ['test000005.ktest', 'EXTI1', 30, 2, 'Exit'] Claim time: 15
-# ['test000005.ktest', 'EXTI1', 37, '1', 'Finish'] Total time: 37
-#
-# test000001.ktest is a dummy task and skipped
-# ['test000002.ktest', 'EXTI1', 0, 1, 'Start']
-# ['test000002.ktest', 'EXTI2', 15, 2, 'Enter']
-#
-# broken down, the first measurement
-# -'test000002.ktest'       the ktest file
-# -'EXTI1'                  the task
-# -'0'                      the time stamp (start from zero)
-# -'1'                      the threshold (priority 1)
-# -'Start'                  the 'Start' event
-#
-# broken down, the second measurement
-# -'test000002.ktest'       the ktest file
-# -'EXTI1'                  the task
-# -'15'                     the time stamp of the 'Enter'
-# -'2'                      the threshold (ceiling 2) of X
-# -'Enter'                  the 'Enter' event
-#
-# after 19 cycles we clam Y, raising threshold to 3
-# after 28 cycles we exit the Y claim, threshold 3 *before unlock Y*
-# after 29 cycles we exit the X claim, threshold 2 *before unlock X*
-# and finally we finish at 36 clock cycles
-#
-# The differences to the hand made measurements are due to details
-# of the gdb integration regarding the return behavior.
-#
-# Verify that you can repeat the experiment.
-# The order of tasks/test and cycles may differ but it should look similar.
-# Two tests for EXTI1 and one for EXTI2 and one for EXTI3
-#
-# Try follow what is going on in the test bed.
-#
-#
-# Assignment 2.
-#
-# The vector
-# interarrival = [100, 30, 40]
-# should match the arrival time of EXTI1, EXTI2, and EXTI3 respectively
-# you may need to change the order depending or your klee/tasks.txt file
-# (in the future interarrival and deadlines will be in the RTFM model,
-# but for now we introduce them by hand)
-#
-# Implement function that takes output data and computes the CPU demand
-# (total utilization factor) Up of
-# http://www.di.unito.it/~bini/publications/2003BinButBut.pdf
-#
-# For this example it should be
-# EXTI1 = 37/100
-# EXTI2 = 11/30
-# EXTI3 = 8/40
-# ------------
-# sum   = 0.93666
-# So we are inside the total utilization bound <1
-#
-# Your implementation should be generic though
-# Looking up the WCETs from the `output_data`.
-# (It may be a good idea to make first pass and extract wcet per task)
-#
-# The total utilisation bound allows us to discard task sets that are
-# obviously illegal (not the case here though)
-#
-# Assignment 3.
-#
-# Under SRP response time can be computed by equation 7.22 from
-# https://doc.lagout.org/science/0_Computer%20Science/2_Algorithms/Hard%20Real-Time%20Computing%20Systems_%20Predictable%20Scheduling%20Algorithms%20and%20Applications%20%283rd%20ed.%29%20%5BButtazzo%202011-09-15%5D.pdf
-#
-# In general the response time is computed as.
-# Ri =  Ci + Bi + Ii
-# Ci the WCET of task i
-# Bi the blocking time task i is exposed to
-# Ii the interference (preemptions) task is exposed to
-#
-# where
-# Pi the priority of task i
-# Ai the interarrival of task i
-#
-# We assign deadline = interarrival and priorities inverse to deadline
-# (rate monotonic assignment, with fixed/static priorities)
-#
-# Lets start by looking at EXTI2 with the highest priority,
-# so no interference (preemption)
-# R_EXTI2 = 11 + B_EXTI2 + 0
-#
-# In general Bi is the max time of any lower priority task
-# (EXTI1, EXTI3 in our case)
-# holds a resource with a ceiling > Pi (ceiling >= 3 in this case)
-# B_EXTI2 = 10 (EXTI1 holding Y for 10 cycles)
-#
-# Notice 1, single blocking, we can only be blocked ONCE,
-# so bound priority inversion
-#
-# Notice 2, `output_data` does not hold info on WHAT exact resource is held
-# merely timestamp information on each Enter/Exit and associated level.
-# This is however sufficient for the analysis.
-#
-# so
-# R_EXTI2 = 11 + 10 = 21, well below our 30 cycle margin
-#
-# Let's look at EXTI3, our mid prio task.
-# R_EXTI3 = C_EXTI3 + B_EXTI3 + I_EXTI3
-# where I_EXTI3 is the interference (preemptions)
-#
-# Here we can undertake a simple approach to start out.
-# Assuming a deadline equal to our interarrival (40)
-# I_EXTI3 is the sum of ALL preemptions until its deadline.
-# in this case EXTI2 can preempt us 2 times (40/30 *rounded upwards*)
-# I_EXTI3 = 2 * 11
-#
-# The worst case blocking time is 15
-# (caused by the lower prio task EXTI1 holding X)
-# R_EXTI3 = 8 + 2 * 11 + 15 = 45, already here we see that
-# EXTI2 may miss our deadline (40)
-#
-# EXTI1 (our lowest prio task)
-# R_EXTI1 = C_EXTI1 + B_EXTI1 + I_EXTI1
-#
-# Here we cannot be blocked (as we have the lowest prio)
-# I_EXTI1 is the sum of preemptions from EXTI2 and EXTI3
-# our deadline = interarrival is 100
-# we are exposed to 100/30 = 4 (rounded upwards) preemptions by EXTI2
-# and 100/40 = 3 (rounded upwards) preemptions by EXTI3
-#
-# I_EXTI1 = 37 + 4 * 11 + 3 * 8 = 105
-#
-# Ouch, even though we had only a WCET of 37 we might miss our deadline.
-# However we might have overestimated the problem.
-#
-# Implement the algorithm in a generic manner
-# Verify that that the results are correct by hand computation (or make an Excel)
-#
-# Assignment 4.
-#
-# Looking closer at 7.22 we see that its a recurrent equation.
-# Ri(0) indicating the initial value
-# Ri(0) = Ci + Bi
-# while
-# Ri(s) = Ci + Bi + sum ..(Ri(s-1))..
-# so Ri(1) is computed from Ri(0) and so forth,
-# this requires a recursive or looping implementation.
-#
-# One can see that as initially setting a "busy period" to Ci+Bi
-# and compute a new (longer) "busy period" by taking into account preemptions.
-#
-# Termination:
-# Either Ri(s) = Ri(s-1), we have a fixpoint and have the exact response time
-# or we hit Ri(s) > Ai, we have missed our deadline
-#
-# Your final assignment is to implement the exact method.
-#
-# Notice, we have not dealt with the case where tasks have equal priorities
-# in theory this is not a problem (no special case needed)
-#
-# However, for exactly analysing the taskset as it would run on the
-# real hardware requires some (minor) modifications.
-# *Not part of this assignment*
-#
-# Examination for full score.
-# Make a git repo of your solution. (With reasonable comments)
-#
-# It should be possible to compile and run, and for the example
-# Print utilization according to Assignment 2
-# Print response times according to Assignment 3
-# Print response times according to Assignment 4
-#
-# It should work with different assignments of the interarrival vector.
-# test it also for
-# [100, 40, 50]
-# [80, 30, 40]
-# (Verify that your results are correct by hand computations)
-#
-# Grading
-# For this part 1/3 of the exam 35 points
-# Assignment 2, 10 points
-# Assignment 3, 10 points
-# Assignment 4, 15 points
-#
-# To make sure the analysis works in the general case
-# you can make further examles based on 'resource.rs'
-#
-# Notice, KLEE analysis does not work on hardware peripherals
-# (this is not yet supported), so your new examples must NOT access
-# any peripherals.
-#
-# HINTS
-# You may start by cut and paste the output (table) to a file 'x.py'
-#
-# Implement the analysis in a seprate python file 'x.py'
-# (reconstruct the 'outputdata' from the table)
-#
-# When you have your analysis working,
-# integrate it in this script (operating on the real 'outputdata')
-#
-#
diff --git a/openocd.gdb b/openocd.gdb
index f505bdc..8add768 100644
--- a/openocd.gdb
+++ b/openocd.gdb
@@ -7,9 +7,9 @@ set print asm-demangle on
 set backtrace limit 32
 
 # detect unhandled exceptions, hard faults and panics
-break DefaultHandler
-break HardFault
-break rust_begin_unwind
+#break DefaultHandler
+#break HardFault
+#break rust_begin_unwind
 # # run the next few lines so the panic message is printed immediately
 # # the number needs to be adjusted for your panic handler
 # commands $bpnum
diff --git a/runner/Cargo.lock b/runner/Cargo.lock
index 748645e..b2f40b4 100644
--- a/runner/Cargo.lock
+++ b/runner/Cargo.lock
@@ -42,6 +42,31 @@ name = "autocfg"
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "backtrace"
+version = "0.3.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "backtrace-sys"
+version = "0.1.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "base64"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "bit-set"
 version = "0.5.1"
@@ -139,6 +164,26 @@ dependencies = [
  "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "failure"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "failure_derive"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "fallible-iterator"
 version = "0.2.0"
@@ -241,6 +286,10 @@ dependencies = [
  "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "ktest"
+version = "0.1.0"
+
 [[package]]
 name = "lazy_static"
 version = "1.4.0"
@@ -389,8 +438,10 @@ dependencies = [
 name = "probe-rs-t2rust"
 version = "0.1.0"
 dependencies = [
+ "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scroll 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -464,6 +515,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 name = "runner"
 version = "0.1.0"
 dependencies = [
+ "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ktest 0.1.0",
  "probe-rs 0.3.0",
 ]
 
@@ -477,6 +530,11 @@ dependencies = [
  "libusb1-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "rustc-demangle"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "scroll"
 version = "0.10.1"
@@ -567,6 +625,17 @@ dependencies = [
  "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "synstructure"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "take_mut"
 version = "0.2.2"
@@ -655,6 +724,9 @@ dependencies = [
 "checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
 "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
 "checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
+"checksum backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea"
+"checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491"
+"checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
 "checksum bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80"
 "checksum bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb"
 "checksum bitfield 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719"
@@ -669,6 +741,8 @@ dependencies = [
 "checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e"
 "checksum dyn-clone 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3ec9c7fb9a2ce708751c98e31ccbae74b6ab194f5c8e30cfb7ed62e38b70866"
 "checksum enum-primitive-derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2b90e520ec62c1864c8c78d637acbfe8baf5f63240f2fb8165b8325c07812dd"
+"checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9"
+"checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08"
 "checksum fallible-iterator 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
 "checksum filetime 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1ff6d4dab0aa0c8e6346d46052e93b13a16cf847b54ed357087c35011048cc7d"
 "checksum flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6bd6d6f4752952feb71363cffc9ebac9411b75b87c6ab6058c40c8900cf43c0f"
@@ -707,6 +781,7 @@ dependencies = [
 "checksum rental-impl 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "475e68978dc5b743f2f40d8e0a8fdc83f1c5e78cbf4b8fa5e74e73beebc340de"
 "checksum rle-decode-fast 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac"
 "checksum rusb 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9c1c7856ddc8f77d741a288176e6c10586c4ac7c56637d33948a7362150a4a26"
+"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
 "checksum scroll 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "abb2332cb595d33f7edd5700f4cbf94892e680c7f0ae56adab58a35190b66cb1"
 "checksum scroll_derive 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8584eea9b9ff42825b46faf46a8c24d2cff13ec152fa2a50df788b87c07ee28"
 "checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449"
@@ -717,6 +792,7 @@ dependencies = [
 "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
 "checksum syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4ff033220a41d1a57d8125eab57bf5263783dfdcc18688b1dacc6ce9651ef8"
 "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
+"checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
 "checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60"
 "checksum tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)" = "b3196bfbffbba3e57481b6ea32249fbaf590396a52505a2615adbb79d9d826d3"
 "checksum target-lexicon 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab0e7238dcc7b40a7be719a25365910f6807bd864f4cce6b2e6b873658e2b19d"
-- 
GitLab