Skip to main content
Visitor
August 5, 2026
Question

STM32L552ZE — -rdu at RDP Level 0 with TZEN=1 leaves the device with secure debug permanently disabled

  • August 5, 2026
  • 1 reply
  • 30 views

On an STM32L552ZE with TZEN=1, RDP=0xAA (Level 0) and BOOT_LOCK=1, the STM32CubeProgrammer command -rdu reported success while explicitly stating that no option byte was modified. From that command onward the device is permanently inaccessible: DAUTHSTATUS shows secure invasive and non-invasive debug disabled, every FLASH register (secure and non-secure alias) fails even on read, and the documented RDP regression path (RDP=0xBBRDP=0xAA TZEN=0x0) can no longer be executed because option byte programming requires those registers.

We would like to understand whether this is expected behaviour, and whether any recovery path exists.

Hardware and tools

Item Value
Device STM32L552ZE-Q on NUCLEO-L552ZE-Q
Device ID 0x472, Revision ID Rev Z (DBGMCU_IDCODE = 0x20016472)
ST-LINK onboard, firmware V2J48M35 (also reproduced with V2J47M34)
STM32CubeProgrammer 2.23.0 (also reproduced with 2.22.0)
Supply 3.26–3.27 V, separate USB port
BOOT0 (PH3) tied to VCC during all operations described below

Option byte state before the failing command

Read successfully via the secure alias 0x50022040 (40 bytes):

 
RDP          : 0xAA (Level 0, no protection)
TZEN : 0x1
BOOT_LOCK : 0x1
HDP1EN : 0x1 HDP1_PEND : 0x22
SECWM1_PSTRT : 0x0 SECWM1_PEND : 0x7F
SECWM2_PSTRT : 0x7F SECWM2_PEND : 0x0
IWDG_SW : 0x0 (hardware independent watchdog)
nSWBOOT0 : 0x1 nBOOT0 : 0x1

Flash was empty at this point (a previous -e all reported Mass erase successfully achieved). With IWDG_SW=0 and no firmware to refresh the watchdog, the device resets roughly every 512 ms. With BOOT_LOCK=1 the BOOT0 pin has no effect — BL Version in the CubeProgrammer banner changed from 0x92 (ROM bootloader running) to 0x0 once BOOT_LOCK was set.

Sequence

All commands used -c port=SWD mode=HotPlug, BOOT0 tied to VCC, full power cycle between steps.

Step 1 — attempt to escalate RDP as the first half of the documented regression:

 
STM32_Programmer_CLI.exe -c port=SWD mode=HotPlug -ob RDP=0xBB

Result: programming was attempted, verification failed. Option bytes remained readable via 0x50022040 afterwards.

 
Error: Expected value for Option Byte "rdp": 0xBB, found: 0xAA
Error: Option Byte Programming failed Or modified by application after OB_LAUNCH

Step 2 — readout unprotect:

 
STM32_Programmer_CLI.exe -c port=SWD mode=HotPlug -rdu

Result: reported as successful, with an explicit statement that nothing was changed:

 
Warning: Option Byte: rdp, value: 0xAA, was not modified.
Warning: Option Bytes are unchanged, Data won't be downloaded

From this point on the device is inaccessible. In all subsequent invocations CubeProgrammer switches from the secure option byte alias 0x50022040 (40 bytes) to the non-secure alias 0x40022040 (32 bytes) and fails. This transition is visible across our logs: 12 consecutive runs before Step 2 used 0x50022040 exclusively; every run after it uses 0x40022040.

Resulting state — register level evidence

Reads that succeed (non-secure address space, debug domain):

Address Register Value
0xE0044000 DBGMCU_IDCODE 0x20016472
0xE0044008 DBGMCU_APB1FZR1 writable — wrote 0x00001000, reads back 0x00001000
0xE000EDFC DEMCR writable — wrote 0x00000001, reads back 0x00000001
0xE000EDF0 DHCSR 0x03080000S_LOCKUP=1, S_RESET_ST=1, C_DEBUGEN=0
0xE000EFB8 DAUTHSTATUS 0x000000AF

DAUTHSTATUS = 0xAF decodes to:

Field Bits Value Meaning
NSID [1:0] 0b11 non-secure invasive debug enabled
NSNID [3:2] 0b11 non-secure non-invasive debug enabled
SID [5:4] 0b10 secure invasive debug disabled
SNID [7:6] 0b10 secure non-invasive debug disabled

Reads that fail with Error: failed to read the requested memory content:

Address Register
0x50022040 FLASH_OPTR, secure alias
0x40022040 FLASH_OPTR, non-secure alias
0x5002204C FLASH_SECBOOTADD0R (contains BOOT_LOCK)

Command level failures:

 
-ob displ            -> Error: Uploading Option Bytes bank: 0 failed
Error: Initializing the Option Bytes failed
-e all -> Error: Mass Erase : Config SAU Failed !
mode=UR -> Error: ST-LINK error (DEV_TARGET_NOT_HALTED)
mode=UR --hardRst -> Error: ST-LINK error (DEV_TARGET_NOT_HALTED)
mode=Normal -> Error: ST-LINK error (DEV_TARGET_NOT_HALTED)
mode=Powerdown -> Error: ST-LINK error (DEV_TARGET_NOT_HALTED)

DEV_TARGET_NOT_HALTED is consistent with SID being disabled: the core is in secure lockup (S_LOCKUP=1, forced by BOOT_LOCK=1 booting into erased flash), and halting a core executing in secure state requires secure invasive debug.

We also armed DEMCR.VC_CORERESET together with DBGMCU_APB1FZR1.DBG_IWDG_STOP to catch the core at the reset vector and freeze the watchdog. Both bits read back correctly and persist across the watchdog resets, but the vector catch never takes effect because DHCSR.C_DEBUGEN cannot be made to stick — consistent with the same SID restriction.

Why we believe this is not the documented behaviour

RDP Level 1 does not normally block option byte programming — that is precisely why the RDP=0xBBRDP=0xAA TZEN=0x0 regression is the documented way out of TrustZone, and we have used it successfully many times on this same board type. Here the FLASH registers cannot even be read, which is a stronger restriction than Level 1.

Two readings seem possible and we cannot distinguish them, because FLASH_OPTR is unreadable:

  1. RDP is now Level 2 — which we never requested; no command in the sequence writes 0xCC.
  2. -rdu initiated an RSS-based TZEN/RDP regression that did not complete, leaving the device in a state where secure debug is closed while RDP is not at a level from which regression is offered.

In either case, the command that caused it reported success and simultaneously reported that no option byte had been modified.

Questions

  1. What does -rdu do on an STM32L552 with TZEN=1 and RDP=0xAA, given that it reports Option Bytes are unchanged? Is it expected to alter the debug authentication state?
  2. Is there any supported recovery for a device with DAUTHSTATUS showing SID/SNID disabled and FLASH_OPTR unreadable — for example a specific RSS entry sequence, or a factory procedure?
  3. Should -rdu be rejected, or should it warn, when the device is already at RDP Level 0? Running it there has no useful effect by its own report, yet it appears to be destructive.
  4. For product design: with IWDG_SW=0 (hardware watchdog) and BOOT_LOCK=1, a device whose firmware stops refreshing the watchdog resets every ~512 ms and BOOT0 has no effect, so no programmer operation longer than that window can complete. Is there a recommended recovery route for this combination, which we intend to use in production?

1 reply

Frantz LEFRERE
ST Technical Moderator
August 5, 2026

Hello Chris,
I would suggest to have a look in the video below.
In RDP1, with Trustzone enable, you can only connect to the target if the core is in non-secure state.
So if there is no code in the flash, at reset the core is in secure state.
A workaround is to activate the embedded bootloader ( this is explain in the video).
But in your case, with BOOTLOCK to 1, the device will noot at SECBOOTADD0 ( probably not the embedded bootloader address, I guess). Unfortunately, there is no way to recover.
Best regards,

Frantz 

https://www.youtube.com/watch?v=4UW8lnbV1cA&list=PLnMKNibPkDnGxKqGyLbiGygmlrvISIBIT&index=2