Выбрать главу

}

}

будет работать так же хороршо.

С этой новой возвожностью, старый код, такой как:

#![allow(unused)]

fn main() {

#[task(spawn = [bar])]

fn foo(cx: foo::Context) {

cx.spawn.bar().unwrap();

}

#[task(schedule = [bar])]

fn bar(cx: bar::Context) {

cx.schedule.foo(/* ... */).unwrap();

}

}

Теперь будет выглядеть так:

#![allow(unused)]

fn main() {

#[task]

fn foo(_c: foo::Context) {

bar::spawn().unwrap();

}

#[task]

fn bar(_c: bar::Context) {

foo::schedule(/* ... */).unwrap();

}

}

Заметьте, что атрибуты spawn и schedule больше не нужны.

Теперь RTIC использует симметричные блокировки, это значит, что метод lock нужно использовать для всех доступов к ресурсам. Поскольку высокоприоритетные задачи имеют эксклюзивный доступ к ресурсу, в старом коде можно было следующее:

#![allow(unused)]

fn main() {

#[task(priority = 2, resources = [r])]

fn foo(cx: foo::Context) {

cx.resources.r = /* ... */;

}

#[task(resources = [r])]

fn bar(cx: bar::Context) {

cx.resources.r.lock(|r| r = /* ... */);

}

}

С симметричными блокировками нужно вызывать lock для обоих задач:

#![allow(unused)]

fn main() {

#[task(priority = 2, resources = [r])]

fn foo(cx: foo::Context) {

cx.resources.r.lock(|r| r = /* ... */);

}

#[task(resources = [r])]

fn bar(cx: bar::Context) {

cx.resources.r.lock(|r| r = /* ... */);

}

}

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

Как программные, так и аппаратные задачи теперь можно определять вне модуля mod app. Ранее это было возможно только путем реализации обертки, вызывающей реализацию задачи.

Смотреть примеры examples/extern_binds.rs и examples/extern_spawn.rs.

Этот раздел описывает как обновить программы, написанные на RTIC v0.4.x на версию v0.5.0 фреймворка.

Во-первых, нужно обновить версию зависимости cortex-m-rtic до "0.5.0". Опцию timer-queue нужно удалить.

[dependencies.cortex-m-rtic]

# изменить это

version = "0.4.3"

# на это

version = "0.5.0"

# и удалить Cargo feature

features = ["timer-queue"]

# ^^^^^^^^^^^^^

Все функции внутри элемента #[rtic::app] должны принимать первым аргументом структуру Context. Этот тип Context будет содержать переменные, которые были магически инъецированы в область видимости функции версией v0.4.x фреймворка: resources, spawn, schedule -- эти переменные станут полями структуры Context. Каждая функция элемента #[rtic::app] получит отдельный тип Context.

#![allow(unused)]

fn main() {

#[rtic::app(/* .. */)]

const APP: () = {

// change this

#[task(resources = [x], spawn = [a], schedule = [b])]

fn foo() {

resources.x.lock(|x| /* .. */);

spawn.a(message);

schedule.b(baseline);

}

// into this

#[task(resources = [x], spawn = [a], schedule = [b])]

fn foo(mut cx: foo::Context) {

// ^^^^^^^^^^^^^^^^^^^^

cx.resources.x.lock(|x| /* .. */);

// ^^^

cx.spawn.a(message);

// ^^^

cx.schedule.b(message, baseline);

// ^^^

}

// change this

#[init]

fn init() {

// ..

}

// into this

#[init]

fn init(cx: init::Context) {

// ^^^^^^^^^^^^^^^^^

// ..

}

// ..

};

}

Синтаксис, используемый, для определения ресурсов был изменен с переменных static mut на структуру Resources.