cancel
Showing results for 
Search instead for 
Did you mean: 

Option bytes in firmware

Shrikrishna
Associate II

Hello,

Device: STM32L443CCU

I am trying set option bytes values in firmware as a ROM constants. The idea is firmware will have option bytes embedded, and when firmware hex will be flashed, it will also flash new option bytes.

So I did following implementation:

  1. Linker script
/* Specify the memory areas */
MEMORY
{
  FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 256K
  RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 48K
  RAM2 (rw)       : ORIGIN = 0x10000000, LENGTH = 16K
  MEMORY_B1 (rx)  : ORIGIN = 0x60000000, LENGTH = 0K
  FUSES (r) 	  : ORIGIN = 0x1FFF7800, LENGTH = 40 	/* Option Bytes (configuration fuses) */
}

Then under SECTIONS.,

 .fuses :
  {
  	. = ALIGN(4);
	KEEP(*(.optionbytes1))
	KEEP(*(.optionbytes1Inverted))
	KEEP(*(.optionbytes2))
	KEEP(*(.optionbytes2Inverted))
	KEEP(*(.optionbytes3))
	KEEP(*(.optionbytes3Inverted))
	KEEP(*(.optionbytes4))
	KEEP(*(.optionbytes4Inverted))
	KEEP(*(.optionbytes5))
	KEEP(*(.optionbytes5Inverted))
	. = ALIGN(4);
  }>FUSES

2. Then in main code., I defined ROM constants with values for option bytes

#pragma GCC push_options
#pragma GCC optimize ("O0")
 
const uint32_t OptionBytes1Default __attribute__(( section(".optionbytes1") )) = platform::OptionByte1DefaultValue;
const uint32_t OptionBytes1InvertedDefault __attribute__(( section(".optionbytes1Inverted") )) = ~platform::OptionByte1DefaultValue;
 
const uint32_t OptionBytes2Default __attribute__(( section(".optionbytes2") )) = platform::OptionByte2DefaultValue;
const uint32_t OptionBytes2InvertedDefault __attribute__(( section(".optionbytes2Inverted") )) = ~platform::OptionByte2DefaultValue;
 
const uint32_t OptionBytes3Default __attribute__(( section(".optionbytes3") )) = platform::OptionByte3DefaultValue;
const uint32_t OptionBytes3InvertedDefault __attribute__(( section(".optionbytes3Inverted") )) = ~platform::OptionByte3DefaultValue;
 
const uint32_t OptionBytes4Default __attribute__(( section(".optionbytes4") )) = platform::OptionByte4DefaultValue;
const uint32_t OptionBytes4InvertedDefault __attribute__(( section(".optionbytes4Inverted") )) = ~platform::OptionByte4DefaultValue;
 
const uint32_t OptionBytes5Default __attribute__(( section(".optionbytes5") )) = platform::OptionByte5DefaultValue;
const uint32_t OptionBytes5InvertedDefault __attribute__(( section(".optionbytes5Inverted") )) = ~platform::OptionByte5DefaultValue;
 
#pragma GCC pop_options

3. it builds successfully, and I verified values and addresses in hex file. Looks right.

4. Using STM32 cube programmer, I tried flashing hex file, with the option "Donwload" and with "Verify Programming" ticked.

5. Then cube programmer does erase and write successfully. But for verify it fails for option byte address,

14:35:16:752 : Reading data...
14:35:16:752 : r ap 0 @0x0801C800 0x00000210 bytes
14:35:16:752 : Reading data...
14:35:16:768 : r ap 0 @0x1FFF7800 0x00000008 bytes
14:35:16:768 : Error: Data mismatch found at address 0x1FFF7802 (byte = 0xE9 instead of 0xEF)
14:35:16:768 : Error: Download verification failed

So looks like option byte flash area is not updated. If I do set option bytes manually from "OB" tab of cube programmer it works perfectly. But flashing option bytes via hex file simply fails.

Anybody has idea what could be wrong?

Also, another point, cube programmer uses address 0x40022020, which is NOT option byte area address.

14:37:29:368 : UPLOADING OPTION BYTES DATA ...
14:37:29:368 : Bank : 0x00
14:37:29:369 : Address : 0x40022020
14:37:29:369 : Size : 20 Bytes
14:37:29:369 : Reading data...
14:37:29:369 : r ap 0 @0x40022020 0x00000014 bytes

}

5 REPLIES 5
Andreas Bolsch
Lead II

Please read RM0394, section 3.4.2, this will answer your questions.

Thanks @Andreas Bolsch​ . I checked that and it explains to program option bytes on the fly during execution of firmware.

What I am looking for is to have option bytes embedded in hex file. And once we program hex file, option bytes should be set,

Right, but that's the only way. The option bytes (and system memory) are not writebable in the same way as 'ordinary' flash locations. E.g. for the H7 the RM states explicitly that the option bytes are *ONLY* accessible (even for reading!) via the flash registers. And there is good reason for *NOT* embedding the option bytes in firmware file, although it might seem to be a nice feature at first glance: If some sectors are write protected, rewrite requires unprotecting (i.e. modifying option bytes), erasure of sectors, programming and protecting the sectors again. Similar problem regarding PCROP. For a virgin device it's still simple (as no protection set), but for development purposes it's not that simple. The corresponding logic would have to be implemented in the programmer ...

Additionally, the way via flash registers ensures (at least partially) that no insane values are programmed.

And there is also a problem regarding the file format: The hex file describes what should be the memory contents *AFTER* the whole programming procedure. There is absolutely *NO* underlying assumption on nor notion of order of programming the individual memory cells. The programmer is free to program the data records in the file in an arbitrary order.

I doubt there is a high demand for this feature, primarily it would be for production programming. And that's certainly not what the ST programming software aims at.

So you're proably left with your firmware programming the option bytes on first run or something similar. Not that difficult anyway.

Thank you @Andreas Bolsch​ . Thats indeed god explaination, and I would likt to opt it. But then firmware needs to apply reset so that new option bytes are loaded to respective hardware circuitratry within mcu?

Yes, there is the OBL_LAUNCH bit in FLASH_CR just for this purpose. But watch out: It causes a system reset, so you *must* ensure that writing the option bytes is done exactly once, otherwise the firmware will be caught in a reset loop.