cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 Discovery - can't flash-program device

pacman
Associate III
Posted on December 17, 2014 at 08:31

(Note: I'm experienced with flash-programming microcontrollers from other vendors, but this is my first go with STM)

I have a STM32F4 Discovery board (with a STM32F407VGT6 fitted).

I use GCC-4.8.3 with OpenOCD-0.9.0.

So far, I've gotten the drivers to build with no errors and warnings (I had to modify them and clean the code).

But when it comes to flash-programming, I had some problems where I got a 'write-protected' error from OpenOCD. After messing around with it, I found out that I should remove 'unlock' and 'erase' from this line...

flash write_image erase unlock file_to_flash.elf

...so it becomes ...

flash write_image file_to_flash.elf

...and it seems that OpenOCD sends the data to the microcontroller.-But where do the data end up ?

The LED-animation stops (expected after a RESET / HALT), but my program does not seem to start.

In OpenOCD, I can do a ...

mdw 0x20000000 32

...and a...

mdw 0x10000000 32

...but both...

mdw 0x00000000

...and...

mdw 0x08000000

fails with the message:

in procedure 'mdw'

-Nothing else. This suggests that OpenOCD had some kind of (read) access-error, and could not read the data from the Flash memory.

All that said, This is the output I get from OpenOCD:

Open On-Chip Debugger 0.9.0-dev-00101-gb15a0ee (2014-11-27-08:50)

Licensed under GNU GPL v2

For bug reports, read

http://openocd.sourceforge.net/doc/doxygen/bugs.html

jtag_ntrst_delay

♯♯♯ Flashing/Board/stm32f4.cfg

Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD

adapter speed: 1000 kHz

adapter_nsrst_delay: 100

&sharp0 : stm32f4x.flash (stm32f2x) at 0x00000000, size 0x00000000, buswidth 0, chipwidth 0

runNow

Info : clock speed 1000 kHz

Info : STLINK v2 JTAG v14 API v2 SWIM v0 VID 0x0483 PID 0x3748

Info : using stlink api v2

Info : Target voltage: 2.893577

Info : stm32f4x.cpu: hardware has 6 breakpoints, 4 watchpoints

target state: halted

target halted due to debug-request, current mode: Thread 

xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc

Info : stm32f4x errata detected - fixing incorrect MCU_IDCODE

Info : device id = 0x10006413

Warn : STM32 flash size failed, probe inaccurate - assuming 1024k flash

Info : flash size = 1024kbytes

wrote 1020 bytes from file output/STM-test8.elf in 0.162985s (6.112 KiB/s)

shutdown command invoked

-I suspect that the file I sent was only transferred to the STM32F4's RAM (although my disassembly clearly indicates that the code should go to 0x08000000, which I understand is where the Flash-memory is located)

#openocd #stm32f4-discovery #flash_cr-flash_keyr-lock #mass_erase-unlock #nwrp #optcr #unlocked-writable-solution
16 REPLIES 16
pacman
Associate III
Posted on December 23, 2014 at 14:00

That's very helpful information.

> 0x1000 0000 is CCM (core coupled memory) data ram.

> On F4 devices it isn't connected to instruction bus, meaning that you can't execute code from it.

> If you want to execute code from internal RAM in must be stored to SRAM1.

Good to hear that at least I got one thing right. 😉

(I intended to use CCM for the exception vectors and data only; the code should go in the 112kB section, if I didn't make any mistakes in my linker script).

> I'm not sure if OOCD is supposed to issue errors, though...

-I did find out that OpenOCD does not report errors when it encounters write errors on the write_image command, so I posted that information on the OpenOCD list.

(Hmm, it seems my mail didn't make it to the list for some reason)

I tried to issue a ...

mdw 0x40023C0C

... command right after the flash write_image command, and the result was...

00000010

-So it definitely fails.

>> 0x40023C18, OPTCR1:     110000c0 (looks even more strange)

> OPTCR1 register doesn't exist on 407 -devices. 

Hmm, I get the feeling that you're pretty experienced with the STM devices. 😉

> 0x40023C14, OPTCR:      00aaaae1 (looks strange)

>> Note: I would expect the 0xAAA to be either 0xFFF or 0x000.

> According to mdw command my device's OPTCR register is at reset value, 0x0FFF AAED.

That is very valuable information, thank you so much for this!

> Have you tried issuing ''stm32f2x unlock 0'' on openocd?

Yes, I think I've issued it 3 or 4 times for every session I started (I know it's not necessary anymore, though). 😉

> Also make sure you have latest version of oocd.

Yes, I'm on the latest HEAD. 

I tried writing the value 0x0FFFAAED to the OPTCR register to see if that made any difference. So far I got an access error, so I probably need to one of the a LOCK bits somewhere. (I already tried with bit 31 cleared in 0x40023C10, but as far as I remember, there's another one),

macfrenz
Associate II
Posted on December 23, 2014 at 14:24

> I tried writing the value 0x0FFFAAED to the OPTCR register to see if

> that made any difference. So far I got an access error, so I probably

> need to one of the a LOCK bits somewhere. (I already tried with bit 31

> cleared in 0x40023C10, but as far as I remember, there's another one),

According to reference manual that's not the way to gain write access. That bit is read/set only. Look at reference manual about registers FLASH_KEYR and FLASH_OPTKEYR, those can be used to unlock the respective registers. Try to set FLASH_OPTCR register to default value (0x0FFF AAED) by unlocking it first by FLASH_OPTKEYR register.

EDIT: When you say that you want some stuff to go into RAM do you mean that:

a) The OpenOCD actually writes that stuff INTO the ram.

b) That the stuff is programmed into flash memory and on startup copied into RAM.

pacman
Associate III
Posted on December 24, 2014 at 08:52

> According to reference manual that's not the way to gain write access.

> That bit is read/set only. Look at reference manual about registers FLASH_KEYR and FLASH_OPTKEYR

That makes sense (in fact, that was exactly the bit I was thinking about).

I'll try it out and post the result.

> those can be used to unlock the respective registers.

> Try to set FLASH_OPTCR register to default value (0x0FFF AAED) by unlocking it first by FLASH_OPTKEYR register.

I think there's a good chance it will work. 😉

> EDIT: When you say that you want some stuff to go into RAM do you mean that:

> a) The OpenOCD actually writes that stuff INTO the ram.

> b) That the stuff is programmed into flash memory and on startup copied into RAM.

Normally, when I've written code for devices from other vendors, I've used a lnker script, which writes the data into flash memory. The data is then copied to RAM, if it's read/write data. (.rodata stays in Flash memory).

I've also had code being copied to SRAM, but with STM, it shouldn't even be necessary, because ART would make executing from the Flash memory just as fast as executing from SRAM, as far as I understand.

-But for some reason, OpenOCD seems to misunderstand my intentions. It should not care about writing anything to SRAM at all, as everything is scheduled to be written to Flash memory (unless I made an error, but my linker-script has been in use for 2 years now and has been pretty stable - of course, that can't rule out the possibility of an error).

Hmm.. I just thought of something.. Maybe I'm not supposed to have two MEMORY sections in the linker script. I think I recall that it might introduce some problems.

pacman
Associate III
Posted on December 24, 2014 at 18:27

John, thank you for your wonderful Christmas-present!

The board now works perfectly!!

> Try to set FLASH_OPTCR register to default value (0x0FFF AAED) by unlocking it first by FLASH_OPTKEYR register.

This is what I did:

> mdw 0 10

0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff 

0x00000020: ffffffff ffffffff 

> mdw 0x40023C14

0x40023c14: 00aaaae1 

> mww 0x40023C14 0x0fffaaed

> mdw 0x40023C14

0x40023c14: 00aaaae1 

> mdw 0x40023C10

0x40023c10: 00000000 

> mdw 0x40023C14; mdw 0x40023C10

0x40023c14: 00aaaae1 

0x40023c10: 00000000 

> mdw 0x40023C14; mdw 0x40023C10

0x40023c14: 00aaaae1 

0x40023c10: 00000000 

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

0x40023c10: 00000000 

> mdw 0x40023C14; mdw 0x40023C10

0x40023c14: 0fffaaed 

0x40023c10: 00000000 

> flash write_image output/STM-test9.elf

stm32f4x errata detected - fixing incorrect MCU_IDCODE

device id = 0x10006413

flash size = 1024kbytes

target state: halted

target halted due to breakpoint, current mode: Thread 

xPSR: 0x61000000 pc: 0x20000042 msp: 0xfffffffc

wrote 488 bytes from file output/STM-test9.elf in 0.132989s (3.583 KiB/s)

> mdw 0 10

0x00000000: 2001c000 08000189 080001e5 080001e5 080001e5 080001e5 080001e5 5a5a5a5a 

0x00000020: 00000000 00000000 

..So I am now able to write to the Flash memory. Fixing the linker script should then be no problem if there are any bugs.

Thank you again!!

pacman
Associate III
Posted on December 24, 2014 at 19:33

It seems that the value in the OPTCR is changed back to 0x00aaaae1 after reset or power-cycling.

That means it has to be done every time flash-programming is needed (eg. whenever you 'unlock').

For anyone else having this problem, I think this is the complete programming sequence:

> reset halt

> stm32f2x unlock 0

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

> flash write_image erase output/STM-test9.elf

macfrenz
Associate II
Posted on December 25, 2014 at 11:00

You're welcome 🙂

> It seems that the value in the OPTCR is changed back to 0x00aaaae1 after reset or power-cycling.

> That means it has to be done every time flash-programming is needed (eg. whenever you 'unlock').

> For anyone else having this problem, I think this is the complete programming sequence:

> > reset halt

> > stm32f2x unlock 0

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

> > flash write_image erase output/STM-test9.elf

See reference manual, 3.7.2. Following that procedure should make the changes permanent. Also I'm not sure if ''stm32f2x unlock 0'' above is really required.

pacman
Associate III
Posted on December 25, 2014 at 23:56

> See reference manual, 3.7.2.

> Following that procedure should make the changes permanent.

This worked!

> Also I'm not sure if ''stm32f2x unlock 0'' above is really required.

I tried a -d3 session and looked at what OpenOCD is doing when issuing the stm32f4x unlock 0. It seems it's unlocking the option register successfully, but I do not know exactly what goes wrong yet. I'll have to investigate further.

After fiddling a little with the option-bits, I arrived at the following sequence, in order to get the value that you've supplied me with. It is necessary to start by writing the value with the low two bits cleared, and then set the low two bits (so we write the locked value)

> 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

The 'sleep' delays are necessary (because if I do a mdw of the status-register right after the mww, I will get an error).

-I'll post the sequence on the OpenOCD developers list, as there might be something unintended going on in the 'unlock' code ('unlock' is written in C, not in a script procedure, which I first assumed).

Thank you so much again for this valuable help. If anyone else has this problem, I hope this will help them getting started. Hopefully I'll be able to find out what goes wrong in the unlock code, so it can be corrected.