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