#[local]
struct Local {}
#[init(local = [x: u32 = 0])]
fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
let _core: cortex_m::Peripherals = cx.core;
let _device: lm3s6965::Peripherals = cx.device;
let _x: &'static mut u32 = cx.local.x;
let _cs_token: bare_metaname = "note" :CriticalSection = cx.cs;
hprintln!("init").unwrap();
debug::exit(debug::EXIT_SUCCESS);
(Shared {}, Local {}, init::Monotonics())
}
}
}
Запуск примера напечатате init в консоли, а затем завершит процесс QEMU.
$ cargo run --example init
init
Функцию, помеченную атрибутом idle может опционально добавить в модуль. Эта функция используется как специальная
Если она присутствует, задача idle будет запущена после init. В отличие от init, idle будет запущена
Если функция idle не определена, среда вполнения устанавливает бит SLEEPONEXIT, а затем отправляет микроконтроллер в сон после запуска init.
Как и в init, static mut переменные будут трансформированы в &'static mut ссылки, безопасные для доступа. Обратите внимание, данная возможность может быть удалена в следующем релизе, см. task_local ресурсы.
Пример ниже показывает, что idle запускается после init.
Примечание: Цикл loop {} в функци ожидания не может быть пустым, так как это сломает микроконтроллер, из-за того, что LLVM компилирует пустые циклы в инструкцию UDF в release mode. Чтобы избежать неопределенного поведения, цикл должен включать "side-effect" путем вставки ассемблерной инструкции (например, WFI) или ключевого слова continue.
#![allow(unused)]
fn main() {
#![deny(unsafe_code)]
#![deny(warnings)]
#![no_main]
#![no_std]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965)]
mod app {
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local, init::Monotonics) {
hprintln!("init").unwrap();
(Shared {}, Local {}, init::Monotonics())
}
#[idle(local = [x: u32 = 0])]
fn idle(cx: idle::Context) -> ! {
let _x: &'static mut u32 = cx.local.x;
hprintln!("idle").unwrap();
debug::exit(debug::EXIT_SUCCESS);
loop {
cortex_m::asm::nop();
}
}
}
}
$ cargo run --example idle
init
idle
Чтобы объявить обработчик прерывания, фреймворк предоставляет атрибут #[task], который можно применять к функциям. Этот атрибут берет аргумент binds, чье значение - это имя прерывания, которому будет назначен обработчик; функция, декорированная этим атрибутом становится обработчиком прерывания. В фреймворке такие типы задач именуются
Пример ниже демонстрирует использование атрибута #[task], чтобы объявить обработчик прерывания. Как и в случае с #[init] и #[idle] локальные static mut переменные безопасны для использования с аппаратной задачей.
#![allow(unused)]
fn main() {
#![deny(unsafe_code)]
#![deny(warnings)]
#![no_main]
#![no_std]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965)]