Steve Krattiger

Lesson Learned - Flash-Write failure and IWDG

Discussion created by Steve Krattiger on Aug 4, 2017
Latest reply on Aug 5, 2017 by STOne -32

I learned a valuable lesson today, and wanted to share with the community.

 

Here's the scenario.   Using an STM32L021 (probably applies to all STM32), I have the IWDG watchdog running, and also do periodic Flash Writes to store parameters.   And everything worked fine.

 

But then I went in to do some debugging and simply commented out the routines in main():

 

//  MX_IWDG_Init();

 

And the routine in my key function:
//  HAL_IWDG_Refresh(&hiwdg);

 

After a day or two, I noticed that Flash Writes were failing randomly.   Some persistent data was stored correctly, and some was not.

 

After hours of debugging, here's the issue.   Since my Write_EE_Param() routine in a different file could take several milliseconds, at some point I had placed a "HAL_IWDG_Refresh(&hiwdg);" at the beginning of the routine, but did not comment this one out...

 

After stepping through the code, I realized that "hiwdg" was uninitialized (set to 0), and HAL_IWDG_Refresh macro doesn't have any code to check for an unitialized pointer.   The result was that my errant Refresh operations were setting the flag FLASH_SR->WRPERR, write-protecting the flash because I had done a watchdog refresh to an invalid memory location.   My bad...

 

Digging deep into the Reference Manual, I found that System Memory at 0x00000000 is WRP (write protected).   Invalid accesses to this area will set WRPERR=1.  Great feature!

 

Lesson learned - When disabling watchdog, always use #ifdef's.

 

#ifdef  WATCHDOG_IS_ENABLED
#include "iwdg.h"
#endif  // WATCHDOG_IS_ENABLED
...

 

#ifdef WATCHDOG_IS_ENABLED
  MX_IWDG_Init();
#endif  // WATCHDOG_IS_ENABLED
...

 

#ifdef WATCHDOG_IS_ENABLED
  HAL_IWDG_Refresh(&hiwdg);
#endif  // WATCHDOG_IS_ENABLED

 

Steve

Outcomes