HomeCommunityEmbedded and Microcontrollers blog
December 24, 2014

Unlocking the STM32F4 Discovery board with OpenOCD

I haven't been able to flash-program the board because my only available tool is OpenOCD; I have no other options. Fortunately, OpenOCD is scriptable, so let's make it work.

By Jens Bauer

Share
Reading time 2 minutes

Update: This will only be needed if you're running OpenOCD from before Jan 16 2015 on Big Endian machines. The problem is fixed in later builds.

I'm not sure this applies to all STMicroelectronics STM32F4 Discovery boards, but it does to mine.

For a while, I haven't been able to flash-program the board, because my only available tool is OpenOCD; I have no other options. The reason I could not flash-program the board, is that the unlock procedure for the board in OpenOCD, does not remove write-protection in the OPTCR register.

Fortunately, this is no problem; OpenOCD is scriptable, so it's possible to make it work.

Let's get started

Let's assume we're running OpenOCD's server and we telnet into the server...

In our first terminal window, we start OpenOCD as a server:

$ openocd -f board/stm32f4discovery.cfg

We open a second terminal window and telnet into the OpenOCD server:

$ telnet localhost 4444

Start by issuing a halt command; this will stop program-execution on the discovery board.

We can either issue a 'halt' or a 'reset halt'; In this example I use 'reset halt':

> reset halt

Next, let's use the official unlock procedure that ships with OpenOCD:

> stm32f2x unlock 0

We will also need to unlock the OPTCR register. This is done by writing a special sequence of data into the OPTKEYR register.

Right after unlocking it, we want to change the value of the OPTCR register:

> mww 0x40023C08 0x08192A3B; mww 0x40023C08 0x4C5D6E7F; mww 0x40023C14 0x0fffaaed

We can now flash-program the board; it is recommended to use the .elf format:

> flash write_image erase led-blinker.elf

This can all be put in a script; For instance, my script resembles the following:

# file: my_stm32f4.cfg

proc myUnlock () {

  stm32f2x unlock 0

  mww 0x40023C08 0x08192A3B; mww 0x40023C08 0x4C5D6E7F

  mww 0x40023C14 0x0fffaaed

}

proc myFlash {file_to_flash} {

    init; sleep 200

    reset halt; wait_halt

    myUnlock ()

    flash write_image erase "$file_to_flash"

    reset run; sleep 10

    shutdown

}

proc myRun () {

    init; sleep 200

    reset halt; wait_halt

    reset run; sleep 10

    shutdown

}

So you can program the discovery board using the following command on the command-line:

$ openocd -f board/stm32f4discovery.cfg -f my_stm32f4.cfg -c "myFlash myFile.elf"

Special thanks go to John Frenz from the my.st.com forum, for helping me find this solution.

Update: You can actually write the OPTCR value, so it will not be changed back after a reset. Again, John Frenz pointed me in the right direction on how to do this:

> reset halt; mww 0x40023C08 0x08192A3B; mww 0x40023C08 0x4C5D6E7F; mdw 0x40023c14

> mww 0x40023C14 0x0fffaaec; sleep 200; mdw 0x40023c14; mww 0x40023C14 0x0fffaaef; sleep 200; mdw 0x40023c14; reset halt; mdw 0x40023c14

Note: In order to write the correct value, 0x0FFFAAED, it is necessary to first write the value with the low two bits cleared, then writing the value with bit 1 set will do the trick. The lock bit can also be set on the second write, but it will automatically be set after a reset anyway.

The 'sleep' commands are necessary, in order to avoid getting errors when reading the status register using 'mdw'.


3Log in to like this post
Share

Article text

Re-use is only permitted for informational and non-commercial or personal use only.

placeholder