aboutsummaryrefslogtreecommitdiff
path: root/book/ru/src/migration/migration_v5.md
diff options
context:
space:
mode:
Diffstat (limited to 'book/ru/src/migration/migration_v5.md')
-rw-r--r--book/ru/src/migration/migration_v5.md208
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`.
+