cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407 FLASH erase fail with IWDG enabled (HAL)

neil239955_st
Associate II
Posted on May 15, 2017 at 12:47

Hi,

I am having a problem writing to flash with the IWDG enabled, presumably I am missing something.

I have cut my project down to a minimum that reproduces the problem.

The program initialises the HAL and system clocks and then erases a flash sector (FLASH_SECTOR_2), the compiler is told not to use sector 2 & 3 so I can store parameters in them.

This gives me a successful return value and all is well.

However if I enable IWDG (HAL_IWDG_Start()), then HAL_FLASHEx_Erase() fails with HAL_FLASH_GetError() = 6.

I've changed the watchdog to a long period to make sure its not interrupting the erase.

Have I skipped over some detail? I had assumed that the watchdog being independent all I needed to do was ensure the watch period was long enough not to interrupt the flash writing.

void MX_IWDG_Init(void)

{

  hiwdg.Instance = IWDG;

  hiwdg.Init.Prescaler = IWDG_PRESCALER_256;

  hiwdg.Init.Reload = 4095;

  HAL_IWDG_Init(&hiwdg);

}

  HAL_Init();

  SystemClock_Config();

  HAL_IWDG_Start(&hiwdg); /* Start Watchdog */

  HAL_FLASH_Unlock(); /* makes no difference */

 

  uint32_t error_sector_num = 0;

 

  FLASH_EraseInitTypeDef EraseInitStruct;

  EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;

  EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;

  EraseInitStruct.Sector = FLASH_SECTOR_2;

  EraseInitStruct.NbSectors = 1u;

 

  /* erase flash */

  if(HAL_FLASHEx_Erase(&EraseInitStruct, &error_sector_num) != HAL_OK)

  {

    /* Error while erasing sectors */

    uint32_t error_code = HAL_FLASH_GetError();

    __ASM volatile('BKPT #01');

  }

  else

  {

    __ASM volatile('BKPT #01');   

  }

Thanks in advance,

11 REPLIES 11

> The problem actually happened when it kicks while programming the FLASH.

So, you are running the FLASH programming code out of RAM? And the IWDG kicking is in RAM, too? Can you please tell us more about your application?

If you modify the code in a minimalistic way, so, that in the piece which kicks the IWDG, you replace only the write to the IWDG register by a write to a volatile variable in RAM, does the problem go away?

Thanks,

JW

Hi Jan,

The FLASH programming function runs in RAM while the IWDG refreshing runs is a Timer Interrupt Handler, in ROM, along some other small pieces of codes in that handler.

Like I've said, the whole program has been running for months without any issue until I accidentally commented out the IWDG_init but the IWDG refresh is still being called regularly. I found out when I try to shorten the data being written to FLASH, the problem did not happen.

But once I commented the IWDG_Refresh macro out in the timer handler, the original FLASH writing works without any issue.

Finally I restore both the IWDG_Init and IWDG_Refresh, and everything works.

Therefore I think writing to the IWDG Key register without IWDG being initiated properly could have caused some reactions in the VDD domain, where FLASH is somehow linked to.

ST