pub resources: Resources<'a>,
}
pub struct Resources<'a> {
pub Y: &'a mut bool,
}
}
pub mod foo {
pub struct Context<'a> {
pub resources: Resources<'a>,
}
pub struct Resources<'a> {
pub X: &'a mut u64,
}
}
pub mod bar {
pub struct Context<'a> {
pub resources: Resources<'a>,
}
pub struct Resources<'a> {
pub X: &'a mut u64,
pub Y: &'a mut bool,
}
}
mod app {
static mut X: u64 = 0;
static mut Y: bool = 0;
unsafe fn main() -> ! {
interrupt::disable();
init(init::Context {
resources: init::Resources {
X: &mut X,
},
});
interrupt::enable();
}
#[no_mangle]
unsafe fn UART0() {
foo(foo::Context {
resources: foo::Resources {
X: &mut X,
},
});
}
#[no_mangle]
unsafe fn UART1() {
bar(bar::Context {
resources: bar::Resources {
X: &mut X,
Y: &mut Y,
},
});
}
}
Некоторые ресурсы инициализируются во время выполнения после завершения функции init. Важно то, что ресурсы (статические переменные) полностью инициализируются до того, как задачи смогут запуститься, вот почему они должны быть инициализированы пока прерывания отключены.
Ниже показан пример кода, генерируемого фреймворком для инициализации позних ресурсов.
#![allow(unused)]
fn main() {
#[rtic::app(device = ..)]
mod app {
struct Resources {
x: Thing,
}
#[init]
fn init() -> init::LateResources {
init::LateResources {
x: Thing::new(..),
}
}
#[task(binds = UART0, resources = [x])]
fn foo(c: foo::Context) {
let x: &mut Thing = c.resources.x;
x.frob();
}
}
}
Код, генерируемы фреймворком выглядит примерно так:
fn init(c: init::Context) -> init::LateResources {
}
fn foo(c: foo::Context) {
}
pub mod init {
pub struct LateResources {
pub x: Thing,
}
}
pub mod foo {
pub struct Resources<'a> {
pub x: &'a mut Thing,
}
pub struct Context<'a> {
pub resources: Resources<'a>,
}
}
mod app {
static mut x: MaybeUninit
#[no_mangle]
unsafe fn main() -> ! {
cortex_m::interrupt::disable();
let late = init(..);
x.as_mut_ptr().write(late.x);
cortex_m::interrupt::enable();
idle(..)
}
#[no_mangle]
unsafe fn UART0() {
foo(foo::Context {