aboutsummaryrefslogtreecommitdiff
path: root/book/ru/src/internals/interrupt-configuration.md
diff options
context:
space:
mode:
Diffstat (limited to 'book/ru/src/internals/interrupt-configuration.md')
-rw-r--r--book/ru/src/internals/interrupt-configuration.md72
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(/* .. */)
+}
+```