ARM versus Thumb

Hi

I’m using a STM32H723ZG on a Nucleo-H723ZG board.
I’m able to compile, and debug but the programs crashes into the HardFault_handle when executing the clib_init_array library function, called from the ARM initialization code.

The instruction that causes the crash is below with a → mark.

0x080041a0: 70 b5 push {r4, r5, r6, lr}
→ 0x080041a2: 0d 4e ldr r6, [pc, #52] ; (0x80041d8 <__libc_init_array+56>)
0x080041a4: 0d 4c ldr r4, [pc, #52] ; (0x80041dc <__libc_init_array+60>)
0x080041a6: a4 1b subs r4, r4, r6

I think this is related with ARM versus Thumb instruction set.
I think the clib_init_array function that the PlatformIO linker is picking-up is for an ARM instruction set whereas the Cortex-M7 only supports the Thumb instruction set.

Anyone has ideas how to solve this? PlatformIO.ini is below. thanks

======================================

[platformio]
#core_dir = ../platform_dir
#platforms_dir = ../platform_dir
#packages_dir = ../platform_dir
#Swap these around to debug different targets
default_envs = env_nucleo_h723zg

[env]
check_tool = cppcheck
check_flags =
    cppcheck: --std=c11 --inline-suppr --inconclusive -j4 --addon=../../scripts/misra/misra.json

[env:env_nucleo_h723zg]
;platform = ststm32@8.0.0
platform = ststm32
board = nucleo_h723zg
framework = stm32cube
src_filter = +<*> -<.git/> -<target/> -<native/>
build_flags =
  -mthumb
  -mfpu=fpv4-sp-d16
  -mfloat-abi=softfp
  -DEVAL
  -DSTM32H723xx
  -I include
  -I src
  -I src/Core/Inc
  -I src/Drivers/CMSIS/Include/
  -I src/Drivers/CMSIS/Device/ST/STM32H7xx/Include/
  -Wl,--whole-archive
  -Wl,--allow-multiple-definition
upload_protocol = stlink
debug_tool = stlink
debug_init_break = tbreak main

No, per decoder the instruction code 0d 4e is Thumb, and not valid ARM.

__libc_init_array is a function that calls into global constructors (see e.g. here), usually from statically and globally constructed C++ objects which have a constructor function in their class.

I see these possibilities:

  • you don’t link properly against the library containing __libc_init_array (which should be libc) and the function results in a crash because that’s a nullptr or something
  • a constructor called inside the __lib_init_array function is crashing
  • entire different issue, e.g., the previous push instructions hardfaulted the processor because the stack was not setup correctly (e.g., initial SP beyond the bounds of RAM). That was e.g. a bug in a recent platform version in combination with a wrong “RAM size” value in the board definition.

Can you further specify whether it is crashing inside the __libc_init_array function (make sure to switch to assembly mode in the debugger and do a stepi to step into instruction-wise) and whether you are using C++ code in your project? Does this appear with the simplest possible code too, an empty main function?

Hm, regarding this, PlatformIO has

So 432 kByte of RAM. If an automatic linker script generation is in place it’ll set the initial SP to 0x2000000 (RAM start) plus the amount of RAM. However, if the RAM is not continuous in the memory map, that’ll again lead to the issue described above. And as I read in the reference manual

that might be the case.

What happens when you add

board_upload.maximum_ram_size = 131072

to the platformio.ini? Does it go beyond the push and ldr instruction then into main()?

It crashes in the 2nd instruction of clib_init_array

clib_init_array:
0x080041a0: 70 b5 push {r4, r5, r6, lr}
→ 0x080041a2: 0d 4e ldr r6, [pc, #52] ; (0x80041d8 <__libc_init_array+56>)

Instruction ldr 56, [pc, #52] opcode 0d 4e

The SP is initialized with the value of 0x2006C000

This seems to be reserved RAM!

Any ideas how to correct this? :slight_smile:

You tried this here?

I have added it here:

[env:env_nucleo_h723zg]
board_upload.maximum_ram_size = 131072
platform = ststm32
board = nucleo_h723zg
framework = stm32cube
src_filter = +<*> -<.git/> -<target/> -<native/>
build_flags =
  -mthumb
  -mfpu=fpv4-sp-d16
  -mfloat-abi=softfp
  -DEVAL
  -DSTM32H723xx
  -I include
  -I src
  -I src/Core/Inc
  -I src/Drivers/CMSIS/Include/
  -I src/Drivers/CMSIS/Device/ST/STM32H7xx/Include/
  -Wl,--whole-archive
  -Wl,--allow-multiple-definition
upload_protocol = stlink
debug_tool = stlink
debug_init_break = tbreak main

But still gives the same SP value 0x2006C000

PlatformIO caches the generated linkerfile. Delete C:/Users/<user>/.platformio/packages/tool-ldscripts-ststm32/stm32h7/STM32H723ZG_DEFAULT.ld and re-upload the project.

Well done, It worked. Another bug bites the dust :slight_smile:

This issue is now tracked in Nucleo-H723ZG board crashes on startup because of incorrect RAM size · Issue #563 · platformio/platform-ststm32 · GitHub so that it may be solved at the root.