This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Cortex-M4F FPU operations break in ISR

Hi everyone,

What I'm trying to do is get an infrared decoding library (IRMP) to run, along with a simple HD47780 LCD display on a Stellaris Launchpad. The IRMP library basically polls the state of an IR receiver every time a timer interrupt fires.

Both libraries work fine by themselves. However, as soon as I execute only a single floating point operation in my main function (or any function called from it), the IRMP signal decoding breaks. So the IRMP code still runs, it still sends debugging data over the UART, still toggles LEDs, etc, but it's unable to correctly decode any input.

In my main function, all I have is a busy loop, checking if the IRMP library has successfully decoded something. I can break the code by executing an FPU operation even before initializing the IRMP library. The very first lines in my main are:

MAP_FPULazyStackingEnable();
MAP_FPUEnable();

An example of a line of code that breaks it all is:

MAP_SysCtlDelay((MAP_SysCtlClockGet()) / 30.0)

Change 30.0 to 30 and everything magically works again.

I've tried removing the MAP_ (or simply not sourcing driverlib/rom.h) to ensure the new StellarisWare driver library gets used instead of the one flashed into the LM4F120, but that didn't fix anything either.

This gets even stranger: if I compile with -O0, the decoding doesn't work either, however with -O1 or -Os (didn't try O2 and O3) it does (provided of course no FPU operations are executed from the main function).

The compiler I'm using is:

arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.7.3 20121207 (release) [ARM/embedded-4_7-branch revision 194305]

Compile flags:

-DPART_LM4F120H5QR -DARM_MATH_CM4 -DTARGET_IS_BLIZZARD_RA1 -I$SOMEDIR/stellarisware -Os -Wall -std=gnu99 -c
-fmessage-length=0 -fsingle-precision-constant -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mthumb -mfloat-abi=softfp
-ffunction-sections -fdata-sections

Compiling with -mfloat-abi=hard doens't work either.

As for linking and startup code, I'm using the one from https://github.com/scompo/stellaris-launchpad-template-gcc.

Do you have any idea on how to solve/fix this? Apart from me wading through all the IRMP code and changing all FP math to integer math. I realize FP math in an ISR is far from ideal, but that's not the point here. It should work and it isn't.

I've spend over 8 hours trying various things, searching all over the net and haven't found anything so far that could explain this behavior. I've also put this question on the IRMP forum and StackExchange Electronics.

  • Floating point should work fine using GCC - we build and test all our binaries using GCC as well as all the other supported toolchains and I've seen no problems in that area. You don't mention specifics of what goes wrong after your floating point use. Are you seeing a fault? Memory corruption? Details would help.

    The example you give isn't a great one because SysCtlDelay takes an unsigned long as parameter and your code would appear to try to pass a float value. The compiler may try to cast this back to an integer but you should definitely see a warning at the least. If you declare a float variable and do some arithmetic with it, do you see the same problem?

    One obvious thing to consider is your stack size. Saving the floating point context takes quite a bit of extra stack space so, if your size is too small, you'll likely see stack overflow a fair bit quicker as soon as you start using floating point. The fact that you have lazy stacking enabled means you wouldn't see this occur until your first use of floating point, I suspect.

  • Thanks a ton! I had been trying to change the stack size, but must have been doing something wrong (I've never touched a linker script before). After some more debugging I managed to isolate a section of code that seemed like the culprit (64 byte of stack allocated arrays in an LCD setup function).

    I then switched to the linker script & init files found here: https://github.com/eehusky/Stellaris-GCC/tree/master/proj0 and everything works. You can't believe how happy that makes me after 10+ hours of looking for the problem :).

  • I'm delighted to hear that you are up and running. By the way, you do know that we distribute sample project and makefiles for 6 toolchains including GCC in the StellarisWare release for LaunchPad and the other LM4F boards? This includes linker scripts and startup code. You are completely at liberty to get code from any repository, of course, but if you start from an official TI release, it may be easier to get things up and running quickly. I should point out that I've not looked at the github repositories you mention, though, so I don't know what's there.

  • I did in fact not yet take a look at the example code in the StellarisWare bundle, maybe I should have :). I was planning on doing that soon as well as check out the Sourcercy CodeBench package, in the hopes of fixing some debug problem I've been having.

  • Strongly recommended...

    http://www.ti.com/ww/en/launchpad/stellaris_head.html?DCMP=stellaris-launchpad&HQS=stellaris-launchpad-b

    Dave Wilson give heap good advice. (As well as being a gentleman and a scholar.)

  • Dave Robinson said:
    Dave Wilson give heap good advice.

    Clearly - yet another, Saturday morn, "Lone Ranger" marathon - "alive/well" in the frozen tundra...