Skip to main content
Explorer
June 5, 2025
Solved

[STM32F405] flash level 2 protection

  • June 5, 2025
  • 2 replies
  • 709 views

Hi,

 

I was trying to test the feature of "Level 2 flash lock" on my custom board. I'm having an unexpected behaviour.

My total application consists of a bootloader responsable to load an application via CAN BUS through a custom communication protocol.

Now, If I load my application program via CAN (via bootloader), the MCU can not set itself to level2 but remains set to level 1. If I transfer the same application with JTAG, the MCU can set itself to level 2 protection and any attempt to connect to it is correctly disabled. (in level 1 I can still connect by erasing the whole chip content).

 

To give further informations, here is the code responsable to set level 2 protection implemented:

FM_ClearFlags();
FM_Unlock();
flashSts = FM_CheckProtectionStatus();
if(flashSts == FM_FLASH_NOT_PROTECTED) // check current protection status
 {
 FM_SetOBConfig();
 flashSts = FM_CheckProtectionStatus();
 }

 FM_Lock();


void FM_ClearFlags(void)
{
 FLASH->SR |= 0xE0; // clear the errors RDERR PGSERR PGPERR
}

void FM_Unlock(void)
{
 FLASH_Unlock(); // unlock flash to deal with it
 FLASH_OB_Unlock(); // unlock option byte to deal with it
}
void FLASH_Unlock(void)
{
 if((FLASH->CR & FLASH_CR_LOCK) != RESET)
 {
 /* Authorize the FLASH Registers access */
 FLASH->KEYR = FLASH_KEY1;
 FLASH->KEYR = FLASH_KEY2;
 } 
}
void FLASH_Lock(void)
{
 /* Set the LOCK Bit to lock the FLASH Registers access */
 FLASH->CR |= FLASH_CR_LOCK;
}
void FM_SetOBConfig(void)
{
 FLASH_OB_RDPConfig(OB_RDP_Level_2); // set to 0xCC to enable the level2 protection --> full chip protection. You cant go back to level 1 or 0. Set a number different (like 0x55) means protection of level 1
 FLASH_OB_Launch(); // launch the option byte writing procedure 
}

 

I think the code itself works, because it's working flashing via JTAG. So, why flashing through a custom bootloader does not work?

 

Thanks,

Marco.

    This topic has been closed for replies.
    Best answer by _marco95_

    I think I found out the root cause.

    After my bootloader flashes the MCU, the RDP register is set to FF. The library I'm using was using 3 defines for the levels:

    level 0 = 0xAA

    level 1 = 0x55

    level 2 = 0xCC

     

    The library was checking against the level0, but FF was somehow an unespected value.

     

    I changed a bit logic and now seems to work.

     

    Thanks,

    Marco.

    2 replies

    Super User
    June 5, 2025

    Did you power cycle the chip? I recall there being some checks for the debugger that only get reset after a power-cycle, or something similar like that.

    Removing the code that sets RDP2 and then comparing the content of the flash after flashing with each method would let you know if there is an issue flashing.

    _marco95_Author
    Explorer
    June 6, 2025

    Hello,

    yes I power cycled the chip but still the level 1 protection is enabled. I will try to insert a sw reset immediatly after the flash lock procedure. Maybe it helps.

     

    I will also try to compare the flash content but I don't think we have issue with the flashing procedure since the application is up and running.

     

    Marco.

    Super User
    June 6, 2025

    If the flash is the same, the behavior after powerup will be the same. The chip doesn't know or care how the flash got loaded.

    Super User
    June 12, 2025

    Could it be an odd behaviour of the chip?

    Yes - in some sense of odd. Try to reset (NVIC_SystemReset) before setting level 2. 

     

    _marco95_AuthorAnswer
    Explorer
    June 12, 2025

    I think I found out the root cause.

    After my bootloader flashes the MCU, the RDP register is set to FF. The library I'm using was using 3 defines for the levels:

    level 0 = 0xAA

    level 1 = 0x55

    level 2 = 0xCC

     

    The library was checking against the level0, but FF was somehow an unespected value.

     

    I changed a bit logic and now seems to work.

     

    Thanks,

    Marco.