cancel
Showing results for 
Search instead for 
Did you mean: 

CubeIDE - How can I Debug Step into functions located in ITCM?

David George
Associate III

I have a STM32H730 Project, using CubeIDE V1.17.0. Code executing from the internal Flash.

I have located some functions into ITCM,

  • added a new .itcram section to the linker LD file
  • added __attribute__((section(".itcram"))) to my functions I want in ITCM
  • at startup I copy from FLASH to ITCM 

This builds and runs okay, the functions in ITCM execute as expected.

But, I can't Debug Step into any function located in ITCM, it just steps over the function.

I can set a breakpoint in a ITCM function, but it never halts there, just ignores the breakpoint.

 

How can I step into functions located in ITCM?

Do I need to tell GDB that I have instruction code in ITCM?

 

Thanks.

 

3 REPLIES 3
Mike Rosing
Associate III

I have exactly the same problem with V2.1.1 on STM32H7S3. The debugger does not halt at main which is the default operation and when I press "pause" it shows the correct location and disassembly in ITCM. All breakpoints are ignored, and the code breaks somewhere because pressing the user button causes the code to go to Default_Handler. I'm using the ST-LINK(OpenOCD) 

I have flipped the Option Bytes so all of RAM is in ITCM and DTCM.  The debugger reports

Error: Failed to read memory at 0x24000000
Warn : no working area available, can't do block memory writes
Warn : couldn't use block writes, falling back to single memory accesses
Warn : keep_alive() was not invoked in the 1000 ms timelimit. GDB alive packet not sent! (5486 ms). Workaround: increase "set remotetimeout" in GDB
[STM32H7S3L8Hx.cm7] halted due to breakpoint, current mode: Thread 
xPSR: 0x01000000 pc: 0x0800100c msp: 0x20030000

I then changed ITCM option to 1 so it is 128K ITCM and 64K SRAM1, and it still says

Error: Failed to read memory at 0x24000000
Warn : no working area available, can't do block memory writes

Address 0x24000000 is supposed to be SRAM1 - so why can't the debugger see it? If the debugger needs that specific RAM to be able to set breakpoints, I can see why things don't work. What more do I need to do to turn it on?

Edit: I set ITCM to 64K with SRAM1 128K and got rid of the memory read problem. But it still wont halt at break points or main on first load. Does that mean the ST-LINK debugger does not work with ITCM, so debug from FLASH, then once it works copy up to ITCM?

Mike Rosing
Associate III

For anyone else who has this problem - I have made some progress.  I tried several things, but I think the main mistake I fixed was the ISR vector table. I used the stm32h7x3_cpu_perf example code including the file startup_stm32h743xx_ITCM.s which copies FLASH to ITCM. What I just figured out the hard way is that this is for a different processor entirely, and the ISR vector table is NOT the same as the stm32h7S3xx processors. Replacing the vector table with those from the sample file startup_stm32h7s3l8hx.s allows the debugger to step through main() while main() resides in ITCM. It does not halt at main on starting the debugger. Nor does it stop at breakpoints set at various places.  Except that sometimes it does at what seems to be random times while attempting to step after a pause.

Also randomly it says I'm out of hardware breakpoints when I set the cursor on a line of code and say "run to line". Most of the time it works, but sometimes it stops at random places instead of the line requested.

I have created an ISR vector block in ITCM from 0x000 to 0x400 (which I called .ITCMVector in the .ld file). In main, I created a duplicate of the ISR vector table from startup as data and referenced the functions as prototypes. I changed the reset location (0x0004) to main(). The startup code copies this block to the ITCM section, then copies all the code from FLASH to ITCM. Before calling main I execute SCB->VTOR = 0x00000000;  The EXTI interrupt gets called correctly - but I usually cannot break inside the interrupt.

This is orders of magnitude better than not working at all, but the OP's question is still valid - why does the debugger not stop at breakpoints in the ITCM?

I posted this same question to Embedded Related and got an answer which combines a few other comments on this topic and adds some new suggestions:

1. Check where the ITCM RAM starts in your linker script if you haven't done it already.
It can point to 0x4000. Not 0x0000 - a NULL Pointer.
2. What is the Debugger Reset Behavior configured as?
In STM32CubeIDE, navigate to Debug Configuration > Debugger tab > Reset behavior: Set it to None
3. Is it a Debug Build and Not a Release Build?
4. If you are here, make sure you do a Full Chip Erase using STM32CubeProgrammer
5. Single stepping will not allow your code to run.
Use break points strategically based on your needs.
6. For the onboard STLink, sometimes USB-C cables are a problem. A - C cables are helpful.
7. If you change the cable, starting from #4 will help

My computer is brand new, so changing the cable made no difference. But I think the full erase did change something because the code now halts at break points in ITCM. It is flaky on F6 or F5 - but it works most of the time. On occasion is reports out of break points so it can't "run to line", but then I try again and it works.

So the answer is YES - the debugger will halt at break points. Just not at main() after reset (or any break point after reset). You have to pause, set break points, then go and it will halt in ITCM code.