Comments (8)
Sounds great!
from cortex-m-rt.
I think this is a good compromise.
from cortex-m-rt.
Seems reasonable to me.
from cortex-m-rt.
This will also affect #77.
Will it possible to grab the &ExceptionFrame
without external or inline assembly using the proposed __arm_rsr
in rust-embedded/wg/pull/184 to read MSP and call the user handler with it? The same idea could be extended to implement #77 in pure Rust without the external assembly.
Some quick experimenting suggests this does work, but I worry about how fragile it might be.
from cortex-m-rt.
@adamgreig I believe that if we implement that in Rust it would not be reliable. If it's all in Rust then the compiler can inline UserHardFault into HardFault which can cause the a function prelude to be generated and the prelude would modify SP before it's read.
We could mark UserHardFault as inline(never)
and that may make it more reliable.
This will also affect #77.
#77 seems complex enough that a Rust implementation would very likely not work properly when unoptimized. In that mode the compiler makes more use of the stack which would modify SP before it's read.
from cortex-m-rt.
It's a shame rust-lang/rust/issues/32408 isn't stabalised yet or we could just use #[naked]
. It's in nightly.
Anyway, I think your suggestion of #[inline(never)
on UserHardFault
, and a HardFault
defined in lib/src.rs
which just reads MSP, casts to a &ExceptionFrame
, and passes to UserHardFault
, which does the same type-checking and then calls the user-provided function as currently, might work. I'll have a play tonight with some long, stack-using user handlers and see how well it works. If so we could retain this feature for stable rust without any asm which would be nice.
I guess we can investigate after resolving the issue here.
from cortex-m-rt.
I've disabled asm.s
, and then implemented my own HardFault
(which could live in cortex-m-rt/src/lib.rs
once msp
can be read from core::arch::arm
):
#[no_mangle]
pub unsafe extern "C" fn HardFault() -> ! {
extern "C" { fn UserHardFault(eh: &ExceptionFrame) -> !; }
let ef: &ExceptionFrame = &*(cortex_m::register::msp::read() as *const _);
UserHardFault(ef);
}
exception!(HardFault, hf);
#[inline(always)]
fn hf(ef: &ExceptionFrame) -> ! {
if ef.pc == 0x0700_0000 {
loop { unsafe { core::ptr::read_volatile(0x0000_1234 as *const u32); } }
} else {
loop { unsafe { core::ptr::read_volatile(0x0000_1238 as *const u32); } }
}
}
I marked UserHardFault
as #[inline(never)]
in the exception!()
macro.
I can then trigger a HardFault with:
fn crasher() {
let x: extern "C" fn() = unsafe { core::mem::transmute(0x07000000 as *const u32) };
x();
}
The generated code in release is identical to the current external assembly solution except for the trailing UDF in HardFault:
080003b2 <HardFault>:
80003b2: f3ef 8008 mrs r0, MSP
80003b6: f000 f804 bl 80003c2 <UserHardFault>
80003ba: defe udf #254 ; 0xfe
080003c2 <UserHardFault>:
80003c2: 6980 ldr r0, [r0, #24]
80003c4: f1b0 6fe0 cmp.w r0, #117440512 ; 0x7000000
80003c8: d103 bne.n 80003d2 <UserHardFault+0x10>
80003ca: f241 2034 movw r0, #4660 ; 0x1234
80003ce: 6801 ldr r1, [r0, #0]
80003d0: e7fd b.n 80003ce <UserHardFault+0xc>
80003d2: f241 2038 movw r0, #4664 ; 0x1238
80003d6: 6801 ldr r1, [r0, #0]
80003d8: e7fd b.n 80003d6 <UserHardFault+0x14>
and in debug, we branch to read MSR but without touching the stack:
0800021a <_ZN8cortex_m8register3msp4read17he228d82a29c1abfbE>:
800021a: f3ef 8008 mrs r0, MSP
800021e: 4770 bx lr
080003f6 <HardFault>:
80003f6: f7ff ff10 bl 800021a <_ZN8cortex_m8register3msp4read17he228d82a29c1abfbE>
80003fa: f000 f832 bl 8000462 <UserHardFault>
80003fe: defe udf #254 ; 0xfe
08000462 <UserHardFault>:
8000462: 6980 ldr r0, [r0, #24]
8000464: f1b0 6fe0 cmp.w r0, #117440512 ; 0x7000000
8000468: d104 bne.n 8000474 <UserHardFault+0x12>
800046a: f241 2034 movw r0, #4660 ; 0x1234
800046e: f7ff fec8 bl 8000202 <_ZN4core3ptr13read_volatile17ha191faccd0dd90d3E>
8000472: e7fa b.n 800046a <UserHardFault+0x8>
8000474: f241 2038 movw r0, #4664 ; 0x1238
8000478: f7ff fec3 bl 8000202 <_ZN4core3ptr13read_volatile17ha191faccd0dd90d3E>
800047c: e7fa b.n 8000474 <UserHardFault+0x12>
It seems to work as required. Even with a bunch of silliness I can't get it to try and touch the stack in the UserHardFault prologue, but anyway since that method is inline(never)
I wouldn't expect it to matter.
That all said I have discovered that in debug mode my gdb crashes during a HardFault unless the debugger is set to intercept it, both on current master and with this change. Fine on release. Maybe a gdb bug, who knows...
from cortex-m-rt.
I have proposed an alternative that doesn't require a breaking change or adding a new Cargo feature in RFC #95.
from cortex-m-rt.
Related Issues (20)
- How to link exceptions to C handlers HOT 2
- "error: cortex-m-rt appears more than once in the dependency graph" HOT 9
- main() calling convention discrepancy HOT 1
- How to utilize CCM SRAM for uninit statics? HOT 4
- VTOR and initial stack for debuggers HOT 5
- undefined reference to `__sheap' HOT 10
- Forward-port Changelog entries for v0.6.x
- RAM initialization code violates pointer provenance HOT 4
- Per crate memory.x file in a workspace. HOT 2
- [feature request] possibility to include asm stub before __pre_init for MCU that starts with RAM disabled HOT 5
- SCB.ICSR is more than 8 bits HOT 1
- Different virtual and physical address for FLAH HOT 1
- Error compiling with rwpi relocation model. HOT 2
- Position Independent Code HOT 2
- Why the code in this repo isn't the same as in crate.io even if the version number is the same? HOT 1
- master branch is out of date relative to 0.6.14 release HOT 2
- Use the semver trick? HOT 3
- Multiple versions of cortex-m-rt result in cryptic error messages HOT 4
- How to prevent generation of 'extra' code for ISR HOT 2
- Using the hard float compiler `thumbv7em-none-eabihf` problematic HOT 29
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cortex-m-rt.