diff --git a/cortex-m-rt/src/lib.rs b/cortex-m-rt/src/lib.rs index 6456a5ea..920c9897 100644 --- a/cortex-m-rt/src/lib.rs +++ b/cortex-m-rt/src/lib.rs @@ -225,12 +225,15 @@ //! - `DefaultHandler`. This is the default handler. If not overridden using `#[exception] fn //! DefaultHandler(..` this will be an infinite loop. //! -//! - `HardFaultTrampoline`. This is the real hard fault handler. This function is simply a -//! trampoline that jumps into the user defined hard fault handler named `HardFault`. The -//! trampoline is required to set up the pointer to the stacked exception frame. -//! -//! - `HardFault`. This is the user defined hard fault handler. If not overridden using -//! `#[exception] fn HardFault(..` it will default to an infinite loop. +//! - `HardFault` and `_HardFault`. These function handle the hard fault handling and what they +//! do depends on whether the hard fault is overridden and whether the trampoline is enabled (which it is by default). +//! - No override: Both are the same function. The function is an infinite loop defined in the cortex-m-rt crate. +//! - Trampoline enabled: `HardFault` is the real hard fault handler defined in assembly. This function is simply a +//! trampoline that jumps into the rust defined `_HardFault` function. This second function jumps to the user-defined +//! handler with the exception frame as parameter. This second jump is usually optimised away with inlining. +//! - Trampoline disabled: `HardFault` is the user defined function. This means the user function is called directly +//! from the vector table. `_HardFault` still exists, but is an empty function that is purely there for compiler +//! diagnostics. //! //! - `__STACK_START`. This is the first entry in the `.vector_table` section. This symbol contains //! the initial value of the stack pointer; this is where the stack will be located -- the stack @@ -724,9 +727,18 @@ pub use macros::entry; /// /// # Usage /// -/// `#[exception] unsafe 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. +/// ## HardFault handler +/// +/// `#[exception(trampoline = true)] unsafe fn HardFault(..` sets the hard fault handler. +/// If the trampoline parameter is set to true, the handler must have signature `unsafe fn(&ExceptionFrame) -> !`. +/// If set to false, the handler must have signature `unsafe fn() -> !`. +/// +/// This handler is not allowed to return as that can cause undefined behavior. +/// +/// To maintain backwards compatibility the attribute can be used without trampoline parameter (`#[exception]`), +/// which sets the trampoline to true. +/// +/// ## Default handler /// /// `#[exception] unsafe 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 @@ -734,6 +746,8 @@ pub use macros::entry; /// 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). /// +/// ## Other handlers +/// /// `#[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