cancel
Showing results for 
Search instead for 
Did you mean: 

Checking if first time run since flashing

PMath.4
Senior III

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

1 ACCEPTED SOLUTION

Accepted Solutions
PMath.4
Senior III

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");
}

View solution in original post

4 REPLIES 4
Uwe Bonnes
Principal III

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

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
Senior III

"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
Senior III

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");
}