on 2025-09-23 5:42 AM
The readout protection (RDP) is a security feature that protects flash memory from any unauthorized access. This protection notably prevents an external debugger from reading or modifying the memory content, which is crucial for safeguarding sensitive code and data.
The readout protection is activated by setting the RDP option byte. Once the RDP level is changed, a system reset is necessary for the new configuration to take effect. When the RDP is set to level 1, this means that if debugger access is detected, the flash memory is locked, preventing any access, even by the core. To regain access to the flash and allow code execution, a full Power-on reset (POR) is required.
However, in some applications, performing a POR can be restrictive or impossible.
This guide explains how to change the readout protection (RDP) level without performing a power-on reset (POR).
The software used in this article are:
The aim of this section, firstly, is to remove the mass storage capability of the embedded STLINK. When activating the RDP level the mass storage is detected as an interruption and the flash is locked. Secondly, check the blinking LED code example (attached at the end of this article as LED_Blinking.7z.)
1. Click on [Firmware upgrade]
2. Click on [Open in update mode] and select [STM32 Debug + VCP]
3. Click on [Upgrade]
4. Click on [Connect] to connect the board
5. Download the extractable file attached at the bottom of the article and add the LED_Blinking.bin as shown in the figure below
6. Open Tera Term and configure it to check the LED status
7. Remove the debugger link by removing CN2 ST-LINK jumpers on the Nucleo board, press the reset button, and we can see the led blinking and this message in Tera Term
The aim of this part is to change the RDP level by entering to standby mode and without power-on reset.
1. Open the attached project using the STM32CubeIDE toolchain
2. Uncomment "#define ACTIVATE_RDP 1" and "#define USE_STANDBY" line in the main.c to run the code
#ifdef ACTIVATE_RDP
if(HAL_FLASH_Unlock() == HAL_OK) { //Unlock the flash
if (HAL_FLASH_OB_Unlock() == HAL_OK) { //Unlock the options bytes
FLASH_OBProgramInitTypeDef pOBInit;
HAL_FLASHEx_OBGetConfig(&pOBInit);//Get the configuration of the options bytes
if (pOBInit.RDPLevel != OB_RDP_LEVEL_1) { //Check the curret RDP level
printf("\r\n*--------> RDP Level 0 \r\n");
pOBInit.OptionType = OPTIONBYTE_RDP; //Program option byte
pOBInit.RDPLevel = OB_RDP_LEVEL_1; //Program option byte
HAL_FLASHEx_OBProgram(&pOBInit); //Program option byte
#ifndef USE_STANDBY
printf("\r\n*--------> HAL_FLASH_OB_Launch \r\n");
HAL_FLASH_OB_Launch();
printf("\r\n*--------> HAL_FLASH_OB_Launch finished \r\n");
#else
__HAL_RCC_PWR_CLK_ENABLE();
HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 36, RTC_WAKEUPCLOCK_RTCCLK_DIV16); // Program the RTC
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
printf("\r\n*--------> Go to standby \r\n");
HAL_PWR_EnterSTANDBYMode(); //Enter standby mode
#endif
} else {
printf("\r\n*--------> RDP Level 1 \r\n");
}
HAL_FLASH_OB_Lock();
}
HAL_FLASH_Lock();
}
#endif
3. Right-click on LED_Blinking project to modify its properties
4. Select [Convert to binary file(-O binary)] to create a binary file as shown in the figure below
4. Build the project
5. Add the new binary and click on [Start Programming] in STM32CubeProgrammer
6. On Nucleo-L456RG, remove the debugger link CN2 ST-LINK jumper and press the reset button
You can see in the Tera Term that the RDP level is changing by transition to standby
To be able to achieve an RDP level change without POR, you need to do the transition to a standby state and then wake-up with RTC.