Printf/Sprintf for float point variables not working.

Asked by The_YongGrand on 2014-03-18

Dear Sir,

I managed to use a printf/sprintf using integers, but not with floating point variables.

In the linker options in the compiler (I used Eclipse and GCC 4.7 2013q3) I've placed "--specs=nano.specs -u _printf_float" but still the printf("%f ", 0.05) returning "-0.0000" or some long random number.

Is there something I've not included in the compilation?

By the way, the processor is STM32F401 (ARM Cortex M4) and I'm using the STM32Cube libraries.

Thanks,
N.

Question information

Language:
English Edit question
Status:
Solved
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Solved by:
The_YongGrand
Solved:
Last query:
Last reply:
Revision history for this message
Terry Guo (terry.guo) said :
#1

I did a little experiment and seems this feature works for me.

terguo01@terry-pc01:tmp$ cat y.c
#include<stdio.h>

void
main ()
{
  printf ("%f\n", 0.05);
}
terguo01@terry-pc01:tmp$ /work/terguo01/tools/gcc-arm-none-eabi-4_7-2013q3/bin/arm-none-eabi-gcc -mthumb -mcpu=cortex-m4 -O2 -lc --specs=nano.specs -u _printf_float --specs=rdimon.specs y.c -lc -lrdimon -Wl,-Map=a.map
terguo01@terry-pc01:tmp$ qemu-system-arm -cpu cortex-m3 -semihosting -kernel ./a.out
Gtk-Message: Failed to load module "overlay-scrollbar"
0.050000
terguo01@terry-pc01:tmp$

What's your complete command line options?

Revision history for this message
The_YongGrand (the-yonggrand) said :
#2

Hello Terry Guo,

Here's the gcc-compiler command line: "-c -fmessage-length=0 -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -fsingle-precision-constant"

and here's the gcc-linker command line: ""-Wl,-Map=${BuildArtifactFileBaseName}.map" -T"..\STM32F407.ld" -Wl,--gc-sections -mthumb -mcpu=cortex-m4 --specs=nano.specs -u _printf_float -u _scanf_float"

I've also included a "syscalls.c" from the STM32 examples and I've slightly modified the printf() function to send the formatted text through the UART peripheral.

All these works for the integer variables and it works good, but it wouldn't work on float or double variables.

Also, should I include the "rdimon.specs" inside the linker options? What does it do?

Thanks,
N.

Revision history for this message
Terry Guo (terry.guo) said :
#3

Seems to me that your linker options are not consistent with your compiler options. This could cause wrong libraries are linked. Please check the .map file to make sure you are using the right libraries. You should have something like below in your .map file:

/work/terguo01/tools/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7e-m/softfp/libc_s.a(lib_a-vfprintf_float.o)
                              (_printf_float)
/work/terguo01/tools/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7e-m/softfp/libc_s.a(lib_a-vfprintf_i.o)

Based on your compiler options, I would recommend you to use link command like below:

arm-none-eabi-gcc -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp YOUR-OTHER-OPTIONS

No need to include rdimon.specs.

Revision history for this message
The_YongGrand (the-yonggrand) said :
#5

Hello again,

After "cleaning up" and relinking, I got the .map file correct:

c:/program files (x86)/gnu tools arm embedded/4.7 2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7e-m/softfp\libc_s.a(lib_a-vfprintf_float.o)
                              (_printf_float)

and

c:/program files (x86)/gnu tools arm embedded/4.7 2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7e-m/softfp\libc_s.a(lib_a-vfprintf_i.o)

but when I compiled and copied it into the microcontroller, it's still -0.0000 as output. The integer works fine, however.

I begin to suspect the heap and the stack sizes are not correct in my compilation. What else should I look into?

Revision history for this message
Terry Guo (terry.guo) said :
#6

In which way are you using to see the output of printf? Through the semihosting or through the serial port?

Revision history for this message
The_YongGrand (the-yonggrand) said :
#7

Hello Terry,

I'm using a UART to send the output to a hyperterminal. I do not have access to any emulator or semihosting apps, so the UART is the most convenient route.

Suddenly I got it to work - the problem is mostly on the linker-directive file ".ld" and the startup file ".s" provided, as I've suspected. I've replaced these files with the original ones in the GCC samples and modify it accordingly. The STM32Cube (Formerly known as STM32 Peripheral Library) GCC Templates are using these .ld and .s files from the Atollic Truestudio and they refuse to work properly in printing a float through printf. I do not know why they have used that. I have to go to the mBed webpage (the board is the newly released STM32 Nucleo), and grab their versions of these files and the float printfs work there. The mBed versions of the files are identical to the ones in the GCC samples.

So, is there a way to modify the amount of stack/heap in the files? Most of the things in the linker scripts and the startup files are very cryptic to me, as they look like assembly with a lot of macros inside. I'm testing some DSP code inside, and I do not want it to crash. I know the printf() are very memory intensive - so any recommendations for a safe amount of stack/heap?

Thanks very much,
N.

Revision history for this message
Joey Ye (jinyun-ye) said :
#8

Hi,

Please make sure that your linker command line include the COMPLETE
compiler options, which means that -mfloat-abit=soft ... must be in linker
command line too to make sure that libs under /softfp got linked.

Thanks,
Joey

On Thu, Mar 20, 2014 at 3:11 PM, The_YongGrand <
<email address hidden>> wrote:

> Question #245658 on GCC ARM Embedded changed:
> https://answers.launchpad.net/gcc-arm-embedded/+question/245658
>
> The_YongGrand gave more information on the question:
> Hello Terry,
>
> I'm using a UART to send the output to a hyperterminal. I do not have
> access to any emulator or semihosting apps, so the UART is the most
> convenient route.
>
> Suddenly I got it to work - the problem is mostly on the linker-
> directive file ".ld" and the startup file ".s" provided, as I've
> suspected. I've replaced these files with the original ones in the GCC
> samples and modify it accordingly. The STM32Cube (Formerly known as
> STM32 Peripheral Library) GCC Templates are using these .ld and .s files
> from the Atollic Truestudio and they refuse to work properly in printing
> a float through printf. I do not know why they have used that. I have to
> go to the mBed webpage (the board is the newly released STM32 Nucleo),
> and grab their versions of these files and the float printfs work there.
> The mBed versions of the files are identical to the ones in the GCC
> samples.
>
> So, is there a way to modify the amount of stack/heap in the files? Most
> of the things in the linker scripts and the startup files are very
> cryptic to me, as they look like assembly with a lot of macros inside.
> I'm testing some DSP code inside, and I do not want it to crash. I know
> the printf() are very memory intensive - so any recommendations for a
> safe amount of stack/heap?
>
> Thanks very much,
> N.
>
> --
> You received this question notification because you are an answer
> contact for GCC ARM Embedded.
>

Revision history for this message
The_YongGrand (the-yonggrand) said :
#9

Hello,

I got these command line as you have mentioned too. I got that to work finally. It's the linker scripts and the startup files which are mismatched.

Thanks,
N.

Revision history for this message
almaz (almaz-1c) said :
#10

Hello!
I download "STM32CubeF4" rar archive of NUCLEO board from here:
http://www.st.com/web/en/catalog/tools/PF259243#
and try to compile using different .ld and startup files in this archive without luck. I am in stuck.

Revision history for this message
Thomas Preud'homme (thomas-preudhomme) said :
#11

Hi Almaz,

I cannot see from your message if your issue is related to the topic at hand (prinf/scanf of float value not working). If it is, can you give more details of what is not working? If it isn't, I suggest you create a new question and again give more details of what is the problem you are encountering.

Best regards.

Revision history for this message
almaz (almaz-1c) said :
#12

Hi Thomas Preud'homme.
I did it!!!!
There is wrong linker script and startup file was the cause of failure ( taken from TrueStudio ). So I change them to GCC versions and get it work. Here is that files:
https://github.com/akupila/stm32f401C-template/tree/master/lib/STM32F401-Discovery_FW_V1.0.0/Libraries/CMSIS/DSP_Lib/Examples/Common/GCC
Thank you guys!!!