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

72 lines
2.9 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. Правильно настроить приоритеты
прерываний и убедиться, что они не изменяются во время выполнения обязательно
для безопасной работы программы.
Фреймворк RTIC представляет приоритеты прерываний, как нечто, что должно быть определено
на этапе компиляции. Однако, статическая настройка должна быть зашита в соответствующие регистры
в процессе инициализации программы. Настройка прерываний происходит до запуска функции `init`.
Этот пример дает представление о коде, запускаемом фреймворком RTIC:
``` rust
#[rtic::app(device = lm3s6965)]
mod app {
#[init]
fn init(c: init::Context) {
// .. пользовательский код ..
}
#[idle]
fn idle(c: idle::Context) -> ! {
// .. пользовательский код ..
}
#[interrupt(binds = UART0, priority = 2)]
fn foo(c: foo::Context) {
// .. пользовательский код ..
}
}
```
Фреймворк генерирует точку входа в программу, которая выглядит примерно так:
``` rust
// настоящая точку входа в программу
#[no_mangle]
unsafe fn main() -> ! {
// преобразует логические приоритеты в аппаратные / NVIC приоритеты
fn logical2hw(priority: u8) -> u8 {
use lm3s6965::NVIC_PRIO_BITS;
// NVIC кодирует приоритеты верхними битами
// большие значения обозначают меньший приоритет
((1 << NVIC_PRIORITY_BITS) - priority) << (8 - NVIC_PRIO_BITS)
}
cortex_m::interrupt::disable();
let mut core = cortex_m::Peripheral::steal();
core.NVIC.enable(Interrupt::UART0);
// значение, определенное пользователем
let uart0_prio = 2;
// проверка на этапе компиляции, что определенный приоритет входит в поддерживаемый диапазон
let _ = [(); (1 << NVIC_PRIORITY_BITS) - (uart0_prio as usize)];
core.NVIC.set_priority(Interrupt::UART0, logical2hw(uart0_prio));
// вызов пользовательского кода
init(/* .. */);
// ..
cortex_m::interrupt::enable();
// вызов пользовательского кода
idle(/* .. */)
}
```