cancel
Showing results for 
Search instead for 
Did you mean: 

Using cortex-m4 FPU with gcc toolchain

chiew_nov82
Associate II
Posted on May 16, 2012 at 06:43

Dear all, I'm using `Keil uVision` with gcc toolchain (Sourcery Codebench lite 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 of single-precision. 

I think I may incorrectly set the compiler directives for the FPU, but was unable to identify it. 

 

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 the 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]

Thanks in advance.
8 REPLIES 8
frankmeyer9
Associate II
Posted on May 16, 2012 at 08:49

> Dear all, I'm using `Keil uVision` with gcc toolchain (Sourcery Codebench lite for ARM EABI) to program the `STM32F4 cortex M4` chip. 

I use Keil uVision rarely, but I'm not aware of any possibility to use the CS-Lite toolchain with uVision. Keil brings it's own toolchain. Are you sure you don't confuse things ?

chiew_nov82
Associate II
Posted on May 16, 2012 at 09:09

Hi fm, uVision has an option to select RealView or GCC as the development tool. 

(

http://www.keil.com/appnotes/docs/apnt_199.asp

)

It is very handy indeed, but I have problem to use the FPU.

I'm a beginner, so my question may be lack of information. Do let me know if I miss out anything. Thanks :) 

frankmeyer9
Associate II
Posted on May 16, 2012 at 11:54

> uVision has an option to select RealView or GCC as the development tool. 

Interesting to know ...

I don't know how ggod the integration of the CSLite toolchain works. This toolchain comes with its own startup code and libraries, you might have to specify this yourself in the project settings.

With the flag  '-mfloat-abi=softfp' you select the ABI of the code generated by the compiler. I'm not sure if the IDE selects chooses the right library for the project when using a non-standard toolchain. (Usually, there is a separate libm.a  version for each float ABI).

If the ABIs of your code and the lib don't match, you will usually end up in the Hardfault routine.

Maybe a Keil MDK guru can give you an advice here.

> I'm a beginner, ...

I would not make things too difficult, and try with the standard toolchain first.

chiew_nov82
Associate II
Posted on May 16, 2012 at 15:59

I tried the realview toolchain with FPU, and the trigonometry functions work perfect, with the disassembly code:

    65:   c = sin(a); 

0x08002A76 F04F507C  MOV           r0,#0x3F000000

0x08002A7A F000FDCB  BL.W          __aeabi_f2d (0x08003614)

0x08002A7E EC410B10  VMOV          d0,r0,r1

0x08002A82 F7FFFA01  BL.W          __hardfp_sin (0x08001E88)

    66:   c = sinf(a); 

0x08002A86 EEB00A48  VMOV.F32      s0,s16

0x08002A8A F7FFFA69  BL.W          __hardfp_sinf (0x08001F60)  

But unfortunately I still have to get the GCC toolchain to work that the project heavily relies on. 

Posted on May 16, 2012 at 16:33

Cortex-M4 (no fp): -mthumb -mcpu=cortex-m4

(or) -mthumb -march=armv7e-m

Cortex-M4(soft fp) : -mthumb -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16

(or) -mthumb -march=armv7e-m -mfloat-abi=softfp -mfpu=fpv4-sp-d16

Cortex-M4(hard fp) : -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16

(or) -mthumb -march=armv7e-m -mfloat-abi=hard -mfpu=fpv4-sp-d16

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

Your setup is slightly confusing.

> 0x08002A82 F7FFFA01  BL.W        __hardfp_sin (0x08001E88)

The name implies that at least this project settings specify hardfp ABI. This is definitely not compatible with '-mfloat-abi=softfp' you used for the CSLite toolchain.

You have 3 options:

-mfloat_abi=soft

This uses no FPU, parameters are passed in core registers, calculations are done in software;

-mfloat_abi=softfp

This uses the FPU, but parameters are passed in core registers, as above;

-mfloat-abi=hard

This uses the FPU, and passes the parameters in FPU registers, not core registers;

Option one and two produce the same code for the caller, only the called code, which is usually located in a library, is different. This means you need another library for both ABIs.

Option three produces different code, and requires its own library version, certainly.

In some cases, your IDE sorts this out when defining your project. uVision is doing this when you use its own toolchain, but I'm sure it doesn't when you use CSLite.

And, as far as I know, there is no ARM standard for the hard-FP ABI. That means, the caller code and the libs need to be compiled by the same toolchain.

I suggest to check the make file for the corresponding compiler/linker flags, and the libraries which are linked in.

chiew_nov82
Associate II
Posted on May 17, 2012 at 07:46

Sorry for the confusion, the disassembly code with hard_fp is just an example using Keil's own toolchain. It is not related to the issue in the first post. 

frankmeyer9
Associate II
Posted on May 17, 2012 at 10:35

> the disassembly code with hard_fp is just an example using Keil's own toolchain.

I understood that.

However, I just wanted to point out where the problem seems to be.

I really cannot judge the CSLite integration in uVision, but modern IDEs tend to obfuscate the build process and all its interdependecies.

I guess the best way to sort it out is to use the CSLite toolchain from command line, and with your own make file. This way, you can control everything directly, and see what you do. This way has a less steep learning curve for beginners, but results in a much better understanding of the build process.

If you don't like this and are required to use CodeSourcery for your project, there are professional versions including an Eclipse-based IDE.