aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cortex-m-rt/Cargo.toml2
-rw-r--r--cortex-m-rt/macros/Cargo.toml3
-rw-r--r--cortex-m-rt/macros/src/lib.rs35
-rw-r--r--cortex-m-rt/src/lib.rs18
4 files changed, 56 insertions, 2 deletions
diff --git a/cortex-m-rt/Cargo.toml b/cortex-m-rt/Cargo.toml
index 3305d34..03cd7f6 100644
--- a/cortex-m-rt/Cargo.toml
+++ b/cortex-m-rt/Cargo.toml
@@ -42,10 +42,12 @@ name = "compiletest"
required-features = ["device"]
[features]
+default = ["hardfault-trampoline"]
device = []
set-sp = []
set-vtor = []
zero-init-ram = []
+hardfault-trampoline = ["cortex-m-rt-macros/hardfault-trampoline"]
[package.metadata.docs.rs]
features = ["device"]
diff --git a/cortex-m-rt/macros/Cargo.toml b/cortex-m-rt/macros/Cargo.toml
index f548e19..287ad9c 100644
--- a/cortex-m-rt/macros/Cargo.toml
+++ b/cortex-m-rt/macros/Cargo.toml
@@ -21,3 +21,6 @@ proc-macro2 = "1.0"
[dependencies.syn]
features = ["extra-traits", "full"]
version = "2.0"
+
+[features]
+hardfault-trampoline = []
diff --git a/cortex-m-rt/macros/src/lib.rs b/cortex-m-rt/macros/src/lib.rs
index 27ee2f1..b529ef2 100644
--- a/cortex-m-rt/macros/src/lib.rs
+++ b/cortex-m-rt/macros/src/lib.rs
@@ -232,7 +232,7 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
#f
)
}
- Exception::HardFault => {
+ Exception::HardFault if cfg!(feature = "hardfault-trampoline") => {
let valid_signature = f.sig.constness.is_none()
&& f.vis == Visibility::Inherited
&& f.sig.abi.is_none()
@@ -283,6 +283,39 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
#f
)
}
+ Exception::HardFault => {
+ let valid_signature = f.sig.constness.is_none()
+ && f.vis == Visibility::Inherited
+ && f.sig.abi.is_none()
+ && f.sig.inputs.len() == 0
+ && f.sig.generics.params.is_empty()
+ && f.sig.generics.where_clause.is_none()
+ && f.sig.variadic.is_none()
+ && match f.sig.output {
+ ReturnType::Default => false,
+ ReturnType::Type(_, ref ty) => matches!(**ty, Type::Never(_)),
+ };
+
+ if !valid_signature {
+ return parse::Error::new(
+ fspan,
+ "`HardFault` handler must have signature `unsafe fn() -> !`",
+ )
+ .to_compile_error()
+ .into();
+ }
+
+ f.sig.ident = Ident::new(&format!("__cortex_m_rt_{}", f.sig.ident), Span::call_site());
+
+ quote!(
+ #[export_name = "HardFault"]
+ // Only emit link_section when building for embedded targets,
+ // because some hosted platforms (used to check the build)
+ // cannot handle the long link section names.
+ #[cfg_attr(target_os = "none", link_section = ".HardFault.user")]
+ #f
+ )
+ }
Exception::NonMaskableInt | Exception::Other => {
let valid_signature = f.sig.constness.is_none()
&& f.vis == Visibility::Inherited
diff --git a/cortex-m-rt/src/lib.rs b/cortex-m-rt/src/lib.rs
index a6d946c..a39d32a 100644
--- a/cortex-m-rt/src/lib.rs
+++ b/cortex-m-rt/src/lib.rs
@@ -458,7 +458,7 @@ use core::fmt;
// HardFault exceptions are bounced through this trampoline which grabs the stack pointer at
// the time of the exception and passes it to the user's HardFault handler in r0.
// Depending on the stack mode in EXC_RETURN, fetches stack from either MSP or PSP.
-#[cfg(cortex_m)]
+#[cfg(all(cortex_m, feature = "hardfault-trampoline"))]
global_asm!(
".cfi_sections .debug_frame
.section .HardFaultTrampoline, \"ax\"
@@ -1061,6 +1061,7 @@ pub static __RESET_VECTOR: unsafe extern "C" fn() -> ! = Reset;
#[allow(unused_variables)]
#[doc(hidden)]
#[cfg_attr(cortex_m, link_section = ".HardFault.default")]
+#[cfg(feature = "hardfault-trampoline")]
#[no_mangle]
pub unsafe extern "C" fn HardFault_(ef: &ExceptionFrame) -> ! {
#[allow(clippy::empty_loop)]
@@ -1068,6 +1069,15 @@ pub unsafe extern "C" fn HardFault_(ef: &ExceptionFrame) -> ! {
}
#[doc(hidden)]
+#[cfg_attr(cortex_m, link_section = ".HardFault.default")]
+#[cfg(not(feature = "hardfault-trampoline"))]
+#[no_mangle]
+pub unsafe extern "C" fn HardFault_() -> ! {
+ #[allow(clippy::empty_loop)]
+ loop {}
+}
+
+#[doc(hidden)]
#[no_mangle]
pub unsafe extern "C" fn DefaultHandler_() -> ! {
#[allow(clippy::empty_loop)]
@@ -1115,7 +1125,10 @@ extern "C" {
fn NonMaskableInt();
+ #[cfg(feature = "hardfault-trampoline")]
fn HardFaultTrampoline();
+ #[cfg(not(feature = "hardfault-trampoline"))]
+ fn HardFault();
#[cfg(not(armv6m))]
fn MemoryManagement();
@@ -1154,9 +1167,12 @@ pub static __EXCEPTIONS: [Vector; 14] = [
handler: NonMaskableInt,
},
// Exception 3: Hard Fault Interrupt.
+ #[cfg(feature = "hardfault-trampoline")]
Vector {
handler: HardFaultTrampoline,
},
+ #[cfg(not(feature = "hardfault-trampoline"))]
+ Vector { handler: HardFault },
// Exception 4: Memory Management Interrupt [not on Cortex-M0 variants].
#[cfg(not(armv6m))]
Vector {