diff options
Diffstat (limited to 'book/ru/src/migration/migration_v5.md')
| -rw-r--r-- | book/ru/src/migration/migration_v5.md | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/book/ru/src/migration/migration_v5.md b/book/ru/src/migration/migration_v5.md new file mode 100644 index 0000000..04aedc5 --- /dev/null +++ b/book/ru/src/migration/migration_v5.md @@ -0,0 +1,208 @@ +# Миграция с v0.5.x на v0.6.0 + +Этот раздел описывает как обновиться с версии v0.5.x на v0.6.0 фреймворка RTIC. + +## `Cargo.toml` - увеличьте версию + +Измените версию `cortex-m-rtic` на `"0.6.0"`. + +## `mod` вместо `const` + +С поддержкой атрибутов над модулями трюк с `const APP` теперь не нужен. + +Измените + +``` rust +#[rtic::app(/* .. */)] +const APP: () = { + [код здесь] +}; +``` + +на + +``` rust +#[rtic::app(/* .. */)] +mod app { + [код здесь] +} +``` + +Так как теперь используется обычный модуль Rust, это значит, что можно использовать +обычный пользовательский код в этом модуле. +Также жто значит, что `use`-выражения для ресурсов (и т.п.) могут понадобиться. + +## Перенос диспетчеров из `extern "C"` в аргументы app. + +Измените + +``` rust +#[rtic::app(/* .. */)] +const APP: () = { + [код здесь] + + // RTIC требует, чтобы неиспользуемые прерывания были задекларированы в блоке extern, когда + // используются программные задачи; эти свободные прерывания будут использованы для управления + // программными задачами. + extern "C" { + fn SSI0(); + fn QEI0(); + } +}; +``` + +на + +``` rust +#[rtic::app(/* .. */, dispatchers = [SSI0, QEI0])] +mod app { + [код здесь] +} +``` + +Это работает и для ОЗУ-функций, см. examples/ramfunc.rs + + +## Init всегда возвращает поздние ресурсы + +С целью сделать API более симметричным задача #[init] всегда возвращает поздние ресурсы. + +С этого: + +``` rust +#[rtic::app(device = lm3s6965)] +mod app { + #[init] + fn init(_: init::Context) { + rtic::pend(Interrupt::UART0); + } + + // [еще код] +} +``` + +на это: + +``` rust +#[rtic::app(device = lm3s6965)] +mod app { + #[init] + fn init(_: init::Context) -> init::LateResources { + rtic::pend(Interrupt::UART0); + + init::LateResources {} + } + + // [еще код] +} +``` + +## Структура Resources - `#[resources]` + +Ранее ресурсы RTIC должны были располагаться в структуре с именем "Resources": + +``` rust +struct Resources { + // Ресурсы определены здесь +} +``` + +В RTIC v0.6.0 структура ресурсов аннотируется также, как и +`#[task]`, `#[init]`, `#[idle]`: атрибутом `#[resources]` + +``` rust +#[resources] +struct Resources { + // Ресурсы определены здесь +} +``` + +На самом деле, имя структуры предоставлено на усмотрение разработчика: + +``` rust +#[resources] +struct Whateveryouwant { + // Ресурсы определены здесь +} +``` + +будет работать так же хороршо. + +## Вызов/планирование откуда угодно + +С этой новой возвожностью, старый код, такой как: + + +``` rust +#[task(spawn = [bar])] +fn foo(cx: foo::Context) { + cx.spawn.bar().unwrap(); +} + +#[task(schedule = [bar])] +fn bar(cx: bar::Context) { + cx.schedule.foo(/* ... */).unwrap(); +} +``` + +Теперь будет выглядеть так: + +``` rust +#[task] +fn foo(_c: foo::Context) { + bar::spawn().unwrap(); +} + +#[task] +fn bar(_c: bar::Context) { + foo::schedule(/* ... */).unwrap(); +} +``` + +Заметьте, что атрибуты `spawn` и `schedule` больше не нужны. + +## Симметричные блокировки + +Теперь RTIC использует симметричные блокировки, это значит, что метод `lock` нужно использовать для +всех доступов к ресурсам. Поскольку высокоприоритетные задачи имеют эксклюзивный доступ к ресурсу, +в старом коде можно было следующее: + +``` rust +#[task(priority = 2, resources = [r])] +fn foo(cx: foo::Context) { + cx.resources.r = /* ... */; +} + +#[task(resources = [r])] +fn bar(cx: bar::Context) { + cx.resources.r.lock(|r| r = /* ... */); +} +``` + +С симметричными блокировками нужно вызывать `lock` для обоих задач: + +``` rust +#[task(priority = 2, resources = [r])] +fn foo(cx: foo::Context) { + cx.resources.r.lock(|r| r = /* ... */); +} + +#[task(resources = [r])] +fn bar(cx: bar::Context) { + cx.resources.r.lock(|r| r = /* ... */); +} +``` + +Заметьте, что скорость работы не изменяется благодаря оптимизациям LLVM, которые убирают ненужные блокировки. + +--- + +## Дополнительно + +### Внешние задачи + +Как программные, так и аппаратные задачи теперь можно определять вне модуля `mod app`. +Ранее это было возможно только путем реализации обертки, вызывающей реализацию задачи. + +Смотреть примеры `examples/extern_binds.rs` и `examples/extern_spawn.rs`. + |
