Skip to main content
PMath.4
Senior III
October 11, 2019
Solved

Checking if first time run since flashing

  • October 11, 2019
  • 4 replies
  • 4090 views

My program writes to flash but needs to know if it has been run before since the chip was re-programmed. I've set up a section in the flash memory that gets written to by the program

FLASH2 (rx) : ORIGIN = 0x08100000, LENGTH = 1024K
 .option :
 {
 . = ALIGN(4);
 _s_my_option = .; 
 *(.my_option)
 . = ALIGN(4) ;
 _e_my_option = .; 
 } >FLASH2

This appears as expected in the load map.

I've then setup an array in this section in the main program

const char initoptions[256]__attribute__ ((section (".option"))) ={0xFF};

but this doesn't appear in the map and is not getting written when I reflash the chip.

What am I missing?

Thanks

This topic has been closed for replies.
Best answer by PMath.4

OK solved it, I'm on an H7 so flash is programmed 32 bytes at a time on 32-byte boundaries

const int64_t initoptions[4] __attribute__ ((aligned (32))) = {-1};
int64_t* volatile test;
test=(int64_t* volatile)initoptions;
 if(*test==-1){ //first time in
// do stuff
	 uint64_t i64[4]={0};
	 int tries=0;
	 while((HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, (uint32_t)test, (uint64_t)((uint32_t)i64)) != HAL_OK) && (tries++ < 10));
	 if(tries==10)error("Flash write fail");
}

4 replies

Uwe Bonnes
Chief
October 11, 2019

I don't think you can do it that way. What about providing some specific address erased after flash. If the program starts and sees the cell erase, it knows it is first start and writes some non-erased value to the cell. On next start, this can be seen.

berendi
Principal
October 11, 2019

On most (all?) STM32 series, it's possible to change a word in flash from 0xFFFFFFFF to some other value. (Changing bits from high to low is usually permitted, from low to high you need to erase the whole sector). Check the reference manual or flash programming manual to learn the exact constraints for your MCU.

Create volatile constant with

const volatile int32_t initoptions = -1;

It's declared const so that it'd end up in the flash, and volatile so that it won't be optimized away. It will be written to the flash as any other initialized variable.

You can then check its value, and if it's -1, unlock the flash, overwrite it, and do whatever you need on the first run.

PMath.4
PMath.4Author
Senior III
October 11, 2019

"Create volatile constant with"

Nice idea but unfortunately GCC is too clever for that it puts the variable into RAM

"What about providing some specific address erased after flash. "

This is what happens now but the problem is that the address is outside of the actual program so doesn't get changed unless I do a full chip erase. This is fine for me but will cause problems for users updating the firmware.

PMath.4
PMath.4AuthorBest answer
Senior III
October 11, 2019

OK solved it, I'm on an H7 so flash is programmed 32 bytes at a time on 32-byte boundaries

const int64_t initoptions[4] __attribute__ ((aligned (32))) = {-1};
int64_t* volatile test;
test=(int64_t* volatile)initoptions;
 if(*test==-1){ //first time in
// do stuff
	 uint64_t i64[4]={0};
	 int tries=0;
	 while((HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, (uint32_t)test, (uint64_t)((uint32_t)i64)) != HAL_OK) && (tries++ < 10));
	 if(tries==10)error("Flash write fail");
}