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

fn bar(c: foo::Context) {

// ..

}

#[interrupt(binds = UART2, priority = 3, resources = [y])]

fn baz(c: foo::Context) {

// ..

}

// ..

}

}

Код, сгенерированный фреймворком, выглядит так:

#![allow(unused)]

fn main() {

// опущено: пользовательский код

pub mod resources {

pub struct x<'a> {

priority: &'a Cell,

}

impl<'a> x<'a> {

pub unsafe fn new(priority: &'a Cell) -> Self {

x { priority }

}

pub unsafe fn priority(&self) -> &Cell {

self.priority

}

}

// repeat for `y`

}

pub mod foo {

pub struct Context {

pub resources: Resources,

// ..

}

pub struct Resources<'a> {

pub x: resources::x<'a>,

pub y: resources::y<'a>,

}

}

mod app {

use cortex_m::register::basepri;

#[no_mangle]

unsafe fn UART1() {

// статический приоритет прерывания (определено пользователем)

const PRIORITY: u8 = 2;

// сделать снимок BASEPRI

let initial = basepri::read();

let priority = Cell::new(PRIORITY);

bar(bar::Context {

resources: bar::Resources::new(&priority),

// ..

});

// вернуть BASEPRI значение из снимка, сделанного ранее

basepri::write(initial); // то же, что и `asm!` блок, виденный ранее

}

// так же для `UART0` / `foo` и `UART2` / `baz`

impl<'a> rtic::Mutex for resources::x<'a> {

type T = u64;

fn lock(&mut self, f: impl FnOnce(&mut u64) -> R) -> R {

unsafe {

// определение максимального приоритет ресурса

const CEILING: u8 = 2;

let current = self.priority().get();

if current < CEILING {

// увеличить динамический приоритет

self.priority().set(CEILING);

basepri::write(logical2hw(CEILING));

let r = f(&mut y);

// восстановить динамический приоритет

basepri::write(logical2hw(current));

self.priority().set(current);

r

} else {

// динамический приоритет достаточно высок

f(&mut y)

}

}

}

}

// повторить для ресурса `y`

}

}

Наконец, компилятор оптимизирует функцию foo во что-то наподобие такого:

#![allow(unused)]

fn main() {

fn foo(c: foo::Context) {

// ПРИМЕЧАНИЕ: BASEPRI содержит значение `0` (значение сброса) в этот момент

// увеличить динамический приоритет до `3`

unsafe { basepri::write(160) }

// две операции над `y` объединены в одну

y += 2;

// BASEPRI не изменяется для доступа к `x`, потому что динамический приоритет достаточно высок

x += 1;

// уменьшить (восстановить) динамический приоритет до `1`

unsafe { basepri::write(224) }

// средина

// увеличить динамический приоритет до `2`

unsafe { basepri::write(192) }

x += 1;

// увеличить динамический приоритет до `3`

unsafe { basepri::write(160) }

y += 1;

// уменьшить (восстановить) динамический приоритет до `2`

unsafe { basepri::write(192) }

// ПРИМЕЧАНИЕ: было вы правильно объединить эту операцию над `x` с предыдущей, но

// compiler fences грубые и предотвращают оптимизацию

x += 1;

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

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

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

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

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

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