Attribute Macro cortex_m_rt_macros::exception[][src]

#[exception]
Expand description

Attribute to declare an exception handler

IMPORTANT: If you are using Rust 1.30 this attribute must be used on reachable items (i.e. there must be no private modules between the item and the root of the crate); if the item is in the root of the crate you’ll be fine. This reachability restriction doesn’t apply to Rust 1.31 and newer releases.

Syntax

#[exception]
fn SysTick() {
    // ..
}

where the name of the function must be one of:

  • DefaultHandler
  • NonMaskableInt
  • HardFault
  • MemoryManagement (a)
  • BusFault (a)
  • UsageFault (a)
  • SecureFault (b)
  • SVCall
  • DebugMonitor (a)
  • PendSV
  • SysTick

(a) Not available on Cortex-M0 variants (thumbv6m-none-eabi)

(b) Only available on ARMv8-M

Usage

#[exception] fn HardFault(.. sets the hard fault handler. The handler must have signature [unsafe] fn(&ExceptionFrame) -> !. This handler is not allowed to return as that can cause undefined behavior.

#[exception] fn DefaultHandler(.. sets the default handler. All exceptions which have not been assigned a handler will be serviced by this handler. This handler must have signature [unsafe] fn(irqn: i16) [-> !]. irqn is the IRQ number (See CMSIS); irqn will be a negative number when the handler is servicing a core exception; irqn will be a positive number when the handler is servicing a device specific exception (interrupt).

#[exception] fn Name(.. overrides the default handler for the exception with the given Name. These handlers must have signature [unsafe] fn() [-> !]. When overriding these other exception it’s possible to add state to them by declaring static mut variables at the beginning of the body of the function. These variables will be safe to access from the function body.

Properties

Exception handlers can only be called by the hardware. Other parts of the program can’t refer to the exception handlers, much less invoke them as if they were functions.

static mut variables declared within an exception handler are safe to access and can be used to preserve state across invocations of the handler. The compiler can’t prove this is safe so the attribute will help by making a transformation to the source code: for this reason a variable like static mut FOO: u32 will become let FOO: &mut u32;.

Examples

  • Setting the HardFault handler
#[exception]
fn HardFault(ef: &cortex_m_rt::ExceptionFrame) -> ! {
    // prints the exception frame as a panic message
    panic!("{:#?}", ef);
}
  • Setting the default handler
#[exception]
fn DefaultHandler(irqn: i16) {
    println!("IRQn = {}", irqn);
}
  • Overriding the SysTick handler
extern crate cortex_m_rt as rt;

use rt::exception;

#[exception]
fn SysTick() {
    static mut COUNT: i32 = 0;

    // `COUNT` is safe to access and has type `&mut i32`
    *COUNT += 1;

    println!("{}", COUNT);
}