Ресурсам могут быть опционально даны начальные значения с помощью атрибута #[init]. Ресурсы, которым не передано начально значение, называются
Каждый контекс (задача-обработчик, init или idle) должен указать ресурсы, к которым он намерен обращаться, в соответсятвующем ему атрибуте с метаданными, используя аргумент resources. Этот аргумент принимает список имен ресурсов в качестве значения. Перечисленные ресурсы становятся доступны в контексте через поле resources структуры Context.
Пример программы, показанной ниже содержит два обработчика прерывания, которые разделяют доступ к ресурсу под названием shared.
#![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};
use lm3s6965::Interrupt;
#[shared]
struct Shared {}
#[local]
struct Local {
local_to_uart0: i64,
local_to_uart1: i64,
}
#[init]
fn init(_: init::Context) -> (Shared, Local, init::Monotonics) {
rtic::pend(Interrupt::UART0);
rtic::pend(Interrupt::UART1);
(
Shared {},
Local {
local_to_uart0: 0,
local_to_uart1: 0,
},
init::Monotonics(),
)
}
#[idle]
fn idle(_cx: idle::Context) -> ! {
debug::exit(debug::EXIT_SUCCESS);
loop {
cortex_m::asm::nop();
}
}
#[task(binds = UART0, local = [local_to_uart0])]
fn uart0(cx: uart0::Context) {
*cx.local.local_to_uart0 += 1;
let local_to_uart0 = cx.local.local_to_uart0;
hprintln!("UART0: local_to_uart0 = {}", local_to_uart0).unwrap();
}
#[task(binds = UART1, local = [local_to_uart1], priority = 2)]
fn uart1(cx: uart1::Context) {
*cx.local.local_to_uart1 += 1;
let local_to_uart1 = cx.local.local_to_uart1;
hprintln!("UART1: local_to_uart1 = {}", local_to_uart1).unwrap();
}
}
}
$ cargo run --example resource
UART1: local_to_uart1 = 1
UART0: local_to_uart0 = 1
Заметьте, что к ресурсу shared нельзя получить доступ из idle. Попытка сделать это приведет к ошибке компиляции.
Критические секции необходимы для разделения изменяемых данных таким образом, чтобы избежать гонок данных.
Поле resources, передаваемого Context реализует трейт Mutex для каждого разделяемого ресурса, доступного задаче.
Единственный метод этого трейта, lock, запускает свой аргумент-замыкание в критической секции.