}
}
будет работать так же хороршо.
С этой новой возвожностью, старый код, такой как:
#![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.