Skip to main content
gfxfloro
Associate III
January 10, 2023
Question

Launching option bytes bricks the MCU

  • January 10, 2023
  • 8 replies
  • 3484 views

Hi,

I am trying to set the write protection on my STM32G071 uC. I found the explanation here on how to do it in code. However once HAL_FLASH_OB_Launch is executed, the debugger loses connection and the uC is bricked. I tried to get a connection again via ST-Link Utility and STM32CubeProgrammer to no avail. I've tried it on a Nucleo and on a custom board.

Below you can see my code, it really isn't much different from the one on the site.

 HAL_Init();
 
 /* USER CODE BEGIN Init */
 
 /* USER CODE END Init */
 
 /* Configure the system clock */
 SystemClock_Config();
 
 /* USER CODE BEGIN SysInit */
 
 /* USER CODE END SysInit */
 
 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_USART2_UART_Init();
 /* USER CODE BEGIN 2 */
 
 /* unlock flash and option bytes*/
 HAL_FLASH_Unlock();
 HAL_FLASH_OB_Unlock();
 
 /* read current config and set WRP settings */
 HAL_FLASHEx_OBGetConfig(&ob);
 
 ob.OptionType = OPTIONBYTE_WRP;
 ob.WRPArea = OB_WRPAREA_ZONE_A;
 ob.WRPStartOffset = 14;
 ob.WRPEndOffset = 15;
 
 
 if ( HAL_OK != HAL_FLASHEx_OBProgram(&ob) )
 {
 HAL_FLASH_OB_Lock();
 HAL_FLASH_Lock();
 for(;;);
 }
 
 HAL_FLASH_OB_Launch();
 
 HAL_FLASH_OB_Lock();
 
 HAL_FLASHEx_OBGetConfig(&ob);

Anybody have an idea what could be going wrong?

This topic has been closed for replies.

8 replies

ST Employee
January 10, 2023

Dear gfxfloro,

I think the code you use is missing a condition on actual OB prior running the programming.

If the option you desire is already set, running the OBprogram will rewrite the Flash (which affect its long term reliability if done more than its max cycle value) and will trig also a reset by the Launch command to apply new config. So consequently you modify at every boot the OB and execute the Launch command which will restart your system and run again this sequence.

In addition I suppose you might try to unplug or reset your code due to the fact that it does not exit this loop and if this happen during the period you erase/program your option byte, you might end up with OB configured to make a device which is fully protected and seems bricked.

I hope it might help to modify the code. The page you checked include such a check on example of 1.2 Modifying Multiple User Options simultaneously for example.

Thank you and regards,

Antoine

gfxfloro
gfxfloroAuthor
Associate III
January 10, 2023

This code was just to test the mechanism. I placed breakpoints before and after, so the intention was not to have it run every time I start the uC, just this once. I forgot to include the while(1), which cubemx generates so it shouldn't loop through the option byte programming.

The debugger loses connection right after HAL_FLASH_OB_Launch. I know this causes a reset, but if that happened I would have run into the breakpoint at the start of the program.

Since I'm not getting a connection even when connected to STM32CubeProgrammer I think the uC must be bricked. If all of the sectors were write protected, I would at least be able to read the option bytes.

ST Employee
January 10, 2023

"If all of the sectors were write protected, I would at least be able to read the option bytes."

This statement is true.

But I am really not sure you would stop on breakpoint after an OBLaunch. The debug access port is kept under system reset, and it allows you to stop on breakpoint by hitting RST button of your IDE, but I think the OBLAunch must reset this too to grant that you don't have intrusion after setting another RDP level for example etc...

gfxfloro
gfxfloroAuthor
Associate III
January 10, 2023

So if it does not hit a breakpoint, the program would have started again and then get stuck in the while loop after programming again. At this point I should have been able to get a connection again right?

Tesla DeLorean
Guru
January 10, 2023

Do NOT USE ST-LINK Utilities for NEWER parts, the application has been deprecated for several years and is more likely to break them.

The STM32 Cube Programmer is the only thing to try.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
ST Employee
January 10, 2023

It's hard to answer without seeing where is located your while loop exactly and which condition it has. But if it's after the OBLaunch line 39 it will never be reached.

gfxfloro
gfxfloroAuthor
Associate III
January 10, 2023

Right so I thought if the option bytes were already programmed as they were, HAL_OK would not be returned and I would catch that with the for(;;), however after looking into the function that does not seem to be the case.

Right now the program seems to be looping through the programming and launching of the option bytes. I guess there's no way to recover that if its restarting a dozen times a second. Unfortunately I also dont have access to the Boot pins for the ROM BL.

Below is my entire main:

int main(void)
{
 /* USER CODE BEGIN 1 */
 
 /* USER CODE END 1 */
 
 /* MCU Configuration--------------------------------------------------------*/
 
 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();
 
 /* USER CODE BEGIN Init */
 
 /* USER CODE END Init */
 
 /* Configure the system clock */
 SystemClock_Config();
 
 /* USER CODE BEGIN SysInit */
 
 /* USER CODE END SysInit */
 
 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_USART2_UART_Init();
 /* USER CODE BEGIN 2 */
 
 /* unlock flash and option bytes*/
 HAL_FLASH_Unlock();
 HAL_FLASH_OB_Unlock();
 
 /* read current config and set WRP settings */
 HAL_FLASHEx_OBGetConfig(&ob);
 
 ob.OptionType = OPTIONBYTE_WRP;
 ob.WRPArea = OB_WRPAREA_ZONE_A;
 ob.WRPStartOffset = 14;
 ob.WRPEndOffset = 15;
 
 
 if ( HAL_OK != HAL_FLASHEx_OBProgram(&ob) )
 {
 HAL_FLASH_OB_Lock();
 HAL_FLASH_Lock();
 for(;;);
 }
 
 HAL_FLASH_OB_Launch();
 
 HAL_FLASH_OB_Lock();
 
 HAL_FLASHEx_OBGetConfig(&ob);
 
 /* USER CODE END 2 */
 
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
 /* USER CODE END WHILE */
 
 /* USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */
}

ST Employee
January 10, 2023

Yes I am afraid there is not much to do on this part if you already tried to connect through cube programmer and it failed. Sorry, I will try to make this more clear in the knowledge base you checked in parallel to be sure no one face this in future too.

regards,