cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G031K6 - self-locking procedure and cannot reach MCU anymore through SWD

RZub
Associate II

Hello,

Having an issue with STM32G031K6Ux MCU. Below added function that checks Options bytes, and if needed - makes changes (power re-cycle is needed after it).

This function CheckOptionBytes() works OK on several MCU's. But on this MCU we have an issue, that sometimes after flashing - we cannot reach MCU anymore, and we are thinking that it locks to Readout Protection Level 2. But it's random. We can reflash the same MCU N amounts, and then it locks in a random moment.

I cannot see anything on Errata about it. Only about the BOOT0 pin issue on RDP1 (2.1.3 section), but it's not our case, we are not using it and it will not block reaching MCU again through SWD.

Does anyone see a possible issue with the function or know another possible cause?

Thank You!

Code below:

static void CheckOptionBytes(void)
{
	FLASH_OBProgramInitTypeDef OBInit =
	{ 0 };
 
	/* Read Option bytes */
	HAL_FLASHEx_OBGetConfig(&OBInit);
 
	/* Check BOR, BOOT0 and RDP Option Bytes */
	if (((OBInit.USERConfig & OB_BOR_ENABLE) != OB_BOR_ENABLE)
			|| ((OBInit.USERConfig & FLASH_OPTR_nBOOT_SEL) != OB_BOOT0_FROM_OB)
			|| ((OBInit.USERConfig & FLASH_OPTR_nBOOT0) != OB_nBOOT0_SET)
			|| (OBInit.RDPLevel != OB_RDP_LEVEL_1))
	{
		/* Lock */
		OBInit.OptionType = (OPTIONBYTE_USER | OPTIONBYTE_RDP);
		OBInit.USERType = (OB_USER_BOR_EN | OB_USER_BOR_LEV | OB_USER_nBOOT_SEL | OB_USER_nBOOT0);
		OBInit.USERConfig = (OB_BOR_ENABLE | OB_BOR_LEVEL_FALLING_2 | OB_BOR_LEVEL_RISING_3 | OB_BOOT0_FROM_OB | OB_nBOOT0_SET);
 
		OBInit.RDPLevel = OB_RDP_LEVEL_1;
 
		/* Unlock the FLASH & Option Bytes Registers access */
		HAL_FLASH_Unlock();
		HAL_FLASH_OB_Unlock();
 
		/* Clear error programming flags */
		__HAL_FLASH_CLEAR_FLAG(FLASH_SR_ERRORS);
 
		/* Program Option bytes */
		if (HAL_FLASHEx_OBProgram(&OBInit) == HAL_OK)
		{
			/* Change OB and Reset MCU */
			HAL_FLASH_OB_Launch();
		}
 
		/* Lock */
		HAL_FLASH_OB_Lock();
		HAL_FLASH_Lock();
	}
}

Update.

Using:

  • STM32Cube FW_G0 V1.5.0,
  • STM32CubeIDE 1.7.0
  • GNU11, GNU Tools for STM32 (9-2020-q2-update)
  • Configuration: Release (Optimize for Size (-Os))
5 REPLIES 5
MM..1
Chief II

You not first , that report this, then maybe in G HAL is some bug. Try debug this or use LL.

RZub
Associate II

Second update.

The second issue - might be related somehow to the first issue?

We deleted in this function everything related to the Readout protection. Left only other OB settings. After flashing - MCU is unprotected.

In the production line, we are using STM32 ST-LINK CLI v3.5.0.0 (tried with v3.6.0.0 too). After flashing firmware and testing functionality - everything works ok. After setting the RDP=1 with the same CLI, the firmware stops working (do not boot or hang somewhere).

BUT. If you set Readout protection with ST-Link Utility (v4.6.0.0) to Level 1 or with STM32CubeProgrammer GUI (or STM32_Programmer_CLI) - firmware is working. 

We understand that ST-LINK CLI v3.5.0.0 is replaced by STM32_Programmer_CLI, but what's the difference between setting OB RDP to level 1? What makes MCU stop working using older CLI?

We did not have any issues with the F0, and L4 series, but with the new G0 - a lot of issues.

STM32 ST-LINK CLI v3.5.0.0:

-c FREQ=4000 SN=55FF71066767564833581967 -P "C:\path\noRDP.hex" 0x08000000 -V -OB RDP=1

STM32_Programmer_CLI:

-c port=swd SN=55FF71066767564833581967 -rdu -q -w "C:\path\noRDP.hex" -ob rdp=1

Antoine Odonne
ST Employee

Hello,

I don't have much clues here. Not clear to me which state the device is in when locks.

Do you have some means to recover it? Or you then continue testing on another platform?

I am wondering how the RDP lvl 1 check is performed as multiple value can define it.

Note: 0xAA: Level 0, read protection not active

0xCC: Level 2, chip read protection active

Others: Level 1, memories read protection active

Which could explain a difference in between Cube programmer and CLI, but it's not clear how.

Regarding known problematic around OPT bytes, we state following caution message in RM:

Caution: Upon an option byte programming failure (for any reason, such as loss of power or a reset

during the option byte change sequence), the mismatch values of the option bytes are

loaded after reset. Those mismatch values force a secure configuration that might

permanently lock the device. To prevent this, only program option bytes in a safe

environment – safe supply, no pending watchdog, and clean reset line.

Best regards,

Antoine

Hi @Antoine Odonne​ 

yes, we are changing MCU - resoldering. We did not find a way to recover.

The drivers are reading RDP correctly:

/**
  * @brief  Return the FLASH Read Protection level.
  * @retval FLASH ReadOut Protection Status:
  *         This return value can be one of the following values:
  *           @arg @ref OB_RDP_LEVEL_0 No protection
  *           @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
  *           @arg @ref OB_RDP_LEVEL_2 Full chip protection
  */
static uint32_t FLASH_OB_GetRDP(void)
{
  uint32_t rdplvl = READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP);
 
  if ((rdplvl != OB_RDP_LEVEL_0) && (rdplvl != OB_RDP_LEVEL_2))
  {
    return (OB_RDP_LEVEL_1);
  }
  else
  {
    return rdplvl;
  }
}

What do You mean by pending watchdog? Where OP should be changed: before or after watchdog initialization? What are recommendations from ST?

Maybe I missed information in the datasheet about how much time it takes to change OB. Is it a long process?

Thank You.

Antoine Odonne
ST Employee

Hello,

This "caution" paragraph is an extract from Reference Manual RM0444. If watchdog is counting prior you start OB programing, it might not be refreshed on time and trig a reset during this window. That would potentially corrupt the option bytes and lead to a device in a locked state.

I would suggest to perform OB update before the watchdog initialization then.

Option byte change time is not directly documented in DS, but you can retrieve this info from Flash characteristics (OB are stored in Flash system memory). Program would be fast cca 85us, but erasure would be longer 22ms.

I don't expect your issue to be related to watchdog however. It would be systeatic and changing programmer would have no impact.

Best regards,

Antoine