2019-10-11 03:53 AM
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
Solved! Go to Solution.
2019-10-11 08:03 AM
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");
}
2019-10-11 04:14 AM
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.
2019-10-11 07:08 AM
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.
2019-10-11 07:44 AM
"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.
2019-10-11 08:03 AM
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");
}