RustのRTFM (Real Time For the Masses)を試してみる②

はじめに

組込みRust界の伝説japaric氏が実装しているReal Time For the Masses (RTFM) framework for ARM Cortex-M microcontrollersを試してみます。

github.com

前回変なところで切ってしまったため、今回は軽めです。

idleタスク

idleタスクは、initタスクの後に実行することができます。 initタスクと異なり、割り込みが有効化された状態で実行します。

関数シグネチャ[unsafe] fn() - > !であり、関数が戻ることは許されません。

下記のようにプログラムを書くことで、initの後にidleを実行します。

#[app(device = lm3s6965)]
const APP: () = {
    #[init]
    fn init() {
        hprintln!("init").unwrap();
    }

    #[idle]
    fn idle() -> ! {
        static mut X: u32 = 0;

        // Safe access to local `static mut` variable
        let _x: &'static mut u32 = X;

        hprintln!("idle").unwrap();

        debug::exit(debug::EXIT_SUCCESS);

        loop {}
    }
};

interrupt / exception

cortex-m-rtクレートを利用する時と同じ方法で、interruptexceptionを使うことができます。

#[app(device = lm3s6965)]
const APP: () = {
    #[init]
    fn init() {
        // Pends the UART0 interrupt but its handler won't run until *after*
        // `init` returns because interrupts are disabled
        rtfm::pend(Interrupt::UART0);

        hprintln!("init").unwrap();
    }

    #[idle]
    fn idle() -> ! {
        // interrupts are enabled again; the `UART0` handler runs at this point

        hprintln!("idle").unwrap();

        rtfm::pend(Interrupt::UART0);

        debug::exit(debug::EXIT_SUCCESS);

        loop {}
    }

    #[interrupt]
    fn UART0() {
        static mut TIMES: u32 = 0;

        // Safe access to local `static mut` variable
        *TIMES += 1;

        hprintln!(
            "UART0 called {} time{}",
            *TIMES,
            if *TIMES > 1 { "s" } else { "" }
        )
        .unwrap();
    }
};

このプログラムを実行すると、2回割り込みをpendしているので、UART0が2回呼ばれます。

実行結果

$ cargo run --example interrupt
init
UART0 called 1 time
idle
UART0 called 2 times