cancel
Showing results for 
Search instead for 
Did you mean: 

Launching option bytes bricks the MCU

gfxfloro
Senior

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?

8 REPLIES 8
Antoine Odonne
ST Employee

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

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.

Antoine Odonne
ST Employee

"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
Senior

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?

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
Up vote any posts that you find helpful, it shows what's working..
Antoine Odonne
ST Employee

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.

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 */
}

Antoine Odonne
ST Employee

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,