2021-09-22 13:22:45 +02:00
|
|
|
# Task priorities
|
|
|
|
|
|
|
|
## Priorities
|
|
|
|
|
2021-12-16 11:54:13 +01:00
|
|
|
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`.
|
|
|
|
|
2021-12-16 11:54:13 +01:00
|
|
|
The highest static priority task takes precedence when more than one
|
|
|
|
task are ready to execute.
|
|
|
|
|
|
|
|
The following scenario demonstrates task prioritization:
|
2022-02-20 19:21:25 +01:00
|
|
|
Spawning a higher priority task A during execution of a lower priority task B suspends
|
|
|
|
task B. Task A has higher priority thus preempting task B which gets suspended
|
2021-12-16 11:54:13 +01:00
|
|
|
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
|
|
|
|
2021-12-16 11:54:13 +01: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
|
2021-12-16 11:54:13 +01:00
|
|
|
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
|
2021-12-16 11:54:13 +01:00
|
|
|
supports will result in a compilation error.
|
2022-02-20 19:21:25 +01:00
|
|
|
|
|
|
|
The error is cryptic due to limitations in the Rust language
|
2021-12-16 11:54:13 +01:00
|
|
|
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.
|