stm32 factory bootloader possibly overwritten with openocd?

2

tl;dr: flashed firmware to 0x00000000 instead of 0x08000000, am I lost?

Hello,

my device is based on a STM32F103CBTx which came with a proprietary firmware and had readout protection on. I connect to it with a ST-Link v2 SWDIO and SWCLK connected to PA13 and PA14 and this command:

sudo openocd -f /usr/share/openocd/scripts/interface/stlink-v2.cfg -f /usr/share/openocd/scripts/target/stm32f1x.cfg

I don't remember how I removed flash protection, but it worked as the original firmware didn't work anymore. Then I created a simple hello world firmware which pulls up and down three gpios and flashed it. The gpios are pulled up and down in 700ms intervals.

After flashing, I can't connect with openocd anymore. I forgot to specify the offset, the manual says the offset defaults to 0 and as it worked, I suppose instead of the boot loader my shitty hello world is pulling up and down some random pins happily… Is this possible? All other threads I found say the boot loader is write protected.

This is the last contact I had:

> halt
halt
target halted due to debug-request, current mode: Handler HardFault
xPSR: 0x01000003 pc: 0xfffffffe msp: 0xffffffdc
> flash write_image erase fw.hex
flash write_image erase fw.hex
auto erase enabled
target halted due to breakpoint, current mode: Handler HardFault
xPSR: 0x61000003 pc: 0x2000003a msp: 0xffffffdc
wrote 4096 bytes from file fw.hex in 0.285697s (14.001 KiB/s)
> reset
reset
jtag status contains invalid mode value - communication failure
Polling target stm32f1x.cpu failed, trying to reexamine
Examination failed, GDB will be halted. Polling again in 100ms

Any directions highly appreciated.

Edit: What I get now, also tried another st-link:

%  sudo openocd -f /usr/share/openocd/scripts/interface/stlink-v2.cfg -f /usr/share/openocd/scripts/target/stm32f1x.cfg 
Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select '.
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
none separate
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : clock speed 950 kHz
Info : STLINK v2 JTAG v17 API v2 SWIM v4 VID 0x0483 PID 0x3748
Info : using stlink api v2
Info : Target voltage: 3.244356
Error: init mode failed (unable to connect to the target)
in procedure 'init' 
in procedure 'ocd_bouncer'
stm32
openocd
asked on Stack Overflow Jun 13, 2018 by PhilK

1 Answer

3

flashed firmware to 0x00000000 instead of 0x08000000, am I lost?

No, it doesn't matter at all, they are the same.

After reset, the MCU loads the word at address 0 in SP, and the next one at address 4 in PC. The BOOT0 and BOOT1 pins control which memory gets mapped to 0x00000000. Usually, BOOT0 is tied low, and flash memory at 0x08000000 gets mirrored at 0x00000000.

instead of the boot loader my shitty hello world is pulling up and down some random pins happily… Is this possible? All other threads I found say the boot loader is write protected.

The factory bootloader is indeed write protected, openocd can't overwrite it.

However, your application could have reconfigured the SWD pins, by writing a wrong value in GPIOA->CRH or AFIO->MAPR, thereby preventing openocd from working. It's the most common cause of this problem.

Fortunately, there is a way to recover.

Connect under Reset

If the reset pin of the controller is held low for a while when openocd is started, the application is prevented from starting, and messing up the GPIO configuration.

Openocd can do this automatically, when

  • It's told to do so, the line reset_config srst_only srst_nogate is present somewhere in the configuration script.
  • The MCU reset pin is connected to the debugger hardware, pin 15 on an official ST-Link/V2.

Or you can do it manually, by whatever means your board provides. If you are lucky, it has a reset button, if not, you must find a way to somehow ground the MCU reset pin.

  • Pull the reset pin low
  • Start openocd
  • Wait until the Info : Target voltage line appears. Maybe a second longer.
  • Release the reset pin.

It requires a bit of trial and error, you'll get better with practice.

Then you can flash your improved application, which carefully avoids reconfiguring the SWD pins.


User contributions licensed under CC BY-SA 3.0