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

64 lines
3.8 KiB
Markdown
Raw Normal View History

2019-02-08 21:18:51 +01:00
# Программные задачи
2020-06-11 19:18:29 +02:00
RTIC обрабатывает прерывания и исключения как *аппаратные* задачи. Аппаратные
2019-02-08 21:18:51 +01:00
задачи могут вызываться устройством в ответ на события, такие как нажатие кнопки.
2020-06-11 19:18:29 +02:00
RTIC также поддерживает *программные* задачи, порождаемые программой из любого
2019-02-08 21:18:51 +01:00
контекста выполнения.
Программным задачам также можно назначать приоритет и диспетчеризовать из
2020-06-11 19:18:29 +02:00
обработчиков прерываний. RTIC требует определения свободных прерываний в блоке
2019-02-08 21:18:51 +01:00
`extern`, когда используются программные задачи; эти свободные прерывания будут использованы, чтобы диспетчеризовать программные задачи. Преимущество программных
задач перед аппаратными в том, что на один обработчик прерывания можно назначить
множество задач.
Программные задачи определяются заданием функциям атрибута `task`. Чтобы было
возможно вызывать программные задачи, имя задачи нужно передать в аргументе
`spawn` контекста атрибута (`init`, `idle`, `interrupt`, etc.).
В примере ниже продемонстрированы три программных задачи, запускаемые на 2-х
разных приоритетах. Трем задачам назначены 2 обработчика прерываний.
``` rust
2019-02-11 21:40:53 +01:00
{{#include ../../../../examples/task.rs}}
2019-02-08 21:18:51 +01:00
```
``` console
$ cargo run --example task
2019-02-11 21:40:53 +01:00
{{#include ../../../../ci/expected/task.run}}```
2019-02-08 21:18:51 +01:00
## Передача сообщений
Другое преимущество программных задач - возможность передавать сообщения задачам
во время их вызова. Тип полезной нагрузки сообщения должен быть определен в
сигнатуре обработчика задачи.
Пример ниже демонстрирует три задачи, две из которых ожидают сообщения.
``` rust
2019-02-11 21:40:53 +01:00
{{#include ../../../../examples/message.rs}}
2019-02-08 21:18:51 +01:00
```
``` console
$ cargo run --example message
2019-02-11 21:40:53 +01:00
{{#include ../../../../ci/expected/message.run}}```
2019-02-08 21:18:51 +01:00
## Ёмкость
Диспетчеры задач *не* используют динамическое выделение памяти. Память
необходимая для размещения сообщений, резервируется статически. Фреймворк
зарезервирует достаточно памяти для каждого контекста, чтобы можно было вызвать
каждую задачу как минимум единожды. Это разумно по умолчанию, но
"внутреннюю" ёмкость каждой задачи можно контролировать используя аргумент
2019-02-09 06:48:12 +01:00
`capacity` атрибута `task`.
2019-02-08 21:18:51 +01:00
В примере ниже установлена ёмкость программной задачи `foo` на 4. Если ёмкость
не определена, тогда второй вызов `spawn.foo` в `UART0` вызовет ошибку.
``` rust
2019-02-11 21:40:53 +01:00
{{#include ../../../../examples/capacity.rs}}
2019-02-08 21:18:51 +01:00
```
``` console
$ cargo run --example capacity
2019-02-11 21:40:53 +01:00
{{#include ../../../../ci/expected/capacity.run}}```