From 81b2043a235375a31468d562cea2a301d2bb9449 Mon Sep 17 00:00:00 2001 From: Ian McIntyre Date: Sat, 22 Feb 2025 13:04:40 -0500 Subject: Document workaround for registering exceptions Given the way this package abuses cortex-m-rt, it's not immediately obvious how to register a Cortex-M exception handler with the `#[exception]` macro. This commit documents and demonstrates the workaround I use. --- CHANGELOG.md | 2 ++ examples/blink-blocking.rs | 24 +++++++++++++++++++++++- src/lib.rs | 25 +++++++++++++++++++++++-- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08f427d..4476385 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ Add new MCU targets: - imxrt1040 - imxrt1160 +Document workaround for registering exception handlers. + ## [0.1.5] 2024-10-26 Add initial support for RT1180. diff --git a/examples/blink-blocking.rs b/examples/blink-blocking.rs index a3a71b9..1ae62b4 100644 --- a/examples/blink-blocking.rs +++ b/examples/blink-blocking.rs @@ -1,7 +1,10 @@ //! Slowly blink an LED while blocking on a timer. //! //! Use this as the minimum-viable runtime support. You don't -//! need interrupts for this example. +//! need MCU-specific interrupts for this example. +//! +//! This example demonstrates how to register an exception +//! handler. See the API documentation for more information. #![no_std] #![no_main] @@ -16,3 +19,22 @@ fn main() -> ! { pit.blocking_delay(); } } + +use imxrt_rt::exception; + +#[exception] +unsafe fn DefaultHandler(_irqn: i16) { + uh_oh() +} + +#[exception] +unsafe fn HardFault(_: &imxrt_rt::ExceptionFrame) -> ! { + uh_oh() +} + +#[inline(never)] +fn uh_oh() -> ! { + loop { + core::sync::atomic::fence(core::sync::atomic::Ordering::SeqCst) + } +} diff --git a/src/lib.rs b/src/lib.rs index fd42472..7ec6557 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,7 +19,7 @@ //! register exceptions, and interrupts. You should be familiar with specifing a linker //! script for your embedded project. //! -//! [cmrt]: https://docs.rs/cortex-m-rt/0.7.1/cortex_m_rt/ +//! [cmrt]: https://docs.rs/cortex-m-rt/0.7.3/cortex_m_rt/ //! //! # Dependencies //! @@ -122,7 +122,7 @@ //! //! # Feature flags //! -//! `imxrt-rt` supports the features available in `cortex-m-rt` version 0.7.2. If you enable a feature, +//! `imxrt-rt` supports the features available in `cortex-m-rt` version 0.7.3. If you enable a feature, //! you must enable it in both the `[dependencies]` and `[build-dependencies]` section of your package //! manifest. For example, if the `cortex-m-rt` `"device"` feature were needed, then enable this crate's //! `"device"` feature in both places. @@ -153,6 +153,27 @@ //! other mechanism for running code before `main()`. //! //! The implementation assumes all flash is FlexSPI. +//! +//! ## Using `#[exception]` to register exception handlers +//! +//! This section only applies to Cortex-M exception handlers, not device-specific +//! interrupt handlers. If you're not sure of the difference, consult the [`cortex-m-rt`][cmrt] +//! documentation. +//! +//! Given the way this crate (ab)uses `cortex-m-rt`, and given the way the `cortex-m-rt` +//! macros work, you may encounter issues using the `#[exception]` macro to register +//! exception handlers. Fortunately, today's workaround is simple. +//! +//! Within the package that registers the exception handler, add a direct dependency +//! on `cortex-m-rt` 0.7, similar to what's shown below. +//! +//! ```toml +//! [dependencies] +//! cortex-m-rt = "0.7" +//! ``` +//! +//! With this in place, your package should be able to use the `#[exception]` macro +//! exported by `imxrt-rt`. See the `imxrt-rt` package examples for a demonstration. #![cfg_attr(all(target_arch = "arm", target_os = "none"), no_std)] -- cgit v1.2.3