cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 simple math calculation causes hardfault

mehmet.karakaya
Associate III
Posted on March 21, 2013 at 18:06

float
hypo2; 
int32_t XH=0,YH=0,ZH=0; 
............... 
hypo2= (XH*(XH*1.0) + YH*(YH*1.0)); 

hello forum, in the above code XH and YH are 32 bit integers hypo2 is float variable becouse I want the calculation result to be float thats why I multiply XH with 1.0 when calculation square of it however at this point the program crashes and uC goes into hardfault handler the same code is workingat STM32F103 without error my compiler is yagarto please advice , thank you #math-stm32f4
6 REPLIES 6
Posted on March 21, 2013 at 19:00

If you are compiling for a cortex-m4 with floating point support you will need to ensure that the FPU is enabled. Typically this is enabled in SystemInit() but depends on a command line define.

If the processor Hard Faults, you should be able to quickly identify the faulting instruction and CPU state, and from that the cause of the issue.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mehmet.karakaya
Associate III
Posted on March 21, 2013 at 19:23

/** 
****************************************************************************** 
* @file startup_stm32f4xx.s 
* @author MCD Application Team 
* @version V1.0.0 
* @date 30-September-2011 
* @brief STM32F4xx Devices vector table for RIDE7 toolchain. 
* This module performs: 
* - Set the initial SP 
* - Set the initial PC == Reset_Handler, 
* - Set the vector table entries with the exceptions ISR address 
* - Configure the clock system and the external SRAM mounted on 
* STM324xG-EVAL board to be used as data memory (optional, 
* to be enabled by user) 
* - Branches to main in the C library (which eventually 
* calls main()). 
* After Reset the Cortex-M4 processor is in Thread mode, 
* priority is Privileged, and the Stack is set to Main. 
****************************************************************************** 
* @attention 
* 
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 
* 
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2> 
****************************************************************************** 
*/
.syntax unified 
.cpu cortex-m3 
.fpu softvfp 
.thumb 
.global g_pfnVectors 
.global Default_Handler

hello this above is the startup file this below is stm32f4xx.h

#if !defined (__FPU_PRESENT) 
#define __FPU_PRESENT 1 /*!< FPU present */ 
#endif /* __FPU_PRESENT */ 

this below is core _cm4.h

/*!< __FPU_USED to be checked prior to making use of FPU specific registers and functions */
#if defined ( __CC_ARM ) 
#if defined __TARGET_FPU_VFP 
#if (__FPU_PRESENT == 1) 
#define __FPU_USED 1 
#else 
#warning ''Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)'' 
#define __FPU_USED 0 
#endif 
#else 
#define __FPU_USED 0 
#endif 
#elif defined ( __ICCARM__ ) 
#if defined __ARMVFP__ 
#if (__FPU_PRESENT == 1) 
#define __FPU_USED 1 
#else 
#warning ''Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)'' 
#define __FPU_USED 0 
#endif 
#else 
#define __FPU_USED 0 
#endif 
#elif defined ( __GNUC__ ) 
#if defined (__VFP_FP__) && !defined(__SOFTFP__) 
#if (__FPU_PRESENT == 1) 
#define __FPU_USED 1 
#else 
#warning ''Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)'' 
#define __FPU_USED 0 
#endif 
#else 
#define __FPU_USED 0 
#endif 
#elif defined ( __TASKING__ ) 
/* add preprocessor checks to define __FPU_USED */
#define __FPU_USED 0 
#endif 

what shall I do to enable the FPU ? thank you
Posted on March 21, 2013 at 21:00

If that's the cause, which is why I'm saying to need to understand the cause of the Hard Fault.

From system_stm32f4xx.c

void SystemInit(void)
{
/* FPU settings ------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
#endif
..

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mehmet.karakaya
Associate III
Posted on March 22, 2013 at 14:21

hello Clive , thank you for your answer

previously FPU_PRESENT was defined but FPU_USED was not defined I defined FPU_USED and run the program again

#define __FPU_USED 1 
/* FPU settings ------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); 
/* set CP10 and CP11 Full Access */
#endif 

however the uC again goes into hardfault I copied the assembly of my code below

hypo2= (XH*(XH*1.0)) <<-- this line causes hardfault

what is your advice ? do I need to enable the clock of FPU like I enable the clok of other components ( like GPIOA for example) ?

hypo2= (XH*(XH*1.0)) 
/* + YH*(YH*1.0)+ ZH*(ZH*1.0))*/
; 
hypo=sqrt(hypo2); 
********************************** 
599 hypo2= (XH*(XH*1.0)) 
/* + YH*(YH*1.0)+ ZH*(ZH*1.0))*/
; 
0800dad6: movw r3, #33420 ; 0x828c 
0800dada: movt r3, #8192 ; 0x2000 
0800dade: ldr r3, [r3, #0] 
0800dae0: mov r0, r3 
0800dae2: blx 0x8015cfc <__floatsidf> 
0800dae6: mov r4, r0 
0800dae8: mov r5, r1 
0800daea: movw r3, #33420 ; 0x828c 
0800daee: movt r3, #8192 ; 0x2000 
0800daf2: ldr r3, [r3, #0] 
0800daf4: mov r0, r3 
0800daf6: blx 0x8015cfc <__floatsidf> 
0800dafa: mov r2, r0 
0800dafc: mov r3, r1 
0800dafe: mov r0, r4 
0800db00: mov r1, r5 
0800db02: blx 0x8015dd8 <__muldf3> 
0800db06: mov r2, r0 
0800db08: mov r3, r1 
0800db0a: mov r0, r2 
0800db0c: mov r1, r3 
0800db0e: blx 0x8016414 <__truncdfsf2> 
0800db12: mov r2, r0 
0800db14: movw r3, #33564 ; 0x831c 
0800db18: movt r3, #8192 ; 0x2000 
0800db1c: str r2, [r3, #0] 
600 hypo=sqrt(hypo2); 

this below is my eclipse makefile maybeyou find an error

# Flags 
CFLAGS = -Wall -fno-common -c -g -mcpu=cortex-m3 -mthumb 
CFLAGS += -g $(OPTIMIZATION) $(INCLUDES) -DTRACE_LEVEL=$(TRACE_LEVEL) 
ASFLAGS = -g -mapcs-32 
LDFLAGS = -mcpu=cortex-m3 -mthumb -g -v -nostartfiles 
OBJCOPYFLAGS = -O binary 
OBJDUMPFLAGS = -x --syms -S 
$(LD) $(LDFLAGS) -T$(LINKER_SCRIPT) -o $(OUTPUT).
out
$(C_OBJECTS) $(ASM_OBJECTS) -lm libgcc.a 

Posted on March 22, 2013 at 14:43

The BLX instructions are indicative of 32-bit ARM code being linked in, the M3/M4 will only run 16-bit THUMB code.

Check that LIBGCC.A at the end there is the right library. This is where the ARM code is coming from, I think. Check also

-mcpu=cortex-m3

, I would expect cortex-m4
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mehmet.karakaya
Associate III
Posted on March 23, 2013 at 12:57

$(LD) $(LDFLAGS) -T$(LINKER_SCRIPT) -o $(OUTPUT).
out
$(C_OBJECTS) $(ASM_OBJECTS) -lm libgcc.a 

0690X0000060Mm2QAE.gifomiting libgcc.a at the end of this line solved the problem changing cortex-m3 to m4 didnot work - it gives error I have aother question now I edited SystemInit() function and let the FPU be initialized how can I be sure that FPU is doing the math now ? ( instead of soft FPU ) thank you