mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-12-24 19:09:33 +01:00
book/resources: rm #[task_local] mention; add #[lock_free] example
the #[task_local] attribute was removed
This commit is contained in:
parent
f9a7efb235
commit
5805a05fac
3 changed files with 85 additions and 7 deletions
|
@ -97,11 +97,15 @@ $ cargo run --example only-shared-access
|
|||
|
||||
## Lock-free resource access of mutable resources
|
||||
|
||||
There exists two other options dealing with resources
|
||||
A critical section is *not* required to access a `#[shared]` resource that's only accessed by tasks running at the *same* priority.
|
||||
In this case, you can opt out of the `lock` API by adding the `#[lock_free]` field-level attribute to the resource declaration (see example below).
|
||||
Note that this is merely a convenience: if you do use the `lock` API, at runtime the framework will *not* produce a critical section.
|
||||
|
||||
* `#[lock_free]`: there might be several tasks with the same priority
|
||||
accessing the resource without critical section. Since tasks with the
|
||||
same priority never can preempt another task on the same priority
|
||||
this is safe.
|
||||
* `#[task_local]`: there must be only one task using this resource,
|
||||
similar to a `static mut` task local resource, but (optionally) set-up by init.
|
||||
``` rust
|
||||
{{#include ../../../../examples/lock-free.rs}}
|
||||
```
|
||||
|
||||
``` console
|
||||
$ cargo run --example lock-free
|
||||
{{#include ../../../../ci/expected/lock-free.run}}
|
||||
```
|
||||
|
|
14
ci/expected/lock-free.run
Normal file
14
ci/expected/lock-free.run
Normal file
|
@ -0,0 +1,14 @@
|
|||
GPIOA/start
|
||||
GPIOA/counter = 1
|
||||
GPIOA/end
|
||||
GPIOB/start
|
||||
GPIOB/counter = 2
|
||||
GPIOB/end
|
||||
GPIOA/start
|
||||
GPIOA/counter = 3
|
||||
GPIOA/end
|
||||
GPIOB/start
|
||||
GPIOB/counter = 4
|
||||
GPIOB/end
|
||||
GPIOA/start
|
||||
GPIOA/counter = 5
|
60
examples/lock-free.rs
Normal file
60
examples/lock-free.rs
Normal file
|
@ -0,0 +1,60 @@
|
|||
//! examples/lock-free.rs
|
||||
|
||||
#![deny(unsafe_code)]
|
||||
#![deny(warnings)]
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
use panic_semihosting as _;
|
||||
|
||||
#[rtic::app(device = lm3s6965)]
|
||||
mod app {
|
||||
use cortex_m_semihosting::{debug, hprintln};
|
||||
use lm3s6965::Interrupt;
|
||||
|
||||
#[shared]
|
||||
struct Shared {
|
||||
#[lock_free] // <- lock-free shared resource
|
||||
counter: u64,
|
||||
}
|
||||
|
||||
#[local]
|
||||
struct Local {}
|
||||
|
||||
#[init]
|
||||
fn init(_: init::Context) -> (Shared, Local, init::Monotonics) {
|
||||
rtic::pend(Interrupt::GPIOA);
|
||||
|
||||
(Shared { counter: 0 }, Local {}, init::Monotonics())
|
||||
}
|
||||
|
||||
#[task(binds = GPIOA, shared = [counter])] // <- same priority
|
||||
fn gpioa(c: gpioa::Context) {
|
||||
hprintln!("GPIOA/start").unwrap();
|
||||
rtic::pend(Interrupt::GPIOB);
|
||||
|
||||
*c.shared.counter += 1; // <- no lock API required
|
||||
let counter = *c.shared.counter;
|
||||
hprintln!(" GPIOA/counter = {}", counter).unwrap();
|
||||
|
||||
if counter == 5 {
|
||||
debug::exit(debug::EXIT_SUCCESS);
|
||||
}
|
||||
hprintln!("GPIOA/end").unwrap();
|
||||
}
|
||||
|
||||
#[task(binds = GPIOB, shared = [counter])] // <- same priority
|
||||
fn gpiob(c: gpiob::Context) {
|
||||
hprintln!("GPIOB/start").unwrap();
|
||||
rtic::pend(Interrupt::GPIOA);
|
||||
|
||||
*c.shared.counter += 1; // <- no lock API required
|
||||
let counter = *c.shared.counter;
|
||||
hprintln!(" GPIOB/counter = {}", counter).unwrap();
|
||||
|
||||
if counter == 5 {
|
||||
debug::exit(debug::EXIT_SUCCESS);
|
||||
}
|
||||
hprintln!("GPIOB/end").unwrap();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue