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 2 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 reference to shared resource, then `borrow_mut` and `deref_mut`
geomatsi marked this conversation as resolved.
Show resolved Hide resolved
should be used instead. The following example makes use of mutable reference TIM2 timer.
geomatsi marked this conversation as resolved.
Show resolved Hide resolved

```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 TIM2 timer, its NVIC interrupt,
geomatsi marked this conversation as resolved.
Show resolved Hide resolved
// 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 `cortex-m` crate hides const versions of some functions
geomatsi marked this conversation as resolved.
Show resolved Hide resolved
> (including `Mutex::new()`) behind the `const-fn` feature. So you need to add
geomatsi marked this conversation as resolved.
Show resolved Hide resolved
> the `const-fn` feature to dependency on cortex-m in Cargo.toml to make
geomatsi marked this conversation as resolved.
Show resolved Hide resolved
> 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.
geomatsi marked this conversation as resolved.
Show resolved Hide resolved
> So this additional switch in Cargo.toml will not be needed as soon as
> it is enabled in `cortex-m` by defauilt.
geomatsi marked this conversation as resolved.
Show resolved Hide resolved
>

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

Expand Down