cancel
Showing results for 
Search instead for 
Did you mean: 

System Bootloader GO command doesn't work

dscdsc
Senior

I'm using stm32flash (https://sourceforge.net/projects/stm32flash) as my host on a raspberry pi. It's connected to the STM32H750 using I2C.

Steps:

Upload the code onto the STM32

./stm32flash -a 0x4E -w stm32-blinky.bin -v -R /dev/i2c-1
 
stm32flash 0.6
 
http://stm32flash.sourceforge.net/
 
Using Parser : Raw BINARY
Size         : 15612
Warning: Not a tty: /dev/i2c-1
Error probing interface "serial_posix"
Interface i2c: addr 0x4e
Version      : 0x12
Device ID    : 0x0450 (STM32H74xxx/75xxx)
- RAM        : Up to 128KiB  (16640b reserved by bootloader)
- Flash      : Up to 2048KiB (size first sector: 1x131072)
- Option RAM : 1b
- System RAM : 122KiB
Write to memory
Erasing memory
Wrote and verified address 0x08003cfc (100.00%) Done.
 
Resetting device... 
Reset done.

Obviously the same result can be achieved with

st-flash --serial $SPI_BOOT_DUT --reset write build/stm32-blinky.bin 0x08000000
 
st-flash 1.7.0
2021-12-07T15:51:38 INFO usb.c: Unable to match requested speed 1800 kHz, using 1000 kHz
2021-12-07T15:51:38 INFO common.c: H74x/H75x: 128 KiB SRAM, 128 KiB flash in at least 128 KiB pages.
file build/stm32-blinky.bin md5 checksum: 75f0e292c262c5491d027b89dd8637, stlink checksum: 0x001891fc
2021-12-07T15:51:38 INFO common.c: Attempting to write 15612 (0x3cfc) bytes to stm32 address: 134217728 (0x8000000)
2021-12-07T15:51:38 INFO common.c: Flash page at addr: 0x08000000 erased
2021-12-07T15:51:38 INFO common.c: Finished erasing 1 pages of 131072 (0x20000) bytes
2021-12-07T15:51:38 INFO common.c: Starting Flash write for H7
15612/15612 bytes written
2021-12-07T15:51:39 INFO common.c: Starting verification of write complete
2021-12-07T15:51:39 INFO common.c: Flash written and verified! jolly good!

Verify that the code works

  • BOOT0 = Low
  • The LED is blinking

So the code is uploaded to the start of flash and is running. Now for the GO command part.

Enter the system bootloader

  • BOOT0 = High, nRST is toggled

Verify that the bootloader is running

  • LED1 is on
  • Can establish the connection with stm32flash
./stm32flash -a 0x4E /dev/i2c-1
 
stm32flash 0.6
 
http://stm32flash.sourceforge.net/
 
Warning: Not a tty: /dev/i2c-1
Error probing interface "serial_posix"
Interface i2c: addr 0x4e
Version      : 0x12
Device ID    : 0x0450 (STM32H74xxx/75xxx)
- RAM        : Up to 128KiB  (16640b reserved by bootloader)
- Flash      : Up to 2048KiB (size first sector: 1x131072)
- Option RAM : 1b
- System RAM : 122KiB

Execute the jump command

./stm32flash -a 0x4E -g 0x08000000 /dev/i2c-1
 
stm32flash 0.6
 
http://stm32flash.sourceforge.net/
 
Warning: Not a tty: /dev/i2c-1
Error probing interface "serial_posix"
Interface i2c: addr 0x4e
Version      : 0x12
Device ID    : 0x0450 (STM32H74xxx/75xxx)
- RAM        : Up to 128KiB  (16640b reserved by bootloader)
- Flash      : Up to 2048KiB (size first sector: 1x131072)
- Option RAM : 1b
- System RAM : 122KiB
 
Starting execution at address 0x08000000... done.

On the I2C protocol side, everything seems fine indeed, the bootloader responds with ACK

write to 0x4E ack data: 0x21 0xDE 
read to 0x4E ack data: 0x79
write to 0x4E ack data: 0x08 0x00 0x00 0x00 0x20 
read to 0x4E ack data: 0x79

0693W00000HnsJIQAZ.png 

But the execution hasn't switched to the user code, as the LED isn't blinking.

In fact, if we connect the debugger and let it run, nothing happens until we execute the GO command, which causes a SIGTRAP, but I'm not sure which one that is or what causes it.

st-util --serial $SPI_BOOT_DUT -p 4241
arm-none-eabi-gdb build/stm32-blinky.elf
(gdb) target extended-remote localhost:4241
Remote debugging using localhost:4241
0x1ff0d838 in ?? ()
(gdb) continue
Continuing.
 
Program received signal SIGTRAP, Trace/breakpoint trap.
0x1ff0b4cc in ?? ()

But I'm not actually sure if this is relevant since if the debugger isn't attached I can send the GO command many times in a row without the bootloader crashing. But it must be relevant somehow since this signal isn't sent during the flash writing or other commands.

There's a note in AN4221: p17 saying:

"Jumping to the application only works if the user application correctly sets the vector table to point to the application address."

But I don't think that applies in this case since the vector table is at it's default place -- the start of the flash, or 0x08000000.

1 ACCEPTED SOLUTION

Accepted Solutions
dscdsc
Senior

Setting BOOT0 to Low before executing the Go command solves the problem.

View solution in original post

3 REPLIES 3
dscdsc
Senior

The instruction at 0x1ff0b4cc is actually DSB SY (https://developer.arm.com/documentation/dui0489/c/arm-and-thumb-instructions/miscellaneous-instructions/dmb--dsb--and-isb) so it makes sense that it doesn't cause a restart. Still not sure why it causes a SIGTRAP or why execution doesn't jump to 0x08000000.

Also, I've set a breakpoint to Reset_Handler (in stm32-blinky.elf), but it isn't hit after the Go command.

And exactly the same issue happens with the SPI bootloader.

dscdsc
Senior

Setting BOOT0 to Low before executing the Go command solves the problem.

For anyone who experiences this problem ("GO command does not work") on a stm32H5xx I'd like to share my experience:

I have this problem on the nucleo-h563zi board and the solution accepted here does not work. Here are the steps to reproduce my experience:

  1. Using STM32CubeIDE I created the GPIO_InfiniteLedToggling_Init example application (without modifications) and downloaded to the target board (from the IDE). It works as expected (led blinks).
  2. I connect BOOT0 to Vcc, hit the reset button and release BOOT0 again (set to low as recommended by the "solution").
  3. I am able to talk to the bootloader via UART (usart3 via stlink as virtual COM port); I can read memory etc. works as expected. I find the expected vector table of the LED example application at 0x08000000.
  4. I issue the GO 0x08000000 with BOOT0 still pulled low.
  5.  => **nothing happens** LED does *not* blink.

I had previously found (using our own proprietary application and some debugging tools) that

  1. The GO command indeed *does* jump to the application code.
  2. However, the application code is not able to manipulate many of the peripherals (GPIOs, RCC, ...); values written to respective registers "don't stick" (they work as expected when starting the user code normally, i.e., not via "GO".)
  3. I suspect that this is due to the security features (which are a useless obstacle to our application) of the chip:

    In Table 119 (RM0481, 14.3.5, pp. 587) "SBS Boot Logic" we find rows 2 + 3 which correspond to an "open" device with "sbs_tzen == 0" for "BOOT0 = '0'" and "BOOT0 = '1'", respectively: what seems to be the *effective* security state `sbs_tz_state` is '0' when we boot the application normally but it is '1' when we boot the STM bootloader. I suspect the bootloader 'GO' command does not leave the secure state when jumping to the target address and thus bricks the device for the application.

=> on the H5xx devices there is currently no known way to use the bootloader's GO command :(