cancel
Showing results for 
Search instead for 
Did you mean: 

How to write option bytes in production?

EStei.3
Associate III

Hi,

i'm currently trying to find a suitable way to programm options bytes in production.

The boards are flashed using a J-Link and we would not like to switch to ST-Link.

Is it possible to simply add the option bytes to our binary?

I guess at least some script would be necessary for unlocking the the write access for the option bytes.

Any help is appreciated!

BR

9 REPLIES 9
Florian LR
ST Employee

Hi @EStei.3​,

You can program your option bytes within the code that you flash on your boards.

In order to do that, you have to create first the programming option structure :

FLASH_OBProgramInitTypeDef OBInitStruct;

You are right about the need to unlock the write access for the option bytes.

You need to unlock the flash, and then the option bytes using :

HAL_FLASH_Unlock();
HAL_FLASH_OB_Unlock();

Then you can fill your OBInitStruct with the options you need (you can find the detail of the possible options and the values you can attribute in the stm32XXxx_hal_flash.h or stm32XXxx_hal_flash_ex.h file, depending on what product you are using.

You can now program the selected option bytes using :

HAL_FLASHEx_OBProgram(&OBInitStruct);

Then you lock what you unlocked earlier using HAL_FLASH_OB_Lock()  and HAL_FLASH_Lock().

Finally, you start the option bytes load operation using :

HAL_FLASH_OB_Launch(); 

This should help you program your option bytes directly into your code.

Best regards,

Florian LR

Pavel A.
Evangelist III

Ask on the Segger J-Flash forum, perhaps they have some utility for STM32 option bytes.

Thanks for the response!

Unfortunately our board won't boot on power up unless the option bytes are set correctly because there is a pull up on the boot pin.

I could probably add the code as you described and somehow start the firmware using the debugger but I was looking for a way to directly set the option bytes using the debugger.

Are there any suggestions on how to set the option bytes with any generic debugger?

The STM32 model isn't mentioned

If you have serial port connectivity, perhaps use the system loader, see AN2606 for pins, AN3155 for protocol

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Thanks for the response!

I didn't mention the STM32 model on purpose because the problem is generic and independent to the exact controller.

Unfortunately there is no serial port connectivity on the board.

In future designs perhaps consider getting some connectivity per AN2606 so you can establish test station connectivity with a low cost, low complexity interface. Pins for a UART, NRST, BOOT0 can be facilitated by Test Points, Edge Castellations, or break-off sections of board when separated from panel.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
PereM
Associate

“Hello @EStei.3 ,

I think it could be done as follows by inserting the option bytes into the hexadecimal file based on the source file and the linker file.
To do this, the linker script (.ld) is modified by adding a new memory block and a new segment. Something like this:

 

/* Memories definition */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 112K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K
OPTION (rw) : ORIGIN = 0x40022020, LENGTH = XX
}

 

where XX refers to the number of option bytes that the microcontroller has (in my case, 84). Option bytes address in my case is 0x40022020.

 

.option_array (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
{
. = ALIGN(4);
_soption_array = .; /* define a global symbol at bss end */
*(.option_array)
(.option_array)
. = ALIGN(4);
_eoption_array = .; /* define a global symbol at bss end */
} >OPTION

 

And in the program code, this section is referenced, where an array is added like this:

 

attribute((used, section(".option_array"))) const uint32_t option_bytes[XX/4] =
{
FLASH_OPTR_PB4_PUPEN | FLASH_OPTR_IRHEN | FLASH_OPTR_NRST_MODE | FLASH_OPTR_nBOOT0 | FLASH_OPTR_CCMSRAM_RST | FLASH_OPTR_SRAM_PE | FLASH_OPTR_nBOOT1 | FLASH_OPTR_nRST_SHDW | FLASH_OPTR_nRST_STDBY | FLASH_OPTR_nRST_STOP | FLASH_OPTR_IWDG_SW | FLASH_OPTR_WWDG_SW | FLASH_OPTR_IWDG_STDBY | FLASH_OPTR_IWDG_STOP | FLASH_OPTR_BOR_LEV_0 | 0xAA,
0xffffffff,
0x7fff0000,
0xff00ffff,
0xff00ffff,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
FLASH_SEC1R_BOOT_LOCK | FLASH_SEC1R_SEC_SIZE1 };

 

The numerically entered values are the ones previously read from the microcontroller.
Now you just need to build the project so that the generated .hex file includes the option bytes at its address

Hi @PereM,
thanks for your response!
To be honest my post was posted 1,5 years ago, so I don't really remember our solution but we had another HW cycle anyway so think we simply changed the pinout.
Just out of curiosity, did you already test this with a board that has a pull up on the boot pin?
And what about unlocking the option btyes?
I thought this would be necessary. Probably ST-Link would do that automatically but for example J-Link won't.

@Tesla DeLorean sorry, I must have missed your response.
Unfortunately most of the time hardware is designed by another department and communication is chronically suboptimal...
Especially when it comes to things like an additional UART or simply some free pins routed to any kind of debug connector. Seems like debugging is something HW designers are likely not to have in mind.


For anyone, especially HW designers, reading this I can highly support @Tesla DeLorean suggestion.
An additional UART  and some unused pins mapped to a debug interface or at least test points can save a huge amount of time for debugging. Seen that many times across several companies.
With the mentioned HW cycle we actually added a UART as well.

BR

Hi @EStei.3 ,

On our board, the boot pin was connected to the CAN_RX signal.

Sorry, but for now we have not been able to program the option bytes; we have only managed to insert them into the .hex file.

To program them at the factory, STM32_Programmer_CLI.exe is used with the -ob option and ST-LINK v3.0.