Is PIO compatible with rom images that do not start at the mcu default address?
I have a no-framework PIO project. I’ve brought all the files in on my own from STM32CubeIDE. I can get into debugging and step over code.
Relavent .ini:
[platformio]
description = Application
src_dir = .\code
include_dir = .\code\sys\core\Inc
lib_dir = .\lib
[env:h743vi]
platform = ststm32
board = h743vi_splitbank
extra_scripts = pre:add_hardfloat_to_build.py
board_build.ldscript = ./code/sys/STM32H743VIHX_FLASH.ld
build_flags =
-DDEBUG
-DUSE_HAL_DRIVER
-I<INCLUDES SNIPPED>
build_src_filter =
+<*>
-<./sys/drivers/CMSIS/Device/ST/STM32H7xx/Source/Templates/*>
build_type = debug
debug_tool = jlink
upload_protocol = jlink
The mcu rom starts at 0x80000000. The linkerscript is adjusted to start the rom at 0x80200000, making a sector reserved for bootloader (not programmed yet).
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 768K
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
The vector table is adjusted at the start of main()
int main(void)
{
SCB->VTOR = 0x08020000;
The first load of PIO Debug works.
There is a hang and a crash on subsequent reloads using the Reset
or CTRLSHIFTF5 shortcut.
I had a similar issue with STM32CubeIDE that always tried to reset to 0x80000000 and would work about 50% of the time. At least STM32CubeIDE would show me processor was in hardfault.
I suspect hitting reset() puts the mcu to 0x80000000 where it hard faults and hangs. PIO shows me nothing.
I am not certain why the initial load settings are different from reset settings. Is there a way to fix this behavior?
EDIT: It is a custom board, same as the WeArt STM32H743, only difference is I cut the rom down to a number I can actually use to show a correct percentage used on building.
EDIT2: I see in builder/main.py for Jlink:
elif upload_protocol.startswith("jlink"):
def _jlink_cmd_script(env, source):
build_dir = env.subst("$BUILD_DIR")
if not isdir(build_dir):
makedirs(build_dir)
script_path = join(build_dir, "upload.jlink")
commands = [
"h",
"loadbin %s, %s" % (source, board.get(
"upload.offset_address", "0x08000000")),
"r",
"q"
]
Seems like code to start at the correct address. Is it possible that the reset() does not have similar thinking and just resets to default/0x80000000?
EDIT3: I’ve called it reset, but the actual command seems to be restart.
EDIT4: I’m not great at Python or JS, but it seems to me that VSCode specifically sends the reset event to PIO Core and then it either turns into a straight JLink command or GDB (more likely?). So maybe I can find a partial solution in GDB (or OpenOCD?), but then I still need to know how this command works and if it’s possible to customize the data sent.