In #[init] and #[idle]local resources have 'static lifetime.
Useful when pre-allocating and/or splitting resources between tasks, drivers
or some other object.
This comes in handy when drivers, such as USB drivers, need to allocate memory and
when using splittable data structures such as heapless::spsc::Queue.
In the following example two different tasks share a heapless::spsc::Queue
for lock-free access to the shared queue.
#![allow(unused)]fnmain() {
//! examples/static.rs#![deny(unsafe_code)]#![deny(warnings)]#![deny(missing_docs)]#![no_main]#![no_std]use panic_semihosting as _;
#[rtic::app(device = lm3s6965, dispatchers = [UART0])]
mod app {
use cortex_m_semihosting::{debug, hprintln};
use heapless::spsc::{Consumer, Producer, Queue};
#[shared]structShared {}
#[local]structLocal {
p: Producer<'static, u32, 5>,
c: Consumer<'static, u32, 5>,
}
#[init(local = [q: Queue<u32, 5> = Queue::new()])]
fninit(cx: init::Context) -> (Shared, Local, init::Monotonics) {
// q has 'static life-time so after the split and return of `init`// it will continue to exist and be allocatedlet (p, c) = cx.local.q.split();
foo::spawn().unwrap();
(Shared {}, Local { p, c }, init::Monotonics())
}
#[idle(local = [c])]
fnidle(c: idle::Context) -> ! {
loop {
// Lock-free access to the same underlying queue!ifletSome(data) = c.local.c.dequeue() {
hprintln!("received message: {}", data);
// Run foo until dataif data == 3 {
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
} else {
foo::spawn().unwrap();
}
}
}
}
#[task(local = [p, state: u32 = 0])]
fnfoo(c: foo::Context) {
*c.local.state += 1;
// Lock-free access to the same underlying queue!
c.local.p.enqueue(*c.local.state).unwrap();
}
}
}
Running this program produces the expected output.
$ cargo run --target thumbv7m-none-eabi --example static
received message: 1
received message: 2
received message: 3