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

3.1 KiB
Raw Blame History

Нереентерабельность

В RTIC задачи-обработчики не могут использоваться повторно. Переиспользование задачи-обработчика может сломать правила заимствования Rust и привести к неопределенному поведению. Задача-обработчик теоретически может быть переиспользована одним из двух способов: программно или аппаратно.

Программно

Чтобы переиспользовать задачу-обработчик программно, назначенный ей обработчик прерывания должен быть вызван с помощью FFI (смотрите пример ниже). FFI требует unsafe код, что уменьшает желание конечных пользователей вызывать обработчик прерывания.

#[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 должен сгенерировать код обработчика прерывания, который вызывает определенные пользователем задачи-обработчики. Мы аккуратны в том, чтобы обеспечить невозможность вызова этих обработчиков из пользовательского кода.

Пример выше раскрывается в:

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