cancel
Showing results for 
Search instead for 
Did you mean: 

Why would FLASH_FLAG_PGPERR and FLASH_FLAG_PGSERR be set after a successful flash write, and at power-up before any flash write operations?

SHers
Associate III

I've written a flash-based bootloader for the STM32F4 using the latest STM32CubeMX tool and its HAL libraries. I've avoided all the usual pitfalls (it's not my first bootloader), and my code works reliably. I'm not erasing my bootloader segment, writing to the wrong address, or failing to account for the instruction pipeline stall that a flash write causes. So far, so good.

However, one problem I encountered was that on power-up, BEFORE any flash operations were done, I would generally find that the flash alignment and parallelism error flags were set. Moreover, during the course of writing a 200K byte image to flash in small chunks, I randomly encounter these error flags after successfully writing data to the last byte in a 256-byte page (this happens at various places in mid-sector, not at the sector boundary).

Specifically, the call to HAL_FLASH_Program() to write a byte at a 256-byte boundary fails because the PGP and PGS flags got set after the end of the last (verified successful) call to HAL_FLASH_Program() for the immediately-prior flash address and the start of the call to HAL_FLASH_Program() for the new address on the boundary.

My flash write algorithm writes 256 bytes at a time with a sequence of calls to HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE...), after which the program goes off and calls LwIP_update(), then comes back to write the next page. Inspection of flash contents shows that the data DID get written to flash, and HAL_FLASH_Program() returns a success code consistent with that. After the overall flash operation is done, I go back and MD5sum the downloaded flash area, and it's always bit-perfect. No other processes are messing with flash, and the MCU supply voltage of 3.3V is compatible with byte-wide flash writing, and the main clock frequency of 144 MHz is within spec. The source of these errors is a mystery.

My temporary solution is to call __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR) before each flash write, and pay attention to any failure code returned by HAL_FLASH_Program. This seems to have fixed the problem, but I remain suspicious. Suggestions?

11 REPLIES 11
jwoerle
Associate III

Are there any updates on this?

I have discovered the same behavior in my application.

I have a custom STM32F4 board with a bootloader and an application. I'm using the eeprom emulation project provided by ST (slightly modified to handle both applications).

The bootloader as well as the application uses the function HAL_FLASH_Program(). The bootloader uses it to flash the new application and writes information about the application in the eeprom. The application uses it to write configuration parameters into the eeprom.

The bootloader works fine. The application works fine at start-up (some values are written to the flash), but if I want to write values to the flash at runtime, the function HAL_FLASH_Program() fails, because FLASH_FLAG_PGPERR and FLASH_FLAG_PGSERR are set.

Currently (as temporary solution) I'm including the __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR) function before every flash write, as suggested by @Steve H Hersey​  .

I'm using Atollic TrueSTUDIO v9.3.0, STM32CubeMX v5.4.0 and STM32Cube_FW_F4_V1.24.1

SBeno.1
Associate II

I am really curious about this as well. I have run in debug few commands and then I run the WaitForLastOperation twice ( since this function actually clears the flags ) everything works fine.

I am using the latest F4 drivers, but somehow I have to put __HAL_FLASH_CLEAR_FLAG() before doing anything flash related.

Any explaination for this ?

I could finally solve this issue, thanks to this thread:

https://community.st.com/s/question/0D50X00009XkWriSAF/stm32f407-flash-programming-error-pgserr-and-pgperr

It was actually a bug introduced by me:

I have a watchdog running and reset it frequently with

HAL_IWDG_Refresh(&hiwdg);

For debugging purpose, I disable my watchdog init

// disable for debugging purpose
// MX_IWDG_Init();

This causes problem in the Flash interface, where the FLASH_WaitForLastOperation() function fails.

My solution is to also disable the HAL_IWDG_Refresh() function in debugging.

Great timing! I had this same FLASH SR register issue that I figured out 4 days ago.

Short answer: find the unintentional 'write' in the code to an address in FLASH. That sets the two bits in question.

In my case there was a write to 0x00000000 from the init function for the ADC. Inside the ADC structure passed to init is the address of the particular ADC to use. My situation had, you guessed it, 0x00000000 instead of a real ADC address. There really ought to be an assert in the ADC init code to catch this.

Brian TIDAL
ST Employee

Hi,

here are my observations on my side regarding some PGxERR  at power-up before any flash operation.

I am using Keil µVision V5.27.1.0.

  • When running my code without debugger, I do not see any PGxERR at power-up
  • When starting the debugger and running my code from the debugger and no breakpoint have been previously defined, I do not see any PGxERR at power-up
  • When starting the debugger and running my code from the debugger and some breakpoint have been previously defined, I have PGAERR PGSERR errors in the FLASH->SR Status Register at power-up (I am using STM32L476)

My conclusion is that the debugger tries to restore the existing breakpoints in an incorrect way and this is causing unexpected PGxERR  errors.

Workarounds:

  •  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS) before any flash erase/write operations
  • remove breakpoints before starting the debugger

Rgds

BT

In order 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.
jrgert
Associate III

My 2¢. I debugged a PGxERR issue on my STM32L496.

  1. I made a few mistakes in my startup code, but ultimately found I was writing to an uninitialized handle (0x00000000), which is in flash. When the code ran, the PGxERR flags were set. I was writing to a 'random' address (in flash).
__HAL_TIM_DISABLE_IT(&htim1, TIM_IT_UPDATE);

FWIW, I have (almost) always seen flash error registers cleared prior to use on other CPU's, Surprising to ST engr's skip that step.

i was using the eeprom.c to use the flash memory as an internal eeprom and got the same problem. clearing flags before writing worked for me. thanks

i was using the eeprom.c to use the flash memory as an internal eeprom and got the same problem. clearing flags before writing worked for me. thanks

ZHaid.1
Associate II

I am also facing this issue. It fails randomly while copying new firmware in the flash. I am copying in chunks of 4KB in Flash. However, it fails randomly when calling FLASH_update(). I am calling 
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
but still no luck. Any help is appreciated

I have added my flash_l4.c for reference