December 19, 2023

STM32H747I-DISCO "Discovery kit with STM32H747XI MCU" -- how does it boot

Here is the conclusion up front. It boots from 0x0800_0000 by default.

How and why this is is more interesting. The manual says that ST ships the device with the option bytes set so it boots from 0x0800_0000. If you know how to set the options bytes, you can make it boot from whereever you might want.

Section 13 of the manual (RM0399) is the sysconfig area and this includes several "registers" that control booting, as follows:

UR1 selects BCM7 and BCM4, (i.e. whether the M7 or the M4 core or both boot up).
UR2 has BCM7_ADD0 (bits 15-0)
UR3 has BCM7_ADD1 and BCM4_ADD0
UR4 has BCM4_ADD1
There is also a "BOOT" pin. On our board it is tied to ground via a 10K resistor. This means BOOT address 0 is permanently selected, and we can ignore the two ADD1 addresses above.

The memory map tells us that 0x0800_0000 is the start of the first 1M flash bank. It is followed immediately by a second 1M flash bank, but I am unlikely to be needing that for some time.

We have a variety of SRAM available. I will be needing some pretty soon for my first examples and there are two areas I am inclined to use.

0x2400_0000 to 0x2407_ffff -- AXI SRAM, 512k

0x3000_0000 to 0x3001_ffff -- SRAM1 - 128K
0x3002_0000 to 0x3003_ffff -- SRAM2 - 128K
0x3004_0000 to 0x3004_7fff -- SRAM3 - 32K
I see no reason not to simply use AXI ram, but the other area at 0x3000_0000 is a contiguous 288K regions.

OpenOCD and flash

We can run OpenOCD then use "telnet localhost 4444" to connect to it. Don't run both in the same window or you will get confusing output both from OpenOCD and from the telnet connection.

I use the following script (named "ocd") to start openocd:

#!/bin/sh

IF=/usr/share/openocd/scripts/interface/stlink.cfg
TG=/usr/share/openocd/scripts/board/stm32h747i-disco.cfg
echo $IF
echo $TG
CMD="openocd -f $IF -f $TG"
echo $CMD
$CMD

Once this is going, we can try commands like these:

targets
flash banks
flash read_bank 0 firmware.bin 0 0x10000
flash read_bank 0 firmware.bin 0 0x10000
flash read_bank 0 firmware2.bin 0 0x100000
flash read_bank 1 firmware3.bin 0 0x100000
flash write_image erase blink.bin 0x08000000
Here we go:
> targets
    TargetName         Type       Endian TapName            State
--  ------------------ ---------- ------ ------------------ ------------
 0* stm32h747xih6.cpu0 hla_target little stm32h747xih6.cpu  running

> flash banks
#0 : stm32h747xih6.bank1.cpu0 (stm32h7x) at 0x08000000, size 0x00000000, buswidth 0, chipwidth 0
#1 : stm32h747xih6.bank2.cpu0 (stm32h7x) at 0x08100000, size 0x00000000, buswidth 0, chipwidth 0
#2 : stm32h747xih6.qspi (stmqspi) at 0x90000000, size 0x00000000, buswidth 0, chipwidth 0

> flash read_bank 0 firmware.bin 0 0x10000
Info : Device: STM32H74x/75x
Info : flash size probed value 2048k
Info : STM32H7 flash has dual banks
Info : Bank (0) size is 1024 kb, base address is 0x08000000
wrote 65536 bytes to file firmware.bin from flash bank 0 at offset 0x00000000 in 0.545259s (117.375 KiB/s)

> flash read_bank 0 firmware2.bin 0 0x100000
wrote 1048576 bytes to file firmware2.bin from flash bank 0 at offset 0x00000000 in 8.706150s (117.618 KiB/s)

> flash read_bank 1 firmware3.bin 0 0x100000
Device: STM32H74x/75x
flash size probed value 2048k
STM32H7 flash has dual banks
Bank (1) size is 1024 kb, base address is 0x08100000
wrote 1048576 bytes to file firmware3.bin from flash bank 1 at offset 0x00000000 in 8.698663s (117.719 KiB/s)
All of these images of ffff ffff .... The flash is blank, nothing has yet been stored there.
Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org