App initialization and the #[init]
task
An RTIC application requires an init
task setting up the system. The corresponding init
function must have the
signature fn(init::Context) -> (Shared, Local, init::Monotonics)
, where Shared
and Local
are the resource
structures defined by the user.
The init
task executes after system reset (after the optionally defined pre-init
and internal RTIC
initialization). The init
task runs with interrupts disabled and has exclusive access to Cortex-M (the
bare_metal::CriticalSection
token is available as cs
) while device specific peripherals are available through
the core
and device
fields of init::Context
.
Example
The example below shows the types of the core
, device
and cs
fields, and showcases the use of a local
variable with 'static
lifetime.
Such variables can be delegated from the init
task to other tasks of the RTIC application.
The device
field is available when the peripherals
argument is set to the default value true
.
In the rare case you want to implement an ultra-slim application you can explicitly set peripherals
to false
.
#![allow(unused)] fn main() { //! examples/init.rs #![deny(unsafe_code)] #![deny(warnings)] #![no_main] #![no_std] use panic_semihosting as _; #[rtic::app(device = lm3s6965, peripherals = true)] mod app { use cortex_m_semihosting::{debug, hprintln}; #[shared] struct Shared {} #[local] struct Local {} #[init(local = [x: u32 = 0])] fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) { // Cortex-M peripherals let _core: cortex_m::Peripherals = cx.core; // Device specific peripherals let _device: lm3s6965::Peripherals = cx.device; // Locals in `init` have 'static lifetime let _x: &'static mut u32 = cx.local.x; // Access to the critical section token, // to indicate that this is a critical seciton let _cs_token: bare_metal::CriticalSection = cx.cs; hprintln!("init").unwrap(); debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator (Shared {}, Local {}, init::Monotonics()) } } }
Running the example will print init
to the console and then exit the QEMU process.
$ cargo run --target thumbv7m-none-eabi --example init
init
NOTE: You can choose target device by passing a target triple to cargo (e.g.
cargo run --example init --target thumbv7m-none-eabi
) or configure a default target in.cargo/config.toml
.For running the examples, we use a Cortex M3 emulated in QEMU, so the target is
thumbv7m-none-eabi
.