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

#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]

mod app {

use cortex_m_semihosting::{debug, hprintln};

#[shared]

struct Shared {}

#[local]

struct Local {}

#[init]

fn init(_: init::Context) -> (Shared, Local, init::Monotonics) {

foo::spawn(/* no message */).unwrap();

(Shared {}, Local {}, init::Monotonics())

}

#[task(local = [count: u32 = 0])]

fn foo(cx: foo::Context) {

hprintln!("foo").unwrap();

bar::spawn(*cx.local.count).unwrap();

*cx.local.count += 1;

}

#[task]

fn bar(_: bar::Context, x: u32) {

hprintln!("bar({})", x).unwrap();

baz::spawn(x + 1, x + 2).unwrap();

}

#[task]

fn baz(_: baz::Context, x: u32, y: u32) {

hprintln!("baz({}, {})", x, y).unwrap();

if x + y > 4 {

debug::exit(debug::EXIT_SUCCESS);

}

foo::spawn().unwrap();

}

}

}

$ cargo run --example message

foo

bar(0)

baz(1, 2)

foo

bar(1)

baz(2, 3)

<p id="Вместимость"><strong><a l:href="#Вместимость">Вместимость</a></strong></p>

RTIC не производит никакого рода аллокаций памяти в куче. Память, необходимая для размещения сообщения резервируется статически. По-умолчанию фреймворк минимизирует выделение памяти программой таким образом, что каждая задача имеет "вместимость" для сообщения равную 1: это значит, что не более одного сообщения можно передать задаче перед тем, как у нее появится возможность к запуску. Это значение по-умолчанию можно изменить для каждой задачи, используя аргумент capacity. Этот аргумент принимает положительное целое, которое определяет как много сообщений буфер сообщений задачи может хранить.

Пример ниже устанавливает вместимость программной задачи foo равной 4. Если вместимость не установить, второй вызов spawn.foo в UART0 приведет к ошибке (панике).

#![allow(unused)]

fn main() {

//! examples/capacity.rs

#![deny(unsafe_code)]

#![deny(warnings)]

#![no_main]

#![no_std]

use panic_semihosting as _;

#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]

mod app {

use cortex_m_semihosting::{debug, hprintln};

use lm3s6965::Interrupt;

#[shared]

struct Shared {}

#[local]

struct Local {}

#[init]

fn init(_: init::Context) -> (Shared, Local, init::Monotonics) {

rtic::pend(Interrupt::UART0);

(Shared {}, Local {}, init::Monotonics())

}

#[task(binds = UART0)]

fn uart0(_: uart0::Context) {

foo::spawn(0).unwrap();

foo::spawn(1).unwrap();

foo::spawn(2).unwrap();

foo::spawn(3).unwrap();

bar::spawn().unwrap();

}

#[task(capacity = 4)]

fn foo(_: foo::Context, x: u32) {

hprintln!("foo({})", x).unwrap();

}

#[task]

fn bar(_: bar::Context) {

hprintln!("bar").unwrap();

debug::exit(debug::EXIT_SUCCESS);

}

}

}

$ cargo run --example capacity

foo(0)

foo(1)

foo(2)

foo(3)

bar

<p id="Обработка_ошибок"><strong><a l:href="#Обработка_ошибок">Обработка ошибок</a></strong></p>

Интерфейс spawn возвращает вариант Err, если для размещения сообщения нет места. В большинстве сценариев возникающие ошибки обрабатываются одним из двух способов:

   • Паника, с помощью unwrap, expect, и т.п. Этот метод используется, чтобы обнаружить ошибку программиста (например bug) выбора вместительности, которая оказалась недостаточна. Когда эта паника встречается во время тестирования, выбирается большая вместительность, и перекомпиляция программы может решить проблему, но иногда достаточно окунуться глубже и провести анализ времени выполнения программы, чтобы выяснить, может ли платформа обрабатывать пиковые нагрузки, или процессор необходимо заменить на более быстрый.

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

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

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

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

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

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