rtic/book/ru/src/internals/non-reentrancy.md
2021-04-08 12:22:43 +03:00

79 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Нереентерабельность
В 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 нет.