## Keyboard shortcuts

Press `←` or `→` to navigate between chapters

Press `S` or `/` to search in the book

Press `?` to show this help

Press `Esc` to hide this help

# 'static super-powers

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)]
    fn main() {
    //! 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]
        struct Shared {}

        #[local]
        struct Local {
            p: Producer<'static, u32, 5>,
            c: Consumer<'static, u32, 5>,
        }

        #[init(local = [q: Queue<u32, 5> = Queue::new()])]
        fn init(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 allocated
            let (p, c) = cx.local.q.split();

            foo::spawn().unwrap();

            (Shared {}, Local { p, c }, init::Monotonics())
        }

        #[idle(local = [c])]
        fn idle(c: idle::Context) -> ! {
            loop {
                // Lock-free access to the same underlying queue!
                if let Some(data) = c.local.c.dequeue() {
                    hprintln!("received message: {}", data);

                    // Run foo until data
                    if data == 3 {
                        debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
                    } else {
                        foo::spawn().unwrap();
                    }
                }
            }
        }

        #[task(local = [p, state: u32 = 0])]
        fn foo(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