diff options
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 нет. |
