This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

FPU usage on MCBSTM32F400 with uVision

Dear sir or madam,

Due to a project using your STM32F407 microcontroller I’ve recently purchased the evaluation board MCBSTM32F400 and downloaded the MDK-ARM lite IDE uVision 4.70.0.0.

So far everything runs fine, but I am having troubles running floating point calculations with the FPU coprocessor. Every time I debug the code and take a look at the disassembly window, there is just a NOP for every action that includes float variables. The Sx Register of the FPU are never filled or changed in any way.

What I’ve done so far to get the FPU running is the following:

- Setting “use FPU” under “Target Options -> Target -> Code Generation”

- Adding “--fpu=FPv4-SP” under “Target Options -> C/C++ -> Misc Controls” and “Target Options -> ASM -> Misc Controls” (most other possible flags are rejected by the compiler)

- Setting the registers for Full Access of coprocessor by using the following code in the main program: SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));
I placed this in the main function because the code should be easy understandable by only looking at the main file.

Probably I could be lacking a compiler option which defines the usage of hard FPU?

The set target device is STM32F407IG as mounted on the eval board. I am using the “Blinky” example as basic project structure to implement the FPU usage. So the entire project is pretty much the same, except for the code in the main function of Blinky.c.

It came to my attention that the generated assembler code for the manipulation of the CPACR register looks as following.

LDR r0,[pc,#164] ; @0x08000478
LDR r0,[r0,#0x00]
ORR r0,r0,#0xF00000
LDR r1,[pc,#156] ; @0x08000478
STR r0,[r1,#0x00]

The write access seems to occur on the wrong address, since the CPACR register is located at 0xE000ED88.

My assumption is that the ARM C Compiler for some reason lacks the correct translation rules to apply to floating point operations.

I’d be glad for any kind of help in this matter.

Kind regards,
Alain Buri

  • Honestly it should just require the correct CPU target selection, Use MicroLIB, Use FPU and enablement code typically found in the SystemInit() routine for the CMSIS library.

    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
    ..
    

    Some of the early Keil examples had code in ResetHandler

    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
    

    Perhaps look at some of the project in ST supplied firmware libraries.
    STM32F4-Discovery_FW_v1.1.0\Libraries\CMSIS\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c

    Remember also it only supports float math in hardware.

  • Thank you very much for your Help.
    As you said, everything was the way it should be to make the FPU running. The mistake was that i finally didnt USE the defined floating variable for any further operations. I just defined it and forced a value (i.e. f2 = f1 * 3.3) on it. Therefore the compiler decided that there is no need to implement any code for the variable f2, since it wont be used anyway. So everything in relation to the float calculation was replaced with a NOP in assembler.

    Thanks again and have a nice day!
    Kind regards,
    Alain