We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I have been investigating signal handling in NuttX for SEGV/BUS/… for armv7-m. I have got some PoC code written (for a backlevel NuttX) that, while I’m in the interrupt handler, will schedule a signal handler. However, when it returns from the interrupt in exception_common and the next instruction is executed:
exception_common
343 bx r14 /* And return */ (gdb) p $r14 $1 = 0xfffffffd (gdb) stepi up_sigdeliver () at armv7-m/up_sigdeliver.c:74 74 struct tcb_s *rtcb = this_task(); (gdb) bt #0 up_sigdeliver () at armv7-m/up_sigdeliver.c:74 #1 <signal handler called>
I get a hardfault with a cfault of 0x1 (instruction access violation) and an hfault of 0x40000000 (“FORCED”):
[ 9.439000] [12] up_hardfault: IRQ: 3 regs: 0xc0327078 [ 9.439000] [12] up_hardfault: BASEPRI: 00000080 PRIMASK: 00000000 IPSR: 00000003 CONTROL: 00000001 [ 9.439000] [12] up_hardfault: CFAULTS: 00000001 HFAULTS: 40000000 DFAULTS: 0000000b BFAULTADDR: 00000000 AFAULTS: 00000000
The registers at the time of the fault:
lr 0xfffffff9 0xfffffff9 pc 0x8161ef0 0x8161ef0 <up_sigdeliver> xPSR 0x1000000 0x1000000 fpscr 0x80000010 0x80000010 msp 0xc03275e8 0xc03275e8 psp 0xc03276b8 0xc03276b8 primask 0x0 0x0 basepri 0x80 0x80 faultmask 0x0 0x0 control 0x3 0x3
In the interrupt handler I thought I was clearing/acknowledging the interrupt in the correct way in up_memfault:
up_memfault
uint32_t cfsr = getreg32(NVIC_CFAULTS); /* NVIC_CFAULTS = 0xe000ed28 */ uint32_t *mfsr = (uintptr_t) NVIC_CFAULTS; : *mfsr |= cfsr; /* Acknowledge interrupt */
I have looked through the ARM-7M Architecture Reference but I can’t work out what the proper way of exiting the memfault handler is (assuming this is the root cause of the problem).