Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

concurrency: update shared resource examples #196

Merged
merged 3 commits into from
Jul 11, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions src/concurrency/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,66 @@ 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 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;
use core::ops::DerefMut;
use cortex_m::interrupt::{self, Mutex};
use cortex_m::asm::wfi;
use stm32f4::stm32f405;

static G_TIM: Mutex<RefCell<Option<Timer<stm32::TIM2>>>> =
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 the 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());
}
});
}

```

> **NOTE**
>
> 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
> [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 default.
>

Whew! This is safe, but it is also a little unwieldy. Is there anything else
we can do?

Expand Down