mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-29 15:04:32 +01:00
Docs: By-example App priorities and message passing
This commit is contained in:
parent
2ac0e1b29d
commit
c55016f4b2
2 changed files with 57 additions and 25 deletions
|
@ -2,26 +2,41 @@
|
||||||
|
|
||||||
## Priorities
|
## Priorities
|
||||||
|
|
||||||
The static priority of each handler can be declared in the `task` attribute
|
The `priority` argument declares the static priority of each `task`.
|
||||||
using the `priority` argument. For Cortex-M, tasks can have priorities in the range `1..=(1 <<
|
|
||||||
NVIC_PRIO_BITS)` where `NVIC_PRIO_BITS` is a constant defined in the `device`
|
For Cortex-M, tasks can have priorities in the range `1..=(1 << NVIC_PRIO_BITS)`
|
||||||
crate. When the `priority` argument is omitted, the priority is assumed to be
|
where `NVIC_PRIO_BITS` is a constant defined in the `device` crate.
|
||||||
`1`. The `idle` task has a non-configurable static priority of `0`, the lowest priority.
|
|
||||||
|
Omitting the `priority` argument the task priority defaults to `1`.
|
||||||
|
The `idle` task has a non-configurable static priority of `0`, the lowest priority.
|
||||||
|
|
||||||
> A higher number means a higher priority in RTIC, which is the opposite from what
|
> A higher number means a higher priority in RTIC, which is the opposite from what
|
||||||
> Cortex-M does in the NVIC peripheral.
|
> Cortex-M does in the NVIC peripheral.
|
||||||
> Explicitly, this means that number `10` has a **higher** priority than number `9`.
|
> Explicitly, this means that number `10` has a **higher** priority than number `9`.
|
||||||
|
|
||||||
When several tasks are ready to be executed the one with highest static
|
The highest static priority task takes precedence when more than one
|
||||||
priority will be executed first. Task prioritization can be observed in the
|
task are ready to execute.
|
||||||
following scenario: during the execution of a low
|
|
||||||
priority task a higher priority task is spawned; this puts the higher priority task in the pending state.
|
|
||||||
The difference in priority results in the higher priority task preempting the
|
|
||||||
lower priority one: the execution of the lower priority task is suspended and
|
|
||||||
the higher priority task is executed to completion. Once the higher priority
|
|
||||||
task has terminated the lower priority task is resumed.
|
|
||||||
|
|
||||||
The following example showcases the priority based scheduling of tasks.
|
The following scenario demonstrates task prioritization:
|
||||||
|
Spawning a higher priority task A during execution of a lower priority task B pends
|
||||||
|
task A. Task A has higher priority thus preempting task B which gets suspended
|
||||||
|
until task A completes execution. Thus, when task A completes task B resumes execution.
|
||||||
|
|
||||||
|
```text
|
||||||
|
Task Priority
|
||||||
|
┌────────────────────────────────────────────────────────┐
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
3 │ Preempts │
|
||||||
|
2 │ A─────────► │
|
||||||
|
1 │ B─────────► - - - - B────────► │
|
||||||
|
0 │Idle┌─────► Resumes ┌──────────► │
|
||||||
|
├────┴──────────────────────────────────┴────────────────┤
|
||||||
|
│ │
|
||||||
|
└────────────────────────────────────────────────────────┘Time
|
||||||
|
```
|
||||||
|
|
||||||
|
The following example showcases the priority based scheduling of tasks:
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
{{#include ../../../../examples/preempt.rs}}
|
{{#include ../../../../examples/preempt.rs}}
|
||||||
|
@ -33,13 +48,24 @@ $ cargo run --target thumbv7m-none-eabi --example preempt
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that the task `bar` does *not* preempt task `baz` because its priority
|
Note that the task `bar` does *not* preempt task `baz` because its priority
|
||||||
is the *same* as `baz`'s. However, once `baz` returns, the execution of
|
is the *same* as `baz`'s. The higher priority task `bar` runs before `foo`
|
||||||
task `bar` is prioritized over `foo` due to its higher priority. `foo`
|
when `baz`returns. When `bar` returns `foo` can resume.
|
||||||
is resumed only after `bar` returns.
|
|
||||||
|
|
||||||
One more note about priorities: choosing a priority higher than what the device
|
One more note about priorities: choosing a priority higher than what the device
|
||||||
supports will result in a compile error. Due to
|
supports will result in a compilation error.
|
||||||
limitations in the language, the error message is currently far from helpful: it
|
The error is cryptic due to limitations in the language,
|
||||||
will say something along the lines of "evaluation of constant value failed" and
|
if `priority = 9` for task `uart0_interrupt` in `example/common.rs` this looks like:
|
||||||
the span of the error will *not* point out to the problematic interrupt value --
|
|
||||||
we are sorry about this!
|
```text
|
||||||
|
error[E0080]: evaluation of constant value failed
|
||||||
|
--> examples/common.rs:10:1
|
||||||
|
|
|
||||||
|
10 | #[rtic::app(device = lm3s6965, dispatchers = [SSI0, QEI0])]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `8_usize - 9_usize`, which would overflow
|
||||||
|
|
|
||||||
|
= note: this error originates in the attribute macro `rtic::app` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
The error message incorrectly points to the starting point of the macro, but at least the
|
||||||
|
value subtracted (in this case 9) will suggest which task causes the error.
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
# Message passing & capacity
|
# Message passing & capacity
|
||||||
|
|
||||||
Software tasks have support for message passing, this means that they can be spawned with an argument
|
Software tasks support message passing, this means that software tasks can be spawned
|
||||||
as `foo::spawn(1)` which will run the task `foo` with the argument `1`. The number of arguments is not
|
with an argument: `foo::spawn(1)` which will run the task `foo` with the argument `1`.
|
||||||
limited and is exemplified in the following:
|
|
||||||
|
Capacity sets the size of the spawn queue for the task, if not specified capacity defaults to 1.
|
||||||
|
|
||||||
|
In the example below, the capacity of task `foo` is `3`, allowing three simultaneous
|
||||||
|
pending spawns of `foo`. Exceeding this capacity is an `Error`.
|
||||||
|
|
||||||
|
The number of arguments to a task is not limited:
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
{{#include ../../../../examples/message_passing.rs}}
|
{{#include ../../../../examples/message_passing.rs}}
|
||||||
|
|
Loading…
Reference in a new issue