#![deny(unsafe_code)]
#![deny(warnings)]
#![no_main]
#![no_std]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965)]
mod app {
use cortex_m_semihosting::hprintln;
use lm3s6965::Interrupt;
#[shared]
struct Shared {
// Some resources to work with
a: u32,
b: u32,
c: u32,
}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local, init::Monotonics) {
rtic::pend(Interrupt::UART0);
rtic::pend(Interrupt::UART1);
(Shared { a: 0, b: 0, c: 0 }, Local {}, init::Monotonics())
}
// Direct destructure
#[task(binds = UART0, shared = [&a, &b, &c])]
fn uart0(cx: uart0::Context) {
let a = cx.shared.a;
let b = cx.shared.b;
let c = cx.shared.c;
hprintln!("UART0: a = {}, b = {}, c = {}", a, b, c).unwrap();
}
// De-structure-ing syntax
#[task(binds = UART1, shared = [&a, &b, &c])]
fn uart1(cx: uart1::Context) {
let uart1::SharedResources { a, b, c } = cx.shared;
hprintln!("UART0: a = {}, b = {}, c = {}", a, b, c).unwrap();
}
}
}
Инструкции по миграции
В этом разделе описывается как мигрировать между различными версиями RTIC. Можно также использовать для сравнения версий.
Миграция с v0.5.x на v0.6.0
Этот раздел описывает как обновиться с версии v0.5.x на v0.6.0 фреймворка RTIC.
Cargo.toml
- увеличьте версию
Измените версию cortex-m-rtic на "0.6.0".
mod
вместоconst
С поддержкой атрибутов над модулями трюк с const APP теперь не нужен.
Измените
#![allow(unused)]
fn main() {
#[rtic::app(/* .. */)]
const APP: () = {
[код здесь]
};
}
на
#![allow(unused)]
fn main() {
#[rtic::app(/* .. */)]
mod app {
[код здесь]
}
}
Так как теперь используется обычный модуль Rust, это значит, что можно использовать обычный пользовательский код в этом модуле. Также жто значит, что use-выражения для ресурсов (и т.п.) могут понадобиться.
Перенос диспетчеров изextern "C"
в аргументы app.
Измените
#![allow(unused)]
fn main() {
#[rtic::app(/* .. */)]
const APP: () = {
[код здесь]
// RTIC требует, чтобы неиспользуемые прерывания были задекларированы в блоке extern, когда
// используются программные задачи; эти свободные прерывания будут использованы для управления
// программными задачами.
extern "C" {
fn SSI0();
fn QEI0();
}
};
}
на
#![allow(unused)]
fn main() {
#[rtic::app(/* .. */, dispatchers = [SSI0, QEI0])]
mod app {
[код здесь]
}
}
Это работает и для ОЗУ-функций, см. examples/ramfunc.rs
Init всегда возвращает поздние ресурсы
С целью сделать API более симметричным задача #[init] всегда возвращает поздние ресурсы.
С этого:
#![allow(unused)]
fn main() {
#[rtic::app(device = lm3s6965)]
mod app {
#[init]
fn init(_: init::Context) {
rtic::pend(Interrupt::UART0);
}
// [еще код]
}
}
на это:
#![allow(unused)]
fn main() {
#[rtic::app(device = lm3s6965)]
mod app {
#[init]
fn init(_: init::Context) -> init::LateResources {
rtic::pend(Interrupt::UART0);
init::LateResources {}
}
// [еще код]
}
}
Структура Resources -#[resources]
Ранее ресурсы RTIC должны были располагаться в структуре с именем "Resources":
#![allow(unused)]
fn main() {
struct Resources {
// Ресурсы определены здесь
}
}
В RTIC v0.6.0 структура ресурсов аннотируется также, как и #[task], #[init], #[idle]: атрибутом #[resources]
#![allow(unused)]
fn main() {
#[resources]
struct Resources {
// Ресурсы определены здесь
}
}
На самом деле, имя структуры предоставлено на усмотрение разработчика:
#![allow(unused)]
fn main() {
#[resources]
struct Whateveryouwant {
// Ресурсы определены здесь
}
}
будет работать так же хороршо.