4
\$\begingroup\$

I would like to know how STM32F2 chips and below that doesn't handle floating point unit, perform float operation.

I read here, it mentions that the floating point is handled by library functions, but when I am writing my firmware code and I didn't include any library to handle those floating point operations.

Example: if I perform a simple float computation

float gain = 1.2 * 1.5;

I didn't include any external library, but it still able to compute the floating value? Or when I compiling, the compiler will handle it automatically for me?

\$\endgroup\$
1
  • \$\begingroup\$ Try looking at the disassembly code. \$\endgroup\$ Commented May 14, 2016 at 17:24

3 Answers 3

6
\$\begingroup\$

In the quote, there is no runtime fp computation, it is made by preprocessor and included to code as a literal. If there would be a computation, it would be handled by compiler low level libraries, which in the case of GCC, you would see fp functions fused into the final binary from one particular version of libgcc.a, depending of hard/soft fp usage. Here on my system there are two versions of libgcc.a for cortex-m4:

/usr/lib/gcc/arm-none-eabi/5.3.0/armv7e-m/softfp/libgcc.a
/usr/lib/gcc/arm-none-eabi/5.3.0/armv7e-m/fpu/libgcc.a

notice: libgcc.a is not only about fp.

\$\endgroup\$
5
\$\begingroup\$

When a microcontroller doesn't have a "hard FPU", then the CPU performs what is called "soft FPU", which is basically using integer arithmetics to perform floating point operations.

When you precise "soft" to the compiler "-mfloat-abi" option, the compiler takes care of making the library calls to make soft floating point operations possible (source).

This soft FPU is explained in the answer to this question.

Here are some details about floating point handling on ARM architectures.

\$\endgroup\$
3
\$\begingroup\$

As previously mentioned, the compiler will sort it out for you.

You may need to check for linker errors though - some compilers do not link in floating-point libraries by default, or will do it by default but allow you to disable them. Space is generally at a premium on small micros, so this is a sensible strategy from the compiler. However it is something to be aware of when setting up the build.

You also need to be very cautious about what floating-point operations you do and where. All floating-point operations will be very slow, so if you do this calculation in a high-performance ISR then you're probably going to bust your timing budget. Generally you can reckon on multiplication being slower than addition/subtraction, and division being slower again.

In the absence of floating-point support, consider using integer values with a binary point. See Wikipedia entry about binary point scaling for some basic details.

\$\endgroup\$
6
  • \$\begingroup\$ I know both Clang and GCC support statically linking libraries and then stripping out unused functions afterwards, but I'm not sure how good microcontroller compilers are about that these days. \$\endgroup\$
    – JAB
    Commented May 13, 2016 at 16:24
  • \$\begingroup\$ @JAB A "static library" is usually really an archive of mostly independent object files (each corresponding to one source file) which each only implement one function or a small number of closely related functions, and linking in only the ones that define functions that are required has been standard practice since the 1970s. \$\endgroup\$
    – Random832
    Commented May 13, 2016 at 17:36
  • \$\begingroup\$ @JAB That isn't the issue. The problem is that emulated floating-point results in the compiler setting up calls to functions which implement that floating-point calculation. There are many ways to skin the floating-point cat (depending on the accuracy you want, for example), so the compiler lets you link with different run-time libraries. If you don't link with a run-time library which provides the relevant functions, linkage will fail. See for example stackoverflow.com/questions/2187379/… where someone has made precisely this mistake. \$\endgroup\$
    – Graham
    Commented May 16, 2016 at 15:18
  • \$\begingroup\$ @Graham Sure, but if you have one you like to use it seems sensible to just include it in your build process by default and let the linker handle not including it if you end up not needing it (meaning the "space is a premium" comment is only meaningful for those vendor-specific linkers that don't perform such code stripping). \$\endgroup\$
    – JAB
    Commented May 16, 2016 at 15:35
  • \$\begingroup\$ @JAB Fair point. But a typical run-time library will come with a gazillion bits and pieces, most of which you'll never need. So it's not unusual to only link with the stuff you actually do need. Also if you have coders who are less experienced, it can be a good plan to restrict how much rope you allow them. I've personally seen an example of this last year - someone brought me some code to help find the fault, and my reply was "here's some things to check, but while I was in there I noticed your main loop is supposed to run in 10ms and actually would be lucky to complete in 10s". \$\endgroup\$
    – Graham
    Commented May 16, 2016 at 16:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.