2022-01-18 02:14 AM
Currently I write locked the first few sectors of my STM32U575xx. However I would also like the unlock the write protection. Since both J-Link and the ST-Link cannot do this I thought about writing a small application and run it from RAM to reset the option bytes. This however does not work.
When I try to write the option bytes the status register returns `Option write error`. Does anyone has an idea on what I'm doing wrong? I previously locked pages 0 to 8, I thought I leave it unchanged. Changing this to the factory default however doesn't work.
The failure occurs on line 82.
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_ICACHE_Init();
/* USER CODE BEGIN 2 */
void disable_wr_protection(void);
disable_wr_protection();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/** Enable write protection on the bootloader region if not yet enabled
*/
void disable_wr_protection(void)
{
// Get FLASH_WRP_SECTORS write protection status
FLASH_OBProgramInitTypeDef option_bytes_init = {0};
option_bytes_init.WRPArea = OB_WRPAREA_BANK1_AREAA;
HAL_FLASHEx_OBGetConfig(&option_bytes_init);
uint32_t wrp_status = ((option_bytes_init.OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP)
&& (option_bytes_init.WRPLock == DISABLE);
// check if write protection is already enabled
if (wrp_status)
{
printf("wrp: write protection disabled\r\n");
return;
}
printf("wrp: disabling write protection on the bootloader sections\r\n");
// allow access to flash control registers and user flash
if (HAL_FLASH_Unlock() != HAL_OK)
// reset on failure, shouldn't happen
NVIC_SystemReset();
// allow access to option bytes sector
if (HAL_FLASH_OB_Unlock() != HAL_OK)
// reset on failure, shouldn't happen
NVIC_SystemReset();
// enable FLASH_WRP_SECTORS write protection
option_bytes_init.OptionType = OPTIONBYTE_WRP;
option_bytes_init.WRPStartOffset = 0;
option_bytes_init.WRPEndOffset = 8;
option_bytes_init.WRPLock = DISABLE;
if (HAL_FLASHEx_OBProgram(&option_bytes_init) != HAL_OK)
// reset on failure, shouldn't happen
NVIC_SystemReset();
// start the option bytes programming process
if (HAL_FLASH_OB_Launch() != HAL_OK)
// reset on failure, shouldn't happen
NVIC_SystemReset();
// prevent access to option bytes sector
if (HAL_FLASH_OB_Lock() != HAL_OK)
// reset on failure, shouldn't happen
NVIC_SystemReset();
// disable the flash option control register access (recommended to protect the option bytes against possible unwanted operations)
if (HAL_FLASH_Lock() != HAL_OK)
// reset on failure, shouldn't happen
NVIC_SystemReset();
// get FLASH_WRP_SECTORS write protection status
HAL_FLASHEx_OBGetConfig(&option_bytes_init);
wrp_status = ((option_bytes_init.OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP)
&& (option_bytes_init.WRPLock == DISABLE);
// check if FLASH_WRP_SECTORS write protection is disabled
if (wrp_status)
printf("wrp: write protection disabled\r\n");
else
printf("wrp: failed to disable write protection\r\n");
}
Related: https://community.st.com/s/question/0D53W00001JVhsxSAD/howto-reset-option-bytes-on-stm32u575xx
2022-01-18 02:24 AM
Oke although this might help someone else, I just found this:
Rules for modifying specific option bytes
Some of the option byte field must respect specific rules before being updated with new
values. These option bytes, as well as the associated constraints, are described below:
• UNLOCK option bits
– These bits can be set only when regressing from RDP level 1 to level 0.
So let's try it...
2022-01-18 02:56 AM
Changing the code to do this however doesn't work. I see the RAM being erased while single stepping and it seems the flash is erased as well, since my bootloader no longer boots but when I program the SRAM application again it still says the section is write protected and the RDP is set to level 1.
2022-01-26 07:18 AM
Oke I got it working, I forgot to reset the actual write protection:
/** This function checks if the lock bit is set and handles unlocking it
*/
static void disable_wrp_1(void)
{
FLASH_OBProgramInitTypeDef ob = {0};
ob.WRPArea = OB_WRPAREA_BANK1_AREAA;
HAL_FLASHEx_OBGetConfig(&ob);
uint32_t wrp_locked = ((ob.OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP)
&& (ob.WRPLock == ENABLE);
if (! wrp_locked)
return;
uint32_t rdp_set = (ob.RDPLevel != OB_RDP_LEVEL_0);
// allow access to flash control registers and user flash
if (HAL_FLASH_Unlock() != HAL_OK)
// reset on failure, shouldn't happen
NVIC_SystemReset();
// allow access to option bytes sector
if (HAL_FLASH_OB_Unlock() != HAL_OK)
// reset on failure, shouldn't happen
NVIC_SystemReset();
// check if we must set the RDP level to 1
if (! rdp_set)
{
// switch to RDP level 1
ob.OptionType = OPTIONBYTE_RDP;
ob.RDPLevel = OB_RDP_LEVEL_1;
// start the option bytes programming process
if (HAL_FLASHEx_OBProgram(&ob) != HAL_OK)
// reset on failure, shouldn't happen
NVIC_SystemReset();
// start the option bytes programming process
if (HAL_FLASH_OB_Launch() != HAL_OK)
// reset on failure, shouldn't happen
NVIC_SystemReset();
}
else
{
// let's disable the lock bit by resetting the RDP to 0 and disabling the bit
ob.OptionType = OPTIONBYTE_WRP | OPTIONBYTE_RDP;
ob.RDPLevel = OB_RDP_LEVEL_0;
ob.WRPLock = DISABLE;
if (HAL_FLASHEx_OBProgram(&ob) != HAL_OK)
// reset on failure, shouldn't happen
NVIC_SystemReset();
// start the option bytes programming process
if (HAL_FLASH_OB_Launch() != HAL_OK)
// reset on failure, shouldn't happen
NVIC_SystemReset();
}
}
/** This function checks if the write protection is in it's default state
* if not, resets to default
*/
static void disable_wrp_2(void)
{
FLASH_OBProgramInitTypeDef ob = {0};
ob.WRPArea = OB_WRPAREA_BANK1_AREAA;
HAL_FLASHEx_OBGetConfig(&ob);
if (ob.WRPStartOffset == 0x7f && ob.WRPEndOffset == 0x00)
return;
// allow access to flash control registers and user flash
if (HAL_FLASH_Unlock() != HAL_OK)
// reset on failure, shouldn't happen
NVIC_SystemReset();
// allow access to option bytes sector
if (HAL_FLASH_OB_Unlock() != HAL_OK)
// reset on failure, shouldn't happen
NVIC_SystemReset();
ob.OptionType = OPTIONBYTE_WRP;
ob.WRPStartOffset = 0x7f;
ob.WRPEndOffset = 0x00;
if (HAL_FLASHEx_OBProgram(&ob) != HAL_OK)
// reset on failure, shouldn't happen
NVIC_SystemReset();
// start the option bytes programming process
if (HAL_FLASH_OB_Launch() != HAL_OK)
// reset on failure, shouldn't happen
NVIC_SystemReset();
// prevent access to option bytes sector
if (HAL_FLASH_OB_Lock() != HAL_OK)
// reset on failure, shouldn't happen
NVIC_SystemReset();
// disable the flash option control register access (recommended to protect the option bytes against possible unwanted operations)
if (HAL_FLASH_Lock() != HAL_OK)
// reset on failure, shouldn't happen
NVIC_SystemReset();
}
/** Enable write protection on the bootloader region if not yet enabled
*/
void disable_wr_protection(void)
{
// disable write protection step 1, clearing the lock bit
disable_wrp_1();
// resetting the write protection
disable_wrp_2();
}