cancel
Showing results for 
Search instead for 
Did you mean: 

Hard Fault-> INVALID STATE when calling WFI() STM32L

ioannis2
Associate II
Posted on July 31, 2014 at 10:46

I hit an issue with our STM32L project that is giving meheadaches.

We have recently upgraded from STM32L151VB to STM32L151VC as we needed the extra RAM.

Migrating the code though, has started triggering HARDfaults with the Invalid state flag set in the CFSR. It just so happens when calling the _WFI() instruction to go to sleep.

(using IAR 7.10.3). The problemdisappears if I put a breakpoint before or on the WFI operation ( see addr  0x800bc1e in disassembly dump ). The problem occurs again in a different location if I modify the code and the binary moves around. 

  

0690X000006051eQAA.png

I have implemented a hard fault handler as suggested by joseph yiu, but the contents of the recovered stack do not tell me much as it looks to be coming from some other interrupt or fault (LR), the PC is invalid (EVEN)

[Hard fault handler - all numbers in hex]

R0       = 0x0

R1       = 0xe000ed10

R2       = 0x1000

R3       = 0x66000000

R12      = 0xe5ffffff

LR [R14] = 0xfffffff9  subroutine call return address

PC [R15] = 0x7000  program counter

PSR      = 0x6000002a

BFAR     = 0xe000ed38

CFSR     = 0x00020000

HFSR     = 0x40000000

DFSR     = 0x1

AFSR     = 0x0

SHCSR    = 0x0

Forced Hard Fault

Usage fault: INV STATE

I have examined all the interrupt vector entries, they all seem to be on an odd address as expected�

Do anybody have any ideas at all?

I have implemented a hard fault handler as suggested by joseph yiu, but the contents of the recovered stack do not tell me much as it looks to be coming from some other interrupt or fault (LR), the PC is invalid (EVEN)

[Hard fault handler - all numbers in hex]

R0       = 0x0

R1       = 0xe000ed10

R2       = 0x1000

R3       = 0x66000000

R12      = 0xe5ffffff

LR [R14] = 0xfffffff9  subroutine call return address

PC [R15] = 0x7000  program counter

PSR      = 0x6000002a

BFAR     = 0xe000ed38

CFSR     = 0x00020000

HFSR     = 0x40000000

DFSR     = 0x1

AFSR     = 0x0

SHCSR    = 0x0

Forced Hard Fault

Usage fault: INV STATE

I have implemented a hard fault handler as suggested by joseph yiu, but the contents of the recovered stack do not tell me much as it looks to be coming from some other interrupt or fault (LR), the PC is invalid (EVEN)

[Hard fault handler - all numbers in hex]

R0       = 0x0

R1       = 0xe000ed10

R2       = 0x1000

R3       = 0x66000000

R12      = 0xe5ffffff

LR [R14] = 0xfffffff9  subroutine call return address

PC [R15] = 0x7000  program counter

PSR      = 0x6000002a

BFAR     = 0xe000ed38

CFSR     = 0x00020000

HFSR     = 0x40000000

DFSR     = 0x1

AFSR     = 0x0

SHCSR    = 0x0

Forced Hard Fault

Usage fault: INV STATE

I have implemented a hard fault handler as suggested by joseph yiu, but the contents of the recovered stack do not tell me much as it looks to be coming from some other interrupt or fault (LR), the PC is invalid (EVEN)

[Hard fault handler - all numbers in hex]

R0       = 0x0

R1       = 0xe000ed10

R2       = 0x1000

R3       = 0x66000000

R12      = 0xe5ffffff

LR [R14] = 0xfffffff9  subroutine call return address

PC [R15] = 0x7000  program counter

PSR      = 0x6000002a

BFAR     = 0xe000ed38

CFSR     = 0x00020000

HFSR     = 0x40000000

DFSR     = 0x1

AFSR     = 0x0

SHCSR    = 0x0

Forced Hard Fault

Usage fault: INV STATE

#hard-fault-stm32l
14 REPLIES 14
stm322399
Senior
Posted on July 31, 2014 at 11:24

Now that you have more SRAM, did you moved the stack pointer to the end or it is still in the middle of SRAM where your large data or bss reside now ?

ioannis2
Associate II
Posted on July 31, 2014 at 12:28

Not sure what you mean by that.

My linker file placement remained the same

''place in RAM_region   { readwrite, block CSTACK, block HEAP }; ''

only thing that changed is the size of RAM_region...

In any case my main stack only gets 25% filled max, and at the time of the __WFI() call stack is <5%...

Posted on July 31, 2014 at 17:09

You'd probably want to look at what's interrupting, and why that might be corrupting the stack frame.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
stm32forum
Associate II
Posted on July 31, 2014 at 23:18

Think you need to set the databarrier just before entering __WFI()

Data Synchronization Barrier followed by the Instruction Synchronization Barrier.

__DSB();

__ISB();

I have implemented a hard fault handler as suggested by joseph yiu, but the contents of the recovered stack do not tell me much as it looks to be coming from some other interrupt or fault (LR), the PC is invalid (EVEN)

[Hard fault handler - all numbers in hex]

R0       = 0x0

R1       = 0xe000ed10

R2       = 0x1000

R3       = 0x66000000

R12      = 0xe5ffffff

LR [R14] = 0xfffffff9  subroutine call return address

PC [R15] = 0x7000  program counter

PSR      = 0x6000002a

BFAR     = 0xe000ed38

CFSR     = 0x00020000

HFSR     = 0x40000000

DFSR     = 0x1

AFSR     = 0x0

SHCSR    = 0x0

Forced Hard Fault

Usage fault: INV STATE

I have implemented a hard fault handler as suggested by joseph yiu, but the contents of the recovered stack do not tell me much as it looks to be coming from some other interrupt or fault (LR), the PC is invalid (EVEN)

[Hard fault handler - all numbers in hex]

R0       = 0x0

R1       = 0xe000ed10

R2       = 0x1000

R3       = 0x66000000

R12      = 0xe5ffffff

LR [R14] = 0xfffffff9  subroutine call return address

PC [R15] = 0x7000  program counter

PSR      = 0x6000002a

BFAR     = 0xe000ed38

CFSR     = 0x00020000

HFSR     = 0x40000000

DFSR     = 0x1

AFSR     = 0x0

SHCSR    = 0x0

Forced Hard Fault

Usage fault: INV STATE

I have implemented a hard fault handler as suggested by joseph yiu, but the contents of the recovered stack do not tell me much as it looks to be coming from some other interrupt or fault (LR), the PC is invalid (EVEN)

[Hard fault handler - all numbers in hex]

R0       = 0x0

R1       = 0xe000ed10

R2       = 0x1000

R3       = 0x66000000

R12      = 0xe5ffffff

LR [R14] = 0xfffffff9  subroutine call return address

PC [R15] = 0x7000  program counter

PSR      = 0x6000002a

BFAR     = 0xe000ed38

CFSR     = 0x00020000

HFSR     = 0x40000000

DFSR     = 0x1

AFSR     = 0x0

SHCSR    = 0x0

Forced Hard Fault

Usage fault: INV STATE

ioannis2
Associate II
Posted on August 06, 2014 at 12:09

Hi Clive and Edje,

I did try the synchronasitation_DSB();__ISB(); but the problem did not disappear.

I have been focusing on the occurring interrupts as suggested, but I am still puzzled why I am seeing what I am seeing.

This is an interrupt log of my project showing hard fault occurring straight after entering TIM10 ISR.  

0690X00000604zOQAQ.png

The first line in the TIM10 ISR is a generic trigger capture: 

if (TIM_GetITStatus(TIM10, TIM_IT_Update) != RESET)

on which I had a breakpoint set, but it never got hit, hard fault occurred before.. So it took <300ns from entering TIM10 ISR to hard fault.. I guess in the context switch

The address location from the .map file is an odd value:

TIM10_IRQHandler        0x0800eee9   0x58  Code  Gb  stm32l1xx_it.o [1]

As mentioned before, this code set is working fine and has been for months when running on STL32L151 VB which is a medium density device. The VC is a medium density plus.. Is there any subtle differences that I am missing? I can't help it but think that there is something I am missing in this migration...

Do anybody have any suggestions at all on where to go next? I am struggling here

cemer
Associate II
Posted on February 19, 2015 at 19:31

Hello Ampa

I have just vitnessed the same issue right after moving to L151VC from L151VB. When I remove the WFI instruction the problem seems to disappear. I am looking for a better solution. How did you solve yours?

Posted on February 19, 2015 at 21:54

Review the register content at the fault, AND the stack frame.

Does the bigger SRAM move the stack or heap. Determined WHAT the interrupt was.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
damh
Associate II
Posted on February 20, 2015 at 07:16

Perhaps the mentioned breakpoint is the problem.

If you use a breakpoint at a 4 byte instruction and you make a new build and now your breakpoint is in the middle of that instruction (and the environment does not correct the address), you will get a hardfault everytime, the instruction with the breakpoint is executed!

[only hardware breakpoints are effected!]

We have had this experience very often 😉 This feature is very annoying, because the stack/registers seemed to be wrong and misleading! Perhaps the environment (with its monitor) does this corruption (and is not capable to handle an interrupt in the middle of an instruction).

cemer
Associate II
Posted on February 20, 2015 at 12:48

Thanks for the reponses.

Clive, each time the hardfault is hit, the main stach contents are different, i.e. potentially a random content. When I checked the process stack, it consistently shows the WFI() call right before the exception. It looks like this happens when the idle task sleeps the cpu for low power. We have SysTick every 1ms for OS and it is the most likely wake up source. Then the wakeup process following the interrupt corrupts the main stack for some reason. When I disable the sleep the problem disappears. My current conclusion is that this might be due to a silicon difference or problem on VC side. I am currently checking the errata sheets for any related information. And I will do more testing today as well.

Damh, even if there is no breakpoint the exception occurs. Using the debugger, start he application, then after a few seconds it hits the hard fault. It is easy to generate.

When I was googling I found a very similar looking problem on another CortexM3 device from different manufacturer: http://e2e.ti.com/support/microcontrollers/stellaris_arm/f/471/t/65372 . I am not sure if the root causes are the same, however, it is certainly an interesting thread...