2012-04-10 02:05 PM
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 #semihosting2012-04-11 06:35 AM
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?
2012-04-11 03:23 PM
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.
2012-04-11 04:46 PM
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); }2012-04-12 08:52 AM
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:2012-05-15 08:31 AM
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.2012-05-15 09:47 AM
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.2012-05-15 05:13 PM
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 */ #endif2013-02-21 03:34 PM
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 ?2013-02-21 04:39 PM
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.