cancel
Showing results for 
Search instead for 
Did you mean: 

WFI instruction causes system crash

Albert Claessen
Associate II
Posted on May 21, 2017 at 18:30

I am using a Nucleo L152RE for a simple interrupt driven application.

I am using an external interrupt (EXTI0) and tim6 interrupt.

Everything works fine but when I try to use HAL_PWR_EnterSLEEPMode (PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI) to save some power during non-activity, the system crashes, does not make it out of sleep mode.

The program counter ends up at  line 130 in startup_stm32l152xe.s line 130  b Infinite_Loop which seems to be the WWDG_IRQ handler. The watchdog is not enabled and what I have found so far indicates that this is caused by an interrupt that is not handled. I have not been able to find a cause. I cannot find any interrupts enabled other than the what I am intending to use.

I am probably making a rookie mistake but would appreciate any help/pointers.

#wfi-pwr_enterstopmode-interrupt
18 REPLIES 18
Posted on May 21, 2017 at 18:43

Are you sure it's not the Default_Handler dumping ground for unhandled interrupts?

RTC Wakeup/Alarm?

One could likely bisect the weak/default handler list into multiple infinite loops to pin down the source.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
RomainR.
ST Employee
Posted on May 21, 2017 at 21:35

What do you mean by the crash system ?

It seems you are in debug mode since you notice a jump in the file startup.s.

As you put the core in Sleep mode by the wfi instruction, if you are in debug mode it is quite normal that you lose communication between your mcu and your environment (IDE) which tells you that the stm32 is no longer responding. What you see next in the startup.s file is then indeterminate! Before calling the

HAL_PWR_EnterSLEEPMode(), y

ou have the option to keep the debug active in sleep mode using the function below:

/ **
 * @brief Enable the Debug Module during SLEEP mode
 * @retval None
 * /
Void HAL_DBGMCU_EnableDBGSleepMode (void)
{
 SET_BIT (DBGMCU-> CR, DBGMCU_CR_DBG_SLEEP);
}�?�?�?�?�?�?�?�?

And if you are using HAL library, keep in mind that systick interrupt are enable because you invoke HAL_Init() by default.

In fact, you should disable it.

HAL_SuspendTick();�?

Otherwise your stm32 will be wake from sleep mode every systick timer interrupt (1ms by default)

Best regards

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Posted on May 22, 2017 at 17:40

Hello Romain,

Thanks for looking at this.

Some background.

I am using the STM32Workbench, the Nucleo L152re has the built in ST-Link.

The system has been generated with CUBEMXL1, I made a small change to the SPI driver to get the select line to go high between SPI operations.

I am also using the serial wire viewer as a standalone output for some diagnostic print information.

The project is in its initial stage of running a wireless device (DecaWave UWB radio) using a polled SPI interface with interrupts from the radio on EXTI0. The radio is running fine and I am getting correct debug info on the serial wire viewer.

I am going to use a timer to kick of transmissions at regular intervals that need to be synchronized with a master (anchor radio) and have a TIM6 with interrupt set up to do that, although the timer just blinks an LED for now.

Everything works as expected until I try the following.

My next step was to reduce power and turn of the processor clock when there is nothing to process.

I inserted the following in my idle processing loop

I experimented with some debug variables and found that the system enters the WFI instruction in HAL_PWR_EnterSLEEPMode but never makes it out, the system freezes/crashes.

When I suspend the debugging the program counter points to line 130 in the code below, suggesting an unhandled interrupt.

Looking at the NVIC and external interrupts It seems that the system crashes when the next EXTI0 interrupt is coming in, but that works fine without the sleep attempt.

I must be missing something basic, I have not been able to find someone else having this issue and I have spent quite some time reading documentation etc.

I am not expecting any debug output when the system is in sleep mode, that has not been an issue (yet).

Albert.

________________

Attachments :

image[3].png : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006Hyek&d=%2Fa%2F0X0000000bAd%2FJUz7jpKGngMWyPXY1zOPPbdHDte.mQgcDiMCaBFieUE&asPdf=false

image[1].png : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006Hyef&d=%2Fa%2F0X0000000bAb%2F45O99ybfK5h2VA6L1K_wMs36u.N0soaBSFHiiEDjx5Q&asPdf=false
Posted on May 23, 2017 at 08:53

Hello Albert,

It seems you enter in Hardfault Handler (image[1].png) because an interrupt event is not correclty handled.

Note that wakeup Pin is dedicated to wake-up fromStandby.

Could you create and test a basic firmware that performs the following functions:

- Configure the User button in Input EXTI rising Edge mode. - Configure LED2 PA5 in Output PushPull mode.

Do not use other peripherals.

In the main function and into the while (1) bloc

- Make a simple Toggle of LED2 PA5 say 10 times to make sure your mcu is in run mode. - Then disable the Systick (with HAL_SuspendTick ();) - Finally put the mcu in Sleep mode, the wake-up from sleep should appear when the User Button ispressed. - Reactivate the Systick (HAL_ResumeTick ();)

Here an example:

int main(void)
{
HAL_Init();
while (1)
{
/* User push-button will be used to wakeup the system from SLEEP mode */
BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);
/* Configure LED2 */
BSP_LED_Init(LED2);
/* Perform 10 LED2 toogle */
for(uint8_t i = 0; i < 10; i++)
{
BSP_LED_Toggle(LED2);
HAL_Delay(1000);
}
/*Suspend Tick increment to prevent wakeup by Systick interrupt. 
Otherwise the Systick interrupt will wake up the device within 1ms (HAL time base)*/
HAL_SuspendTick();
/* Enter Sleep Mode , wake up is done once User push-button is pressed */
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
/* Resume Tick interrupt if disabled prior to SLEEP mode entry */
HAL_ResumeTick();
 
BSP_LED_On(LED2);// Place a breakpoint here
}
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Posted on May 23, 2017 at 09:53

Sorry, don't forget to define EXTI Interrupt handler into stm32l152_it.c otherwise you will enter into hardfault handler.

/**
 * @brief This function handles External lines 15 to 10 interrupt request.
 * @param None
 * @retval None
 */
void EXTI15_10_IRQHandler(void)
{
 HAL_GPIO_EXTI_IRQHandler(USER_BUTTON_PIN);
}�?�?�?�?�?�?�?�?�?

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Posted on May 23, 2017 at 17:20

Hello Romain, Thanks for that, I will try that.

I have been experimenting and made some progress.

I made a simple application with just TIM6 toggling LED2 on interrupt.

It had the same issue, not recovering from the WFI. I power cycled the system (for an unrelated problem) and noticed that the LED was actually working as intended without the debugging active.

I did dig into that further and found that by default debugging on SleepMode StopMode and StandbyMode is enabled (DBGMCU CR bit 0,1,2 set 1).

I set the bits low in my code and the system works as intended but of course I lose debugging at the first WFI instruction. I don’t get debugging back if I re-enable after the WFI.

I am sure there is a clue somewhere in here but I don’t know anything about the debugging implementation to understand what is going on.

Albert.

Posted on May 28, 2017 at 18:17

Hello Romain,

I have been distracted with another project for a few days. I have tried the simple interrupt experiment.

I did let CUBEMX generate the interrupt handler for the pushbutton pin (GPIO 13 on the Nucleo L152RE)

Using STM32 workbench I got some weird behavior setting the breakpoint that did not make any sense.

The debugger claims to set the breakpoint in the proper location but the system halts when going into the clock setup routine which follows main immediately after where the breakpoint is supposed to go.

Besides that, the sleep instruction is ignored (Systick is suspended).

In contrast to my previous experiment, without debugger attached, the sleep instruction is still ignored and the LED keeps blinking. I am thinking that I corrupted my installation and need start from scratch.

I switched over to Atollic Truestudio 7.1, the results are different. The processor also halts as intended but does not recover after the pushbutton and never makes it to the breakpoint.

It ends up in the same hard error handling routine. However, in this case without debugger attached the experiment behaves as intended, goes to sleep and wakes up for another set of blinks after pushing the button.

I will keep experimenting and let you know if I find something. For the time being I am continuing without the sleep mode and will add that when going to the final hardware setup.

Thanks for your help.

ALbert.

Posted on May 29, 2017 at 10:46

Hello Albert,

I took a little time and tried the basic code of Sleep Mode on a board NucleoF446 (because I do not have an L15x).

I have all implemented with the latest version of SW4STM32 v2.0.0.

I did not have any problems with the debug as you can see in the code below. It works fine.

I placed two breakpoint, one at line 110 and the next line 116.

After LED2 toggle loop, and first breakpoint. the core enter in sleep mode. The last breakpoint is reached when PC13 - USER Button is pressed. And theLED toogle restart.

0690X000006077sQAA.png

Let me know if you have any issues.

Best regards

romain,

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Posted on May 30, 2017 at 18:33

Hello Romain,

Thanks for sticking with me.

I have used another board (STM32F4-Discovery) that I had and generated the code with CUBEMX.

I did run the test and it behaves as it should with debugger attached breakpoints and all.

I am concluding that either my Nucleo 152 is damaged, maybe by ESD, or there is a design issue. I am going to get another board to continue.

The code that I used:

for (uint8_t i=0;i<10;i++){

HAL_GPIO_TogglePin(LD4_GPIO_Port, LD4_Pin);

HAL_Delay (1000);

}

HAL_SuspendTick();

HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON,PWR_SLEEPENTRY_WFI);

HAL_ResumeTick();

HAL_GPIO_WritePin(LD4_GPIO_Port, LD4_Pin,GPIO_PIN_SET);

Thanks again and best regards,

Albert.