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