0

I'm using Keil uVision with gcc compiler (Sourcery Codebenchlite for ARM EABI ) to program the STM32F4 cortex M4 chip.

The compiler control strings I have set are:

-march=armv7e-m -mfpu=fpv4-sp-d16  -mfloat-abi=softfp -std=gnu99 -fsingle-precision-constant

When the debugger encounters some mathematical functions (e.g. asinf(), atan2f() etc), it stops.

I have checked that the arguments for these functions are also single-precision.

I think it is because of some missing compiler directives for the use of VFP floating point, but was unable to identify it.

Is there anything I have missed out?

The disassembly code of an example I did:

The debugger can evaluate atan2f(0.3,0.4), but stops at 0x0803B9CA when it evaluates atan2f(a,b). Didn't know why the number works but not variables.

   377:         float a = 0.3; 
0x0803B9BA 4B1E      LDR           r3,[pc,#120]  ; @0x0803BA34
0x0803B9BC 63BB      STR           r3,[r7,#0x38]
   378:         float b = 0.4; 
   379:  
0x0803B9BE 4B1E      LDR           r3,[pc,#120]  ; @0x0803BA38
0x0803B9C0 637B      STR           r3,[r7,#0x34]
   380:         float c = atan2f(0.3,0.4); 
0x0803B9C2 4B1E      LDR           r3,[pc,#120]  ; @0x0803BA3C
0x0803B9C4 633B      STR           r3,[r7,#0x30]
   381:         float d = atan2f(a,b); 
   382:          
0x0803B9C6 6BB8      LDR           r0,[r7,#0x38]
0x0803B9C8 6B79      LDR           r1,[r7,#0x34]
0x0803B9CA F004F993  BL.W          atan2f (0x0803FCF4)
0x0803B9CE 62F8      STR           r0,[r7,#0x2C]
soonhooi
  • 1
  • 2

1 Answers1

1

On the STM32F4 you first need to enable the FPU - otherwise the CPU will jump into the HardFault_Handler or BusFault_Handler (I'm not shure which one).

You can do it in C/C++ anywhere before you use floating point instructions (maybe at the beginning of main()?). Assuming you use the CMSIS library and have the core_m4.h included (maybe through stm32f4xx.h):

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

The alternative is assembler code in the startup file:

/*enable fpu begin*/
ldr     r0, =0xe000ed88           /*; enable cp10,cp11 */
ldr     r1,[r0]
ldr     r2, =0xf00000
orr     r1,r1,r2
str     r1,[r0]
/*enable fpu end*/

(I found the code somewhere on the internet, don't know where though. I used it myself, it works).

Maybe your problem is located there?

Nils Hesse
  • 41
  • 4