cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f4 random hard faults (solved)

aperles
Associate II
Posted on April 10, 2012 at 23:05

Hi all,

With Keil MDK-ARM I had a random hard fault when I change the optimization level of the compiler.

The reason is a VPUSH.64 assembler instruction that tries to use the FPU. This instruction is added by the compiler before entering the main() function, so, at this point, the PFU is not enable.

I found a solution at http://e2e.ti.com/support/microcontrollers/stellaris_arm_cortex-m3_microcontroller/f/471/t/155025.aspx?PageIndex=2

Edit startup_stm32f4xx.s file and add the following code in the Reset_handler

                ; CPACR is located at address 0xE000ED88

                LDR.W   R0, =0xE000ED88

                ; Read CPACR

                LDR     R1, [R0]

                ; Set bits 20-23 to enable CP10 and CP11 coprocessors

                ORR     R1, R1, ♯(0xF << 20)

                ; Write back the modified value to the CPACR

                STR     R1, [R0]; wait for store to complete

                DSB

                ;reset pipeline now the FPU is enabled

                ISB

Regrds,

�ngel

#semihosting
13 REPLIES 13
Posted on April 11, 2012 at 15:35

Keil has this code in the startup file since at least v4.22, and it has been working fine for me. Basically if you expect the FPU co-processor to be working you have to enable it.

Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
;FPU settings
LDR R0, =0xE000ED88 ; Enable CP10,CP11
LDR R1,[R0]
ORR R1,R1,#(0xF << 20)
STR R1,[R0]
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP

How exactly are the Hard Fault's random, I think it would pretty predictably fail if the FPU were not enabled? And wouldn't a branch succeed in breaking the pipeline? How close to the enabling point would an FPU instruction need to be to induce ''random'' failure?
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
aperles
Associate II
Posted on April 12, 2012 at 00:23 Thanks for the information, it is very interesting. Now I can complete the information. I agree that the “random�? word in the title is not appropriated. I am using the latest version of

http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32f4discovery_fw.zip

and Keil MDK-ARM 4.50 (I tried to upgraded it from 4.23 in order to solve this issue, but no luck). The projects in the firmware package utilize the startup_stm32f4xx.s in this path: STM32F4-Discovery_FW_V1.1.0/Libraries/CMSIS/ST/STM32F4xx/Source/Templates/arm/starttup_stm32f4xx.s Head of the file and reset handler are showed bellow. The FPU IS NOT ENABLED HERE.

;******************** (C) COPYRIGHT 2011 STMicroelectronics ********************
;* File Name : startup_stm32f4xx.s
;* Author : MCD Application Team
;* Version : V1.0.0
;* Date : 30-September-2011
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP

I tested now the same file distributed with Keil MDK-ARM 4. The head is older than the previous one, but, as clive1 states, the FPU is enabled here.

;******************** (C) COPYRIGHT 2011 STMicroelectronics ********************
;* File Name : startup_stm32f4xx.s
;* Author : MCD Application Team
;* Version : V1.0.0RC1
;* Date : 25-August-2011

So the problem is with the starttup_stm32f4xx.s file distributed with the discovery. Well, now about the term “random�?. When I put the compiler at optimizing level -O3, all worked well. But I prefer to disable optimization when I debug. In this case, the compiler generates FPU instructions before I have the opportunity for enabling the FPU from C code. See image bellow. 0690X00000605TvQAI.png I don't know the reason for that. But it seems highly dependent on the code of the project. You change some parts of the code, and these offending instructions disappear. Regards, Àngel
Posted on April 12, 2012 at 01:46

The package you cite is ST's own release

Keil has some of their own variants preinstalled, see \Keil\ARM\Boards\ST\STM32F4-Discovery\Blinky

I'd have to look at the optimization, do you have some float code in your application?

I'll have to try something like

#include <stdio.h>

#include <math.h>

void test(float x, float y)

{

  printf(''%f\n'', (x / y));

}

int main()

{

  test(22.0, 7.0);

  while(1);

}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
aperles
Associate II
Posted on April 12, 2012 at 17:52

Hi,

I tried to find the reason for the generation of V* instruction, but without fortune.

I removed all my modules that use floating point and played with optimisations.

Bellow is an image of C optimization level -O0 generating V* instructions (bellow the PUSH instruction). This happened in a call to a USB initialisation:

0690X00000605RMQAY.png

If I increase the optimization level (-O3). The V* instructions disappear. So no hard faults.

0690X00000605U5QAI.png

It seems that it happen in calls to complex functions with lots of parameters.

In any case, enabling the FPU its the workaround for me.

Regards,

Àngel

redmonds2
Associate II
Posted on May 15, 2012 at 17:31

I agree. Enabling the FPU is not a solution. It's a workaround. I think its reasonable for us to expect a solution.

When I hit this problem I resorted back to the ''STM32F4-Discovery_FW_v1.10'' example firmware from st.com, changed the optimisation level to 0 and ran it on the STM32F4 Discovery board. That was all that was needed to reproduce the problem.

It's either a compiler bug or there is some problem with the example firmware.

Until I can be confident that its not a compiler bug, I can't move forward. I can't waste any more time chasing problems like this.

Posted on May 15, 2012 at 18:47

Don't want it generating FPU instructions, and/or don't want to enable the FPU, make sure the project sets the ''Floating Point Hardware'' option to ''Not Used'' instead of ''Use FPU''.

If you think there is a compiler bug, go discuss/submit that to your Keil support contact.

0690X00000605JDQAY.png

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
bjfree
Associate II
Posted on May 16, 2012 at 02:13

in the system_stm32f4xx.c

void SystemInit(void)

uses

  /* FPU settings ------------------------------------------------------------*/

  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)

    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */

  #endif

alcoholyst
Associate
Posted on February 22, 2013 at 00:34

i dont understand but mcu not jumping to hard faulthandler after ticking

Use MicroLİB at code generation tab is there some one who can explain that ?

Posted on February 22, 2013 at 01:39

i dont understand but mcu not jumping to hard faulthandler after ticking Use MicroLİB at code generation tab is there some one who can explain that ?

Yeah, without the MicroLIB the code you link in to support printf, scanf, etc generates a SWI (Software Interrupt) for some OS level code, and you don't have any code to support it and implement the functions.

Examine the code at the faulting address.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..