diff options
Diffstat (limited to 'book/ru/src/by-example/timer-queue.md')
| -rw-r--r-- | book/ru/src/by-example/timer-queue.md | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/book/ru/src/by-example/timer-queue.md b/book/ru/src/by-example/timer-queue.md new file mode 100644 index 0000000..8995bd0 --- /dev/null +++ b/book/ru/src/by-example/timer-queue.md @@ -0,0 +1,90 @@ +# Очередь таймера + +Когда включена опция `timer-queue`, фреймворк RTFM включает +*глобальную очередь таймера*, которую приложения могут использовать, чтобы +*планировать* программные задачи на запуск через некоторое время в будущем. + +Чтобы была возможность планировать программную задачу, имя задачи должно +присутствовать в аргументе `schedule` контекста атрибута. Когда задача +планируется, момент ([`Instant`]), в который задачу нужно запустить, нужно передать +как первый аргумент вызова `schedule`. + +[`Instant`]: ../../api/rtfm/struct.Instant.html + +Рантайм RTFM включает монотонный, растущий только вверх, 32-битный таймер, +значение которого можно запросить конструктором `Instant::now`. Время ([`Duration`]) +можно передать в `Instant::now()`, чтобы получить `Instant` в будущем. Монотонный +таймер отключен пока запущен `init`, поэтому `Instant::now()` всегда возвращает +значение `Instant(0 /* циклов тактовой частоты */)`; таймер включается сразу перед +включением прерываний и запуском `idle`. + +[`Duration`]: ../../api/rtfm/struct.Duration.html + +В примере ниже две задачи планируются из `init`: `foo` и `bar`. `foo` - +запланирована на запуск через 8 миллионов тактов в будущем. Кроме того, `bar` +запланирован на запуск через 4 миллиона тактов в будущем. `bar` запустится раньше +`foo`, т.к. он запланирован на запуск первым. + +> **ВАЖНО**: Примеры, использующие API `schedule` или абстракцию `Instant` +> **не** будут правильно работать на QEMU, потому что функциональность счетчика +> тактов Cortex-M не реализована в `qemu-system-arm`. + +``` rust +{{#include ../../../../examples/schedule.rs}} +``` + +Запуск программы на реальном оборудовании производит следующий вывод в консоли: + +``` text +{{#include ../../../../ci/expected/schedule.run}} +``` + +## Периодические задачи + +Программные задачи имеют доступ к `Instant` в момент, когда были запланированы +на запуск через переменную `scheduled`. Эта информация и API `schedule` могут +быть использованы для реализации периодических задач, как показано в примере ниже. + +``` rust +{{#include ../../../../examples/periodic.rs}} +``` + +Это вывод, произведенный примером. Заметьте, что есть смещение / колебание нуля +даже если `schedule.foo` была вызвана в *конце* `foo`. Использование +`Instant::now` вместо `scheduled` имело бы влияние на смещение / колебание. + +``` text +{{#include ../../../../ci/expected/periodic.run}} +``` + +## Базовое время + +Для задач, планируемых из `init` мы имеем точную информацию о их планируемом +(`scheduled`) времени. Для аппаратных задач нет `scheduled` времени, потому +что эти задачи асинхронны по природе. Для аппаратных задач рантайм предоставляет +время старта (`start`), которе отражает время, в которое обработчик прерывания +был запущен. + +Заметьте, что `start` **не** равен времени возникновения события, вызвавшего +задачу. В зависимости от приоритета задачи и загрузки системы время +`start` может быть сильно отдалено от времени возникновения события. + +Какое по Вашему мнению будет значение `scheduled` для программных задач которые +*вызываются*, вместо того чтобы планироваться? Ответ в том, что вызываемые +задачи наследуют *базовое* время контекста, в котором вызваны. Бызовым для +аппаратных задач является `start`, базовым для программных задач - `scheduled` +и базовым для `init` - `start = Instant(0)`. `idle` на сомом деле не имеет +базового времени но задачи, вызванные из него будут использовать `Instant::now()` +как их базовое время. + +Пример ниже демонстрирует разное значение *базового времени*. + +``` rust +{{#include ../../../../examples/baseline.rs}} +``` + +Запуск программы на реальном оборудовании произведет следующий вывод в консоли: + +``` text +{{#include ../../../../ci/expected/baseline.run}} +``` |
