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 の強力な力

#[init]#[idle]、および発散するソフトウェアタスクでは、local リソースは 'static ライフタイムを持ちます。

これは、リソースを事前に割り当てたり、タスク、ドライバー、またはその他のオブジェクト間でリソースを分割したりする際に便利です。これは、USB ドライバーのようにメモリを割り当てる必要があるドライバーや、heapless::spsc::Queue のような分割可能なデータ構造を使用する場合に役立ちます。

次の例では、2 つの異なるタスクが heapless::spsc::Queue を共有し、共有キューにロックフリーでアクセスします。

//! examples/static-resources-in-init.rs

#![no_main]
#![no_std]
#![deny(warnings)]
#![deny(unsafe_code)]
#![deny(missing_docs)]

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) {
        // 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 })
    }

    #[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], priority = 1)]
    async 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();
    }
}

このプログラムを実行すると、期待どおりの出力が得られます。

$ cargo xtask qemu --verbose --example static-resources-in-init
received message: 1
received message: 2
received message: 3