mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-24 12:42:52 +01:00
75 lines
2 KiB
Markdown
75 lines
2 KiB
Markdown
|
# Interrupt configuration
|
||
|
|
||
|
Interrupts are core to the operation of RTFM applications. Correctly setting
|
||
|
interrupt priorities and ensuring they remain fixed at runtime is a requisite
|
||
|
for the memory safety of the application.
|
||
|
|
||
|
The RTFM framework exposes interrupt priorities as something that is declared at
|
||
|
compile time. However, this static configuration must be programmed into the
|
||
|
relevant registers during the initialization of the application. The interrupt
|
||
|
configuration is done before the `init` function runs.
|
||
|
|
||
|
This example gives you an idea of the code that the RTFM framework runs:
|
||
|
|
||
|
``` rust
|
||
|
#[rtfm::app(device = ..)]
|
||
|
const APP: () = {
|
||
|
#[init]
|
||
|
fn init(c: init::Context) {
|
||
|
// .. user code ..
|
||
|
}
|
||
|
|
||
|
#[idle]
|
||
|
fn idle(c: idle::Context) -> ! {
|
||
|
// .. user code ..
|
||
|
}
|
||
|
|
||
|
#[interrupt(binds = UART0, priority = 2)]
|
||
|
fn foo(c: foo::Context) {
|
||
|
// .. user code ..
|
||
|
}
|
||
|
};
|
||
|
```
|
||
|
|
||
|
The framework generates an entry point that looks like this:
|
||
|
|
||
|
``` rust
|
||
|
// the real entry point of the program
|
||
|
#[no_mangle]
|
||
|
unsafe fn main() -> ! {
|
||
|
// transforms a logical priority into a hardware / NVIC priority
|
||
|
fn logical2hw(priority: u8) -> u8 {
|
||
|
// this value comes from the device crate
|
||
|
const NVIC_PRIO_BITS: u8 = ..;
|
||
|
|
||
|
// the NVIC encodes priority in the higher bits of a bit
|
||
|
// also a bigger numbers means lower priority
|
||
|
((1 << NVIC_PRIORITY_BITS) - priority) << (8 - NVIC_PRIO_BITS)
|
||
|
}
|
||
|
|
||
|
cortex_m::interrupt::disable();
|
||
|
|
||
|
let mut core = cortex_m::Peripheral::steal();
|
||
|
|
||
|
core.NVIC.enable(Interrupt::UART0);
|
||
|
|
||
|
// value specified by the user
|
||
|
let uart0_prio = 2;
|
||
|
|
||
|
// check at compile time that the specified priority is within the supported range
|
||
|
let _ = [(); (1 << NVIC_PRIORITY_BITS) - (uart0_prio as usize)];
|
||
|
|
||
|
core.NVIC.set_priority(Interrupt::UART0, logical2hw(uart0_prio));
|
||
|
|
||
|
// call into user code
|
||
|
init(/* .. */);
|
||
|
|
||
|
// ..
|
||
|
|
||
|
cortex_m::interrupt::enable();
|
||
|
|
||
|
// call into user code
|
||
|
idle(/* .. */)
|
||
|
}
|
||
|
```
|