//! examples/cfg-monotonic.rs #![deny(unsafe_code)] #![deny(warnings)] #![deny(missing_docs)] #![no_main] #![no_std] use panic_semihosting as _; #[rtic::app(device = lm3s6965, dispatchers = [SSI0, QEI0])] mod app { use cortex_m_semihosting::{debug, hprintln}; use systick_monotonic::*; // Implements the `Monotonic` trait // A monotonic timer to enable scheduling in RTIC #[cfg(feature = "killmono")] #[monotonic(binds = SysTick, default = true)] type MyMono = Systick<100>; // 100 Hz / 10 ms granularity // Not allowed by current rtic-syntax: // error: `#[monotonic(...)]` on a specific type must appear at most once // --> examples/cfg-monotonic.rs:23:10 // | // 23 | type MyMono = Systick<100>; // 100 Hz / 10 ms granularity // | ^^^^^^ // #[monotonic(binds = SysTick, default = true)] // type MyMono = Systick<100>; // 100 Hz / 10 ms granularity // Not allowed by current rtic-syntax: // error: this interrupt is already bound // --> examples/cfg-monotonic.rs:31:25 // | // 31 | #[monotonic(binds = SysTick, default = true)] // | ^^^^^^^ // #[monotonic(binds = SysTick, default = true)] // type MyMono2 = DwtSystick<100>; // 100 Hz / 10 ms granularity // Resources shared between tasks #[shared] struct Shared { s1: u32, s2: i32, } // Local resources to specific tasks (cannot be shared) #[local] struct Local { l1: u8, l2: i8, } #[init] fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) { let _systick = cx.core.SYST; // Initialize the monotonic (SysTick rate in QEMU is 12 MHz) #[cfg(feature = "killmono")] let mono = Systick::new(systick, 12_000_000); // Spawn the task `foo` directly after `init` finishes foo::spawn().unwrap(); debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator ( // Initialization of shared resources Shared { s1: 0, s2: 1 }, // Initialization of task local resources Local { l1: 2, l2: 3 }, // Move the monotonic timer to the RTIC run-time, this enables // scheduling #[cfg(feature = "killmono")] init::Monotonics(mono), init::Monotonics(), ) } // Background task, runs whenever no other tasks are running #[idle] fn idle(_: idle::Context) -> ! { loop { continue; } } // Software task, not bound to a hardware interrupt. // This task takes the task local resource `l1` // The resources `s1` and `s2` are shared between all other tasks. #[task(shared = [s1, s2], local = [l1])] fn foo(_: foo::Context) { // This task is only spawned once in `init`, hence this task will run // only once hprintln!("foo"); } // Software task, also not bound to a hardware interrupt // This task takes the task local resource `l2` // The resources `s1` and `s2` are shared between all other tasks. #[task(shared = [s1, s2], local = [l2])] fn bar(_: bar::Context) { hprintln!("bar"); // Run `bar` once per second // bar::spawn_after(1.secs()).unwrap(); } // Hardware task, bound to a hardware interrupt // The resources `s1` and `s2` are shared between all other tasks. #[task(binds = UART0, priority = 3, shared = [s1, s2])] fn uart0_interrupt(_: uart0_interrupt::Context) { // This task is bound to the interrupt `UART0` and will run // whenever the interrupt fires // Note that RTIC does NOT clear the interrupt flag, this is up to the // user hprintln!("UART0 interrupt!"); } }