Skip to content

Commit b229e8e

Browse files
bors[bot]geomatsi
andcommitted
Merge #196
196: concurrency: update shared resource examples r=andre-richter a=geomatsi Hi all, This PR suggests the following updates for the section on concurrency: 1. Use lazy_static macro to declare shared resources Suggested example of shared resource declaration does not compile neither on stable (edition 2018) nor on nightly with the following error: "error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants" 2. Add example of mutable references to shared resources Regards, Sergey Co-authored-by: Sergey Matyukevich <geomatsi@gmail.com>
2 parents ef27b51 + 314a00b commit b229e8e

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

src/concurrency/index.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,66 @@ Since we can't move the `GPIOA` out of the `&Option`, we need to convert it to
512512
an `&Option<&GPIOA>` with `as_ref()`, which we can finally `unwrap()` to obtain
513513
the `&GPIOA` which lets us modify the peripheral.
514514

515+
If we need a mutable references to shared resources, then `borrow_mut` and `deref_mut`
516+
should be used instead. The following code shows an example using the TIM2 timer.
517+
518+
```rust,ignore
519+
use core::cell::RefCell;
520+
use core::ops::DerefMut;
521+
use cortex_m::interrupt::{self, Mutex};
522+
use cortex_m::asm::wfi;
523+
use stm32f4::stm32f405;
524+
525+
static G_TIM: Mutex<RefCell<Option<Timer<stm32::TIM2>>>> =
526+
Mutex::new(RefCell::new(None));
527+
528+
#[entry]
529+
fn main() -> ! {
530+
let mut cp = cm::Peripherals::take().unwrap();
531+
let dp = stm32f405::Peripherals::take().unwrap();
532+
533+
// Some sort of timer configuration function.
534+
// Assume it configures the TIM2 timer, its NVIC interrupt,
535+
// and finally starts the timer.
536+
let tim = configure_timer_interrupt(&mut cp, dp);
537+
538+
interrupt::free(|cs| {
539+
G_TIM.borrow(cs).replace(Some(tim));
540+
});
541+
542+
loop {
543+
wfi();
544+
}
545+
}
546+
547+
#[interrupt]
548+
fn timer() {
549+
interrupt::free(|cs| {
550+
if let Some(ref mut tim)) = G_TIM.borrow(cs).borrow_mut().deref_mut() {
551+
tim.start(1.hz());
552+
}
553+
});
554+
}
555+
556+
```
557+
558+
> **NOTE**
559+
>
560+
> At the moment, the `cortex-m` crate hides const versions of some functions
561+
> (including `Mutex::new()`) behind the `const-fn` feature. So you need to add
562+
> the `const-fn` feature as a dependency for cortex-m in the Cargo.toml to make
563+
> the above examples work:
564+
>
565+
> ``` toml
566+
> [dependencies.cortex-m]
567+
> version="0.6.0"
568+
> features=["const-fn"]
569+
> ```
570+
> Meanwhile, `const-fn` has been working on stable Rust for some time now.
571+
> So this additional switch in Cargo.toml will not be needed as soon as
572+
> it is enabled in `cortex-m` by default.
573+
>
574+
515575
Whew! This is safe, but it is also a little unwieldy. Is there anything else
516576
we can do?
517577

0 commit comments

Comments
 (0)