cancel
Showing results for 
Search instead for 
Did you mean: 

OpenOCD reset command

DietWall
Associate III

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

monitor reset halt
before Flashing the firmware, The result is as described above
 
 
Manually typing:
monitor reset init

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

16 REPLIES 16
TDK
Super User

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.

If you feel a post has answered your question, please click "Accept as Solution".
Pavel A.
Super User

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.

 

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 3333

 I 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. 

The main thing is it needs to start at Reset_Handler. The code will be compiled with the correct calls to initialize things.

If you feel a post has answered your question, please click "Accept as Solution".
DietWall
Associate III

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:

volatile int random_variable = 1337;
 
Looking at the startup code. I guess the symbol LoopCopyDataInit (Lines 73-81) is responsible for loading the correct values into the globals. Or provide the addresses to the  __libc_init_array. Which then copies the data from Flash to RAM. 
__libc_init_array is located inside newlib. 
 
And one more observation: SystemCoreClock is set to 30MHz after SystemClock_Config(). But inside generated Code it is already used in
HAL_Init()->HAL_InitTick(TICK_INT_PRIORITY);
I tried to call HAL_InitTick again after SystemClock_Config(). But the effect was still the same.
 
What is still confusing to me, is why this initialization sometimes works and sometimes not. This should not change, if I am connected with openocd or not. So maybe there are actually 2 issues to solve.
 
I will debug the same startup procedure from STM32CubeIDE and see, if there ís something different. And more specifically, when SystemCoreClock is initialized.
 
And I could load the binary into STM32CubeIDE environment, by doing so, I could identify whether it is a debugger or a linker error.
DietWall
Associate III

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.

 

 

DietWall
Associate III

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...