Skip to main content
VYoun
Associate III
February 13, 2020
Solved

stm32h7 dtcm ram overflowed

  • February 13, 2020
  • 13 replies
  • 4806 views

Hello,

I am relatively new in this field, and need assistance for my project at work.

Recently, in order to have more RAM, I switched from STM32F4 to STM32H7.

I saw that STM32H7 has 1MB of RAM, and decided to base our system on this MCU.

However, after compiling my code, I see that only DTCM RAM is used by the MCU and others are not used.

The DTCM RAM is now full and I can not move any further with my code.

How can I make use of RAM_D1 or RAM_D2 for my variables?

I am using CubeMX and Atollic Truestudio.

Please kindly help me as this is vital for my work. Any help is greatly appreciated.

This topic has been closed for replies.
Best answer by alister

Despite its name, this link describes your situation: https://community.st.com/s/article/FAQ-DMA-is-not-working-on-STM32H7-devices.

Find your linker script (file with .ld extension). If there's more than one or you're not sure, open Tool Settings and navigate to the "General" leaf of "C Linker". The path of the linker script there is relative your build directory.

Read https://sourceware.org/binutils/docs/ld/Scripts.html#Scripts to learn its syntax.

Blocks and sizes of memory vary. Read RM0433 to learn how memory's arranged for your part and populate your MEMORY regions accordingly. As example, these are the blocks from my STM32H7 project's linker script:

MEMORY
{
 ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
 DTCMRAM (rw) : ORIGIN = 0x20000000, LENGTH = 128K
 AXI_SRAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
 SRAM1_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 128K
 SRAM2_D2 (xrw) : ORIGIN = 0x30020000, LENGTH = 128K
 SRAM3_D2 (xrw) : ORIGIN = 0x30040000, LENGTH = 32K
 SRAM4_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
 BACKUP_SRAM_D3 (rw) : ORIGIN = 0x38800000, LENGTH = 4K
 
<snip>
}

Probably you should move .data, .bss, heap (if you have any) and stack or initial stack (depending whether you're bare-metal or OS) to the region corresponding the one I've named AXI_SRAM_D1.

In that first link, there's discussion too about placing objects at specific memory locations. That's not pertinent yet. When you come to it though, read about the section attribute at https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#Common-Variable-Attributes.

13 replies

alister
alisterBest answer
Senior III
February 14, 2020

Despite its name, this link describes your situation: https://community.st.com/s/article/FAQ-DMA-is-not-working-on-STM32H7-devices.

Find your linker script (file with .ld extension). If there's more than one or you're not sure, open Tool Settings and navigate to the "General" leaf of "C Linker". The path of the linker script there is relative your build directory.

Read https://sourceware.org/binutils/docs/ld/Scripts.html#Scripts to learn its syntax.

Blocks and sizes of memory vary. Read RM0433 to learn how memory's arranged for your part and populate your MEMORY regions accordingly. As example, these are the blocks from my STM32H7 project's linker script:

MEMORY
{
 ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
 DTCMRAM (rw) : ORIGIN = 0x20000000, LENGTH = 128K
 AXI_SRAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
 SRAM1_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 128K
 SRAM2_D2 (xrw) : ORIGIN = 0x30020000, LENGTH = 128K
 SRAM3_D2 (xrw) : ORIGIN = 0x30040000, LENGTH = 32K
 SRAM4_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
 BACKUP_SRAM_D3 (rw) : ORIGIN = 0x38800000, LENGTH = 4K
 
<snip>
}

Probably you should move .data, .bss, heap (if you have any) and stack or initial stack (depending whether you're bare-metal or OS) to the region corresponding the one I've named AXI_SRAM_D1.

In that first link, there's discussion too about placing objects at specific memory locations. That's not pertinent yet. When you come to it though, read about the section attribute at https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#Common-Variable-Attributes.

VYoun
VYounAuthor
Associate III
February 25, 2020

I was reading my linker file more carefully, and realised that mine has no AXI_SRAM_D1.

Instead I have SRAM_D1 which is 512k, could this be the reason why my code stops working when I bring .bss, stack, and data to SRAM_D1?

Thank you in advance for your help.

Best regards,

Vouria

alister
Senior III
February 25, 2020

Atollic TrueSTUDIO uses GNU toolchain. GNU linker is described at https://sourceware.org/binutils/docs/ld/index.html. GCC compiler is described at https://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html. These links are their head doc versions. TrueSTUDIO 9.3.0 uses "GCC 6.3.1 20170215 + patches" and "Binutils 2.27.90.20170215". If you hunt around a bit you'll find earlier version docs closer to your tools. But these'll serve for most matters.

>mine has no AXI_SRAM_D1.

The question is quickly answered in the section in the linker doc about the MEMORY command.

>my code stops working when I bring .bss, stack, and data to SRAM_D1

It'd be much easier to help if you provided more details. In no particular order...

  1. Where does it stop working?
  2. How does it stop working?
  3. What version of TrueSTUDIO are you using?
  4. Did you create the project with Cube?
  5. What version of Cube?
  6. Other observations?
  7. Guesses?

A general practice for debugging...

  1. Execute until it fails. Glean details from the machine state (registers, variables, memory, etc), to learn e.g. where has it executed to, what is the nature of the fail. For hard faults I Googled and found https://www.youtube.com/watch?v=E52v1p6CN5A about TrueSTUDIO's Fault Analyzer. I haven't viewed this one. If it's no good, Google another.
  2. Set a breakpoint somewhere earlier and step closer to the fail location and confirm, e.g. by inspecting yours and GCC's and ST's code, the prerequisites are met, and events are consistent with states, etc.
  3. If the fail is more complex, instrument the code, e.g. add static-storage-class variables (globals) to store details that you can check after the fail, or add printfs if you've implemented ARM ITM or other mechanism for standard output (and there's not much output, as if you overrun this it'll probably be ineffecive), to understand the path of execution.
  4. If the fail is more complex, find some unused pins, turn them into outputs and wire them to a CRO to show the path of execution, critical timings, decisions, etc.

VYoun
VYounAuthor
Associate III
February 14, 2020

Thank you very much for your answer, it was really helpful.

I used the link that you mentioned and could bring everything into SRAM_D1, but my program stopped working after that.

I think the variables are not recognised anymore.

I am really confused.

Ozone
Principal
February 14, 2020

> I used the link that you mentioned and could bring everything into SRAM_D1, but my program stopped working after that.

Not every RAM is the same.

Some regions are unreachable by DMA. Some are not regions are not connected to the I-Bus (e.g. DTCMRAM (rw)).

You might need to review the datsheet / Reference manual.

Perhaps re-thinking your application, and memory layout.

Eliminate unused data storage, reducing buffer sizes and operate on less data on-the-fly.

And last but not least, compiler optimization options.

VYoun
VYounAuthor
Associate III
February 14, 2020

Thank you very much for your reply.

I am not using DMA in my application.

I think I need to go through the reference manual to learn which blocks are connected to each RAM area.

I will use your suggestions, thank you again.

Best regards,

Vouria

Ozone
Principal
February 14, 2020

And don't forget to review the map file.

Your heap/stack might be oversized.

VYoun
VYounAuthor
Associate III
February 17, 2020

Thanks everybody for your suggestions. I will go through the application note and reference manual.

But just to briefly confirm, I can only make use of the DTCMRAM for my code, is that true?

Your help is greatly appreciated, since I am under time pressure for my project.

Best regards,

Vouria

alister
Senior III
February 18, 2020

> I can only make use of the DTCMRAM for my code

See AN4891.

In your question, you had everything in DTCMRAM. As your app grew, it became full.

Normally you'd reserve DTCM-RAM for critical data and move .bss/.data/heap to AXI-SRAM as they grow too large. To place critical data in AXI-SRAM you'd use GCC's section attributes and suitable changes to your linker command file.

I see my earlier post incorrectly said don't use D1. Sorry I meant don't use DTCM-RAM. I'll edit that.

VYoun
VYounAuthor
Associate III
February 18, 2020

Hello,

Thank you very much, I will go through the document and will ask if there are any questions.

I tried to use D1 using the linker commands, and I succeeded. But then my program stopped working.

I think I need to go through the reference manual and the AN4891 to figure out how to use D1 correctly, so that the program does not stop working.

Best regards,

Vouria

VYoun
VYounAuthor
Associate III
February 26, 2020

Hello,

Thank a lot for this complete answer. I will go through the links regarding the GNU linker and the GCC compiler. These are very good to learn, in order to improve my knowledge. I am using TrueSTUDIO 9.3.0.

Thanks very much for the suggestions regarding debugging, and fault finding in the code. These are very useful for me, cause I am really new in this field, and normally under much pressure from my work cause I do not yet know my way around things.

Yesterday, I used the memory map and the suggestions here to make changes in the linker file. I brought .bss to the RAM_D1 and left the rest as it is. Now the program is working fine.

I think the problem was that I brought heap and stack into the RAM_D1. Now I left heap and stack to be in DTCMRAM.

Thank a lot for your help.

Best regards,

Vouria