diff options
| author | Henrik Tjäder <henrik@grepit.se> | 2021-12-16 11:54:13 +0100 |
|---|---|---|
| committer | Henrik Tjäder <henrik@grepit.se> | 2021-12-19 01:33:15 +0100 |
| commit | c55016f4b237a9f25e5a0d86b42dc3ff39bf69b7 (patch) | |
| tree | 490a763177bcba3145047ec3510d0145bea6ac4a /book/en/src/by-example/app_priorities.md | |
| parent | 2ac0e1b29ddbe4fdc4e9b67b486eeb69a106e9c6 (diff) | |
Docs: By-example App priorities and message passing
Diffstat (limited to 'book/en/src/by-example/app_priorities.md')
| -rw-r--r-- | book/en/src/by-example/app_priorities.md | 70 |
1 files changed, 48 insertions, 22 deletions
diff --git a/book/en/src/by-example/app_priorities.md b/book/en/src/by-example/app_priorities.md index 934359d..1a92ec8 100644 --- a/book/en/src/by-example/app_priorities.md +++ b/book/en/src/by-example/app_priorities.md @@ -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 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. +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. |
