2025-12-28 3:00 AM - edited 2025-12-28 3:01 AM
Hello,
I am using a custom environment for development and debugging for NUCLEIO-STM32F767ZI.
It is based on a custom devcontainer, VSCode and gdb-multiarch. On the server side I have OpenOCD, running on a ubuntu 24.04 PC. This is connected via USB to the board. The Board itself is not changed in any way, maybe I changed jumpers at some point, I would need to check this if this might effect the behavior.
The first connection after Powerup works always as expected, the Firmware is flashed and works as expected.
If I rebuild the project or flash the firmware again, the MCU is in some kind of undefined state.
Calls to different HAL functions fail, return Errors. As some return values are not verified within the generated calls, I don´t see the errors immediately, but very late during debugging. Missing interrupts as an example. The code is a simply generated STM32CubeMX project, without any changes. I am using only GPIOs and Systick interrupt so far.
I need the right Reset command for OpenOCD BEFORE or AFTER Firmware flashing.
According OpenOCD documentation, this depends on the board and how STLink is wired to the MCU.
Does anyone has experience on such a setup and have some tipps for the correct Reset command.
And which type of Reset is used inside STM32CubeIDE? Is there a way to retrieve any Logs from GDBServer and GDB inside STM32CubeIDE? If I try to connect STM32CubeIDE to OpenOCD, it fails with something like: This is not a STM32 Chip.
If I plug the board into my Windows PC, everything works as expected. But I want to use my Ubuntu PC for debugging and Development.
I tried to use
shows also the same, The chip restarts with initialization, but the errors are still there.
Inside OpenOCD are also commands like:
monitor soft_reset_halt
But they are refused by openocd with:
[stm32f7x.cpu] requesting target halt and executing a soft reset
Target stm32f7x.cpu does not support soft_reset_halt
I do not have further configuration in OpenOCD beside the delivered scripts for initialization. My openocd startup arguments look like this:
-f /usr/share/openocd/scripts/interface/stlink.cfg -f /usr/share/openocd/scripts/target/stm32f7x.cfg -f /home/<user>/openocd.cfg.
openocd.cfg contains only: bindto 0.0.0.0
I know, that there are STM32 Extensions for VSCode, But in the Videos I saw, they used a direct USB connection.
I want OpenOCD to be available on my network.
Thanks in Advance and Best Regards.
Dietrich
Solved! Go to Solution.
2025-12-28 5:42 PM
Looks like the debugger isn't set up correctly. Maybe it's not initializing things correctly, maybe it's not flashing correctly. If you can reset the chip and trace through starting at Reset_Handler, might be able to see something. Weigh the benefit of going a non-standard route vs using the VSCode default working debug configuration.
2025-12-28 5:43 PM - edited 2025-12-28 5:45 PM
Before main() the program executes the (assembly) startup function Reset_Handler that should re-initialize static variables such as SystemCoreClock. It *should* be correct at main() entry. Make sure you arrive at the Reset_Handler.
2025-12-28 11:19 PM - edited 2025-12-28 11:36 PM
Yes, I´m also thinking that this is the correct approach right now.
I will try to setup a breakpoint, that halts the execution, whenever this variable changes or observe its value during single stepping.
I don´t know enough yet about the static initialization routines. Which calls in arm-gcc and newlib(-nano) should initialize the correct values in static variables?
And after reading through the messages again, There is an openocd setup integrated into STM32CubeIDE. I created a debug configuration for local USB debugging. It created a full initialization script for me :)
It looks like this: (I removed some comments)
source [find interface/stlink-dap.cfg]
set WORKAREASIZE 0x8000
transport select "dapdirect_swd"
set CHIPNAME STM32F767ZITx
set BOARDNAME NUCLEO-F767ZI
set ENABLE_LOW_POWER 1
set STOP_WATCHDOG 1
set CLOCK_FREQ 8000
reset_config srst_only srst_nogate connect_assert_srst
set CONNECT_UNDER_RESET 1
set CORE_RESET 0
set AP_NUM 0
set GDB_PORT 3333I can't test it right now, whether this script works locally. But this are the type of commands I was looking for initially.
That Kudos Button is not big enough. :) @Pavel A.
2025-12-29 5:51 AM
The main thing is it needs to start at Reset_Handler. The code will be compiled with the correct calls to initialize things.
2025-12-29 7:52 AM - edited 2025-12-29 8:13 AM
I found little time for debugging.
After starting/restarting the debugging session my code lands at the Reset Handler, first instruction is:
Reset_Handler:
ldr sp, =_estack /* set stack pointer */
Reset Handler itself should be just an instruction address, loaded to the Reset Vector. And the ldr instruction is the first one to execute.
So this should be fine from my understanding.
On the other side, the static initialization is definitevely not happening. I introduced some more global integers and they keep their random value from the beginning.
&SystemCoreClock = 0x20000074
*&SystemCoreClock = 1177051676
&random_variable = 0x2000006c
*(&random_variable) = 537079928
C-Declaration looks like this:
2025-12-29 10:38 AM - edited 2025-12-29 10:39 AM
Ok, after debugging both versions, I can conclude. it is some kind of a compilation/linking error.
I will compare all compile/linker flags from my environment to STMCubeIDE in the next days.
The initialization of globals is in fact between Lines 73-81. The values in STMCubeIDEs application are copied in this lines from FLASH to RAM. My application behaves with STMs OpenOCD very similarly to my Linux OpenOCD environment. SystemCoreClock is not initialized at beginning of main.
STMCubeIDEs version is working as expected.
2025-12-30 3:03 PM - edited 2025-12-30 3:19 PM
Found it,
I have been using the wrong linker script.
For some reason, STMCubeMX generated 2 linker scripts: <device>_FLASH.ld and <device>_RAM.ld.
What I did, was just to copy both linker scripts into my build environment and writing this into my cmake files:
target_link_options(${PROJECT_NAME}
PUBLIC "-TSTM32F767ZITX_FLASH.ld"
PUBLIC "-TSTM32F767ZITX_RAM.ld"
PUBLIC "-Wl,-Map=${PROJECT_NAME}.map"
#export map after linking, still required for debugging
)There were some warnings at the beginning of development, because some sections were defined twice. So instead of really taking care of this warning, I just commented the second definition in RAM.ld out. (I guess gcc takes the second linker script, if 2 are given?)
Because of that, the variable _sidata (I guess an abbreviaton for: Statically Initialized DATA) in the startup_<device>.s file was not properly linked.
So therefore the underlying array had a length of 0, and no data was copied from FLASH to RAM.
The linking command from CubeIDE includes only the flash linker script.
My Linux OpenOCD works actually good enough now without any changes. But I am still wondering why it has been working sometimes...