@@ -612,13 +612,13 @@ pub use macros::entry;
612
612
///
613
613
/// # Usage
614
614
///
615
- /// `#[exception] fn HardFault(..` sets the hard fault handler. The handler must have signature
616
- /// `[ unsafe] fn(&ExceptionFrame) -> !`. This handler is not allowed to return as that can cause
617
- /// undefined behavior.
615
+ /// `#[exception] unsafe fn HardFault(..` sets the hard fault handler. The handler must have
616
+ /// signature ` unsafe fn(&ExceptionFrame) -> !`. This handler is not allowed to return as that can
617
+ /// cause undefined behavior.
618
618
///
619
- /// `#[exception] fn DefaultHandler(..` sets the *default* handler. All exceptions which have not
620
- /// been assigned a handler will be serviced by this handler. This handler must have signature
621
- /// `[ unsafe] fn(irqn: i16) [-> !]`. `irqn` is the IRQ number (See CMSIS); `irqn` will be a negative
619
+ /// `#[exception] unsafe fn DefaultHandler(..` sets the *default* handler. All exceptions which have
620
+ /// not been assigned a handler will be serviced by this handler. This handler must have signature
621
+ /// `unsafe fn(irqn: i16) [-> !]`. `irqn` is the IRQ number (See CMSIS); `irqn` will be a negative
622
622
/// number when the handler is servicing a core exception; `irqn` will be a positive number when the
623
623
/// handler is servicing a device specific exception (interrupt).
624
624
///
@@ -637,6 +637,24 @@ pub use macros::entry;
637
637
/// the attribute will help by making a transformation to the source code: for this reason a
638
638
/// variable like `static mut FOO: u32` will become `let FOO: &mut u32;`.
639
639
///
640
+ /// # Safety
641
+ ///
642
+ /// It is not generally safe to register handlers for non-maskable interrupts. On Cortex-M,
643
+ /// `HardFault` is non-maskable (at least in general), and there is an explicitly non-maskable
644
+ /// interrupt `NonMaskableInt`.
645
+ ///
646
+ /// The reason for that is that non-maskable interrupts will preempt any currently running function,
647
+ /// even if that function executes within a critical section. Thus, if it was safe to define NMI
648
+ /// handlers, critical sections wouldn't work safely anymore.
649
+ ///
650
+ /// This also means that defining a `DefaultHandler` must be unsafe, as that will catch
651
+ /// `NonMaskableInt` and `HardFault` if no handlers for those are defined.
652
+ ///
653
+ /// The safety requirements on those handlers is as follows: The handler must not access any data
654
+ /// that is protected via a critical section and shared with other interrupts that may be preempted
655
+ /// by the NMI while holding the critical section. As long as this requirement is fulfilled, it is
656
+ /// safe to handle NMIs.
657
+ ///
640
658
/// # Examples
641
659
///
642
660
/// - Setting the `HardFault` handler
0 commit comments