cancel
Showing results for 
Search instead for 
Did you mean: 

How to read the boot enabled/disabled bits in the user configuration option bytes of an STM32H7?

mwb
Associate III

Hi all,

in the STM32CubeProgrammer section Option bytes (OB) there's one group called "user configuration". This group list the two checkboxes BCM4 and BCM7 to enable/disable booting each core. I assume that there are two bits in some R/W configuration register of the option bytes.

How do I (read-)access these two bits from code running on the MCU, if possible at all?

I was trying to find it in the reference manual (e.g. FLASH_OPTSR_CUR) but I need some more guidance here.

Best regards,

Matthias

3 REPLIES 3
Petr DAVID
ST Employee

Hello @mwb​ ,

these bits are part of SYSCFG_UR1 register please check the reference manual rm0399. If you have in your code include CMSIS Device Peripheral Access Layer Header File(for example stm32H745xx.h) you can easily write something like :

uint32_t registerValue=0;
registerValue= SYSCFG->UR1;

Regarding this topic of of BCM4 and BCM7 option bits you could find interesting Boot configuration chapter starting on page 143 and Hold boot function description on page 362 of RM0399. The register description itself is on page 600. These option bits also have strong connection to BOOT_C1 and BOOT_C2 bits from RCC global control register (RCC_GCR). I would also recommend to check this register description.

If I have answered your question and you have find my answer useful, please click on Select as Best. This will help other users with the same problem to find the solution faster!

mwb
Associate III

Hello @Petr DAVID​,

thank you for your reply and your help. That pretty much sums up what I was looking for.

Some additional details about my use scenario: I have deactivated CM4 boot in my dual-core configuration (using STM32CubeProgrammer) whereas colleagues haven't done so.

This led to runtime issues when debugging the same code base as there's some auto-generated code:

      /* Wait until CPU2 boots and enters in stop mode or timeout*/
      timeout = 0xFFFF;
      while((__HAL_RCC_GET_FLAG(RCC_FLAG_D2CKRDY) != RESET) && (timeout-- > 0));
      if ( timeout < 0 )
      {
      Error_Handler();
      }

When I execute this, I get trapped in the Error_Handler().

I tried to write a small workaround to get this working for both use scenarios: STM32H745 dual-core with enabled and disabled CM4.

  /* Check "hold boot function":
   * Only wait until CPU2 (Cortex-M4 core aka CM4) boots, if booting is enabled.
   * This is done by
   * - checking BCM4 bit ("Boot Cortex-M4") in SYSCFG user register 1 (SYSCFG_UR1),
   * - checking BOOT_C2 bit ("Allows CPU2 to boot") in RCC global control register (RCC_GCR).
   * If CPU2 is not enabled to boot, simply do not wait here.
   */
  if( (SYSCFG->UR1 & SYSCFG_UR1_BCM4_Msk) || (RCC->CR & RCC_GCR_BOOT_C2_Msk) )
  {
      /* Wait until CPU2 boots and enters in stop mode or timeout*/
      timeout = 0xFFFF;
      while((__HAL_RCC_GET_FLAG(RCC_FLAG_D2CKRDY) != RESET) && (timeout-- > 0));
      if ( timeout < 0 )
      {
      Error_Handler();
      }
  }
  else
  {
      /* CPU2 is disabled to boot, add 'nop' instruction just for debugging purposes
       * (e.g. to allow setting a breakpoint here).
       */
      asm("nop;");
  }

I always get trapped in the else-clause now, even when I reactivate the CM4 boot using STM32CubeProgrammer - which I really do not understand. Any further help is much appreciated.

Thanks,

Matthias

Petr DAVID
ST Employee

Hello Matthias,

the problem is most likely happening, because the mentioned registers are part of SYSCFG and you need to first start the clock of the configuration controller in RCC if you would like to correctly read them out. If you will add line following line before the if statement it should work correctly:

 RCC->APB4ENR|=RCC_APB4ENR_SYSCFGEN;

Best regards,

Petr David