aboutsummaryrefslogtreecommitdiff
path: root/book/en/src/by-example/app_priorities.md
diff options
context:
space:
mode:
authorHenrik Tjäder <henrik@grepit.se>2021-12-16 11:54:13 +0100
committerHenrik Tjäder <henrik@grepit.se>2021-12-19 01:33:15 +0100
commitc55016f4b237a9f25e5a0d86b42dc3ff39bf69b7 (patch)
tree490a763177bcba3145047ec3510d0145bea6ac4a /book/en/src/by-example/app_priorities.md
parent2ac0e1b29ddbe4fdc4e9b67b486eeb69a106e9c6 (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.md70
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.