From a0f62dd355647e12b07428429e7faeadb400d1ff Mon Sep 17 00:00:00 2001 From: Sergey Matyukevich Date: Tue, 9 Jul 2019 22:11:09 +0300 Subject: [PATCH 1/3] concurrency: example of mutable reference to shared resource Add example of mutable reference to shared resource using borrow_mut and deref_mut. Signed-off-by: Sergey Matyukevich --- src/concurrency/index.md | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/concurrency/index.md b/src/concurrency/index.md index 75bd53c5..057818ec 100644 --- a/src/concurrency/index.md +++ b/src/concurrency/index.md @@ -512,6 +512,49 @@ Since we can't move the `GPIOA` out of the `&Option`, we need to convert it to an `&Option<&GPIOA>` with `as_ref()`, which we can finally `unwrap()` to obtain the `&GPIOA` which lets us modify the peripheral. +If we need a mutable reference to shared resource, then `borrow_mut` and `deref_mut` +should be used instead. The following example makes use of mutable reference TIM2 timer. + +```rust,ignore +use core::cell::RefCell; +use core::ops::DerefMut; +use cortex_m::interrupt::{self, Mutex}; +use cortex_m::asm::wfi; +use stm32f4::stm32f405; + +static G_TIM: Mutex>>> = + Mutex::new(RefCell::new(None)); + +#[entry] +fn main() -> ! { + let mut cp = cm::Peripherals::take().unwrap(); + let dp = stm32f405::Peripherals::take().unwrap(); + + // Some sort of timer configuration function. + // Assume it configures TIM2 timer, its NVIC interrupt, + // and finally starts the timer. + let tim = configure_timer_interrupt(&mut cp, dp); + + interrupt::free(|cs| { + G_TIM.borrow(cs).replace(Some(tim)); + }); + + loop { + wfi(); + } +} + +#[interrupt] +fn timer() { + interrupt::free(|cs| { + if let Some(ref mut tim)) = G_TIM.borrow(cs).borrow_mut().deref_mut() { + tim.start(1.hz()); + } + }); +} + +``` + Whew! This is safe, but it is also a little unwieldy. Is there anything else we can do? From 18557e748642fa960db44cb3143ee948f94cf990 Mon Sep 17 00:00:00 2001 From: Sergey Matyukevich Date: Tue, 9 Jul 2019 23:15:49 +0300 Subject: [PATCH 2/3] concurrency: add note about const-fn feature in cortex-m crate At the moment cortex-m crate hides const versions of some functions, including Mutex::new(), behind the const-fn feature. So this feature needs to be enabled to cortex-m in Cargo.toml for shared resource examples. Signed-off-by: Sergey Matyukevich --- src/concurrency/index.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/concurrency/index.md b/src/concurrency/index.md index 057818ec..a4393c58 100644 --- a/src/concurrency/index.md +++ b/src/concurrency/index.md @@ -555,6 +555,23 @@ fn timer() { ``` +> **NOTE** +> +> At the moment `cortex-m` crate hides const versions of some functions +> (including `Mutex::new()`) behind the `const-fn` feature. So you need to add +> the `const-fn` feature to dependency on cortex-m in Cargo.toml to make +> the above examples work: +> +> ``` toml +> [dependencies.cortex-m] +> version="0.6.0" +> features=["const-fn"] +> ``` +> Meanwhile `const-fn` has been working on stable Rust for some time now. +> So this additional switch in Cargo.toml will not be needed as soon as +> it is enabled in `cortex-m` by defauilt. +> + Whew! This is safe, but it is also a little unwieldy. Is there anything else we can do? From 314a00be58f0bc5b7c09605b562f5e1dd92a4c34 Mon Sep 17 00:00:00 2001 From: Sergey Matyukevich Date: Thu, 11 Jul 2019 21:43:19 +0300 Subject: [PATCH 3/3] fixup: address review comments Address review comments by @andre-richter: proof-reading Signed-off-by: Sergey Matyukevich --- src/concurrency/index.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/concurrency/index.md b/src/concurrency/index.md index a4393c58..5035852f 100644 --- a/src/concurrency/index.md +++ b/src/concurrency/index.md @@ -512,8 +512,8 @@ Since we can't move the `GPIOA` out of the `&Option`, we need to convert it to an `&Option<&GPIOA>` with `as_ref()`, which we can finally `unwrap()` to obtain the `&GPIOA` which lets us modify the peripheral. -If we need a mutable reference to shared resource, then `borrow_mut` and `deref_mut` -should be used instead. The following example makes use of mutable reference TIM2 timer. +If we need a mutable references to shared resources, then `borrow_mut` and `deref_mut` +should be used instead. The following code shows an example using the TIM2 timer. ```rust,ignore use core::cell::RefCell; @@ -531,7 +531,7 @@ fn main() -> ! { let dp = stm32f405::Peripherals::take().unwrap(); // Some sort of timer configuration function. - // Assume it configures TIM2 timer, its NVIC interrupt, + // Assume it configures the TIM2 timer, its NVIC interrupt, // and finally starts the timer. let tim = configure_timer_interrupt(&mut cp, dp); @@ -557,9 +557,9 @@ fn timer() { > **NOTE** > -> At the moment `cortex-m` crate hides const versions of some functions -> (including `Mutex::new()`) behind the `const-fn` feature. So you need to add -> the `const-fn` feature to dependency on cortex-m in Cargo.toml to make +> At the moment, the `cortex-m` crate hides const versions of some functions +> (including `Mutex::new()`) behind the `const-fn` feature. So you need to add +> the `const-fn` feature as a dependency for cortex-m in the Cargo.toml to make > the above examples work: > > ``` toml @@ -567,9 +567,9 @@ fn timer() { > version="0.6.0" > features=["const-fn"] > ``` -> Meanwhile `const-fn` has been working on stable Rust for some time now. +> Meanwhile, `const-fn` has been working on stable Rust for some time now. > So this additional switch in Cargo.toml will not be needed as soon as -> it is enabled in `cortex-m` by defauilt. +> it is enabled in `cortex-m` by default. > Whew! This is safe, but it is also a little unwieldy. Is there anything else