diff --git a/nrf52/Cargo.toml b/nrf52/Cargo.toml index 5ffc232acbd89a21bfc0323ae987dcecb20c94d1..160f71018965d998f2050bb456fc75c62ce32e9d 100644 --- a/nrf52/Cargo.toml +++ b/nrf52/Cargo.toml @@ -1,5 +1,5 @@ [package] -authors = ["Jorge Aparicio <jorge.aparicio@ferrous-systems.com>"] +authors = ["Per Lindgren <per.lindgren@ltu.se>"] edition = "2018" license = "MIT OR Apache-2.0" name = "nrf52" @@ -19,6 +19,7 @@ async-cortex-m = { path = "../async-cortex-m" } cortex-m = "0.6.2" cortex-m-rt = "0.6.12" pac = { package = "nrf52840-pac", version = "0.9.0", features = ["rt"] } +cortex-m-rtfm = "0.5.1" [dependencies.chrono] default-features = false diff --git a/nrf52/README.md b/nrf52/README.md index 342a2dc90a8e414fcc3b995b8b37c84e718164c1..4f33aa0fce08fef774a212f3158711e302c3c880 100644 --- a/nrf52/README.md +++ b/nrf52/README.md @@ -1,3 +1,3 @@ # `nrf52` -> Async examples on the nRF52840 +> RTFM Async examples on the nRF52840 diff --git a/nrf52/examples/1-rtfm.rs b/nrf52/examples/1-rtfm.rs new file mode 100644 index 0000000000000000000000000000000000000000..61aebf6c71abc564e772a95b0cb871369e50f7a0 --- /dev/null +++ b/nrf52/examples/1-rtfm.rs @@ -0,0 +1,79 @@ +#![deny(unsafe_code)] +#![deny(warnings)] +#![no_main] +#![no_std] + +use async_cortex_m::{task, unsync::Mutex}; +use cortex_m::asm; +use cortex_m_semihosting::hprintln; +// use pac::Interrupt::TIMER0; +use panic_udf as _; // panic handler +use rtfm::app; + +#[app(device = pac)] +const APP: () = { + struct Resources { + #[init(9)] + x:u32, + } + + #[idle(resources = [x])] + fn idle(mut cx: idle::Context) -> ! { + static mut X: Mutex<i64> = Mutex::new(0); + let c: &'static _ = X; + + cx.resources.x.lock(|x| { + hprintln!("x {}", x).ok(); + }); + + task::spawn(async move { + loop { + hprintln!("A: before lock").ok(); + + let mut lock = c.lock().await; + + hprintln!("A: before write {}", *lock).ok(); + *lock += 1; + drop(lock); + + hprintln!("A: after releasing the lock").ok(); + + hprintln!("A: manual yield").ok(); + task::r#yield().await; + + + } + }); + + task::block_on(async { + loop { + hprintln!("B: before lock").ok(); + + // cannot immediately make progress; context switch to A + let mut lock = c.lock().await; + + hprintln!("B: {}", *lock).ok(); + *lock += 1; + + + if *lock > 10 { + loop { + asm::bkpt(); + } + } else { + drop(lock); + hprintln!("B: yield").ok(); + task::r#yield().await; + } + } + }); + + loop { + continue; + } + } + #[task(binds = TIMER0, resources = [x])] + fn rt_task(cx:rt_task::Context) { + hprintln!("x {}", cx.resources.x).ok(); + } +}; diff --git a/nrf52/examples/1-yield.rs b/nrf52/examples/1-yield.rs index 8de0eff1d55ea2e7019a616e8a8bdde74c4e98b9..2f2f53412f45f3c5536a2bf4b8761883c22c5bb5 100644 --- a/nrf52/examples/1-yield.rs +++ b/nrf52/examples/1-yield.rs @@ -11,12 +11,11 @@ //! ``` #![deny(unsafe_code)] -// #![deny(warnings)] +#![deny(warnings)] #![no_main] #![no_std] use async_cortex_m::task; -use cortex_m::asm; use cortex_m_rt::entry; use cortex_m_semihosting::hprintln; use nrf52 as _; // memory layout @@ -25,10 +24,6 @@ use panic_udf as _; // panic handler #[entry] fn main() -> ! { // task A - hprintln!("here").ok(); - - //loop { continue; } - task::spawn(async { loop { hprintln!("A: yield").ok(); @@ -40,20 +35,16 @@ fn main() -> ! { // task B task::block_on(async { loop { - hprintln!("B1: yield").ok(); - - // context switch to A - task::r#yield().await; + hprintln!("B1: yield").ok(); - hprintln!("B2: yield").ok(); + // context switch to A + task::r#yield().await; - task::r#yield().await; + hprintln!("B2: yield").ok(); - hprintln!("DONE").ok(); + task::r#yield().await; - // loop { - // asm::bkpt(); - // } + hprintln!("DONE").ok(); } }) } diff --git a/nrf52/examples/2-rtfm.rs b/nrf52/examples/2-rtfm.rs new file mode 100644 index 0000000000000000000000000000000000000000..339ab86c993af2abd5476b27a8dbe9323748d8cc --- /dev/null +++ b/nrf52/examples/2-rtfm.rs @@ -0,0 +1,97 @@ +#![deny(unsafe_code)] +// #![deny(warnings)] +#![no_main] +#![no_std] + +use async_cortex_m::{task, unsync::Mutex}; +use cortex_m::asm; +use cortex_m_semihosting::hprintln; +use pac::Interrupt::TIMER0; +use panic_udf as _; // panic handler +use rtfm::app; + +#[app(device = pac)] +const APP: () = { + struct Resources { + #[init(9)] + rtfm_x:u64, + } + + #[idle(resources = [rtfm_x])] + fn idle(mut cx: idle::Context) -> ! { + static mut X: Mutex<i64> = Mutex::new(0); + let c: &'static _ = X; + // static mut RT_X : impl rtfm::Mutex = &mut cx.resources.x; + + // rt_x.lock(|x| { + // hprintln!("x {}", x); + // }); + + cx.resources.rtfm_x.lock(|x| { + hprintln!("x {}", x); + }); + + // let cc:&'static _ = &cx.resources.x; + + task::spawn(async { + loop { + hprintln!("A: before lock").ok(); + + // let mut lock = c.lock().await; + + // hprintln!("A: before write {}", *lock).ok(); + // *lock += 1; + // drop(lock); + + hprintln!("A: after releasing the lock").ok(); + + hprintln!("A: manual yield").ok(); + task::r#yield().await; + // cc.lock(|x| { + // hprintln!("x {}", x); + // }); + + cx.resources.rtfm_x.lock(|x| { + hprintln!("x {}", x); + }); + + } + }); + + task::block_on(async { + loop { + hprintln!("B: before lock").ok(); + + // cannot immediately make progress; context switch to A + let mut lock = c.lock().await; + + hprintln!("B: {}", *lock).ok(); + *lock += 1; + + + if *lock > 10 { + loop { + asm::bkpt(); + } + } else { + drop(lock); + hprintln!("B: yield").ok(); + task::r#yield().await; + } + + cx.resources.rtfm_x.lock(|x| { + hprintln!("x {}", x); + }); + } + }); + + loop { + continue; + } + } + + #[task(priority = 2, binds = TIMER0, resources = [rtfm_x])] + fn rt_task(cx:rt_task::Context) { + hprintln!("x {}", cx.resources.rtfm_x); + } +}; diff --git a/nrf52/examples/3-mutex.rs b/nrf52/examples/3-mutex.rs index 288b781254d568dfe60d5665fffdc3c17a6a7892..f437572ad40205b5c91c93d5935cc1232f705a96 100644 --- a/nrf52/examples/3-mutex.rs +++ b/nrf52/examples/3-mutex.rs @@ -38,13 +38,13 @@ use panic_udf as _; // panic handler #[entry] fn main() -> ! { static mut X: Mutex<i64> = Mutex::new(0); - + task::block_on(async { loop { hprintln!("A: before lock").ok(); - + let mut lock = X.lock().await; - + hprintln!("A: before write {}", *lock).ok(); *lock += 1; drop(lock); @@ -65,18 +65,20 @@ fn main() -> ! { hprintln!("B: {}", *lock).ok(); *lock += 1; - - if *lock == 10 { + + if *lock > 10 { loop { asm::bkpt(); - } + } } else { drop(lock); - hprintln!("X: yield").ok(); - task::r#yield().await; + hprintln!("B: yield").ok(); + task::r#yield().await; } } }); - loop { continue; } + loop { + continue; + } } diff --git a/nrf52/examples/3-mutex2.rs b/nrf52/examples/3-mutex2.rs index bb8dbceae686c05015db4474a3fce626f75fbd80..429cc1ae32773a00d1c19f936d2fdd252edc4eb7 100644 --- a/nrf52/examples/3-mutex2.rs +++ b/nrf52/examples/3-mutex2.rs @@ -17,9 +17,9 @@ fn main() -> ! { task::spawn(async move { loop { hprintln!("A: before lock").ok(); - + let mut lock = c.lock().await; - + hprintln!("A: before write {}", *lock).ok(); *lock += 1; drop(lock); @@ -40,18 +40,20 @@ fn main() -> ! { hprintln!("B: {}", *lock).ok(); *lock += 1; - + if *lock > 10 { loop { asm::bkpt(); - } + } } else { drop(lock); hprintln!("B: yield").ok(); - task::r#yield().await; + task::r#yield().await; } } }); - loop { continue; } -} \ No newline at end of file + loop { + continue; + } +}