Showing results for 
Search instead for 
Did you mean: 

HAL_FLASH_Program not writing to flash permanently

Associate II

Hi all,

I am using HAL_FLASH_Program() to program an uuid into a specific address. I can verify it write successfully by reading from the address. However, if I power cycle the MCU, the memory at that address returns to the original value. If I write it directly through ST-Link then it stays permanently. Does anyone know why is that? Do I need to erase the memory location before write to it using HAL_FLASH_Program()? I am using STM32F745.

Thank you


How exactly do you write it?

I posted the code in the comment below.

The address must be aligned, 0x080BFFFB is not aligned for halfword writes, use an even number (and for full words, one divisible by 4).

set PG before STRT.
I dont think HAL is the problem here.
If you feel a post has answered your question, please click "Accept as Solution".


> set PG before STRT.

No need for that on the F7

Thank you. Changing the address solved the PGPERR problem. However, my original problem still remains. The flash write is not permanent, and when I power cycle the MCU, it goes back to 0xFFFF.

What is interesting is if I run the MCU in debugger mode, put a break point anywhere inside the FA_program_uuid() above, it works. I then can stop the debug session, power reset, and the memory data remains.

However if I run in debugger mode without any break point, the memory data is reverted back to 0xFFFF.

What could be the difference between running in debugger mode, with a break point, vs running in normal (release) mode (and vs running in debugger mode without a break point)?

Fixed it:

FLASH->CR |= 0x1;     //Set PG bit
*(volatile uint16_t*) 0x080BFFFA = uuid;
while(FLASH->SR & 0x0100)
  1. Don't limit comparison to >0, when you can do !=0 (the same as leaving it out completely) - it's safer relative to potential code changes in future.
  2. As berendi said, the address for half-word writes must be half-word aligned.
  3. Target type of casting must be volatile to prevent compiler from reordering the write operation relative to other volatile accesses - in this case register accesses.
  4. As flash memory region is not configured as device or strongly ordered memory, the store instruction must be encapsulated with DMB instructions to force CPU to complete previous stores and prevent from reordering instructions and doing speculative reads. This is recommended for all ARM CPU cores, but Cortex-M7 is the first from Cortex-M series, for which it is mandatory!

P.S. And of course the HAL code is broken in this regard...

Thank you! It now works properly.