cancel
Showing results for 
Search instead for 
Did you mean: 

On what address do the Option Bytes on STM32F446 reside on?

arnold_w
Senior

I want to read the Option Bytes values from my STM32F446 in order to debug strange behavior. On what addresses do they reside? According to the Reference Manual they reside on addresses 0x1FFFC000 and 0x1FFFC008, but when I look at the implementation of HAL_FLASHEx_OBGetConfig it is reading from addresses OPTCR_BYTE0_ADDRESS, OPTCR_BYTE1_ADDRESS, OPTCR_BYTE2_ADDRESS, and OPTCR_BYTE3_ADDRESS (0x40023C14 - 0x40023C17). Can someone please clarify?

19 REPLIES 19

The option register which governs the behaviour is at 0x40023C14. The option bits are loaded with values from Flash memory (i.e. from the 0x1FFFC00x adresses) at reset release. See Flash option control register (FLASH_OPTCR) in RM0390.

JW

arnold_w
Senior

Thank you.

But what do you mean by 0x1FFFC00x addresses in flash? If I convert 0x1FFFC000 from hex to dec then I get 536854528 = 511 Mega. The flash in the STM32F446 is only 512 kBytes, not 512 MByte. How is it then possible to store something at address 0x1FFFC000 in the flash?

The FLASH is not a single piece, and it is not mapped from 0x0000'0000.

FLASH in STM32 comes in several pieces, and these pieces are mapped at different addresses within the 4GB address space of STM32.

Maybe it's confusing to say that the option bytes are loaded from FLASH, and ST avoids to say this. Nevertheless, the physical implementation is FLASH (electrically erasable, electrically programmable memory), although it's not part of the 512kBy *user* FLASH array.

Similarly, what ST calls ROM (System memory), or OTP, are physically FLASH, except the former is programmed in factory and then locked, and the latter does not have the erasing circuitry connected. Again, these portions are mapped at different addresses, non-continuously.

The user FLASH is basically mapped from 0x0800'0000 upwards. If booted into this FLASH, it is mirrored at the 0x0000'0000 space (but that space can mirror also the System memory described above, or SRAM, or FMC banks, depending on SYSCFG_MEMRMP.MEM_MODE.

JW

arnold_w
Senior

So, the microcontroller looks at addresses 0x40023C14 - 0x40023C17 to decide what to do. The addresses 0x40023C14 - 0x40023C17 are initialized with values from addresses 0x1FFFC000 and  0x1FFFC008 after reset. But how do I update the values at addresses 0x1FFFC000 and  0x1FFFC008? When I look inside the function HAL_FLASHEx_OBProgram all I see is writes to addresses 0x40023C14 - 0x40023C17, not 0x1FFFC000 and  0x1FFFC008. Is there another function for writing to addresses 0x1FFFC000 and  0x1FFFC008?

My end-goal is to be able to embed all my option bytes into the hex-file (so that I know with 100% certainty what option bytes a particular firmware version is running on) using a home-made function called updateOptionBytesIfNecessary(), but my first attempts at this resulted in very strange behavior (such as automatic enabling of the read protect if I connect twice in a row with ST Link Utility).

That might be right. Programming option bytes is described in Programming user option bytes subchapter of FLASH chapter (ch.3) of RM0390; the FLASH controller takes care to program the values to proper address.

Typically, option bytes are programmed together with the program, using whichever programming tool you use, e.g. STLink Utility, or CubeProgrammer. Whether the given programming tool supports having the option bytes as part of the .hex, is dependent on that particular tool, I don't believe there is a common standard obeyed by all tools out there.

JW

arnold_w
Senior

Yes, there is a section detailing how to program the user option bytes. However, user option bytes only include 3 parameters: nRST_STDBY, rRST_STOP and WDG_SW. There is no section describing how to change SPRMOD, Read Protection (RDP) and nWRPi. I could look at what the HAL-functions are doing, but it's exactly those that give me the weird behavior with read protection being enabled all of a sudden...

Aren't SPRMOD, RDP and nWRPi all contained in FLASH_OPTCR, as described in chapter 3.8.6 Flash option control register (FLASH_OPTCR) of RM0390 rev.4? So I would expect they can be changed in the same way as other items in FLASH_OPTCR, i.e. nRST_STDBY, rRST_STOP and WDG_SW.

JW

The terminology is confusing, in Table 9 "Description of the option bytes", the following text can be found:

"USER: User option byte

This byte is used to configure the following features:

Select the watchdog event: Hardware or software

Reset event when entering the

Stop mode Reset event when entering the Standby mode"

Then in section 3.6.2 "Programming user option bytes" it says:

"To run any operation on this sector..."

So does "sector" refer to the option bytes at addresses 0x1FFFC000 and 0x1FFFC008 or just the USER bits (nRST_STDBY, rRST_STOP and WDG_SW)?