Skip to content

Conversation

fouge
Copy link
Contributor

@fouge fouge commented Jun 20, 2025

when writing the read-back protection option byte, the stm32 target must go through a power-on reset to reload the option bytes correctly, which is achieved by going into Standby or Shutdown mode.

using the OBL bit locks the microcontroller in a bad state waiting for a full power cycle, this buggy behavior has been added in that PR.

Instead of force-reloading when writing any option byte, it's now performed when re-locking the option bytes, and if OBL bit is defined. Locking doesn't apply when changing the RDP level, since it goes through a POR, so this solution allows to set and reload any option byte correctly.

see extract from stm32g4xx datasheet:

image

a few concerns:

  • the user must have a wakeup source configured for the microcontroller to reset, this can be through the reset pin, iwdg, rtc alarm or wakeup pins. ideally we should have a way to ensure this.
  • to fully work, the debugger must be detached, which can be achieved by these lines:
         /* Clear the low-power debug bits */
         if (DBGMCU->CR & (DBGMCU_CR_DBG_SLEEP | DBGMCU_CR_DBG_STOP | DBGMCU_CR_DBG_STANDBY)) {
             LOG_WRN("Clearing low-power debug bits before RDP change");
             DBGMCU->CR &= ~(DBGMCU_CR_DBG_SLEEP | DBGMCU_CR_DBG_STOP | DBGMCU_CR_DBG_STANDBY);
         }
    

do not force option byte reloading in the write function because RDP
byte cannot be reloaded that way: it needs a POR through Standby mode.
when FLASH_CR_OBL_LAUNCH is defined, use it to force-reload option bytes
directly in the locking function.

Signed-off-by: Cyril Fougeray <[email protected]>
@fouge fouge force-pushed the fouge/stm32-rdp-option-byte-runtime branch from 51b4abc to 79d7d57 Compare June 20, 2025 09:47
@erwango erwango requested a review from JordanYates June 20, 2025 09:50
for the read-back protection option byte to be successfully reloaded at
runtime, a power-on reset can be achieved by putting the microcontroller
into Standby mode and waking up from that mode.

Signed-off-by: Cyril Fougeray <[email protected]>
@fouge fouge force-pushed the fouge/stm32-rdp-option-byte-runtime branch from 79d7d57 to 57a3135 Compare June 20, 2025 11:02
@sonarqubecloud
Copy link

@github-actions
Copy link

This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time.

Comment on lines +330 to +331
/* enter SLEEP mode : WFE or WFI */
k_cpu_idle();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/* enter SLEEP mode : WFE or WFI */
k_cpu_idle();
__disable_irq();
__SEV();
__WFE();
__WFE();

otherwise entry in low-power state is not guaranteed (and even this sequence may not be 100% safe)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should have a STM32 SoC helper function to go into Standby mode.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should go in common flash code if anywhere; PM needs something else (we don't want to force entry in low-power mode while doing PM, unlike here)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that is function should never return unless it fails (to reach SoC standby mode). I think the function declaration inline description should reflect this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True too, I guess it should be FUNC_NORETURN + end with an infinite loop

Comment on lines 21 to 23
#include <stm32_ll_system.h>
#include <stm32l4xx_ll_cortex.h>
#include <stm32l4xx_ll_pwr.h>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why adding these header files?

}

/* Force the option byte loading */
regs->CR |= FLASH_CR_OBL_LAUNCH;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Option bytes other than RDP in OTPR require OBL_LAUNCH or power reset to be loaded.
I think setting here OBL_LAUNCH is still applicable while flash_stm32_set_rdp_level() can still force a power reset (as proposed in next commit).

/* Force the option byte loading before locking */
if (enable) {
regs->CR |= FLASH_CR_OBL_LAUNCH;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this change makes sense but would deserve a dedicated commit, aside proposing changes in flash_stm32_option_bytes_write().

Comment on lines +330 to +331
/* enter SLEEP mode : WFE or WFI */
k_cpu_idle();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should have a STM32 SoC helper function to go into Standby mode.

@erwango
Copy link
Member

erwango commented Oct 20, 2025

@fouge Do you plan to push this PR further ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants