diff options
Diffstat (limited to 'book/ru/src/by-example/timer-queue.md')
| -rw-r--r-- | book/ru/src/by-example/timer-queue.md | 108 |
1 files changed, 0 insertions, 108 deletions
diff --git a/book/ru/src/by-example/timer-queue.md b/book/ru/src/by-example/timer-queue.md deleted file mode 100644 index c8818d7..0000000 --- a/book/ru/src/by-example/timer-queue.md +++ /dev/null @@ -1,108 +0,0 @@ -# Очередь таймера - -В отличие от интерфейса `spawn`, который немедленно передает программную задачу -планировщику для немедленного запуска, интерфейс `schedule` можно использовать -для планирования задачи к запуске через какое-то время в будущем. - -Чтобы использовать интерфейс `schedule`, предварительно должен быть определен -монотонный таймер с помощью аргумента `monotonic` атрибута `#[app]`. -Этот аргумент принимает путь к типу, реализующему трейт [`Monotonic`]. -Ассоциированный тип, `Instant`, этого трейта представляет метку времени в соответствущих -единицах измерения и широко используется в интерфейсе `schedule` -- предлагается смоделировать -этот тип позднее [один из таких есть в стандартной библиотеке][std-instant]. - -Хотя это не отражено в определении трейта (из-за ограничений системы типов / трейтов), -разница двух `Instant`ов должна возвращать какой-то тип `Duration` (см. [`core::time::Duration`]) -и этот `Duration` должен реализовывать трейт `TryInto<u32>`. -Реализация этого трейта должна конвертировать значение `Duration`, которое -использует какую-то определенную единицу измерения времени, в единицы измерения "тактов системного таймера -(SYST)". Результат преобразований должен быть 32-битным целым. -Если результат не соответствует 32-битному целому, тогда операция должна возвращать ошибку любого типа. - -[`Monotonic`]: ../../../api/rtic/trait.Monotonic.html -[std-instant]: https://doc.rust-lang.org/std/time/struct.Instant.html -[`core::time::Duration`]: https://doc.rust-lang.org/core/time/struct.Duration.html - -Для целевых платформ ARMv7+ крейт `rtic` предоставляет реализацию `Monotonic`, основанную на -встроенном CYCle CouNTer (CYCCNT). Заметьте, что это 32-битный таймер, работающий на -частоте центрального процессора, и поэтому не подходит для отслеживания интервалов времени в секундах. - -Когда планируется задача, (определенный пользователем) `Instant`, в который задача должна быть -выполнена, должен передаваться в качестве первого аргумента вызова `schedule`. - -К тому же, выбранный `monotonic` таймер, необходимо сконфигурировать и инициализировать в -фазе работы `#[init]`. Заметьте, что *также* касается случая использования `CYCCNT`, -предоставляемого крейтом `cortex-m-rtic`. - -Пример ниже планирует к выполнению две задачи из `init`: `foo` и `bar`. `foo` запланирована -к запуску через 8 миллионов циклов в будущем. Далее, `bar` запланировано запустить через -4 миллиона циклов в будущем. Таким образом, `bar` запустится до `foo`, так как и запланировано. - -> **DF:YJ**: Примеры, использующие интерфейс `schedule` или абстракцию `Instant` -> **не будут** правильно работать на эмуляторе QEMU, поскольку счетчик циклов Cortex-M -> функционально не был реализован в `qemu-system-arm`. - -``` rust -{{#include ../../../../examples/schedule.rs}} -``` - -Запусе программы на реальном оборудовании создает следующий вывод в консоли: - -``` text -{{#include ../../../../ci/expected/schedule.run}} -``` - -Когда интерфейс `schedule` используется, среда исполнения использует внутри -обработчик прерываний `SysTick` и периферию системного таймера (`SYST`), поэтому ни -тот ни другой нельзя использовать в программе. Это гарантируется изменением типа -`init::Context.core` с `cortex_m::Peripherals` на `rtic::Peripherals`. -Последняя структура содержит все поля из предыдущей кроме `SYST`. - -## Периодические задачи - -Программные задачи имеют доступ к моменту времени `Instant`, в который они были запланированы -на выполнение переменной `scheduled`. Эта информация и интерфейс `schedule` можно использовать, -чтобы реализовать периодические задачи, как показано ниже. - -``` rust -{{#include ../../../../examples/periodic.rs}} -``` - -Это вывод, создаваемый примером. Заметьте, что здесь пристствует небольшой дрейф / колебания -даже несмотря на то, что `schedule.foo` была вызвана в *конце* `foo`. Использование -`Instant::now` вместо `scheduled` вызвало бы дрейф / колебания. - -``` text -{{#include ../../../../ci/expected/periodic.run}} -``` - -## Базовое время - -Для задач, вызываемых из `init` мы имеем точную информацию о их `scheduled` времени. -Для аппаратных задач такого времени нет, поскольку они асинхронны по природе. -Для аппаратных задач среда исполнения предоставляет время запуска (`start`), которое отражает -время, в которое обработчик прерывания будет запущен. - -Заметьте, что `start` **не** равно времени прихода события, которое вызывает задачу. -В зависимости от приоритета задачи и загрузки системы, время `start` может сильно отдалиться от -времени прихода события. - -Какое по вашему мнению будет значение `scheduled` для программных задач, которые вызываются через -`spawn` вместо планирования? Ответ в том, что вызываемые задачи наследуют -*базовое* время того контекста, который их вызывает. Базовое время аппаратных задач - -это их время `start`, базовое время программных задач - их время `scheduled`, а -базовое время `init` - время старта системы, или нулевое -(`Instant::zero()`). `idle` на самом деле не имеет базового времени, но задачи вызываемые из нее, -используют `Instant::now()` в качестве базового. - -Пример ниже демонстрирует разные смыслы *базового времени*. - -``` rust -{{#include ../../../../examples/baseline.rs}} -``` - -Запуск программы на реальном оборудовании приведет к следующему выводу в консоли: - -``` text -{{#include ../../../../ci/expected/baseline.run}} -``` |
