cancel
Showing results for 
Search instead for 
Did you mean: 

H7A3 - Code not loaded into ITCM-RAM

CBerg
Senior

Hi all,

i have an issue with an STM32-H7A3, which is going into hard fault, when calling a function, which is moved to the ITCM-RAM.

I have defined a section for ITCM-RAM in the Linker-Script:

 

 

_siitcmram = LOADADDR(.itcmram);	/* size of ITCM-RAM */

.itcmram : {			/* ITCM-RAM Section */
	. = ALIGN(4);		/* Alignment: 4 Bytes - "Word" - u32 */
	_sitcmram = .; 		/* define a global symbols at itcmram start */
	*(.itcmram)
	*(.itcmram*)
	. = ALIGN(4);
	_eitcmram = .; 		/* define a global symbols at itcmram end */
} >ITCMRAM AT> FLASH	/* reseve memory in flash for this section */

 

 

I copy the code from the flash to the ITCM-RAM in the startup

 

 

// BEGIN MODIFICATION - STM-CubeMX Code above

  /* Copy from flash to ITCMRAM */
  ldr r0, = _sitcmram		// start: itcmram start
  ldr r1, = _eitcmram		// end: itcmram end
  ldr r2, = _siitcmram		// size
  movs r3, #0
  b LoopCopyCCMInit

CopyCCMInit:
  ldr r4, [r2, r3]
  str r4, [r0, r3]
  adds r3, r3, #4

LoopCopyCCMInit:
  adds r4, r0, r3
  cmp r4, r1
  bcc CopyCCMInit
/* End of copy to ITCMRAM */

// END MODIFICATION  - STM-CubeMX Code below

 

 

basically the code above is just a "Copy & Paste" of the section above, where the data get copied from Flash to RAM. I Just edited the names and symbols.

I got the same ruinning - with the same functions - in a Test Project without any issues. The only issue I had at the beginning in the test project was, that I did not copy the code from flash to the ITCM-RAM, but when I did that it worked as intended.

But in this case i can litterally see, that somthing is wrong, because when I step through my code in the debugger, I can not jump (with "step into (F5)") into the function. The debugger simply steps over and quickly goes into hard fault. So my asumption is: for some reason the code is not copied into the ITCMRAM, and the copied functions seem to have the address 0x00 - which is the reason why it goes into hard fault quickly.

Obviously I am missing something. But I don't know what. Can anyone help me out?

Additional Info:

In the CubeIDE Memory Details, I can see the code that should be in the ITCM-RAM is allocated in the ITCM-RAM. There is also a ITCM-RAM section in the flash, where the code that gets copied is stored.

4 REPLIES 4

thanks for the input. It's a nice tutorial to explain how to use the ITCM-RAM.

If it is your tutorial I have 2 comments: 
a) typo the 3rd line, the ITCM RAM has 16 kB not 16 MB

b) i wonder how the tutorial works without copying the flash contents into the ITCM-RAM? AFAIK this is "mandatory" to copy the ITCM-Code from the Flash into the ITCM-RAM at the startup ...

but I used your input to check the Memory in the Memory Viewer. And the result is: the whole ITCM-RAM starting at 0x00 seems to be full with random data. This means my code in the startup script somehow has no effect. The same code is working in another project on the same Nucleo, and I wonder why it works in one build but not in another? Thats weird ...

I don't have a H7 device, nor I'm really experienced with this variants.
However, two points you might consider.


First, I assume the code you copy is linked for this address, or PIC.


And second, the issues might be related to clock / system setup. I had similiar issues with external RAM, which is of course a different matter.
But perhaps you can try to copy the code after the setup.


Another possible reason might be the MPU, if you use it in your application.

Thanks @Ozone 

what do you mean with


First, I assume the code you copy is linked for this address, or PIC.


What I do is:

if I have e.g. the function void MyFunction(void) and I want this function to run from the ITCM-RAM, I take the following steps:

a) i create a symbol for the ITCM-RAM in the linker file - as described in my initial post

b) I add code to the startup_stm32xxxxx.s file - as shown in my initial post - that copies the code from the flash memory to the ITCM-RAM at startup

c) I add a __attribute__((section(".itcmram"))) to the function, e.g.

__attribute__((section(".itcmram"))) void MyFunction(void) {
   do_some_stuff();
}

and this works normaly. It just won't work in my current project. So I wonder if I forgot something or whatever it might be? It also looks like the startup_stm32xxxx.s does not get compliled every time?

I assumed It might be I had to declare variables for the symbols created in the linker file, because those exists for the other symbols from the linker file:

/* start address for the initialization values of the .data section. 
defined in linker script */
.word  _sidata
/* start address for the .data section. defined in linker script */
.word  _sdata
/* end address for the .data section. defined in linker script */
.word  _edata
/* start address for the .bss section. defined in linker script */
.word  _sbss
/* end address for the .bss section. defined in linker script */
.word  _ebss
/* stack used for SystemInit_ExtMemCtl; always internal RAM used */

so I created .word entries for _siitcmram, _sitcmram and _eitcmram. But that did nothing first. But after a "Project Clean" it lead to a hard fault, even before the first breakpoint in the main.c was reached. After I removed them, cleaned the project, recompiled and started it again, the issue was gone ...

Is there anyone out there who could write me a few lines of assembler, that fill the ITCM-RAM with zeros? I have no assembler skills, I don't know how to do that.

I want to fill the ITCM with zeros (or 0xff, whatever) so I can check in the Memory Viewer, if the init code is working. ATM I can only compare the contents of the memory from Project A (working) and Project B (hard fault) and the look the same. But It is just a bunch of hex values, so it's hard to tell if it is correct or not ...