cancel
Showing results for 
Search instead for 
Did you mean: 

Flash Programming Locked Out

pweber
Associate II
Posted on June 18, 2012 at 22:12

I am using an STM32F407 device, with OpenOCD and a J-Link adapter for debugging and flash programming.

Everything has been working great until I suddenly am unable to program the flash on the device.  OpenOCD reports ''stm32x device protected''.  I traced this down to the WRPERR bit in the FLASH_SR.

For some reason this bit seems to be latched.  The flash reports that it is unlocked.  The OPTCR register has a value of 0x0FFFBBED.  I think that the BB should be AA and I modified OpenOCD to try to change that back (unlock, write the bits, write the start bit...). To no avail.

Is there any other reason that WRPERR would be latched?  I have read the programming manual and am out of ideas.

Thanks for any help/suggestions.

#stm32-flash
8 REPLIES 8
frankmeyer9
Associate II
Posted on June 19, 2012 at 08:52

Is it possible you accidently enabled CRP ?

A Flash mass erase should always work in this case, using ST-Link Utility, and getting the F4 into bootloader mode..

pweber
Associate II
Posted on June 19, 2012 at 15:43

I am not familiar with CRP?  What is that?  Searching the programming and device manuals did not come up with anything.

EDIT:  Nevermind... I just realized that CRP is RDP Level 2.  This is not the case.  The device seems to be in Level 1, and I am having difficulty resetting it to Level 0.  I believe if it were Level 2 (CRP) then the JTAG would not be working.

frankmeyer9
Associate II
Posted on June 19, 2012 at 16:02

Maybe I used NXP term for that feature - sorry.

It is ''Code Readout Protection'', and limits access to Flash reads and debug functionality.

In the ST implementation, it is found in the option bytes, as ''Read Out Protection''.

Consult the Ref. Manual in this case, you might to get it into bootloader mode.

And, as I remember, you need to do a mass erase when removing the Read-Out-Protection.

(I think, it is described that this mass erase happens automatically if you reset the ROP level - this is part of the protection).

I avoided this stuff up to now, for good reasons...

pweber
Associate II
Posted on June 21, 2012 at 15:32

Thanks for your help.  I was finally able to get the device unlocked again.  I was able to reset the RDP bytes in OPTCR through a GDB session.  Whew...

frankmeyer9
Associate II
Posted on June 21, 2012 at 15:45

I was able to reset the RDP bytes in OPTCR through a GDB session..

 

The STM32 ST-Link Utility could do the same for you.

It's a nice tool, and freely available on the ST webpage (if you don't have it already).

amail
Associate
Posted on October 19, 2014 at 20:18

hey guys!

thanks alot for your thread! nearly the whole day i struggled with a ''write protected'' stm32l1 device.

maybe it is clear for most of the users, but i think some more information may help 🙂 :

i use openocd with gdb. after many many successful flash write actions my device was suddenly locked. the following message occured with openocd debug_level 3:

Debug: 146 74371 target.c:1930 target_read_u32(): address: 0x40023c18, value: 0x0000050c

Error: 147 74371 stm32lx.c:869 stm32lx_wait_until_bsy_clear(): access denied / write protected

as the thread starter i traced this to

stm32lx.c : static int stm32lx_wait_until_bsy_clear(struct flash_bank *bank)

this function checks the FLASH_SR register bits. as already mentioned the WPRERR bit (and the SIZERR) were set.

this could be checked via:

(gdb) mon mdw 0x40023C18

0x40023c18: 0000050e

(address info: flash registers at stm32l1 devices start as described in refman ''2.3 memory map'' at 0x4002 3C00.  FLASH_SR has address offset of 0x18)

in the refman for stm32l1 devices ''3.9.7 Status register (FLASH_SR)'' there is a solution described: ''Cleared by writing it to 1.''

so i tried to clear the error bits with

(gdb) mon mww 0x40023C18 0x00000f00

this cleared the error bits WPRERR and SIZERR. ***BUT ONLY FOR RUNTIME***

after reset they are immediately set to 1 again :\ . and this was the reason openocd failed. (at first i thought multiple write actions (3+) to the unlock key registers

FLASH_PEKEYR, FLASH_PRGKEYR or FLASH_OPTKEY were the cause, but the openocd binary stayed the same and worked few hours ago ...)

so i checked the read protection of the device. it was very strange because the RDP was already at level 0 !

in the ''information block'' of the NVM module at 0x1ff80000 i found some information (see refman ''3.5 Option byte description''):

0x1ff80004 Bit 8: SPRMOD: sector protection mode selection

as referenced there a detailed description is found at

refman ''3.7.4 PCROP'' . there stand the magical line

''Deactivation of SPRMOD and/or unprotection of user sectors can only occurs when the RDP is changing from level-1 to level-0.''

after doing this, everything worked fine! openocd maybe was disturbed during a write cycle and wrote some invalid value to RDP or the information block.

the old value of 0x1ff80004 of my device was

(gdb) mon mdw 0x1FF80004

0x1ff80004: ff870078

after resetting with RDP level 1 to level 0 transition:

(gdb) mon mdw 0x1ff80004

0x1ff80004: 00000000

(and now everything works fine :))

for manually setting RDP levels i post the necessary gdb commands (stm32l1 device):

1) clear write protect of option bytes

(gdb) mon reset halt

(gdb) mon mww 0x40023c14 0xFBEAD9C8

(gdb) mon mww 0x40023c14 0x24252627

(gdb) mon mdw 0x1ff80000

3) check RDP level

(gdb) mon mdw 0x1ff80000

0x1ff80000: ff5500aa

(level is 0 according to 0x1ff80000 Bits [7:0]: RDP = 0xaa)

4) set RDP to level 1 (everything else than 0xaa or 0xcc.Bits [23:16] shall be complement 0x11 -> 0xee)

(gdb) mon mww 0x1ff80000 0xffee0011

(gdb) mon mdw 0x1ff80000

0x1ff80000: ffee0011

5) do reset, from now read requests to 0x1ff80000 lead to JTAG-DP STICKY ERROR

6) repeat step 1)

7) set RDP level to 0 again

(gdb) mon mww 0x1ff80000 0xff5500aa

(gdb) mon mdw 0x1ff80000

0x1ff80000: ff5500aa

😎 reset and be happy to have a flashable device 🙂

(gdb) mon flash write_image [path].elf

cheers

flo
gaborpaller
Associate
Posted on June 27, 2016 at 14:48

Thanks, Florian, this was helpful.

However, it only worked for me after I unlocked FLASH_PEKEYR.

As per 3.9.4 and 3.9.6

gaborpaller
Associate
Posted on June 28, 2016 at 15:42

As this issue occured to me repeatedly, I turned this into an openocd procedure. See stm_force_erase in the attached file.

________________

Attachments :

stm32l152-openocd.cfg : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006Hyhl&d=%2Fa%2F0X0000000bk4%2FMOrG4M7hLwjbDSYxSpmjK8CXGbjwwlHSTHI9gFJhpK0&asPdf=false