aboutsummaryrefslogtreecommitdiff
path: root/book/ru/src/internals/non-reentrancy.md
diff options
context:
space:
mode:
authorAndrey Zgarbul <zgarbul.andrey@gmail.com>2021-04-04 08:15:13 +0300
committerAndrey Zgarbul <zgarbul.andrey@gmail.com>2021-04-08 12:22:43 +0300
commit05bda2b1bd2e15f5a20cda1444992eb9b6c8887e (patch)
tree25330724d4e6d9ea3a62b592c07bfc5799c7da57 /book/ru/src/internals/non-reentrancy.md
parent83cdf00eecb0f14857b5e0f28e884b2120eabb18 (diff)
update russian translation of the book
Diffstat (limited to 'book/ru/src/internals/non-reentrancy.md')
-rw-r--r--book/ru/src/internals/non-reentrancy.md79
1 files changed, 79 insertions, 0 deletions
diff --git a/book/ru/src/internals/non-reentrancy.md b/book/ru/src/internals/non-reentrancy.md
new file mode 100644
index 0000000..98eb00f
--- /dev/null
+++ b/book/ru/src/internals/non-reentrancy.md
@@ -0,0 +1,79 @@
+# Нереентерабельность
+
+В RTIC задачи-обработчики *не* могут использоваться повторно. Переиспользование задачи-обработчика
+может сломать правила заимствования Rust и привести к *неопределенному поведению*.
+Задача-обработчик теоретически может быть переиспользована одним из двух способов: программно или аппаратно.
+
+## Программно
+
+Чтобы переиспользовать задачу-обработчик программно, назначенный ей обработчик прерывания
+должен быть вызван с помощью FFI (смотрите пример ниже). FFI требует `unsafe` код,
+что уменьшает желание конечных пользователей вызывать обработчик прерывания.
+
+``` rust
+#[rtic::app(device = ..)]
+mod app {
+ #[init]
+ fn init(c: init::Context) { .. }
+
+ #[interrupt(binds = UART0)]
+ fn foo(c: foo::Context) {
+ static mut X: u64 = 0;
+
+ let x: &mut u64 = X;
+
+ // ..
+
+ //~ `bar` может вытеснить `foo` в этом месте
+
+ // ..
+ }
+
+ #[interrupt(binds = UART1, priority = 2)]
+ fn bar(c: foo::Context) {
+ extern "C" {
+ fn UART0();
+ }
+
+ // этот обработчик прерывания вызовет задачу-обработчик `foo`, что сломает
+ // ссылку на статическую переменную `X`
+ unsafe { UART0() }
+ }
+}
+```
+
+Фреймворк RTIC должен сгенерировать код обработчика прерывания, который вызывает
+определенные пользователем задачи-обработчики. Мы аккуратны в том, чтобы обеспечить
+невозможность вызова этих обработчиков из пользовательского кода.
+
+Пример выше раскрывается в:
+
+``` rust
+fn foo(c: foo::Context) {
+ // .. пользовательский код ..
+}
+
+fn bar(c: bar::Context) {
+ // .. пользовательский код ..
+}
+
+mod app {
+ // все в этом блоке невидимо для пользовательского кода
+
+ #[no_mangle]
+ unsafe fn USART0() {
+ foo(..);
+ }
+
+ #[no_mangle]
+ unsafe fn USART1() {
+ bar(..);
+ }
+}
+```
+
+## Аппаратно
+
+Обработчик прерывания также может быть вызван без программного вмешательства.
+Это может произойти, если один обработчик будет назначен двум или более прерываниям
+в векторе прерываний, но синтаксиса для такого рода функциональности в RTIC нет.