Module cortex_m::ctxt
[−]
[src]
Interrupt / Exception context local data
The main use case is safely adding state to exception / interrupt handlers.
This is done in two stages, first you define a token that will appear in the
interrupt handler signature; each handler will have its unique token. This
token must be zero sized type because interrupt handlers' real signature is
fn()
and it must also implement the Context
trait. You must also make
sure that the token can't be constructed outside of the crate where it's
defined.
// This must be in a library crate /// Token unique to the TIM7 interrupt handler pub struct Tim7 { _0: () } unsafe impl Context for Tim7 {}
Then in the application one can pin data to the interrupt handler using
Local
.
// omitted: how to put this handler in the vector table extern "C" fn tim7(ctxt: Tim7) { static STATE: Local<Cell<bool>, Tim7> = Local::new(Cell::new(false)); let state = STATE.borrow(&ctxt); // toggle state state.set(!state.get()); if state.get() { // something } else { // something else } }
Note that due to the uniqueness of tokens, other handlers won't be able to access context local data. (Given that you got the signatures right)
static TIM3_DATA: Local<Cell<bool>, Tim3> = Local::new(Cell::new(false)); extern "C" fn tim3(ctxt: Tim3) { let data = TIM3_DATA.borrow(&ctxt); } extern "C" fn tim4(ctxt: Tim4) { //let data = TIM3_DATA.borrow(&ctxt); // ^ wouldn't work }
To have the application use these tokenized function signatures, you can
define, in a library, a Handlers
struct that represents the vector table:
#[repr(C)] pub struct Handlers { tim1: extern "C" fn(Tim1), tim2: extern "C" fn(Tim2), tim3: extern "C" fn(Tim3), tim4: extern "C" fn(Tim4), /* .. */ } pub const DEFAULT_HANDLERS: Handlers = Handlers { tim1: default_handler, tim2: default_handler, tim3: default_handler, tim4: default_handler, /* .. */ };
Then have the user use that struct
to register the interrupt handlers:
extern "C" fn tim3(ctxt: Tim3) { /* .. */ } // override the TIM3 interrupt handler #[no_mangle] static _INTERRUPTS: Handlers = Handlers { tim3: tim3, ..DEFAULT_HANDLERS };
This pattern is implemented for exceptions in this crate. See
exception::Handlers
and exception::DEFAULT_HANDLERS
.
Structs
Local |
Data local to a context |
Traits
Context |
A token unique to a context |