cancel
Showing results for 
Search instead for 
Did you mean: 

f4-discovery, fpu not working in timer interrupt?

ian239955
Associate II
Posted on May 21, 2013 at 16:55

Hi, I'm testing the f4 and the fpu. I have a small fpu test like this:

volatile float a=0;

volatile float b=.1;

int c;

for(;;)

    {

      GPIOD->ODR^=0x8000;

      for (c=0;c<100;c++)

        a=a+b;

    }

So by looking at PD15 on a scope I can measure how long it takes to do 100 adds of 0.1.

I'm using IAR and there is a project option to switch on / off the fpu.

If I put this in the idle loop, I get about 20us for no fpu and about 8us for fpu - not a big difference but I suppose it might be greater for divide, square root, etc. 

But if I try it in a timer interrupt, I don't get any improvement switching on the fpu. I've seen some hint of issues around stacking the fpu state, adding some assembler code etc. but not enough to work out what I actually have to do. Can anyone help?

Thanks  

#m4-fpu
3 REPLIES 3
ian239955
Associate II
Posted on May 21, 2013 at 17:18

I think I might have solved this, was something daft as usual: 

In my interrupt test I had

float test=0;

test=test+.1;

and in my idle test I had

float test=0;

float testa=.1;

test=test+testa;

.. so if you add literal .1 to a float, you don’t get the fpu, if you add 2 floats, you do!

I guess this might be because the compiler assumes .1 is a double, and the fpu works with singles only?

From: belchamber.ian

Posted: Tuesday, May 21, 2013 4:55 PM

Subject: f4-discovery, fpu not working in timer interrupt?

Hi, I'm testing the f4 and the fpu. I have a small fpu test like this:

volatile float a=0;

volatile float b=.1;

int c;

for(;;)

    {

      GPIOD->ODR^=0x8000;

      for (c=0;c<100;c++)

        a=a+b;

    }

So by looking at PD15 on a scope I can measure how long it takes to do 100 adds of 0.1.

I'm using IAR and there is a project option to switch on / off the fpu.

If I put this in the idle loop, I get about 20us for no fpu and about 8us for fpu - not a big difference but I suppose it might be greater for divide, square root, etc. 

But if I try it in a timer interrupt, I don't get any improvement switching on the fpu. I've seen some hint of issues around stacking the fpu state, adding some assembler code etc. but not enough to work out what I actually have to do. Can anyone help?

Thanks  

Posted on May 21, 2013 at 17:23

Perhaps, depends I guess on what the optimizer is up to.

I can't speak to IAR, but the problem using the FPU under interrupt is to ensure that sufficient state is saved so you don't break other threads of execution. This will be true of RTOS context switches as well.

One of the safer paths is to do all the float math in one thread.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on May 21, 2013 at 17:38

> I guess this might be because the compiler assumes .1 is a double,

> and the fpu works with singles only?

Probably yes (provided ''test'' was volatile too), because there's no such simple relationship between single and double float as is e.g. between int16 and int32.

You should confirm the compiler's default by reading the compiler's manual and/or checking the compilation result (asm/disassm listing). The latter is always imperative if you work towards minimal execution time anyway.

The float-in-interrupt(-and-multitasking-aka-RTOS) gotchas are nicely described in ARM's Application Note 298, ''Cortex-M4(F) Lazy Stacking and Context Switching'', which is a must-read if you intend to go in this way.

JW