I'm having some trouble diagnosing the cause of an INVSTATE UsageFault that appears to be occurring on a push
instruction in a particular circumstance.
Here's what I know:
INVSTATE
UsageFault
.Here are the registers just before the instruction runs on fresh boot:
(gdb) info registers
r0 0x8001000 134221824
r1 0x8020000 134348800
r2 0x8020000 134348800
r3 0x40022014 1073881108
r4 0x0 0
r5 0x0 0
r6 0x0 0
r7 0x20009fc0 536911808
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0x0 0
r12 0x0 0
sp 0x20009fc0 0x20009fc0
lr 0x8000259 134218329
pc 0x8000178 0x8000178 <wait_for_busy>
xPSR 0x81000000 -2130706432
... and here they are just before the instruction after software reset:
(gdb) info registers
r0 0x8001000 134221824
r1 0x8020000 134348800
r2 0x8020000 134348800
r3 0x40022014 1073881108
r4 0x4028 16424
r5 0x0 0
r6 0x20009a90 536910480
r7 0x20009fc0 536911808
r8 0x4028 16424
r9 0x0 0
r10 0x0 0
r11 0x0 0
r12 0x0 0
sp 0x20009fc0 0x20009fc0
lr 0x8000259 134218329
pc 0x8000178 0x8000178 <wait_for_busy>
xPSR 0x81000000 -2130706432
Some more facts:
0x2000A000
.lr
contains the expected value (instruction after branch to this func).The instructions at and just after pc
are:
(gdb) disassemble 0x08000178
Dump of assembler code for function wait_for_busy:
0x08000178 <+0>: push {r7}
0x0800017a <+2>: sub sp, #12
0x0800017c <+4>: add r7, sp, #0
0x0800017e <+6>: ldr r3, [pc, #28] ; (0x800019c <wait_for_busy+36>)
0x08000180 <+8>: str r3, [r7, #4]
0x08000182 <+10>: nop
If I break at 0x08000178
, then nexti
, I drop in to an exception handler. Registers are now:
(gdb) info register
r0 0x8001000 134221824
r1 0x8020000 134348800
r2 0x8020000 134348800
r3 0xe000ed04 -536810236
r4 0x4028 16424
r5 0x0 0
r6 0x20009a90 536910480
r7 0x20009fc0 536911808
r8 0x4028 16424
r9 0x0 0
r10 0x0 0
r11 0x0 0
r12 0x0 0
sp 0x20009f78 0x20009f78
lr 0xfffffff1 -15
pc 0x8000368 0x8000368 <Stub_Handler+2>
xPSR 0x81000003 -2130706429
A frame up is:
0x20009f98: 0x08001000 0x08020000 0x08020000 0x40022014
0x20009fa8: 0x00000000 0x08000259 0x08000178 0x81000200
The value of the HFSR is (below), suggesting a forced hard fault:
(gdb) x/1wx 0xE000ED2C
0xe000ed2c: 0x40000000
The value of the CSFR is (below), suggesting an INVSTATE
UsageFault:
(gdb) x/1wx 0xE000ED28
0xe000ed28: 0x00020000
The description for INVSTATE
is:
When this bit is set to 1, the PC value stacked for the exception return points to the instruction that attempted the illegal use of the EPSR.
And this is where I'm stuck. What might be different after a software reset that could cause this? Is this even the real problem?
Any direction on where to go from here would be great!
User contributions licensed under CC BY-SA 3.0