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

Давайте сначала глянем на код, генерируемый фреймворком для диспетчеризации задач. Рассмотрим пример:


#![allow(unused)]

fn main() {

#[rtic::app(device = ..)]

mod app {

// ..


#[interrupt(binds = UART0, priority = 2, spawn = [bar, baz])]

fn foo(c: foo::Context) {

foo.spawn.bar().ok();


foo.spawn.baz(42).ok();

}


#[task(capacity = 2, priority = 1)]

fn bar(c: bar::Context) {

// ..

}


#[task(capacity = 2, priority = 1, resources = [X])]

fn baz(c: baz::Context, input: i32) {

// ..

}


extern "C" {

fn UART1();

}

}

}

Фреймворк создает следующий диспетчер задач, состоящий из обработчика прерывания и очереди готовности:


#![allow(unused)]

fn main() {

fn bar(c: bar::Context) {

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

}


mod app {

use heapless::spsc::Queue;

use cortex_m::register::basepri;


struct Ready {

task: T,

// ..

}


/// вызываемые (`spawn`) задачи, выполняющиеся с уровнем приоритета `1`

enum T1 {

bar,

baz,

}


// очередь готовности диспетчера задач

// `U4` - целое число, представляющее собой емкость этой очереди

static mut RQ1: Queue, U4> = Queue::new();


// обработчик прерывания, выбранный для диспетчеризации задач с приоритетом `1`

#[no_mangle]

unsafe UART1() {

// приоритет данного обработчика прерывания

const PRIORITY: u8 = 1;


let snapshot = basepri::read();


while let Some(ready) = RQ1.split().1.dequeue() {

match ready.task {

T1::bar => {

// **ПРИМЕЧАНИЕ** упрощенная реализация


// используется для отслеживания динамического приоритета

let priority = Cell::new(PRIORITY);


// вызов пользовательского кода

bar(bar::Context::new(&priority));

}


T1::baz => {

// рассмотрим `baz` позднее

}

}

}


// инвариант BASEPRI

basepri::write(snapshot);

}

}

}

Вызов задачи

Интерфейс spawn предоставлен пользователю как методы структурв Spawn. Для каждой задачи существует своя структура Spawn.

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


#![allow(unused)]

fn main() {

mod foo {

// ..


pub struct Context<'a> {

pub spawn: Spawn<'a>,

// ..

}


pub struct Spawn<'a> {

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

priority: &'a Cell,

}


impl<'a> Spawn<'a> {

// `unsafe` и спрятано, поскольку сы не хотит, чтобы пользователь вмешивался сюда

#[doc(hidden)]

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

self.priority

}

}

}


mod app {

// ..


// Поиск максимального приоритета для конечного производителя `RQ1`

const RQ1_CEILING: u8 = 2;


// используется, чтобы отследить сколько еще сообщений для `bar` можно поставить в очередь

// `U2` - емкость задачи `bar`; максимум 2 экземпляра можно добавить в очередь

// эта очередь заполняется фреймворком до того, как запустится `init`

static mut bar_FQ: Queue<(), U2> = Queue::new();


// Поиск максимального приоритета для конечного потребителя `bar_FQ`

const bar_FQ_CEILING: u8 = 2;


// приоритет-ориентированная критическая секция

//

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

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

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

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

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

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