diff options
| author | Andrey Zgarbul <zgarbul.andrey@gmail.com> | 2021-04-04 08:15:13 +0300 |
|---|---|---|
| committer | Andrey Zgarbul <zgarbul.andrey@gmail.com> | 2021-04-08 12:22:43 +0300 |
| commit | 05bda2b1bd2e15f5a20cda1444992eb9b6c8887e (patch) | |
| tree | 25330724d4e6d9ea3a62b592c07bfc5799c7da57 /book/ru/src/internals/non-reentrancy.md | |
| parent | 83cdf00eecb0f14857b5e0f28e884b2120eabb18 (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.md | 79 |
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 нет. |
