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

64 lines
2.2 KiB
Markdown
Raw Normal View History

2018-11-03 17:02:41 +01:00
# Software tasks
RTFM treats interrupt and exception handlers as *hardware* tasks. Hardware tasks
are invoked by the hardware in response to events, like pressing a button. RTFM
also supports *software* tasks which can be spawned by the software from any
execution context.
Software tasks can also be assigned priorities and are dispatched from interrupt
handlers. RTFM requires that free interrupts are declared in an `extern` block
when using software tasks; these free interrupts will be used to dispatch the
software tasks. An advantage of software tasks over hardware tasks is that many
tasks can be mapped to a single interrupt handler.
Software tasks are declared by applying the `task` attribute to functions. To be
able to spawn a software task the name of the task must appear in the `spawn`
argument of the context attribute (`init`, `idle`, `interrupt`, etc.).
The example below showcases three software tasks that run at 2 different
priorities. The three tasks map to 2 interrupts handlers.
``` rust
2019-02-11 21:40:53 +01:00
{{#include ../../../../examples/task.rs}}
2018-11-03 17:02:41 +01:00
```
``` console
$ cargo run --example task
2019-02-11 21:40:53 +01:00
{{#include ../../../../ci/expected/task.run}}```
2018-11-03 17:02:41 +01:00
## Message passing
The other advantage of software tasks is that messages can be passed to these
tasks when spawning them. The type of the message payload must be specified in
the signature of the task handler.
The example below showcases three tasks, two of them expect a message.
``` rust
2019-02-11 21:40:53 +01:00
{{#include ../../../../examples/message.rs}}
2018-11-03 17:02:41 +01:00
```
``` console
$ cargo run --example message
2019-02-11 21:40:53 +01:00
{{#include ../../../../ci/expected/message.run}}```
2018-11-03 17:02:41 +01:00
## Capacity
Task dispatchers do *not* use any dynamic memory allocation. The memory required
to store messages is statically reserved. The framework will reserve enough
space for every context to be able to spawn each task at most once. This is a
sensible default but the "inbox" capacity of each task can be controlled using
2018-12-21 18:15:16 +01:00
the `capacity` argument of the `task` attribute.
2018-11-03 17:02:41 +01:00
The example below sets the capacity of the software task `foo` to 4. If the
capacity is not specified then the second `spawn.foo` call in `UART0` would
fail.
``` rust
2019-02-11 21:40:53 +01:00
{{#include ../../../../examples/capacity.rs}}
2018-11-03 17:02:41 +01:00
```
``` console
$ cargo run --example capacity
2019-02-11 21:40:53 +01:00
{{#include ../../../../ci/expected/capacity.run}}```