cancel
Showing results for 
Search instead for 
Did you mean: 

Issue with STM32H735 Bootloader in RDP Level 1 (0xBB) Mode

SHm
Associate II

Hello,

I’m working with the STM32H735, and I need to enter bootloader mode to program the microcontroller. I modify the SYSCFG->UR2 register to set the address to 0x1FF00000, then perform a software reset. I use this method because I have no control over the BOOT0 pin (it's directly connected to GND) and the reset pin. After the reset, I use STM32_Programmer_CLI.exe to program the microcontroller with the following python script:

 

 

 

import subprocess

# Define the path to STM32_Programmer_CLI.exe
stm32_cli_path = "STM32_Programmer_CLI.exe"

# Define the commands to be executed
command1 = [stm32_cli_path, "-c", "port=COM7", "br=115200", "-rdu"]
command2 = [stm32_cli_path, "-c", "port=COM7", "br=115200", "-e", "all", "-w", "Test.hex", "-v", "-ob", "rdp=0xBB"]

try:
    # Execute the first command
    result1 = subprocess.run(command1, capture_output=True, text=True, check=True)
    print("Command 1 Output:")
    print(result1.stdout)
    
    # Execute the second command
    result2 = subprocess.run(command2, capture_output=True, text=True, check=True)
    print("Command 2 Output:")
    print(result2.stdout)

except subprocess.CalledProcessError as e:
    print(f"An error occurred while executing the command: {e}")
    print(f"Error Output: {e.stderr}")

 

 

 

 

This works fine when the microcontroller is in unprotected mode (RDP=0xAA). However, when RDP is set to 0xBB, after the software reset, the bootloader does not program the microcontroller (I get a timeout error). I see that the Flash memory is empty after this process, so it seems the protection is disabled temporarily, but the programming of the .hex file does not proceed.

Has anyone encountered a similar issue or have any suggestions on how to resolve this?

best Regards,

1 ACCEPTED SOLUTION

Accepted Solutions
SHm
Associate II

Hello,

I found a solution to modify the RDP level from a function that runs directly from SRAM. This approach is necessary because I do not have control over the BOOT0 and NRST pins (BOOT0 is tied to 0V, and NRST is connected to 3.3V), which means I cannot manually trigger the bootloader through hardware. Here are the steps:

  1. Disable IRQs: The first step is to disable all interrupts to ensure there are no disruptions during the critical operations.

  2. Adjust FLASH Wait States: Set the FLASH wait states to FLASH_LATENCY_7 to ensure stable operation while working with the memory.

  3. Change BOOT0 Address via Option Bytes: Modify the BOOT0 address through the Option Bytes to point to the bootloader. This involves changing the Option Bytes configuration to set the boot address accordingly.

  4. Change the RDP Level to Level 0: Adjust the RDP (Read Protection) level back to Level 0 through the Option Bytes. This change will initiate a mass erase of the FLASH memory.

  5. Wait for the Mass Erase to Complete: Monitor the status of the FLASH controller to ensure the mass erase is completed before proceeding.

  6. Perform a Software Reset: Once the mass erase is done, perform a software reset to apply the changes and restart the microcontroller.

  7. Bootloader Launch and Flashing: Use the STM32 Programmer CLI to flash the firmware, specifying the BOOT0_CM7_ADDR0 option to set the appropriate boot address. This ensures that after the reset, the microcontroller will boot from the correct memory region.

Best Regards,

View solution in original post

12 REPLIES 12
embedko
Associate II

Hi. See RM0468 Reference manual. With RDP Level 2 boot from RAM and System Flash memory are disabled.

embedko_0-1730887711805.png

If you want to use RDP Level 2, you must write your own loader.

SHm
Associate II

Hello,

Another approach I’m considering is to disable the RDP level directly through code before attempting the bootloader entry. Here’s the outline of the process:

  1. After setting the boot address in the SYSCFG->UR2 register, I would disable the RDP protection by modifying the option bytes to change the RDP level from Level 1 to Level 0.
  2. This code should be executed from RAM, writing option bytes and performing a soft reset requires execution outside of Flash, because when changing the RDP level the Flash will be erased

I would copy the code that changes the RDP level and initiates the software reset into RAM, then execute it from there.

This way, I would effectively downgrade the RDP level to allow bootloader access and proceed with programming.

Does this approach seem feasible, or are there any potential issues with executing the RDP downgrade and reset sequence from RAM?

AScha.3
Chief III

>Has anyone encountered a similar issue or have any suggestions on how to resolve this?

1. There is no "issue" here with the chip. The "issue" is just stupidity and ignorance.

2. To resolve "this" : 

A:  rtfm. Before setting any RDP level !

B: Replace (now useless chip) and try again.

C: And trust the rm, if read rm : 

AScha3_0-1730890652827.png

 

If you feel a post has answered your question, please click "Accept as Solution".
SHm
Associate II

Apologies for the confusion. I made a mistake in the title. It should have read "Issue with STM32H735 Bootloader in RDP Level 1 (0xBB) Mode" instead of "Issue with STM32H735 Bootloader in RDP Level 2 (0xBB) Mode."

I corrected the title, I'm talking about Level 1

Ok, so now for rdp1 :

AScha3_0-1730900910644.png

After set rdp1->rdp0 , did you try a power cycle ? Then start bootloader...

 

If you feel a post has answered your question, please click "Accept as Solution".

In my current project, the only way to enter bootloader mode is to change the next boot address via the SYSCFG->UR2 register by setting it to 0x1FF00000U, followed by a software reset. This means I can only enter bootloader mode from software located in flash memory.

To address this, I wrote the following function, placed in RAM, to change the RDP level from level 1 to level 0 without losing execution of HAL_NVIC_SystemReset(), since moving from RDP level 1 to 0 normally erases flash:

 

static void __attribute__((section(".RamFunc"))) Boot(void)
{
    uint32_t u32TmpReg;
    u32TmpReg = SYSCFG->UR2;
    u32TmpReg &= ~(U32_BOOT_ADDR0_MSK);
    SYSCFG->UR2 |= (U32_BOOTLOADER_ADDRESS & U32_BOOT_ADDR0_MSK);

    HAL_FLASH_OB_Unlock();
    HAL_FLASH_Unlock();

    RDP_init.OptionType = OPTIONBYTE_RDP;
    RDP_init.RDPLevel = OB_RDP_LEVEL_0;
    HAL_FLASHEx_OBProgram(&RDP_init);
    HAL_FLASH_OB_Launch();
    HAL_NVIC_SystemReset();
}

 

 After running this code, I expected the RDP level to change, but it didn’t.

From my understanding, it appears that downgrading RDP from level 1 to level 0 might not be achievable programmatically. Am I missing something in my approach?

Here are some additional details:

  1. Placing the Function in RAM: Since flash memory will be erased when changing RDP levels, I put this function in RAM to ensure HAL_NVIC_SystemReset() still executes.
  2. Bootloader Address Setup: I’m modifying SYSCFG->UR2 to set the bootloader address before resetting the system.
  3. Sequence for Changing RDP: I unlock the flash and configure RDP_init to change the level, then launch the option bytes with HAL_FLASH_OB_Launch().

The main.c file is attached.

Any insights on handling this, or alternative approaches, would be appreciated!

Best Regards,

Pavel A.
Evangelist III

 

Since flash memory will be erased when changing RDP levels, I put this function in RAM 

But other HAL functions referenced from it are not located in RAM. Including the HAL_NVIC_SystemReset. Where is the vectors table, systick handler?

 

Just...why call the bootloader at all ?

-> You want "protection" ....ok. set rdp1 .

Now in your program user selected :> update, then do it yourself (loading data and erase/flash some memory).

No need to call system bootloader or change rdp.

If you have enough flash (dual bank flash) you can load the new firmware in the "other" flash bank, 

and only after successful (crc...etc) download move this internally to execution flash (or switch banks).

So you can keep it in save condition, even if flash/upload crashes, because power loss in middle of download.

Just look for examples with "custom bootloader" etc.

 

If you feel a post has answered your question, please click "Accept as Solution".