Библиотека knigago >> Компьютеры и Интернет >> Учебники и самоучители по компьютеру >> Real-Time Interrupt-driven Concurrency


СЛУЧАЙНЫЙ КОММЕНТАРИЙ

# 2177, книга: Заветная дочь
автор: Корнелия Бер

"Заветная дочь" - это увлекательная и захватывающая книга ужасов, которая оставит вас с мурашками по коже и жаждой большего. Автор Корнелия Бер создает мир, который одновременно пугающий и манящий, с персонажами, вызывающими как симпатию, так и отвращение. Главная героиня, Элизабет, сильная и независимая женщина, оказавшаяся втянутой в зловещий культ ведьм. История рассказывает о ее борьбе против зла, раскрывая темные секреты ее прошлого и исследуя зловещие границы человеческой...

Коллектив авторов - Real-Time Interrupt-driven Concurrency

Real-Time Interrupt-driven Concurrency
Книга - Real-Time Interrupt-driven Concurrency.   Коллектив авторов  - прочитать полностью в библиотеке КнигаГо
Название:
Real-Time Interrupt-driven Concurrency
Коллектив авторов

Жанр:

Учебники и самоучители по компьютеру

Изадано в серии:

неизвестно

Издательство:

неизвестно

Год издания:

ISBN:

неизвестно

Отзывы:

Комментировать

Рейтинг:

Поделись книгой с друзьями!

Помощь сайту: донат на оплату сервера

Краткое содержание книги "Real-Time Interrupt-driven Concurrency"

https://rtic.rs/dev/book/ru/
Конкурентный фреймворк для создания систем реального времени
#Rust , #RTIC , #RTOS

Читаем онлайн "Real-Time Interrupt-driven Concurrency". [Страница - 24]

такого сценария, системный таймер должен работать на приоритете, равном наивысшему из приоритетов планируемых задач; в этом примере это 3.

Анализ приоритетов

Очередь таймера - это ресурс, разделяемый всеми задачами, которые могут планировать (schedule) задачи и обработчиком SysTick. Также интерфейс schedule соперничает с интерфейсом spawn за списки свободной памяти. Все это должно уситываться в анализе приоритетов.

Чтобы проиллюстрировать, рассмотрим следующий пример:


#![allow(unused)]

fn main() {

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

mod app {

#[task(priority = 3, spawn = [baz])]

fn foo(c: foo::Context) {

// ..

}


#[task(priority = 2, schedule = [foo, baz])]

fn bar(c: bar::Context) {

// ..

}


#[task(priority = 1)]

fn baz(c: baz::Context) {

// ..

}

}

}

Анализ приоритетов происходил бы вот так:

   • foo (prio = 3) и baz (prio = 1) планируемые задачи, поэтому SysTick должен работать на максимальном из этих двух приоритетов, т.е. 3.

   • foo::Spawn (prio = 3) и bar::Schedule (prio = 2) соперничают за конечный потребитель baz_FQ; это приводит к максимальному приоритету 3.

   • bar::Schedule (prio = 2) имеет экслюзивный доступ к конечному потребителю foo_FQ; поэтому максимальный приоритет foo_FQ фактически 2.

   • SysTick (prio = 3) и bar::Schedule (prio = 2) соперничают за очередь таймера TQ; это приводит к максимальному приоритету 3.

   • SysTick (prio = 3) и foo::Spawn (prio = 3) оба имеют неблокируемый доступ к очереди готовности RQ3, что хранит записи foo; поэтому максимальный приоритет RQ3 фактически 3.

   • SysTick имеет эксклюзивный доступ к очереди готовности RQ1, которая хранит записи baz; поэтому максимальный приоритет RQ1 фактически 3.

Изменения в реализации spawn

Когда интерфейс schedule используется, реализация spawn немного изменяется, чтобы отслеживать baseline задач. Как можете видеть в реализации schedule есть буферы INSTANTS, используемые, чтобы хранить время, в которое задача была запланирована навыполнение; этот Instant читается диспетчером задач и передается в пользовательский код, как часть контекста задачи.


#![allow(unused)]

fn main() {

mod app {

// ..


#[no_mangle]

unsafe UART1() {

const PRIORITY: u8 = 1;


let snapshot = basepri::read();


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

match ready.task {

Task::baz => {

let input = baz_INPUTS[ready.index as usize].read();

// ADDED

let instant = baz_INSTANTS[ready.index as usize].read();


baz_FQ.split().0.enqueue_unchecked(ready.index);


let priority = Cell::new(PRIORITY);

// ИЗМЕНЕНО instant передан как часть контекста задачи

baz(baz::Context::new(&priority, instant), input)

}


Task::bar => {

// выглядит также как ветка для `baz`

}


}

}


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

basepri::write(snapshot);

}

}

}

И наоборот, реализации spawn нужно писать значение в буфер INSTANTS. Записанное значение располагается в структуре Spawn и это либо время start аппаратной задачи, либо время scheduled программной задачи.


#![allow(unused)]

fn main() {

mod foo {

// ..


pub struct Spawn<'a> {

priority: &'a Cell<u8>,

// ADDED

instant: Instant,

}


impl<'a> Spawn<'a> {

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

&self.priority

}


// ADDED

pub unsafe fn instant(&self) -> Instant {

self.instant

}

}

}


mod app {

impl<'a> foo::Spawn<'a> {

/// Spawns the `baz` task

pub fn baz(&self, message: u64) -> Result<(), u64> {

unsafe {

match lock(self.priority(), baz_FQ_CEILING, || {

baz_FQ.split().1.dequeue()

}) {

Some(index) => {

baz_INPUTS[index as usize].write(message);

// ADDED

baz_INSTANTS[index as usize].write(self.instant());


lock(self.priority(), RQ1_CEILING, || {

RQ1.split().1.enqueue_unchecked(Ready {

task: Task::foo,

index,

});

});


rtic::pend(Interrupt::UART0);

}


None => {

// достигнута максимальная вместительность; неудачный вызов

Err(message)

}

}

}

}

}

}

}



--">

Оставить комментарий:


Ваш e-mail является приватным и не будет опубликован в комментарии.