2021-05-21 03:19 PM
Hello,
I am looking to be able to do in-the-field firmware upgrades with the STM32G071 board. I have used the STMCubeProg tool to be able to modify the nBOOT0 user bit with the ST-Link built into the NUCLEO board.
What I am looking to do is
The issues are that I can't figure out how to modify the nBOOT0 bit in the firmware. Also, I am unsure if my STM32G071 will be able to flip its nBOOT0 pin back itself after the firmware update.
I have read through the AN2606 and AN3155 and cannot find an answer to my question. Everything points back to the STM32Prog tool which I don't want to have to rely on.
Solved! Go to Solution.
2021-05-26 03:58 PM
Hello,
I understand the theory of setting the nBOOT0 user bit in software, but the examples I have found do not seem to work. I suspect I am missing a basic step here. From what I understand, I need to:
unlock the flash
unlock the Option Bytes flash
Program the Option Bytes
lock the Option Bytes flash
lock the flash
reset the system
Currently, this is what I have. I have confirmed that all of the HAL function calls are returning HAL_OK, I just removed the error checking to reduce the code size.
uint8_t startBootloader(){
FLASH_OBProgramInitTypeDef ob_cfg;
HAL_FLASHEx_OBGetConfig(&ob_cfg);
/*
From ST AN2606, pattern 11 Only nBOOT0 bit needs to change.
nBOOT0(bit) == 0 for bootloader therefore OB_nBOOT0_RESET
*/
ob_cfg.OptionType = OPTIONBYTE_USER;
ob_cfg.USERType = OB_USER_nBOOT0;
ob_cfg.USERConfig = OB_nBOOT0_RESET;
// of any ifs are true, throw error.
HAL_FLASH_Unlock();
HAL_FLASH_OB_Unlock();
HAL_FLASHEx_OBProgram(&ob_cfg);
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
return 0;
}
If I do another function call of:
HAL_FLASHEx_OBGetConfig()
After the HAL_FLASH_Lock, I find that the option bytes has not changed.
When I try to do the function call HAL_FLASH_OB_Launch(void) To reset the device, it returns with HAL_ERROR.
Am I missing a step?
2021-05-26 04:23 PM
Sequence should be:
HAL_FLASH_Unlock();
HAL_FLASH_OB_Unlock();
HAL_FLASHEx_OBProgram(&ob_cfg);
HAL_FLASHEx_OB_Launch();
The last function causes a reset which makes the option bytes active. It doesn't matter what code you have after this because the mcu resets, but I would still monitor the return value.
The reference manual goes over the sequence needed to perform these steps. You can also look at the source to find out what HAL is doing. For example:
/**
* @brief Launch the option byte loading.
* @retval HAL Status
*/
HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
{
/* Set the bit to force the option byte reloading */
SET_BIT(FLASH->CR, FLASH_CR_OBL_LAUNCH);
/* We should not reach here : Option byte launch generates Option byte reset
so return error */
return HAL_ERROR;
}
It makes sense that this returns HAL_ERROR. The first statement, which would normally reset the chip, doesn't work because the option bytes are locked.
If you find checking for return values a pain, consider defining a macro:
#define RUN_HAL(x) if ((x) != HAL_OK) {while (1);}
...
RUN_HAL(HAL_FLASH_Unlock());
At least that way you have a chance of catching errors when they happen, instead of having to hunt them down afterwards.
2021-05-26 04:28 PM
That was it, thank you.