2017-05-15 03:47 AM
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,
2017-05-15 04:20 AM
https://community.st.com/0D50X00009XkY4mSAF
(with explanation inhttps://community.st.com/0D50X00009XkW4gSAF
) might be relevant.I am not going to comment on Cube.
JW
2017-05-15 08:15 AM
Thanks for the suggestion.
I've read through the links you posted and they read as if the problem occurs immediately after changing the watchdog settings, my full project can run for hours of kicking the dog before attempting the flash write and failing.
I have attempted the delays as suggested in the links anyway including kicking it every millisecond for 100mS before erasing the flash and it makes no difference.
I've also tested that the watchdog times out at the intended time using a while() loop and that works fine too.
I won't comment on the cube either as I'm 15k+ lines too deep already.
(I missed off the call to MX_IWDG_Init() just after SystemClock_Config() in my previous post)
2017-05-15 08:24 AM
Okay and what is the ratio between the dog's timeout and the FLASH erase/programming time then?
JW
2017-05-15 08:59 AM
I'm not really sure what you mean by ratio but using the DWT_CYCCNT to time the flash erase it takes 195mS, and the watchdog times out after ~34seconds which looks reasonable for the settings +- a bit of RC clock wobble.
On the other hand I just pulled another 9 PCB's to test the code on and it only fails on this one...
I suspect I maybe have been a bit premature assuming this was a software fault...
I appreciate the help regardless.
2017-05-15 09:29 AM
Neil,
On the other hand I just pulled another 9 PCB's to test the code on and it only fails on this one...Huh. Please come back with your findings.
I'm not really sure what you mean by ratio [...]
I meant, whether the dog's timeout is not too close to the erasing/programming time.
flash erase it takes 195mSSo you use the 32-bit parallelism for programming/erasing, do you have adequate power supply for that (min. 2.7V)?
Jan
2017-08-10 12:13 AM
I appear to be having the same issue Neil. Did you resolve you issue?
2017-08-10 04:07 AM
Please open a new thread (linking perhaps here for reference) with describing your own particular set of circumstances.
JW
2017-08-11 08:42 PM
I was following the below example, but the erase was failing (returning 6).
\Projects\STM32F4-Discovery\Examples\FLASH\FLASH_EraseProgram\
Reading other posts, I noticed the following line was added after the flash was unlocked.
/* Clear FLASH error flags */
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);This fixed my issue.
My approach to managing the IWDG when writing to flash (in my case, doing an infield firmware upgrade) is to restart the application, NOT initialize the IWDG, update the firmware, restart, and then restart the IWDG. Hope that makes sense.
2018-11-28 12:55 AM
Hi, I accidentally created a problem in my application with the IWDG and FLASH programming.
In my program, the IWDG is initialised during boot up sequence in Cube's way, and the FLASH programming is initiated by user.
It has been working fine until a recent change made the FLASH erroneously flip some bits on wrong memory locations.
I have made sure that the addresses passed to the FLASH_Program_size are all correct, and searched to the end of the world until I found out that the root cause was actually that I have commented out the Initialization part of the IWDG peripheral, but the firmware still regularly kick the dog. The problem actually happened when it kicks while programming the FLASH.
I could not find any note on this in the reference manual, however the IWDG block diagram kind of hinting that kicking the dog may have affected the VDD voltage bus, which is essential for the FLASH erasing and programming routine! You can see the relationship in the PWR-Power Supply overview of the MCU.
I think this could be also the reason for Neil's problem, that when you try to Erase the FLASH shortly after starting the IWDG ( if the compiler did it that way without optimisation change), the voltage drop caused by IWDG starting raised some flags in FLASH registers.
Just my humble opinion on this issue.
Seng Tak