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

pwr_mgmt_fpu_sleep_prepare fails with assert

Hello,

We have an application with a S132 device, SDK 14 and Softdevice v5.0.0. On some devices, an assert is being thrown in the sleep prepare function. This is the line ASSERT((fpscr & 0x07) == 0);

What could the possible cause of this be? Is there any special PCB support required for this to work? The devices that work have a different PCB revision. Is there chip errata pertaining to this?

Thanks

Parents
  • It appears this isn't an issue after all. The sample application works on boards that previously failed. Reverted to an older version of our firmware and that works as well.

    On a side note, the ASSERT indicates that the exception condition existed, not that it was unable to clear the exceptions in the register. Removing the ASSERT condition enables the failed boards to function normally.

    The mystery is why 1 board works.

  • Ah hah, now I got it, it seems more like a bug to me now :) I will check with R&D and confirm this back.

  • Not only is the assert checking the FPU flag conditions prior to clearing, but the assert currently occurs outside the critical section.  An interrupt could occur between the critical section end and assert, in which the FPU flags are modified.  The assert needs to move into the critical section or be removed altogether.

  • Hi Hung, do you have an answer to this question?  We are experiencing a similar problem.

  • I have not seen a fix for this issue. However we determined that there was a real math error somewhere which was causing the problem. Usually a divide by zero (0)

  • My understanding is that it's not a bug. 

    The application should handle FPU exceptions in FPU_IRQHandler() .

    What this code does:

            CRITICAL_REGION_ENTER();

            fpscr = __get_FPSCR();

            /*

             * Clear FPU exceptions.

             * Without this step, the FPU interrupt is marked as pending,

             * preventing system from sleeping. Exceptions cleared:

             * - IOC - Invalid Operation cumulative exception bit.

             * - DZC - Division by Zero cumulative exception bit.

             * - OFC - Overflow cumulative exception bit.

             * - UFC - Underflow cumulative exception bit.

             * - IXC - Inexact cumulative exception bit.

             * - IDC - Input Denormal cumulative exception bit.

             */

            __set_FPSCR(fpscr & ~0x9Fu);

            __DMB();

            NVIC_ClearPendingIRQ(FPU_IRQn);

            CRITICAL_REGION_EXIT();

     

            /*

             * Assert no critical FPU exception is signaled:

             * - IOC - Invalid Operation cumulative exception bit.

             * - DZC - Division by Zero cumulative exception bit.

             * - OFC - Overflow cumulative exception bit.

             */

            ASSERT((fpscr & 0x07) == 0);

     

    Is to avoid the exception prevents the CPU from sleeping (that has not been handled by the FPU_IRQHandler). However, the critical FPU should be assert, that's why we have the last check    ASSERT((fpscr & 0x07) == 0); to assert if there is any critical exception. 

     

Reply
  • My understanding is that it's not a bug. 

    The application should handle FPU exceptions in FPU_IRQHandler() .

    What this code does:

            CRITICAL_REGION_ENTER();

            fpscr = __get_FPSCR();

            /*

             * Clear FPU exceptions.

             * Without this step, the FPU interrupt is marked as pending,

             * preventing system from sleeping. Exceptions cleared:

             * - IOC - Invalid Operation cumulative exception bit.

             * - DZC - Division by Zero cumulative exception bit.

             * - OFC - Overflow cumulative exception bit.

             * - UFC - Underflow cumulative exception bit.

             * - IXC - Inexact cumulative exception bit.

             * - IDC - Input Denormal cumulative exception bit.

             */

            __set_FPSCR(fpscr & ~0x9Fu);

            __DMB();

            NVIC_ClearPendingIRQ(FPU_IRQn);

            CRITICAL_REGION_EXIT();

     

            /*

             * Assert no critical FPU exception is signaled:

             * - IOC - Invalid Operation cumulative exception bit.

             * - DZC - Division by Zero cumulative exception bit.

             * - OFC - Overflow cumulative exception bit.

             */

            ASSERT((fpscr & 0x07) == 0);

     

    Is to avoid the exception prevents the CPU from sleeping (that has not been handled by the FPU_IRQHandler). However, the critical FPU should be assert, that's why we have the last check    ASSERT((fpscr & 0x07) == 0); to assert if there is any critical exception. 

     

Children
No Data
Related