Git Product home page Git Product logo

Comments (8)

hannobraun avatar hannobraun commented on May 16, 2024

Sounds great!

from cortex-m-rt.

korken89 avatar korken89 commented on May 16, 2024

I think this is a good compromise.

from cortex-m-rt.

thejpster avatar thejpster commented on May 16, 2024

Seems reasonable to me.

from cortex-m-rt.

adamgreig avatar adamgreig commented on May 16, 2024

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.

japaric avatar japaric commented on May 16, 2024

@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.

adamgreig avatar adamgreig commented on May 16, 2024

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.

#77

I guess we can investigate after resolving the issue here.

from cortex-m-rt.

adamgreig avatar adamgreig commented on May 16, 2024

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.

japaric avatar japaric commented on May 16, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.