AnsweredAssumed Answered

STM32 f3xx flash read out protection and option bytes programming: Mysteries solved

Question asked by Alam.Muhammad_Asrar on Feb 28, 2017
Latest reply on Feb 28, 2017 by Nesrine M

Hello All,

I have been trolling across several forums in order to be able to read protect my stm32f334 flash memory from within the code. I tried to use the hal functions provided in the stm32f3xx_hal_flash and stm32f3xx_hal_flash_ex files provided by the stm32cube in the exact sequence as stated in the driver files but was in no way successful. I could get through flash and option bytes unlocking and enabling the option bytes programming bit (OPTPG) byte upon writing the desired value to the designated option byte (RDP byte in my case in order to change the flash memory read protection level), i would get a PGERR bit set indicating that the programming was not successful because the location to be written was not erased.

Upon digging in a little more i found that Option bytes erasure was the step that was missed in the FLASH_OB_RDP_LevelConfig function of the hal. I also looked into the flash application example provided by the STMCube but it also had this problem.

 

So I added the erasure steps and finally got it all working. 

In a nutshell, this sequence involves:
1. Unlock flash (LOCK bit is reset) – it will only be reset by hardware itself upon writing two keys to the FLASH_KEYR.
2. Unlock option bytes (OPTWRE is set) - it will only be reset by hardware itself upon writing two keys to the FLASH_OPTKEYR.
– wait until flash is ready
3. Erase option bytes by setting OPTER bit and after that STRT bit
– wait until flash is ready
4. After the erasure is complete, reset the OPTER bit
5. Set the OPTPG bit to allow programming option bytes
6. Write the data (half word) to the desired address
– wait until flash is ready
7. Reset the OPTPG bit to complete/close programming option bytes
8. Launch/Apply the Option bytes (OBL_LAUNCH bit is set-system reset will be performed after this) – This step can be skipped as the option bytes will automatically load upon next reset.
9. Lock option bytes (OPTWRE is reset)
10. Lock the Flash (LOCK bit is set)

 

A more or less pseudo code is as follows:

 

1. 

 if((READ_BIT(FLASH->CR, FLASH_CR_LOCK)) != RESET)

  {

    /* Authorize the FLASH Registers access */

    WRITE_REG(FLASH->KEYR, FLASH_KEY1);

    WRITE_REG(FLASH->KEYR, FLASH_KEY2);

  }

 

2.

if((READ_BIT(FLASH->CR, FLASH_CR_OPTWRE)) == RESET)

  {

    /* Authorizes the Option Byte register programming */

    WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);

    WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);

  }

 

3.

FLASH->CR |= FLASH_CR_OPTER;

            FLASH->CR |= FLASH_CR_STRT;

4.

                FLASH->CR &= ~FLASH_CR_OPTER;

5.

                SET_BIT(FLASH->CR, FLASH_CR_OPTPG);

6.

                WRITE_REG(OB->RDP, ReadProtectLevel);

                Or

                *(__IO uint16_t*)Address = Data;

7.

                CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);

8.

                SET_BIT(FLASH->CR, FLASH_CR_OBL_LAUNCH);

9.

                CLEAR_BIT(FLASH->CR, FLASH_CR_OPTWRE);

10.

                SET_BIT(FLASH->CR, FLASH_CR_LOCK);

 

The same procedure must be followed to bring down the read protection level from level 1 to level 0.

The data to be written at the RDP byte (address: 0x1ffff800) for the different protection levels is:

Level 0 : 0xAA

Level 1: 0xBB (anything except 0xAA and 0xCC)

Level 2: 0xCC

Note: That a flash wide mass erase will automatically be performed upon bringing down the read protection level from level 1 to level 0.

Note Stronger: That there is no turning back from level 2.

 

Hope this helps.

 

Regards,

Asrar

Outcomes