cancel
Showing results for 
Search instead for 
Did you mean: 

WFI returns to unexpected address after DEEPSLEEP

greg2
Associate
Posted on December 03, 2013 at 23:55

Hi,

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,&sharp1

;;;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,&sharp4;

        WFI;

        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.

Greg

#deepsleep #wfi #stm32f103rf
10 REPLIES 10
Posted on December 04, 2013 at 01:00

Does the problem occur if the code is run in RAM, or only in FLASH?

Does the problem occur only if the device is on the debugger, or in free standing operation too?
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mckenney
Senior
Posted on December 04, 2013 at 13:57

I don't have an answer, but I've seen this symptom (running from flash on F103). In my case the fault was a Hard Fault promoted from (I think) a MM fault on the 3rd instruction after the WFI, but it was also  (coincidentally?) halfway through the instruction. I didn't find anything obvious in the RM or the Errata. I didn't think of your counting trick. (What did v1 contain in the failure case?)

I eventually discovered that inserting (at least) 6x NOPs after the WFI made the symptom vanish. I don't know whether this worked by giving the CPU some idle ''warmup'' time or by providing (effectively) a do-nothing random-branch table.

I'm pretty sure my block comments describing all this contained the word ''Ick''.
Posted on December 04, 2013 at 17:25

It does sound a lot like a TI/Stellaris errata, not sure I could pin it to the core.

Watch the flash wait states, and specifically the prefetch buffering.

3 The prefetch buffer must be kept on when using a prescaler different from 1 on the AHB clock.

 

4 The prefetch buffer must be switched on/off only when SYSCLK is lower than 24 MHz and no prescaler is applied on the AHB clock (SYSCLK must be equal to HCLK). The prefetch buffer is usually switched on/off during the initialization routine, while the microcontroller is running on the internal 8 MHz RC (HSI) oscillator.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mn2
Associate II
Posted on December 05, 2013 at 11:04

Hi,

try this:

__asm void myWFI(void)

{

  wfi

  nop

  bx   lr

}

You will find this workaroung also in errata sheet

Posted on December 05, 2013 at 13:23

You will find this workaround also in errata sheet

Which one, can you provide a cite for the document you are looking at?
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mn2
Associate II
Posted on December 05, 2013 at 13:47

DM00027213 Errata sheet STM32F2

DM00037591 Errata shhet STM32F$

Hier you see the email (names replaced with xxx) from ST from 01.06.2010

Dear Mr. xxx,

after some investigation of our designers we found a suitable workaround for this issue. What you need to do is to embed the WFI/WFE instruction into a simple assembly function like:

__asm void _WFI_instruction(void)

{

    wfi

    nop

    bx lr

}

the nop inside function is important, it must be there. As well as the method of exit of the function must be BX LR.

Could you please test on your side and let me know your results?

Please let me again mention that this issue can be seen only in debug mode.

Best regards,

xxx

T.O.M.A.S - Technically Oriented Microcontroller Application Services

ST Microelectronics 

mn2
Associate II
Posted on December 05, 2013 at 14:25

Here the link for STMF1 

http://www.st.com/web/en/resource/technical/document/errata_sheet/CD00197763.pdf

2.5 Debugging STOP mode with WFE entry

mckenney
Senior
Posted on December 05, 2013 at 14:32

Thanks for the pointer.

This code sequence also appears in the F1 Errata (CD00197763-r12, 2.5), along with the note ''This affects only Stop debug mode with WFE entry.''
Posted on December 05, 2013 at 15:23

''This affects only Stop debug mode with WFE entry.''

Key terms here DEBUG and WFE
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..