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.

TM4C1294KCPDT: Why FPU exception Nmi multiplying 2 floating point values

Guru 55913 points
Part Number: TM4C1294KCPDT

Unknowingly been trying to get FPU to multiply two values ARM engineers seem to believe possible 7M4 FPU. Have single stepped CCS debug to discover horrific failure occurs, multiply 2 floating point values produce DEN. The exception occurs few instructions below the multiplication. The FPU is fully enabled and CPAC REG80 (CP10, CP11) have full access. The IP will not get past this issue cause Nmi exception. The value (theta) is being passes into the function prior to CPU IP vectoring into the void.

BTW: input theta = 0.0123450002 and how the 0002 gets added into float 32 bit array, e.g. theta[1]={0.0} value (0.012345) is a mystery.

Compiler TI v18.12.4.LTS, RunTimeSupport rtsv7M4_T_le_v4SPD16_eabi.lib, --float_support FPv4SDP16

Why is the 7M4 FPU not able to do single precision floating point multiplication, seems to be the question? I'm familiar with NAN acronym but what does DEN mean? 

  • Below are EK-TM4C1294NCPD FPU configurations and exception FPSCR register value that occurs after the faulting instruction.

    Part of the issue being multiplication results were >32 bits, temp and in variables were made long long (float64_t) . The code gets a bit further prior to faulting but the exception bus error (0x3) his address is imprecise though near the FPU region of memory space. 

    /* Enable NVIC Floating Point Unit, FPU */
    MAP_FPUEnable();

    /* Floating-point state is not saved on interrupt entry */
    MAP_FPULazyStackingEnable();

      

  • FPSCR[4] (0x10) is Inexact Exception (IXC) which as near as I can tell happens routinely, and is rarely an actual error. [Ref Cortex-M4 TRM (r0p1) sec 7.2.6]

    I suspect SYSEXCIM:FPIXCIM has somehow become set=1. [Ref data sheet (SPMS433B) p. 526]. If so, try clearing it=0.

    See also:

    https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/978615/msp432p401r-cortex-m4f-fpu_irqhandler---ccs-usage-example/3619260

    [Edit: A better reference for IXC is probably DDI0403E(rev D) Table A2-3: "Inexact. The bit is set to 1 if the result of an operation is not equivalent to the value that would be produced if the operation were performed with unbounded precision and exponent range", i.e. rounded]

  • Hello Gl,

    This seems more like an Arm FPU issue than something specific to our device - I can try and look into the DEN piece but I don't really have any knowledge with floating point math on the MCU. It looks like Bruce has some ideas to try in the meantime. Let us know if those work.

  • Hi Ralph && Bruce,

    Talk about a crash course in FPU floating decimal point math :-)

    ut I don't really have any knowledge with floating point math on the MCU.

    Well it seems the (f) suffix has some controversial compiler actions upon the FPU, where printf() via switch (f) specifies double precision FPU operations. ARM engineers of CMSIS v5.7 suggest (f) suffix, e.g. (0.123456789f) mandates compiler Not preform double precision operation.

    According to TM4C datasheet (Pg.142) 7M4 FPU can not do double precision operations as noted IEEE 754 standard amended C99. Seems somebody is not following the IEEE rules and the compiler (float) appended (f) attempts to do double precision. Hence a float64_t somehow skirts around C99 and the FPU preforms single precision on a long long rather than a long adding double precision (f).

  • Does this mean that the compiler emitted a double-precision VFP instruction? If so I would expect a Hard Fault (Usage-UNDEFINED) rather than an NMI or a Floating-point (SYSEXC) exception. What instruction was it? Was this in the generated code or in a library? What happens if you define SYSEXC_IrqHandler (or whatever that name is precisely)?

    BTW: input theta = 0.0123450002 and how the 0002 gets added into float 32 bit array, e.g. theta[1]={0.0} value (0.012345) is a mystery.

    Two different calculators I found on the web say that 0.012345 is really 0.012345000170171260833740234375 in single precision.

  • Also brings up a good point if the project optimizations (Relaxed) floating point actually converts doubles to singles. The drop down text seems to imply that Relaxed does convert doubles to singles. What does Strict floating point operations do for (f) suffix is the better question?

    Was this in the generated code or in a library?

    In the app code table values end with (f) to inform the compiler not cast or use FPU double precision. The suffix seems to be having a bad effect with relaxed floating point instructions. Code faults immediately via multiplication of two float32_t, oddly not when changed to float64_t. The FPU exception handler interrupt 5 is built into hardware, startup_ccs.c traps into exception handler, a while loop for debug register inspections. 

        FaultISR,                               // The bus fault handler     (INT5) -11 

  • I can try and look into the DEN piece

    ■ Hardware support for denormals and all IEEE rounding modes

  • I noticed the CMSIS project compile flags had not added -mv7M4 --float_support=FPv4SPD16.  Yet the CMSIS project has runtime support selected (FPv4SPD16) but the flag was never added summary of compile flags. However the application only references this CMSIS DSP project build and application does set flags -mv7M4 --float_support=FPv4SPD16.

    The CMSIS project manager upon testing with compiler (clang) did not set symbol flag --define=__FPU_PRESENT=1 as the TI compilers add to summary of flags. Could it be their test build bamboozled was not even using 7M4 FPU for single precision float32_t operations rather Clang is simply adding floating CPU support for (f) suffix?

  • Hi Gl,

    I am not familiar with CMSIS projects but that sounds like it could be a possible issue. I think it would depend how the projects are all tied together, what is being used by what etc. It sounds like a possible issue though and should be easy enough to set across the board.

    Best Regards,
    Ralph

  • The problem was more how the FPU calculation was being exported into array cells, direction of pointer to into each array. The direction of data flow into the included project library was more the issue causing Nmi faults. The layout for each function lacked clarity as to the direction of a  passed variable of several functions that where invoked in the interrupt handler.