aboutsummaryrefslogtreecommitdiff
path: root/book/ru/src/migration
diff options
context:
space:
mode:
Diffstat (limited to 'book/ru/src/migration')
-rw-r--r--book/ru/src/migration/migration_v5.md289
1 files changed, 223 insertions, 66 deletions
diff --git a/book/ru/src/migration/migration_v5.md b/book/ru/src/migration/migration_v5.md
index 04aedc5..870c20f 100644
--- a/book/ru/src/migration/migration_v5.md
+++ b/book/ru/src/migration/migration_v5.md
@@ -30,7 +30,46 @@ mod app {
Так как теперь используется обычный модуль Rust, это значит, что можно использовать
обычный пользовательский код в этом модуле.
-Также жто значит, что `use`-выражения для ресурсов (и т.п.) могут понадобиться.
+Также это значит, что `use`-выражения для ресурсов, используемые
+в пользовательском коде должны быть перемещены внутрь `mod app`,
+либо на них можно сослаться с помощью `super`. Например, измените:
+
+```rust
+use some_crate::some_func;
+
+#[rtic::app(/* .. */)]
+const APP: () = {
+ fn func() {
+ some_crate::some_func();
+ }
+};
+```
+
+на
+
+```rust
+#[rtic::app(/* .. */)]
+mod app {
+ use some_crate::some_func;
+
+ fn func() {
+ some_crate::some_func();
+ }
+}
+```
+
+или
+
+```rust
+use some_crate::some_func;
+
+#[rtic::app(/* .. */)]
+mod app {
+ fn func() {
+ super::some_crate::some_func();
+ }
+}
+```
## Перенос диспетчеров из `extern "C"` в аргументы app.
@@ -63,137 +102,255 @@ mod app {
Это работает и для ОЗУ-функций, см. examples/ramfunc.rs
-## Init всегда возвращает поздние ресурсы
+## Структуры ресурсов - `#[shared]`, `#[local]`
-С целью сделать API более симметричным задача #[init] всегда возвращает поздние ресурсы.
+Ранее ресурсы RTIC должны были размещаться в структуре с именем "Resources":
-С этого:
+``` rust
+struct Resources {
+ // Ресурсы определяются здесь
+}
+```
+
+Начиная с RTIC v0.6.0 структуры ресурсов аннотируются подобно
+`#[task]`, `#[init]`, `#[idle]`: аттрибутами `#[shared]` и `#[local]`
``` rust
-#[rtic::app(device = lm3s6965)]
-mod app {
- #[init]
- fn init(_: init::Context) {
- rtic::pend(Interrupt::UART0);
- }
+#[shared]
+struct MySharedResources {
+ // Разделяемые задачами ресурсы определены здесь
+}
- // [еще код]
+#[local]
+struct MyLocalResources {
+ // Ресурсы, определенные здесь нельзя передавать между задачами; каждый из них локальный для единственной задачи
}
```
-на это:
+Эти структуры разработчик может называть по своему желанию.
+
+## `shared` и `local` аргументы в `#[task]`'ах
+
+В v0.6.0 ресурсы разделены на `shared` ресурсы и `local` ресурсы.
+`#[task]`, `#[init]` и `#[idle]` больше не имеют аргумента `resources`;
+они должны использовать аргументы `shared` и `local`.
+
+В v0.5.x:
``` rust
-#[rtic::app(device = lm3s6965)]
-mod app {
- #[init]
- fn init(_: init::Context) -> init::LateResources {
- rtic::pend(Interrupt::UART0);
+struct Resources {
+ local_to_b: i64,
+ shared_by_a_and_b: i64,
+}
- init::LateResources {}
- }
+#[task(resources = [shared_by_a_and_b])]
+fn a(_: a::Context) {}
- // [еще код]
+#[task(resources = [shared_by_a_and_b, local_to_b])]
+fn b(_: b::Context) {}
+```
+
+В v0.6.0:
+
+``` rust
+#[shared]
+struct Shared {
+ shared_by_a_and_b: i64,
}
+
+#[local]
+struct Local {
+ local_to_b: i64,
+}
+
+#[task(shared = [shared_by_a_and_b])]
+fn a(_: a::Context) {}
+
+#[task(shared = [shared_by_a_and_b], local = [local_to_b])]
+fn b(_: b::Context) {}
```
-## Структура Resources - `#[resources]`
+## Симметричные блокировки
-Ранее ресурсы RTIC должны были располагаться в структуре с именем "Resources":
+Теперь RTIC использует симметричные блокировки, это значит, что метод `lock` нужно использовать для
+всех доступов к `shared` ресурсам. Поскольку высокоприоритетные задачи имеют эксклюзивный доступ к ресурсу,
+в старом коде можно было следующее:
``` rust
-struct Resources {
- // Ресурсы определены здесь
+#[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 = /* ... */);
}
```
-В RTIC v0.6.0 структура ресурсов аннотируется также, как и
-`#[task]`, `#[init]`, `#[idle]`: атрибутом `#[resources]`
+С симметричными блокировками нужно вызывать `lock` для обоих задач:
``` rust
-#[resources]
-struct Resources {
- // Ресурсы определены здесь
+#[task(priority = 2, shared = [r])]
+fn foo(cx: foo::Context) {
+ cx.shared.r.lock(|r| r = /* ... */);
+}
+
+#[task(shared = [r])]
+fn bar(cx: bar::Context) {
+ cx.shared.r.lock(|r| r = /* ... */);
}
```
-На самом деле, имя структуры предоставлено на усмотрение разработчика:
+Заметьте, что скорость работы не изменяется благодаря оптимизациям LLVM, которые убирают ненужные блокировки.
+
+## Неблокирующий доступ к ресурсам
+
+В RTIC 0.5 к ресурсам разделяемым задачами, запускаемыми с одинаковым
+приоритетом, можно получить доступ *без* `lock` API.
+Это все еще возможно в 0.6: ресурс `#[shared]` должен быть аннотирован
+аттрибутом поля `#[lock_free]`.
+
+v0.5 код:
``` rust
-#[resources]
-struct Whateveryouwant {
- // Ресурсы определены здесь
+struct Resources {
+ counter: u64,
+}
+
+#[task(resources = [counter])]
+fn a(cx: a::Context) {
+ *cx.resources.counter += 1;
+}
+
+#[task(resources = [counter])]
+fn b(cx: b::Context) {
+ *cx.resources.counter += 1;
}
```
-будет работать так же хороршо.
+v0.6 код:
-## Вызов/планирование откуда угодно
+``` rust
+#[shared]
+struct Shared {
+ #[lock_free]
+ counter: u64,
+}
-С этой новой возвожностью, старый код, такой как:
+#[task(shared = [counter])]
+fn a(cx: a::Context) {
+ *cx.shared.counter += 1;
+}
+
+#[task(shared = [counter])]
+fn b(cx: b::Context) {
+ *cx.shared.counter += 1;
+}
+```
+
+## нет преобразования `static mut`
+`static mut` переменные больше не преобразуются в безопасные `&'static mut` ссылки.
+Вместо этого синтаксиса используйте аргумент `local` в `#[init]`.
+
+v0.5.x code:
``` rust
-#[task(spawn = [bar])]
-fn foo(cx: foo::Context) {
- cx.spawn.bar().unwrap();
+#[init]
+fn init(_: init::Context) {
+ static mut BUFFER: [u8; 1024] = [0; 1024];
+ let buffer: &'static mut [u8; 1024] = BUFFER;
}
+```
-#[task(schedule = [bar])]
-fn bar(cx: bar::Context) {
- cx.schedule.foo(/* ... */).unwrap();
+v0.6.0 code:
+
+``` rust
+#[init(local = [
+ buffer: [u8; 1024] = [0; 1024]
+// type ^^^^^^^^^^^^ ^^^^^^^^^ initial value
+])]
+fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
+ let buffer: &'static mut [u8; 1024] = cx.local.buffer;
+
+ (Shared {}, Local {}, init::Monotonics())
}
```
-Теперь будет выглядеть так:
+## Init всегда возвращает поздние ресурсы
+
+С целью сделать API более симметричным задача #[init] всегда возвращает поздние ресурсы.
+
+С этого:
``` rust
-#[task]
-fn foo(_c: foo::Context) {
- bar::spawn().unwrap();
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[init]
+ fn init(_: init::Context) {
+ rtic::pend(Interrupt::UART0);
+ }
+
+ // [еще код]
}
+```
-#[task]
-fn bar(_c: bar::Context) {
- foo::schedule(/* ... */).unwrap();
+на это:
+
+
+``` rust
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[shared]
+ struct MySharedResources {}
+
+ #[local]
+ struct MyLocalResources {}
+
+ #[init]
+ fn init(_: init::Context) -> (MySharedResources, MyLocalResources, init::Monotonics) {
+ rtic::pend(Interrupt::UART0);
+
+ (MySharedResources, MyLocalResources, init::Monotonics())
+ }
+
+ // [more code]
}
```
-Заметьте, что атрибуты `spawn` и `schedule` больше не нужны.
+## Вызов/планирование откуда угодно
-## Симметричные блокировки
+С этой новой возвожностью, старый код, такой как:
-Теперь RTIC использует симметричные блокировки, это значит, что метод `lock` нужно использовать для
-всех доступов к ресурсам. Поскольку высокоприоритетные задачи имеют эксклюзивный доступ к ресурсу,
-в старом коде можно было следующее:
``` rust
-#[task(priority = 2, resources = [r])]
+#[task(spawn = [bar])]
fn foo(cx: foo::Context) {
- cx.resources.r = /* ... */;
+ cx.spawn.bar().unwrap();
}
-#[task(resources = [r])]
+#[task(schedule = [bar])]
fn bar(cx: bar::Context) {
- cx.resources.r.lock(|r| r = /* ... */);
+ cx.schedule.foo(/* ... */).unwrap();
}
```
-С симметричными блокировками нужно вызывать `lock` для обоих задач:
+Теперь будет выглядеть так:
``` rust
-#[task(priority = 2, resources = [r])]
-fn foo(cx: foo::Context) {
- cx.resources.r.lock(|r| r = /* ... */);
+#[task]
+fn foo(_c: foo::Context) {
+ bar::spawn().unwrap();
}
-#[task(resources = [r])]
-fn bar(cx: bar::Context) {
- cx.resources.r.lock(|r| r = /* ... */);
+#[task]
+fn bar(_c: bar::Context) {
+ foo::schedule(/* ... */).unwrap();
}
```
-Заметьте, что скорость работы не изменяется благодаря оптимизациям LLVM, которые убирают ненужные блокировки.
+Заметьте, что атрибуты `spawn` и `schedule` больше не нужны.
---