mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-30 15:34:33 +01:00
book/example polish
This commit is contained in:
parent
a8d890db3d
commit
0f513e1e20
2 changed files with 28 additions and 25 deletions
|
@ -6,12 +6,13 @@ This can be achieved by instantiating a monotonic timer:
|
|||
|
||||
``` rust
|
||||
...
|
||||
rtic_monotonics::make_systick_timer_queue!(TIMER);
|
||||
rtic_monotonics::make_systick_handler!();
|
||||
|
||||
#[init]
|
||||
fn init(cx: init::Context) -> (Shared, Local) {
|
||||
let systick = Systick::start(cx.core.SYST, 12_000_000);
|
||||
TIMER.initialize(systick);
|
||||
hprintln!("init");
|
||||
|
||||
Systick::start(cx.core.SYST, 12_000_000);
|
||||
...
|
||||
```
|
||||
|
||||
|
@ -21,8 +22,10 @@ A *software* task can `await` the delay to expire:
|
|||
#[task]
|
||||
async fn foo(_cx: foo::Context) {
|
||||
...
|
||||
TIMER.delay(100.millis()).await;
|
||||
Systick::delay(100.millis()).await;
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Technically, the timer queue is implemented as a list based priority queue, where list-nodes are statically allocated as part of the underlying task `Future`. Thus, the timer queue is infallible at run-time (its size and allocation is determined at compile time).
|
||||
|
@ -54,8 +57,8 @@ Using the `select_biased` macro from the `futures` crate it may look like this:
|
|||
``` rust
|
||||
// Call hal with short relative timeout using `select_biased`
|
||||
select_biased! {
|
||||
v = hal_get(&TIMER, 1).fuse() => hprintln!("hal returned {}", v),
|
||||
_ = TIMER.delay(200.millis()).fuse() => hprintln!("timeout", ), // this will finish first
|
||||
v = hal_get(1).fuse() => hprintln!("hal returned {}", v),
|
||||
_ = Systick::delay(200.millis()).fuse() => hprintln!("timeout", ), // this will finish first
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -64,8 +67,8 @@ Assuming the `hal_get` will take 450ms to finish, a short timeout of 200ms will
|
|||
``` rust
|
||||
// Call hal with long relative timeout using `select_biased`
|
||||
select_biased! {
|
||||
v = hal_get(&TIMER, 1).fuse() => hprintln!("hal returned {}", v), // hal finish first
|
||||
_ = TIMER.delay(1000.millis()).fuse() => hprintln!("timeout", ),
|
||||
v = hal_get(1).fuse() => hprintln!("hal returned {}", v), // hal finish first
|
||||
_ = Systick::delay(1000.millis()).fuse() => hprintln!("timeout", ),
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -75,7 +78,7 @@ Using `select_biased` any number of futures can be combined, so its very powerfu
|
|||
|
||||
``` rust
|
||||
// Call hal with long relative timeout using monotonic `timeout_after`
|
||||
match TIMER.timeout_after(1000.millis(), hal_get(&TIMER, 1)).await {
|
||||
match Systick::timeout_after(1000.millis(), hal_get(1)).await {
|
||||
Ok(v) => hprintln!("hal returned {}", v),
|
||||
_ => hprintln!("timeout"),
|
||||
}
|
||||
|
@ -87,26 +90,26 @@ In cases you want exact control over time without drift. For this purpose we can
|
|||
|
||||
``` rust
|
||||
// get the current time instance
|
||||
let mut instant = TIMER.now();
|
||||
let mut instant = Systick::now();
|
||||
|
||||
// do this 3 times
|
||||
for n in 0..3 {
|
||||
// exact point in time without drift
|
||||
// absolute point in time without drift
|
||||
instant += 1000.millis();
|
||||
TIMER.delay_until(instant).await;
|
||||
Systick::delay_until(instant).await;
|
||||
|
||||
// exact point it time for timeout
|
||||
// absolute point it time for timeout
|
||||
let timeout = instant + 500.millis();
|
||||
hprintln!("now is {:?}, timeout at {:?}", TIMER.now(), timeout);
|
||||
hprintln!("now is {:?}, timeout at {:?}", Systick::now(), timeout);
|
||||
|
||||
match TIMER.timeout_at(timeout, hal_get(&TIMER, n)).await {
|
||||
Ok(v) => hprintln!("hal returned {} at time {:?}", v, TIMER.now()),
|
||||
match Systick::timeout_at(timeout, hal_get(n)).await {
|
||||
Ok(v) => hprintln!("hal returned {} at time {:?}", v, Systick::now()),
|
||||
_ => hprintln!("timeout"),
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`instant = TIMER.now()` gives the baseline (i.e., the exact current point in time). We want to call `hal_get` after 1000ms relative to this exact point in time. This can be accomplished by `TIMER.delay_until(instant).await;`. We define the absolute point in time for the `timeout`, and call `TIMER.timeout_at(timeout, hal_get(&TIMER, n)).await`. For the first loop iteration `n == 0`, and the `hal_get` will take 350ms (and finishes before the timeout). For the second iteration `n == 1`, and `hal_get` will take 450ms (and again succeeds to finish before the timeout). For the third iteration `n == 2` (`hal_get` will take 5500ms to finish). In this case we will run into a timeout.
|
||||
`instant = Systick::now()` gives the baseline (i.e., the absolute current point in time). We want to call `hal_get` after 1000ms relative to this absolute point in time. This can be accomplished by `Systick::delay_until(instant).await;`. We define the absolute point in time for the `timeout`, and call `Systick::timeout_at(timeout, hal_get(n)).await`. For the first loop iteration `n == 0`, and the `hal_get` will take 350ms (and finishes before the timeout). For the second iteration `n == 1`, and `hal_get` will take 450ms (and again succeeds to finish before the timeout). For the third iteration `n == 2` (`hal_get` will take 5500ms to finish). In this case we will run into a timeout.
|
||||
|
||||
|
||||
The complete example:
|
||||
|
|
|
@ -61,11 +61,11 @@ mod app {
|
|||
|
||||
// do this 3 times
|
||||
for n in 0..3 {
|
||||
// exact point in time without drift
|
||||
// absolute point in time without drift
|
||||
instant += 1000.millis();
|
||||
Systick::delay_until(instant).await;
|
||||
|
||||
// exact point it time for timeout
|
||||
// absolute point it time for timeout
|
||||
let timeout = instant + 500.millis();
|
||||
hprintln!("now is {:?}, timeout at {:?}", Systick::now(), timeout);
|
||||
|
||||
|
|
Loading…
Reference in a new issue