mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-25 21:19:35 +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
|
||||
|
||||
The static priority of each handler can be declared in the `task` attribute
|
||||
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`
|
||||
crate. When the `priority` argument is omitted, the priority is assumed to be
|
||||
`1`. The `idle` task has a non-configurable static priority of `0`, the lowest priority.
|
||||
The `priority` argument declares the static priority of each `task`.
|
||||
|
||||
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` crate.
|
||||
|
||||
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
|
||||
> Cortex-M does in the NVIC peripheral.
|
||||
> 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
|
||||
priority will be executed first. Task prioritization can be observed in the
|
||||
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 highest static priority task takes precedence when more than one
|
||||
task are ready to execute.
|
||||
|
||||
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
|
||||
{{#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
|
||||
is the *same* as `baz`'s. However, once `baz` returns, the execution of
|
||||
task `bar` is prioritized over `foo` due to its higher priority. `foo`
|
||||
is resumed only after `bar` returns.
|
||||
is the *same* as `baz`'s. The higher priority task `bar` runs before `foo`
|
||||
when `baz`returns. When `bar` returns `foo` can resume.
|
||||
|
||||
One more note about priorities: choosing a priority higher than what the device
|
||||
supports will result in a compile error. Due to
|
||||
limitations in the language, the error message is currently far from helpful: it
|
||||
will say something along the lines of "evaluation of constant value failed" and
|
||||
the span of the error will *not* point out to the problematic interrupt value --
|
||||
we are sorry about this!
|
||||
supports will result in a compilation error.
|
||||
The error is cryptic due to limitations in the language,
|
||||
if `priority = 9` for task `uart0_interrupt` in `example/common.rs` this looks like:
|
||||
|
||||
```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
|
||||
|
||||
Software tasks have support for message passing, this means that they can be spawned with an argument
|
||||
as `foo::spawn(1)` which will run the task `foo` with the argument `1`. The number of arguments is not
|
||||
limited and is exemplified in the following:
|
||||
Software tasks support message passing, this means that software tasks can be spawned
|
||||
with an argument: `foo::spawn(1)` which will run the task `foo` with the argument `1`.
|
||||
|
||||
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
|
||||
{{#include ../../../../examples/message_passing.rs}}
|
||||
|
|
Loading…
Reference in a new issue