diff options
Diffstat (limited to 'book/ru/src/internals/interrupt-configuration.md')
| -rw-r--r-- | book/ru/src/internals/interrupt-configuration.md | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/book/ru/src/internals/interrupt-configuration.md b/book/ru/src/internals/interrupt-configuration.md new file mode 100644 index 0000000..5631b37 --- /dev/null +++ b/book/ru/src/internals/interrupt-configuration.md @@ -0,0 +1,72 @@ +# Настройка прерываний + +Прерывания - это основа работы программ на 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(/* .. */) +} +``` |
