mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-12-02 00:14:33 +01:00
64 lines
2.2 KiB
Markdown
64 lines
2.2 KiB
Markdown
|
# 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
|
||
|
{{#include ../../../examples/task.rs}}
|
||
|
```
|
||
|
|
||
|
``` console
|
||
|
$ cargo run --example task
|
||
|
{{#include ../../../ci/expected/task.run}}```
|
||
|
|
||
|
## 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
|
||
|
{{#include ../../../examples/message.rs}}
|
||
|
```
|
||
|
|
||
|
``` console
|
||
|
$ cargo run --example message
|
||
|
{{#include ../../../ci/expected/message.run}}```
|
||
|
|
||
|
## 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
|
||
|
the `capacicy` argument of the `task` attribute.
|
||
|
|
||
|
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
|
||
|
{{#include ../../../examples/capacity.rs}}
|
||
|
```
|
||
|
|
||
|
``` console
|
||
|
$ cargo run --example capacity
|
||
|
{{#include ../../../ci/expected/capacity.run}}```
|