From d4a683663edb21829b4879c7465e1f535d9c0ebd Mon Sep 17 00:00:00 2001
From: Per Lindgren <per.lindgren@ltu.se>
Date: Fri, 19 Apr 2019 19:43:49 +0200
Subject: [PATCH] app cleanup

---
 .vscode/launch.json | 30 ++++++++++++++++++++
 .vscode/tasks.json  | 48 +++++++++++++++++++++++++++++++
 Cargo.toml          | 23 ++++++---------
 examples/app2.rs    |  3 +-
 examples/app4.rs    |  4 +--
 examples/app5.rs    |  7 ++---
 examples/app6.rs    | 20 ++++++-------
 examples/app7.rs    | 22 ++++++---------
 examples/app8.rs    | 31 ++++++++++----------
 examples/app9.rs    | 69 ++++++++++++++++++++++++++++++++++-----------
 10 files changed, 175 insertions(+), 82 deletions(-)

diff --git a/.vscode/launch.json b/.vscode/launch.json
index f6d7a6f..a62f415 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -160,6 +160,36 @@
             ],
             "cwd": "${workspaceRoot}"
         },
+        {
+            "type": "cortex-debug",
+            "request": "launch",
+            "servertype": "openocd",
+            "name": "app6 (debug)",
+            "preLaunchTask": "cargo build --example app6",
+            "executable": "./target/thumbv7em-none-eabihf/debug/examples/app6",
+            "configFiles": [
+                "./openocd_jlink.cfg",
+            ],
+            "postLaunchCommands": [
+                "monitor arm semihosting enable"
+            ],
+            "cwd": "${workspaceRoot}"
+        },
+        {
+            "type": "cortex-debug",
+            "request": "launch",
+            "servertype": "openocd",
+            "name": "app7 (debug)",
+            "preLaunchTask": "cargo build --example app7",
+            "executable": "./target/thumbv7em-none-eabihf/debug/examples/app7",
+            "configFiles": [
+                "./openocd_jlink.cfg",
+            ],
+            "postLaunchCommands": [
+                "monitor arm semihosting enable"
+            ],
+            "cwd": "${workspaceRoot}"
+        },
         {
             "type": "cortex-debug",
             "request": "launch",
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index fd89034..aafbd05 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -123,6 +123,54 @@
                 "isDefault": true
             }
         },
+        {
+            "type": "shell",
+            "label": "cargo build --example app6",
+            "command": "cargo build --example app6 --features timer-queue",
+            "problemMatcher": [
+                "$rustc"
+            ],
+            "group": {
+                "kind": "build",
+                "isDefault": true
+            }
+        },
+        {
+            "type": "shell",
+            "label": "cargo build --example app7",
+            "command": "cargo build --example app7 --features timer-queue",
+            "problemMatcher": [
+                "$rustc"
+            ],
+            "group": {
+                "kind": "build",
+                "isDefault": true
+            }
+        },
+        {
+            "type": "shell",
+            "label": "cargo build --example app8",
+            "command": "cargo build --example app8 --features timer-queue",
+            "problemMatcher": [
+                "$rustc"
+            ],
+            "group": {
+                "kind": "build",
+                "isDefault": true
+            }
+        },
+        {
+            "type": "shell",
+            "label": "cargo build --example app9",
+            "command": "cargo build --example app9 --features timer-queue",
+            "problemMatcher": [
+                "$rustc"
+            ],
+            "group": {
+                "kind": "build",
+                "isDefault": true
+            }
+        },
         {
             "type": "shell",
             "label": "cargo build --example panic",
diff --git a/Cargo.toml b/Cargo.toml
index 77c34e6..2eaeae2 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -5,10 +5,6 @@ readme = "README.md"
 name = "app"
 version = "0.1.0"
 
-# [patch.crates-io]
-# # stm32f4xx-hal = { path = "../stm32f4xx-hal" }
-# stm32fxx-hal = {git = "https://github.com/stm32-rs/stm32f4xx-hal.git" }
-
 [dependencies]
 cortex-m-rt = "0.6.8"
 cortex-m-semihosting = "0.3.2"
@@ -27,11 +23,8 @@ embedded-hal = "0.2.2"
 [dependencies.nrf52832-hal]
 version = "0.7.0"
 
-
-
 [dependencies.cortex-m-rtfm]
-version = "0.4.1"
-# optional = true
+version = "0.4.2"
 
 [dependencies.cortex-m]
 version = "0.6.0"
@@ -53,17 +46,17 @@ version = "0.6.0"
 # features = ["stm32f413", "rt"]
 # optional = true
 
-# [features]
+[features]
 # pac = ["stm32f4"]
 # hal = ["stm32f4xx-hal"]
 # rtfm = ["cortex-m-rtfm"]
-# rtfm-tq = ["cortex-m-rtfm/timer-queue"]
+timer-queue = ["cortex-m-rtfm/timer-queue"]
 
-# this lets you use `cargo fix`!
-[[bin]]
-name = "app"
-test = false
-bench = false
+# # this lets you use `cargo fix`!
+# [[bin]]
+# name = "app"
+# test = false
+# bench = false
 
 [profile.release]
 incremental = false # disable incremental build to allow lto on nightly
diff --git a/examples/app2.rs b/examples/app2.rs
index 44f18c6..150fafd 100644
--- a/examples/app2.rs
+++ b/examples/app2.rs
@@ -39,8 +39,7 @@ const APP: () = {
         hprintln!("SWI0_EGU0 end").unwrap();
     }
 
-    #[interrupt(priority = 2, 
-                resources = [SHARED])]
+    #[interrupt(priority = 2, resources = [SHARED])]
     fn SWI1_EGU1() {
         hprintln!("SWI1_EGU1").unwrap();
         *resources.SHARED += 1;
diff --git a/examples/app4.rs b/examples/app4.rs
index 398d162..32c062a 100644
--- a/examples/app4.rs
+++ b/examples/app4.rs
@@ -37,8 +37,6 @@ const APP: () = {
         loop {
             if let Some(data) = resources.C.dequeue() {
                 hprintln!("received message: {}", data).unwrap();
-
-                
             } else {
                 rtfm::pend(interrupt::SWI0_EGU0);
             }
@@ -47,7 +45,7 @@ const APP: () = {
 
     #[interrupt(resources = [P])]
     fn SWI0_EGU0() {
-        static mut NUMBER : u32 = 0;
+        static mut NUMBER: u32 = 0;
         hprintln!("SWI0_EGU0: {}", NUMBER).unwrap();
         resources.P.enqueue(*NUMBER).unwrap();
         *NUMBER += 1;
diff --git a/examples/app5.rs b/examples/app5.rs
index 0a5ba5a..3b2b10e 100644
--- a/examples/app5.rs
+++ b/examples/app5.rs
@@ -19,18 +19,17 @@ use hal::prelude::GpioExt;
 const APP: () = {
     // Late resources
     static mut LED: P0_14<gpio::Output<PushPull>> = ();
-    
+
     #[init]
     fn init() -> init::LateResources {
-         hprintln!("init").unwrap();
+        hprintln!("init").unwrap();
         let port0 = device.P0.split();
         let led = port0.p0_14.into_push_pull_output(Level::High);
-        init::LateResources { LED : led }
+        init::LateResources { LED: led }
     }
 
     #[idle(resources = [LED])]
     fn idle() -> ! {
-
         let led = resources.LED;
         loop {
             hprintln!("low").unwrap();
diff --git a/examples/app6.rs b/examples/app6.rs
index 8a4ab77..69263c9 100644
--- a/examples/app6.rs
+++ b/examples/app6.rs
@@ -13,37 +13,33 @@ use hal::gpio::Level;
 use hal::gpio::*;
 use hal::prelude::GpioExt;
 
-const PERIOD : u32 = 64_000_000;
+const PERIOD: u32 = 64_000_000;
 
 #[app(device = crate::hal::target)]
 const APP: () = {
     // Late resources
     static mut LED: P0_14<gpio::Output<PushPull>> = ();
-    
+
     #[init(spawn = [low])]
     fn init() -> init::LateResources {
-         hprintln!("init").unwrap();
+        hprintln!("init").unwrap();
         let port0 = device.P0.split();
         let led = port0.p0_14.into_push_pull_output(Level::High);
         spawn.low().unwrap();
-        init::LateResources { LED : led }
+        init::LateResources { LED: led }
     }
 
     #[task(schedule = [high], resources = [LED])]
     fn low() {
-        	resources.LED.set_low();
+        resources.LED.set_low();
 
-        	schedule.high(
-			scheduled + PERIOD.cycles()
-		).unwrap();
+        schedule.high(scheduled + PERIOD.cycles()).unwrap();
     }
 
     #[task(schedule = [low], resources = [LED])]
     fn high() {
-        	resources.LED.set_high();
-        	schedule.low(
-			scheduled + PERIOD.cycles()
-		).unwrap();
+        resources.LED.set_high();
+        schedule.low(scheduled + PERIOD.cycles()).unwrap();
     }
 
     extern "C" {
diff --git a/examples/app7.rs b/examples/app7.rs
index 691656f..061258b 100644
--- a/examples/app7.rs
+++ b/examples/app7.rs
@@ -13,37 +13,33 @@ use hal::gpio::Level;
 use hal::gpio::*;
 use hal::prelude::GpioExt;
 
-const PERIOD : u32 = 64_000_000;
+const PERIOD: u32 = 64_000_000;
 
 #[app(device = crate::hal::target)]
 const APP: () = {
     // Late resources
     static mut LED: P0_14<gpio::Output<PushPull>> = ();
-    
+
     #[init(spawn = [low])]
     fn init() -> init::LateResources {
-         hprintln!("init").unwrap();
+        hprintln!("init").unwrap();
         let port0 = device.P0.split();
         let led = port0.p0_14.into_push_pull_output(Level::High);
         spawn.low().unwrap();
-        init::LateResources { LED : led }
+        init::LateResources { LED: led }
     }
 
     #[task(schedule = [high], resources = [LED])]
     fn low() {
-        	toggler(resources.LED, false);
+        toggler(resources.LED, false);
 
-        	schedule.high(
-			scheduled + PERIOD.cycles()
-		).unwrap();
+        schedule.high(scheduled + PERIOD.cycles()).unwrap();
     }
 
     #[task(schedule = [low], resources = [LED])]
     fn high() {
-        	toggler(resources.LED, true);
-        	schedule.low(
-			scheduled + PERIOD.cycles()
-		).unwrap();
+        toggler(resources.LED, true);
+        schedule.low(scheduled + PERIOD.cycles()).unwrap();
     }
 
     extern "C" {
@@ -52,7 +48,7 @@ const APP: () = {
 };
 
 // Arument is Exclusive access to a specific pin
-fn toggler(mut led : Exclusive<P0_14<Output<PushPull>>>, state : bool ) {
+fn toggler(mut led: Exclusive<P0_14<Output<PushPull>>>, state: bool) {
     if state {
         led.set_high();
     } else {
diff --git a/examples/app8.rs b/examples/app8.rs
index 60ccc16..4edfcd5 100644
--- a/examples/app8.rs
+++ b/examples/app8.rs
@@ -4,7 +4,7 @@ use cortex_m_semihosting::hprintln;
 use nrf52832_hal as hal;
 #[allow(unused_imports)]
 use panic_semihosting;
-use rtfm::{app};
+use rtfm::app;
 
 use embedded_hal::digital::OutputPin;
 use hal::gpio;
@@ -13,38 +13,34 @@ use hal::gpio::Level;
 use hal::gpio::*;
 use hal::prelude::GpioExt;
 
-const PERIOD : u32 = 64_000_000;
+const PERIOD: u32 = 64_000_000;
 
 #[app(device = crate::hal::target)]
 const APP: () = {
     // Late resources
     // static mut LED: OutputPin = (); <= size not known
     static mut LED: P0_14<gpio::Output<PushPull>> = ();
-    
+
     #[init(spawn = [low])]
     fn init() -> init::LateResources {
-         hprintln!("init").unwrap();
+        hprintln!("init").unwrap();
         let port0 = device.P0.split();
         let led = port0.p0_14.into_push_pull_output(Level::High);
         spawn.low().unwrap();
-        init::LateResources { LED : led }
+        init::LateResources { LED: led }
     }
 
     #[task(schedule = [high], resources = [LED])]
     fn low() {
-        	toggler(&mut *resources.LED, false);
+        toggler(&mut *resources.LED, false);
 
-        	schedule.high(
-			scheduled + PERIOD.cycles()
-		).unwrap();
+        schedule.high(scheduled + PERIOD.cycles()).unwrap();
     }
 
     #[task(schedule = [low], resources = [LED])]
     fn high() {
-        	toggler(&mut *resources.LED, true);
-        	schedule.low(
-			scheduled + PERIOD.cycles()
-		).unwrap();
+        toggler(&mut *resources.LED, true);
+        schedule.low(scheduled + PERIOD.cycles()).unwrap();
     }
 
     extern "C" {
@@ -52,11 +48,14 @@ const APP: () = {
     }
 };
 
-// Arument is an Output pin
-fn toggler(led : &mut OutputPin, state : bool ) {
+// Argument is a borrowed trait object
+fn toggler(led: &mut OutputPin, state: bool) {
     if state {
         led.set_high();
     } else {
         led.set_low();
     }
-}
\ No newline at end of file
+}
+
+// The full type is ...
+// fn toggler(led : &mut dyn OutputPin, state : bool )
diff --git a/examples/app9.rs b/examples/app9.rs
index 51bfa2f..86822a6 100644
--- a/examples/app9.rs
+++ b/examples/app9.rs
@@ -4,7 +4,7 @@ use cortex_m_semihosting::hprintln;
 use nrf52832_hal as hal;
 #[allow(unused_imports)]
 use panic_semihosting;
-use rtfm::{app};
+use rtfm::app;
 
 use embedded_hal::digital::OutputPin;
 use hal::gpio;
@@ -13,38 +13,42 @@ use hal::gpio::Level;
 use hal::gpio::*;
 use hal::prelude::GpioExt;
 
-const PERIOD : u32 = 64_000_000;
+const PERIOD: u32 = 64_000_000;
 
 #[app(device = crate::hal::target)]
 const APP: () = {
     // Late resources
     // static mut LED: OutputPin = (); <= size not known
-    static mut LED: P0_14<gpio::Output<PushPull>> = ();
-    
+    // So unfortunately we cannot use that
+    //
+    // static mut LED: impl OutputPin = (); <= impl not allowed here
+    // That may be possible in the future, hope so...
+    //
+    // In the meantime:
+    // We can use the type alias (defined in a library)
+    // to make it easier on the eye.
+    static mut LED: LED1 = ();
+
     #[init(spawn = [low])]
     fn init() -> init::LateResources {
-         hprintln!("init").unwrap();
+        hprintln!("init").unwrap();
         let port0 = device.P0.split();
         let led = port0.p0_14.into_push_pull_output(Level::High);
         spawn.low().unwrap();
-        init::LateResources { LED : led }
+        init::LateResources { LED: led }
     }
 
     #[task(schedule = [high], resources = [LED])]
     fn low() {
-        	toggler(&mut *resources.LED, false);
+        toggler(&mut *resources.LED, false);
 
-        	schedule.high(
-			scheduled + PERIOD.cycles()
-		).unwrap();
+        schedule.high(scheduled + PERIOD.cycles()).unwrap();
     }
 
     #[task(schedule = [low], resources = [LED])]
     fn high() {
-        	toggler(&mut *resources.LED, true);
-        	schedule.low(
-			scheduled + PERIOD.cycles()
-		).unwrap();
+        toggler(&mut *resources.LED, true);
+        schedule.low(scheduled + PERIOD.cycles()).unwrap();
     }
 
     extern "C" {
@@ -52,11 +56,42 @@ const APP: () = {
     }
 };
 
-// Arument is an Output pin
-fn toggler(led : &mut impl OutputPin, state : bool ) {
+// toggler is generic over OutputPin implementers
+fn toggler(led: &mut impl OutputPin, state: bool) {
     if state {
         led.set_high();
     } else {
         led.set_low();
     }
-}
\ No newline at end of file
+}
+
+// the full type is...
+// fn toggler<P>(led: &mut P, state: bool) where P: OutputPin
+//
+// Why is this important you may ask?
+// Well, the Rust compiler/LLVM is very good at momonorphing generics
+// while trait objects may be harder to optimize.
+// In certain cases, we need dynamic dispatch but in this case not.
+// So here (and similar cases) generics are preferrable.
+//
+// Thanks to Jorge Aparicio for pointing me in the right direction:)
+//
+// -----------------------------------------------------------------
+//
+// Define the type alias in the library
+type LED1 = P0_14<gpio::Output<PushPull>>;
+// Notice,
+// This is a poor mans solution, we cannot make resource
+// definitions type generic with concrete type inferred.
+//
+// This is not specific to RTFM but a rather a
+// shortcoming of the Rust type system, that requires
+// explicit types for statics. A possible workaround would
+// be to have a run once (at Init time) allocator.
+// Drawback is that LLVM would not be able to optimize out
+// the indirections, thus we stick with static allocation.
+//
+// Side note: The Timber language (a fore-runner to RTFM)
+// has a static heap collected after init (as above),
+// but Timber cannot compete with Rust-RTFM from a performance
+// perspektive.
-- 
GitLab