diff options
author | 2023-05-19 10:49:46 +0200 | |
---|---|---|
committer | 2023-05-19 10:51:17 +0200 | |
commit | 70c3d0a2a1b3aeb97f5835dc481a767ecea909a4 (patch) | |
tree | 8bc5be381516c51aba1d59bf252f8c4e4f28ebf2 | |
parent | 82fa94d2cd2829cc37111d247e913cecdad561ac (diff) | |
download | cortex-m-70c3d0a2a1b3aeb97f5835dc481a767ecea909a4.tar.gz cortex-m-70c3d0a2a1b3aeb97f5835dc481a767ecea909a4.tar.zst cortex-m-70c3d0a2a1b3aeb97f5835dc481a767ecea909a4.zip |
Hardfault trampoline is now optional
-rw-r--r-- | cortex-m-rt/Cargo.toml | 2 | ||||
-rw-r--r-- | cortex-m-rt/macros/Cargo.toml | 3 | ||||
-rw-r--r-- | cortex-m-rt/macros/src/lib.rs | 35 | ||||
-rw-r--r-- | cortex-m-rt/src/lib.rs | 18 |
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 { |