rtic/book/en/src/by-example/app_priorities.md

72 lines
3.4 KiB
Markdown
Raw Normal View History

2021-09-22 13:22:45 +02:00
# Task priorities
## Priorities
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.
2021-09-22 13:22:45 +02:00
> 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`.
The highest static priority task takes precedence when more than one
task are ready to execute.
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
```
2021-09-22 13:22:45 +02:00
The following example showcases the priority based scheduling of tasks:
2021-09-22 13:22:45 +02:00
``` rust
{{#include ../../../../examples/preempt.rs}}
```
``` console
$ cargo run --target thumbv7m-none-eabi --example preempt
{{#include ../../../../ci/expected/preempt.run}}
```
Note that the task `bar` does *not* preempt task `baz` because its priority
is the *same* as `baz`'s. The higher priority task `bar` runs before `foo`
when `baz`returns. When `bar` returns `foo` can resume.
2021-09-22 13:22:45 +02:00
One more note about priorities: choosing a priority higher than what the device
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.