This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

FPU Error on printf() for "%g" for large numbers

Hello,

I am porting a software to the nRF52 SDK16.0 . This software uses Floating Point numbers with Exponent-Byte=0x7F to signal Error conditions (then treated as unsigned ints with 24 bits).

However, these values are still numbers. Like 

hk_hum.floatval = 1.71141e38   ( = 0x7F 00 XX XX == ERROR XXXX) 

But if printf has printed the number (which is OK), the nrf_pwr_mgmt.c trigger this assert (line 125):

...

hk_hum.floatval = 1.71141e38; // Force Error
tb_printf("H:%g\n",hk_hum.floatval); // Output is H:1.71141e38

. . .

ASSERT((original_fpscr & 0x7) == 0);  // in nrf_pwr_mgmt.c

...

Best regards,
Jo

  • Hi JoWi, 

    can you add a breakpoint after the tb_printf call and then post the content of the FPU registers here?

    Best regards

    Bjørn

  • Floats are AFAIK promoted to double for variable argument functions, and the optimzier might just put the (compile time constant) value directly into the tb_printf() call - either on the stack or into FPU registers.

    You might need to look at the generated assembly code here - the FPU exception flag could be generated further down when actually using hk_hum.floatval (or writing it into memory).

  • Hello Bjjørn and Turbo,

    hmm, SES (4.20a) tells me: FPU unused (?). However, this is a sample output (the number is read by atof(), hence not optimised..)

    >x123e-3
    Test: '0.123'
    >x1.712e38
    Test: '1.712e+38'
    FATAL ERROR: DEADBEEF Line 125 'C:\nordic\nRF5_SDK_16.0.0_98a08e2\components\libraries\pwr_mgmt\nrf_pwr_mgmt.c'
    

    I have put the complete project to the attached zip. It should compile if places in the examples folder of SDK16. Just run it on a pca100056 and enter numbers on the Virtual COM).

    (This project contains also the code for my currently 2.nd problem with the 2.nd UART from this morning: https://devzone.nordicsemi.com/f/nordic-q-a/56760/problem-with-uarte-error-conditions-on-nrf52840 )

    Thanks for your help! 

    Best regards, Jo

    Problem_UART.zip

  • Hi Jowi, 

    altering the Code > Printf/Scanf > Printf Floating Point Supported from Float to Double in the Project settings removes the assert. However, then I guess the FPU might not be used at all. 

    I must admit that im not quite sure why you're getting an FPU exception, but could it be because 1.712e38 is larger than 2^+127, i.e. ~1.701,411,83 x10^+38 which is the largest signed number that can be represented?

    We have added the assert here to notify the uses about FPU, but you can remove the assert if you know that its OK to ignore it. 

            /*
             * The last chance to indicate an error in FPU to the user 
             * as the FPSCR is now cleared
             *
             * This assert is related to previous FPU operations 
             * and not power management.
             *
             * Critical FPU exceptions signaled:
             * - IOC - Invalid Operation cumulative exception bit.
             * - DZC - Division by Zero cumulative exception bit.
             * - OFC - Overflow cumulative exception bit.
             */
            ASSERT((original_fpscr & 0x7) == 0);

    Best regards

    Bjørn

Related