AnsweredAssumed Answered

WFI returns to unexpected address after DEEPSLEEP

Question asked by whiteley.greg on Dec 3, 2013
Latest reply on Dec 6, 2013 by mckenney.bruce

I'm experiencing an odd problem on the STM32F103RF where I get a hard fault UNDEFINSTR on return from WFI in DEEPSLEEP.  Here's a summary of my observations:

1. The hardfault occurs attempting to execute code at an address that is offset 2-bytes into a 4-byte command just following the FI (the POP - aka return - below).

;;;649        // Stay here and wait for an RTC alarm, or an external interrupt
;;;650        __WFI();
00007a  bf30              WFI      
;;;651        return true;
00007c  2001              MOVS     r0,#1
;;;652    }
00007e  e8bd81f0          POP      {r4-r8,pc}
2. Reproduction is highly susceptible to the structure of the function that is invoking WFI - inserting LED debug outputs before or after, changing compiler flags, all make the issue unreproducible.  I've narrowed it down to the WFI instruction only through luck that there are external function calls very closely around the WFI that allowed me to hook debugging into.

3. PRIMASK is 1 (ie interrupts are disabled) so there's no other actor present to be corrupting a stack, for example.

4. I can't reproduce the problem single-stepping under the debugger, it will happily run a number of times, but once I leave it free running it will reproduce almost immediately.

To further illustrate the problem I've added a specific bit of code to trap the return behaviour after WFI:

    // Manually code the WFI, but check the return from WFI is accurate
    unsigned v1;
    __asm {
        mov r0,#4;
        adds r0, r0, 1;
        adds r0, r0, 1;
        adds r0, r0, 1;
        adds r0, r0, 1;
        mov v1, r0;

    if (v1 != 8)
        __aeabi_assert("v1 != 8",__FILE__, v1);

With the debugger single-stepping I can see the behaviour is as expected v1 is always 8, however if I leave it free running I regularly get the assertion line to pop.

Any help would be a appreciated.