Читаем Real-Time Interrupt-driven Concurrency полностью

cortex-m-rtfm = "0.5.3"

# на это

cortex-m-rtic = "0.5.3"

<p id="Изменения_в_коде"><strong><a l:href="#Изменения_в_коде">Изменения в коде</a></strong></p>

Единственное изменение в коде, которое нужно сделать - поменять все ссылки на rtfm, чтобы они указывали на rtic:

#![allow(unused)]

fn main() {

//

// Измените это

//

#[rtfm::app(/* .. */, monotonic = rtfm::cyccnt::CYCCNT)]

const APP: () = {

// ...

};

//

// На это

//

#[rtic::app(/* .. */, monotonic = rtic::cyccnt::CYCCNT)]

const APP: () = {

// ...

};

}

<p id="Под_капотом"><strong><a l:href="#Под_капотом">Под капотом</a></strong></p>

Этот раздел в настоящий момент находится в разработке, он появится снова, когда будет завершен

Этот раздел описывает внутренности фреймворка RTIC на высоком уровне. Низкоуровневые детали, такие как парсинг и генерация кода, выполняемые процедурным макросом (#[app]) объясняться не будут. Внимание будет сосредоточено на анализе спецификации пользователя и структурах данных, используемых на этапе выполнения.

Мы настоятельно рекомендуем вам прочитать раздел о конкуренции в embedonomicon перед тем, как погружаться в материал.

<p id="Настройка_прерываний"><strong><a l:href="#Настройка_прерываний">Настройка прерываний</a></strong></p>

Прерывания - это основа работы программ на RTIC. Правильно настроить приоритеты прерываний и убедиться, что они не изменяются во время выполнения обязательно для безопасной работы программы.

Фреймворк RTIC представляет приоритеты прерываний, как нечто, что должно быть определено на этапе компиляции. Однако, статическая настройка должна быть зашита в соответствующие регистры в процессе инициализации программы. Настройка прерываний происходит до запуска функции init.

Этот пример дает представление о коде, запускаемом фреймворком RTIC:

#![allow(unused)]

fn main() {

#[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) {

// .. пользовательский код ..

}

}

}

Фреймворк генерирует точку входа в программу, которая выглядит примерно так:

// настоящая точку входа в программу

#[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(/* .. */)

}

<p id="Нереентерабельность"><strong><a l:href="#Нереентерабельность">Нереентерабельность</a></strong></p>

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

<p id="Программно"><strong><a l:href="#Программно">Программно</a></strong></p>

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

Перейти на страницу:

Похожие книги

Компьютерные сети. 6-е изд.
Компьютерные сети. 6-е изд.

Перед вами шестое издание самой авторитетной книги по современным сетевым технологиям, написанное признанным экспертом Эндрю Таненбаумом в соавторстве со специалистом компании Google Дэвидом Уэзероллом и профессором Чикагского университета Ником Фимстером. Первая версия этого классического труда появилась на свет в далеком 1980 году, и с тех пор каждое издание книги неизменно становилось бестселлером. В книге последовательно изложены основные концепции, определяющие современное состояние компьютерных сетей и тенденции их развития. Авторы подробно объясняют устройство и принципы работы аппаратного и программного обеспечения, рассматривают все аспекты и уровни организации сетей — от физического до прикладного. Изложение теоретических принципов дополняется яркими, показательными примерами функционирования интернета и компьютерных сетей различного типа. Большое внимание уделяется сетевой безопасности. Шестое издание полностью переработано с учетом изменений, произошедших в сфере сетевых технологий за последние годы, и, в частности, освещает такие технологии, как DOCSIS, 4G и 5G, беспроводные сети стандарта 802.11ax, 100-гигабитные сети Ethernet, интернет вещей, современные транспортные протоколы CUBIC TCP, QUIC и BBR, программно-конфигурируемые сети и многое другое.

Дэвид Уэзеролл , Ник Фимстер , Эндрю Таненбаум

Учебные пособия, самоучители