2012-05-15 09:43 PM
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-constantWhen 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.2012-05-15 11:49 PM
> 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 ?2012-05-16 12:09 AM
Hi fm, uVision has an option to select RealView or GCC as the development tool.
()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 :)2012-05-16 02:54 AM
> 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.2012-05-16 06:59 AM
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,#0x3F0000000x08002A7A F000FDCB BL.W __aeabi_f2d (0x08003614)0x08002A7E EC410B10 VMOV d0,r0,r10x08002A82 F7FFFA01 BL.W __hardfp_sin (0x08001E88) 66: c = sinf(a); 0x08002A86 EEB00A48 VMOV.F32 s0,s160x08002A8A F7FFFA69 BL.W __hardfp_sinf (0x08001F60) But unfortunately I still have to get the GCC toolchain to work that the project heavily relies on.2012-05-16 07:33 AM
Cortex-M4 (no fp): -mthumb -mcpu=cortex-m4
(or) -mthumb -march=armv7e-mCortex-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-d16Cortex-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-d162012-05-16 07:48 AM
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.2012-05-16 10:46 PM
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.
2012-05-17 01:35 AM
> 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.